#resize TRUE
#jumptomain SHORT

#define SCREENSIZE 64000
#define MEMBLOCKSIZE SCREENSIZE/16
#define SEEK_SET 0

word screen;
word texture;
word anis;
byte pal[1024];

float const1=128;
float const2=256;
float const3=512;

word FOPEN(DX,AL);
word FSEEK(BX,CX,DX,AL);
word FREAD(BX,DX,CX);

void main()
float time=0;
{
	screen=GETMEM(MEMBLOCKSIZE);
	texture=GETMEM(0x1000);
	anis=GETMEM(MEMBLOCKSIZE*2);
	@SETVIDEOMODE(byte 0x13);
	readbmp();
	initanis();
	setcolortable();
	WHILE(!@KBHIT()){
		renderanis(time);
		copyvirtualscreen();
		time+=0.01;
	}
	@SETVIDEOMODE(byte 0x3);
	@BIOSREADKEY();
}

void readbmp()
word in;
int y;
{
	in=@FOPEN("texture.bmp",0);
	@FSEEK(in,0,54,SEEK_SET);
	FREAD(in,#pal,1024);
	FOR(BX=0;BX<1024;BX++)pal[BX]>>=2;
	$push DS
	DS=texture;
	FOR(y=255;y>=0;y--)FREAD(in,y*256,256);
	$pop DS
	@FCLOSE(,in);
}

void initanis()
long x,y,u,v;
{
	DI=0;
	ES=anis;
	for(y=-100;y<100;y++){
		FOR(x=-160;x<160;x++){
			u=x*x;
			v=y*y+u;
			asm{
				fild v
				fsqrt
				fistp v
				fwait
			}
			IF(v<1)v=1;
			asm{
				fild x
				fild y
				fpatan
				fldpi
				faddp st(1)
				fmul const1
				fldpi
				fdivp st(1)
				fistp u
				fwait
			}
			v=v&0xFF<<8;
			AX=u&0xFF+v;
			$stosw
			IF(DI==0)ES=ES+0x1000;
		}
	}
}

void renderanis(float time)
long u,v;
{
	asm{
		fld time
		fld st(0)
		fcos
		fmul const2
		fistp u
		fsin
		fmul const3
		fistp v
		fwait
	}
	v<<=8;
	EBX=0;
	ES=screen;
	FS=anis;
	GS=texture;
	FOR(SI=0;SI<64000;SI++){
		IF(EBX==65536)FS=FS+0x1000;
		AX=FSWORD[BX]+u+v;
		DI><AX;
		ESBYTE[SI]=GSBYTE[DI];
		EBX+=2;
	}
}

void copyvirtualscreen()
{
	@WAITVSYNC();
	copyfard(0xA000,0,screen,0,16000);
}

void setcolortable()
{
	FOR(CX=0;CX<256;CX++){
		BX=CX<<2;
		setrgbpalette(byte CL,byte pal[BX+2],byte pal[BX+1],byte pal[BX]);
	}
}

void setrgbpalette(char color,r,g,b)
{
	DX=0x3C8;
	outp(color,DX);
	DX++;
	outp(r,DX);
	outp(g,DX);
	outp(b,DX);
}
