#resize TRUE
#jumptomain SHORT

#define SCREENSIZE 64000
#define MEMBLOCKSIZE SCREENSIZE/16

#include "random.h--"

word screen;
word buffer;

void setrgbpalette(char color,r,g,b);

main()
{
	@RANDOMIZE();
	@SETVIDEOMODE(byte 0x13);
	setcolortable();
	screen=GETMEM(MEMBLOCKSIZE);
	CLEARBLOCK();
	buffer=GETMEM(MEMBLOCKSIZE);
	CLEARBLOCK();
	WHILE(!KBHIT()){
		incfire();
		trueflamescreen();
		copybufferscreen();
		copyvirtualscreen();
	}
	@BIOSREADKEY();
	WHILE(!KBHIT()){
		incfire();
		fastflamescreen();
		copyvirtualscreen();
	}
	@BIOSREADKEY();
	WHILE(!KBHIT()){
		incfire();
		fastestflamescreen();
		copyvirtualscreen();
	}
	@SETVIDEOMODE(byte 0x3);
	@BIOSREADKEY();
}

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

void setcolortable()
{
	FOR(CL=0;CL<=63;CL++){
		setrgbpalette(CL,CL,0,0);
		setrgbpalette(CL+64,63,CL,0);
		setrgbpalette(CL+128,63,63,CL);
		setrgbpalette(CL+192,63,63,63);
	}
}

void incfire()
{
	ES=screen;
	FOR(DI=63360;DI<63680;){
		AX=RAND();
		AH=AL;
		$push AX
		$push AX
		$pop EAX
		$stosd
		ESDWORD[DI+316]=EAX;
	}
}

void trueflamescreen()
{
	ES=screen;
	FS=buffer;
	DI=320;
	SI=0;
	FOR(DX=1;DX<199;DX++){
		FOR(BX=0;BX<320;BX++,DI++,SI++){
			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]>>3;
			IF(AL>1)AL--;
			ELSE AL=0;
			FSBYTE[SI]=AL;
		}
	}
}

void copybufferscreen()
{
	ES=screen;
	$push DS
	DS=buffer;
	SI=0;
	DI=0;
	CX=16000;
	$rep $movsd
	$pop DS
}

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

void fastflamescreen()
{
	ES=screen;
	DI=0;
	FOR(SI=0;SI<199;SI++)
		FOR(BX=0;BX<320;BX++){
			AX=ESBYTE[DI+319]+ESBYTE[DI+320]+ESBYTE[DI+321]+ESBYTE[DI+640]>>2;
			IF(AL>1)AL--; ELSE AL=0;
			$stosb;
		}
}

void fastestflamescreen()
{
	ES=screen;
	DI=0;
	FOR(BX=0;BX<197;BX+=2){
		FOR(SI=0;SI<320;SI++){
			AX=ESBYTE[DI+639]+ESBYTE[DI+640]+ESBYTE[DI+641];
			AX><DX;
			CX=ESBYTE[DI+1280];
			AX=CX+DX>>2;
			IF(AL>2)AL-=2; ELSE AL=0;
			$stosb
			ESBYTE[DI+319]=int AL+CL>>1;
		}
		DI+=320;
	}
}

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

