//Пример к статье "ЭФФЕКТ: RADIAL BLUR"
//Если вы захотите подставить какую-нибудь другую картинку, то проделайте
//следующую последовательность действий: нарисуйте или считайте другую
//двух-цветную картинку в PaintBrush, засавте ее как монохромную картинку,
//а потом как 256-цветную, и вот эту 256 цветную картинку можно подставлять
//вместо intel.bmp.(Размер картинки естественно дожен составлять 320x200,
//и bmp`ешка не должна быть упакованной, иначе у вас ничего не получиться)
#resize TRUE
#jumptomain SHORT

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

word screen;
word pics;
word sqr; //размер буфера 128000
long bbx,bby;
float time=0;

float const0=0.05;
float const1=0.8;
float const2=1.1;
float const3=1.5;
float const4=90;
float const5=120;

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

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

void main()
{
	screen=GETMEM(MEMBLOCKSIZE);
	pics=GETMEM(MEMBLOCKSIZE);
	sqr=GETMEM(MEMBLOCKSIZE*2);
	@SETVIDEOMODE(byte 0x13);
	initsqr();
	readbmp();
	blurpics();
	setcolortable();
	WHILE(!@KBHIT()){
		asm{
			fld time
			fadd const0
			fst time
			fmul const2
			fadd const3
			fsin
			fmul const5
			fistp bbx
			fwait
		}
		bbx+=160;
//		bbx=160+120*sin(time*1.1+1.5);
		asm{
			fld time
			fmul const1
			fadd const2
			fcos
			fmul const4
			fistp bby
			fwait
		}
		bby+=100;
//		bby=100+90*cos(time*0.8+1.1);
		copypicsvirtual();
		radialblurscreen();
		blurscreen();
		copyvirtualscreen();
	}
	@BIOSREADKEY();
	@SETVIDEOMODE(byte 0x3);
}

void readbmp()
word in;
int y;
{
	in=@FOPEN("intel.bmp",0);
	@FSEEK(in,0,1078,SEEK_SET);
	$push DS
	DS=pics;
	FOR(y=199;y>=0;y--)FREAD(in,y*320,320);
	$pop DS
	@FCLOSE(,in);
	ES=pics;
	FOR(DI=0;DI<64000;){
		AL=ESBYTE[DI];
		IF(AL==1)AL=255;
		ELSE AL=0;
		$stosb
	}
}

void blurpics()
{
	ES=pics;
	FOR(DI=320;DI<64000-320-320;){
		AX=ESBYTE[DI-320]+ESBYTE[DI-1]+ESBYTE[DI+1]+ESBYTE[DI+320]>>2;
		$stosb
	}
}

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(CX=0;CX<=255;CX++){
		AL=255-CL/4;
		setrgbpalette(CL,AL,AL,AL);
	}
}

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

void radialblurscreen()
int x,y,vx,p1;
int t;
{
	ES=screen;
	FS=sqr;
	GS=64000/16+sqr;
	t=0;
	AX=bby-1<<6;
	BX=AX<<2;
	DI=AX+BX+bbx-1;
	FOR(y=bby-1;y>=0;y--){
		FOR(x=bbx-1;x>=0;x--){
			p1=ESBYTE[DI];
			SI=t;
			vx=GSBYTE[SI];	//*((char*)(t+64000));
			AX=FSBYTE[SI];	//*((char*)(t));
			AX<<=6;
			BX=AX<<2;
			AX=ESBYTE[DI+vx+AX+BX]; //*((char*)(s+vx+(vy<<8)+(vy<<6)));
			ESBYTE[DI]=word AX+p1>>1; //*((char*)(s))=(p1+p2)>>1;
			DI--;
			t++;
		}
		DI=DI-320+bbx;
		t+=320-bbx;
	}
	AX=bby-1<<6;
	BX=AX<<2;
	DI=AX+BX+bbx;
	t=0;
	FOR(y=bby-1;y>=0;y--){
		FOR(x=bbx;x<320;x++){
				p1=ESBYTE[DI];	//p1=*((char*)(s));
				SI=t;
				vx=GSBYTE[SI];	//*((char*)(t+64000));
				AX=FSBYTE[SI];	//*((char*)(t));
				AX<<=6;
				BX=AX<<2;
				AX=ESBYTE[DI-vx+AX+BX]; //*((char*)(s-vx+(vy<<8)+(vy<<6)));
				ESBYTE[DI]=word AX+p1>>1; //*((char*)(s))=(p1+p2)>>1;
				DI++;
				t++;
			}
		DI=DI-640+bbx;
		t+=bbx;
	}
	AX=bby<<6;
	BX=AX<<2;
	DI=AX+BX+bbx-1;
	t=0;	//t=tn;
	FOR(y=bby;y<200;y++){
		FOR(x=bbx-1;x>=0;x--){
				p1=ESBYTE[DI];	//p1=*((char*)(s));
				SI=t;
				vx=GSBYTE[SI];	//*((char*)(t+64000));
				AX=FSBYTE[SI];	//*((char*)(t));
				AX<<=6;
				BX=AX<<2;
				AX=ESBYTE[DI+vx-AX-BX]; //*((char*)(s+vx-(vy<<8)-(vy<<6)));
				ESBYTE[DI]=word AX+p1>>1; //*((char*)(s))=(p1+p2)>>1;
				DI--;
				t++;
			}
		DI=DI+320+bbx;
		t+=320-bbx;
	}
	AX=bby<<6;
	BX=AX<<2;
	DI=AX+BX+bbx;
	t=0;	//t=tn;
	FOR(y=bby;y<200;y++){
		FOR(x=bbx;x<320;x++){
			p1=ESBYTE[DI];	//p1=*((char*)(s));
			SI=t;
			vx=GSBYTE[SI];	//*((char*)(t+64000));
			AX=FSBYTE[SI];	//*((char*)(t));
			AX<<=6;
			BX=AX<<2;
			AX=ESBYTE[DI-vx-AX-BX]; //*((char*)(s-vx-(vy<<8)-(vy<<6)));
			ESBYTE[DI]=word AX+p1>>1; //*((char*)(s))=(p1+p2)>>1;
			DI++;
			t++;
		}
		DI+=bbx;
		t+=bbx;
	}
}

void blurscreen()
{
	ES=screen;
	FOR(DI=320;DI<64000-320-320;){
		AX=ESBYTE[DI-320]+ESBYTE[DI-1]+ESBYTE[DI+1]+ESBYTE[DI+320]>>2;
		$stosb
	}
}

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

void initsqr()
int x,y;
dword n;
{
	ES=sqr;
	GS=64000/16+sqr;
	FOR(x=0;x<320;x++){
		FOR(y=0;y<200;y++){
			AX=y*y;
			BX><AX;
			n=x*x+BX;
			asm{
				fild n
				fsqrt
				fistp n
				fwait
			}
			n=n/8+1;//			n=(sqrt(x*x+y*y)/8)+1;
			SI=y*320+x;
			AX=int x/n;
			GSBYTE[SI]=AL;
			AX=int y/n;
			ESBYTE[SI]=AL;
		}
	}
}

