?resize FALSE
?use80386
?codesize
?parsecommandline TRUE

?include "random.h--"
?include "PCXLOAD.H--"

?define NUMSHAR 3

word segm_buf,seg2;

struct SHARINFO{
	int X;
	int Y;
	int R;
	int Dx;
	int Dy;
	int Clinch;
}sharinfo[NUMSHAR];

main()
int i;
{
	AX=0x13;
	$int 0x10
	IF(@PARAMCOUNT()!=1)Error(
											"\nДля запуска необходимо задать имя PCX файла.\n");
	segm_buf=CS+0x1000;
	seg2=AX+0x1000;
	@RANDOMIZE();
	IF(loadPCX(@PARAMSTR(0),segm_buf)!=0)Error("\nОшибка чтения PCX файла.\n");
	InitShar();
	do{
		COPYSEG(seg2,segm_buf);
		FOR(i=0;i<NUMSHAR;i++){
			SI=i*sizeof(SHARINFO)+#sharinfo;
			Shar(DSWORD[SI],DSWORD[SI+2],DSWORD[SI+4]);
		}
		COPYSEG(0xA000,seg2);
		CalcNewPos();
		AH=1;
		$int 0x16
	}while(ZEROFLAG);
	@BIOSREADKEY();
	AX=0x3;
	$int 0x10
}

void Error(word msg)
{
	AX=3;
	$int 0x10
	@WRITESTR(msg);
	@ABORT();
}

void Shar(int cx,cy,sr)
int Rad_V_Kv;
int Y;
int Z;
{
	Rad_V_Kv=sr*sr;
	ES=segm_buf;
	FS=seg2;
	for(Y=-sr;Y<sr;Y++){
		FOR(CX=-sr;int CX<sr;CX++){
			AX=CX;
			BX=AX*AX;
			AX=Y;
			AX=AX*AX;
			BX+=AX;
			IF(BX<=Rad_V_Kv){
				Z=Rad_V_Kv-BX;
				BX=cx+CX;
				IF(PLUSFLAG)&&(BX<320){
					AX=cy+Y;
					IF(PLUSFLAG)&&(AX<200){
						DI=AX*320+BX;
						$fild Z
						$fsqrt
						$fistp Z
						BX=Z+sr;
						AX=int Y*sr/BX+cy*320;
						AX><SI;
						AX=int CX*sr/BX+cx+SI;
						AX><SI;
						FSBYTE[DI]=ESBYTE[SI];
					}
				}
			}
		}
	}
}

void COPYSEG()
{
	$push DS
	ES=AX;
	DS=BX;
	SI=0;
	DI=0;
	CX=16000;
	$rep
	$movsd
	$pop DS
}

void InitShar()
int i;
{
	FOR(i=0;i<NUMSHAR;i++){
		DI=i*sizeof(SHARINFO)+#sharinfo;
		DSWORD[DI+4]=RAND()%32+10;
		do{
			BX=DSWORD[DI+4]<<1;
			DSWORD[DI]=320-BX;
			DSWORD[DI+2]=200-BX;
			DSWORD[DI]=RAND()%DSWORD[DI]+DSWORD[DI+4];
			DSWORD[DI+2]=RAND()%DSWORD[DI+2]+DSWORD[DI+4];
		}while(CalcDist(DSWORD[DI],DSWORD[DI+2],DSWORD[DI+4],i)!=-1);
		DSWORD[DI+6]=SelectNapravl();
		DSWORD[DI+8]=SelectNapravl();
		DSWORD[DI+10]=0;
	}
}

int SelectNapravl()
{
	AX=RAND()%2;
	IF(AX==0)AX--;
}

int CalcDist(int x,y,r,i)
dword z;
{
	FOR(CX=0;CX<i;CX++){
		SI=CX*sizeof(SHARINFO)+#sharinfo;
		AX=x-DSWORD[SI];
		IF(CARRYFLAG)-AX;
		z=AX*AX;
		AX=y-DSWORD[SI+2];
		IF(CARRYFLAG)-AX;
		EAX=AX*AX;
		z+=EAX;
		$fild z
		$fsqrt
		$fistp z
		IF(DSWORD[SI+4]+r>=z){
			AX><CX;
			RETURN;
		}
	}
	return -1;
}

void CalcNewPos()
{
	for(BX=0;BX<NUMSHAR;BX++){
		DI=BX*sizeof(SHARINFO)+#sharinfo;
		IF(DSWORD[DI]+DSWORD[DI+4]+DSWORD[DI+6]>320)DSWORD[DI+6]=-1;
		ELSE IF(DSINT[DI]-DSINT[DI+4]+DSINT[DI+6]<0)DSWORD[DI+6]=1;
		IF(DSWORD[DI+2]+DSWORD[DI+4]+DSWORD[DI+8]>200)DSWORD[DI+8]=-1;
		ELSE IF(DSINT[DI+2]-DSINT[DI+4]+DSINT[DI+8]<0)DSWORD[DI+8]=1;
		CalcDist(DSWORD[DI]+DSWORD[DI+6],DSWORD[DI+2]+DSWORD[DI+8],
						 DSWORD[DI+4],BX);
		IF(AX!=-1){
			SI=AX*sizeof(SHARINFO)+#sharinfo;
			SWITCH(DSWORD[DI+10]){
				case 0:
					ReversNapravl(#DSWORD[SI+6]);
				case 1:
					ReversNapravl(#DSWORD[DI+6]);
				case 2:
					ReversNapravl(#DSWORD[SI+8]);
				case 3:
					ReversNapravl(#DSWORD[DI+8]);
			}
			DSWORD[SI]+=DSWORD[SI+6];
			DSWORD[SI+2]+=DSWORD[SI+8];
			DSWORD[DI+10]++;
		}
		ELSE DSWORD[DI+10]=0;
		DSWORD[DI]+=DSWORD[DI+6];
		DSWORD[DI+2]+=DSWORD[DI+8];
	}
}

void ReversNapravl(word ADR)
{
	$push SI
	SI=ADR;
	IF(DSWORD[SI]==1)DSWORD[SI]=-1;
	ELSE DSWORD[SI]=1;
	$pop SI
}
