#include <vga.h>
#include <stdlib.h>

#include "sintab.h"

#define S() (srand48(getpid()))
#define R(x) (drand48()*x)

#define NOSHOW (4)
#define XSIZE (320/XMAG)
#define YSIZE ((200/YMAG)+NOSHOW)
#define XMAG (8)
#define YMAG (8)
#define MOVE (2)
#define CMOVE (4)
#define SPOTS (8)

int spots[6][SPOTS];
char line[XSIZE*XMAG*3];

int world[YSIZE][XSIZE][3][2];
#define W(x,y,z) (world[y][x][z][f])
#define O(x,y,z) (world[y][x][z][1-f])

frame() {
	static int f=0;
	int x,y,xx,yy,i,j,k,c[3];
	unsigned char *lp;


	f=1-f;
	yy=0;
	for(i=0;i<3;i++) for(j=0;j<SPOTS;j++) O(spots[3][j],YSIZE-2,i)+=spots[i][j];
	for(y=0;y<YSIZE;y++) {
		lp=line;
		for(x=0;x<XSIZE;x++) {
			for(i=0;i<3;i++) {
				if((y==0)||(x==0)||(y==(YSIZE-1))||(x==(XSIZE-1))) W(x,y,i)=0;
				else if(y==(YSIZE-2)) {
					W(x,y,i)=0;
					for(j=0;j<SPOTS;j++) if (spots[3][j]==x) W(x,y,i)+=spots[i][j];
				}
				else W(x,y,i)=(
					O(x-1,y,i)+O(x-1,y+2,i)+O(x+1,y,i)+O(x+1,y+2,i)+
					O(x,y+2,i)+O(x,y,i)+O(x-1,y+1,i)+O(x+1,y+1,i))
					/8-3;
				if (W(x,y,i)<0) W(x,y,i)=0;
				j=W(x,y,i); if(j>255)j=255;
				c[i]=j;
			}
			for(xx=0;xx<XMAG;xx++) {
				*(lp++)=c[0];
				*(lp++)=c[1];
				*(lp++)=c[2];
			}
		}
		if (y<(YSIZE-NOSHOW)) for(xx=0;xx<YMAG;xx++) vga_drawscansegment(line,0,yy++,3*XSIZE*XMAG); 
	}
	for(j=0;j<SPOTS;j++) for(k=0;k<MOVE;k++) {
		spots[3][j]+=((int)R(3))-1; if(spots[3][j]<1)spots[3][j]=1; if(spots[3][j]>XSIZE-2)spots[3][j]=XSIZE-2;
	}
	for(j=0;j<SPOTS;j++) for(k=0;k<CMOVE;k++) {
		spots[4][j]+=((int)R(3))-1; if(spots[4][j]<0)spots[4][j]=0; if(spots[4][j]>(TABSIZE/4))spots[4][j]=TABSIZE/4;
		spots[5][j]+=((int)R(3))-1; if(spots[5][j]<0)spots[5][j]=0; if(spots[5][j]>(TABSIZE/4))spots[5][j]=TABSIZE/4;
	}
	for(j=0;j<SPOTS;j++) {
		int r,t;
		r=spots[4][j]; t=spots[5][j];
		spots[0][j]=(SIN(r)*COS(t))/(TABMAG*TABMAG/512);
		spots[1][j]=COS(r)*COS(t)/(TABMAG*TABMAG/512);
		spots[2][j]=SIN(t)/(TABMAG/512);
	}
}
	
main(int argc, char **argv[]) {
	int i,j,r,t;

	S();

	vga_setmode(G320x200x16M); 

	for(j=0;j<SPOTS;j++) {
		spots[3][j]=R(XSIZE-2)+1;
		spots[4][j]=r=R(TABSIZE/4);	
		spots[5][j]=t=R(TABSIZE/4);
		spots[0][j]=(SIN(r)*COS(t))/(TABMAG*TABMAG/512);
		spots[1][j]=COS(r)*COS(t)/(TABMAG*TABMAG/512);
		spots[2][j]=SIN(t)/(TABMAG/512);
	}

 	while(1) frame();
}
