#resize TRUE
#jumptomain SHORT

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

#include "random.h--"

word buf1;
word buf2;
word screen_end;
word pics;

byte	pal[1024];

word buf1_ptr;
word buf2_ptr;

float time=0;
float const1=1.5;
float const2=2.5;
float const3=60;
float const4=120;

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

void main()
{
	@RANDOMIZE();
	buf1=GETMEM(MEMBLOCKSIZE);
	buf1_ptr=AX;
	CLEARBLOCK();
	buf2=GETMEM(MEMBLOCKSIZE);
	buf2_ptr=AX;
	CLEARBLOCK();
	screen_end=GETMEM(MEMBLOCKSIZE);
	CLEARBLOCK();
	pics=GETMEM(MEMBLOCKSIZE);

	@SETVIDEOMODE(byte 0x13);
	readbmp();
	setcolortable1();
	WHILE(!KBHIT())
	{
		setwater();
		waterscreen1();
		copyvirtualscreen1();
	}
	@BIOSREADKEY();
	setcolortable2();
	WHILE(!KBHIT())
	{
		setwater();
		waterscreen2();
		copyvirtualscreen2();
	}
	@BIOSREADKEY();
	WHILE(!KBHIT())
	{
		setwater();
		waterscreen3();
		copyvirtualscreen2();
	}
	@SETVIDEOMODE(byte 0x3);
	@BIOSREADKEY();
}

void CLEARBLOCK()
{
	ES=AX;
	EAX=0;
	DI=0;
	CX=16000;
	$rep $stosd
}

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

void setcolortable1()
{
	FOR(CX=0;CX<256;CX++){
		setrgbpalette(char CL,char CL/4,char CL/4,char 63);
	}
}

void setcolortable2()
{
	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);
}

void setwater()
long xd,dy;
{
	if(buf1_ptr==buf1){
		ES=buf1;
		EAX=RAND()<<1%62000;
		SI=AX+320;
		ESDWORD[SI]=0x7FFFFF7F;
		ESDWORD[SI+320]=0xFFFFFFFF;
		ESDWORD[SI+640]=0xFFFFFFFF;
		ESDWORD[SI+960]=0x7FFFFF7F;
		asm{
			fld time
			fmul const2
			fadd const1
			fsin
			fmul const4
			fistp xd
			fwait
		}
		xd+=160;
//		sin(time*2.5+1.5)*120+160;
		asm{
			fld time
			fmul const1
			fadd const2
			fcos
			fmul const3
			fistp dy
			fwait
		}
		dy+=100;
		AX=dy*320+xd;
		SI><AX;
//		cos(time*1.5+2.5)*60+100;
		ESWORD[SI+320]=0xFFFF;
		ESWORD[SI+640]=0xFFFF;
		asm{
			fld time
			fmul const1
			fadd const2
			fsin
			fmul const4
			fistp xd
			fwait
		}
		xd+=160;
//		sin(time*1.5+2.5)*120+160;
		asm{
			fld time
			fmul const2
			fadd const1
			fcos
			fmul const3
			fistp dy
			fwait
		}
		dy+=100;
		AX=dy*320+xd;
		SI><AX;
//		cos(time*2.5+1.5)*60+100;
		ESWORD[SI+320]=0xFFFF;
		ESWORD[SI+640]=0xFFFF;
		time+=0.03;
	}
}


void waterscreen1()
{
	ES=buf1_ptr;
	FS=buf2_ptr;
	FOR(DI=321;DI<64000-321;DI++){
		AX=ESBYTE[DI-321]+ESBYTE[DI-320]+ESBYTE[DI-319]+ESBYTE[DI-1]+ESBYTE[DI+1]
				+ESBYTE[DI+319]+ESBYTE[DI+320]+ESBYTE[DI+321]>>2-FSBYTE[DI];
		IF(int AX<0)AX=0;
		FSBYTE[DI]=AL;
	}
	buf1_ptr><buf2_ptr;
}

void copyvirtualscreen1()
{
	WAITVSYNC();
	copyfard(0xA000,0,buf1_ptr,0,16000);
}

void waterscreen2()
{
	ES=buf1_ptr;
	FS=buf2_ptr;
	FOR(DI=321;DI<64000-321;DI++){
		AX=ESBYTE[DI-321]+ESBYTE[DI-320]+ESBYTE[DI-319]+ESBYTE[DI-1]+ESBYTE[DI+1]
				+ESBYTE[DI+319]+ESBYTE[DI+320]+ESBYTE[DI+321]>>2-FSBYTE[DI];
		IF(int AX<0)AX=0;
		FSBYTE[DI]=AL;
		AX>>=2;
		DX=AX;
		AX<<=6;
		CX=AX;
		AX<<=2;
		BX=AX+DI+DX+CX;
		IF(BX>63999)BX=63999;
		GS=pics;
		AL=GSBYTE[BX];
		GS=screen_end;
		GSBYTE[DI]=AL;
	}
	buf1_ptr><buf2_ptr;
}

void copyvirtualscreen2()
{
	WAITVSYNC();
	copyfard(0xA000,0,screen_end,0,16000);
}

void waterscreen3()
long x,x1,x2,y,y1,y2;
{
	ES=buf1_ptr;
	FS=buf2_ptr;
	for(DI=321;DI<64000-321;DI++){
		EBX=ESBYTE[DI-321];
		y1=ESBYTE[DI-320];
		EBX+=EAX;
		EBX+=ESBYTE[DI-319];
		x1=ESBYTE[DI-1];
		EBX+=EAX;
		x2=ESBYTE[DI+1];
		EBX+=EAX;
		EBX+=ESBYTE[DI+319];
		y2=ESBYTE[DI+320];
		EAX+=EBX;
		EAX+=ESBYTE[DI+321];
		EAX>>=2;
		EAX-=FSBYTE[DI];
		IF(long EAX<0)AX=0;
		FSBYTE[DI]=AL;
		x=x2-x1>>2;
		y=y2-y1>>2;
		y1=EAX<<6;
		y2=y<<8;
		EDI=DI;
		EBX=EDI+x+y1+y2;
		IF(long EBX<0)BX=0;
		ELSE IF(EBX>63999)BX=63999;
		GS=pics;
		AL=GSBYTE[BX];
		GS=screen_end;
		GSBYTE[DI]=AL;
	}
	buf1_ptr><buf2_ptr;
}

