program flammes;

{
  Auteur     : Vincent PRAT
  Plateforme : DOS / Win 9x
  Compilateur: Turbo pascal 7
  Creation   : 18 avril 1997
}

Uses crt, dos;

type     T_buff        = ARRAY [0..64959] of BYTE ;
	 P_buff        = ^T_buff ;
	 
var  	 Ecran         : ARRAY [0..63999] of BYTE ABSOLUTE $0A000:$00000 ;
	 Moy, u, v     : Integer;
	 Buff1, Buff2  : P_buff ;
	 x, y, i, j, f : integer;
	
{ note : f est le nbre de foyers. }

{ procedure qui attend le retour de balayage vertical de l'écran par le faisceau }

procedure WaitVBL; assembler ;

asm
	MOV DX, 03DAh
  @@1:  IN   AL, DX
	TEST AL, 8
	JNE  @@1
  @@2:  IN   AL, DX
	TEST AL, 8
	JE   @@2
end;

{ procedure qui prépare la palette }

Procedure Prep_Pal_fire;

Var i:byte;

Begin
  for i := 0 to 31 do
	begin
	  port[$03C8] := i;
	  port[$03C9] := i;
	  port[$03C9] := 0;
	  port[$03C9] := 0;
	end;
  for i := 32 to 63 do
	begin
	  port[$03C8] := i;
	  port[$03C9] := i;
	  port[$03C9] := i-32;
	  port[$03C9] := 0;
	end;
  for i := 64 to 95 do
	begin
	  port[$03C8] := i;
	  port[$03C9] := 63;
	  port[$03C9] := i-32;
	  port[$03C9] := i-64;
	end;
  for i := 96 to 127 do
	begin
	  port[$03C8] := i;
	  port[$03C9] := 63;
	  port[$03C9] := 63;
	  port[$03C9] := i-64;
	end;
  for i := 128 to 255 do
	begin
	  port[$03C8] := i;
	  port[$03C9] := 63;
	  port[$03C9] := 63;
	  port[$03C9] := 63;
	end;
End;

begin
  { initialisation mémoire + palette + variables }

  Randomize;

  Getmem( Buff1 , 64960 );
  Getmem( Buff2 , 64960 );

  fillchar( Buff1^ , 64960 , 0 );
  fillchar( Buff2^ , 64960 , 0 );
  fillchar( Ecran  , 64000 , 0 );

  Prep_Pal_fire;

{ on initialise le mode graphique 013h 320x200x256c }

  asm
	MOV AX, 013h
	INT 010h
  end;

{ pour voir la palette

  while not keypressed do
	begin
	  For x := 0 to 255 do
		begin
		  ecran[320*100+x] := x;
		  ecran[320*101+x] := x;
		  ecran[320*102+x] := x;
		end;
	end;
}

  f := 20 ;


  { boucle des flammes }

  while not Keypressed do
	begin

	{ 3 lignes aléatoires }
	  For x := 0 to 319 do
		begin
		  Buff1^[320*200+x] := round(Random(31));
		  Buff1^[320*201+x] := round(Random(31));
		  Buff1^[320*202+x] := round(Random(31));
		end;


	{ foyers }
	  for x := 1 to f do
		begin
		  i := random(319);
		  for j := 0 to 2 do
			begin
			  buff1^[320*202+i+j] := 254;
			  buff1^[320*201+i+j] := 254;
			  buff1^[320*200+i+j] := 254;
			end;
		end;

	{ calcul des points de buff2^ }
	  For x := 1 to 318 do
		For y := 1 to 201 do
		  begin
			if buff1^[320*y+x] = 255 then
			  buff2^[320*(y-1)+x] := buff1^[320*(y-1)+x]
			else
			begin
			  moy := buff1^[320*(y-1) + (x-1)] + buff1^[320*y+(x-1)] + buff1^[320*(y+1)+(x-1)] + buff1^[320*(y-1)+x]
				  + buff1^[320*(y+1)+x] +buff1^[320*(y-1)+(x+1)] + buff1^[320*y+x+1] +buff1^[320*(y+1)+x+1] ;
			  moy := moy SHR 3;
			  if moy > 0 then moy := moy -1;
			  buff2^[320*(y-1)+x] := moy;
			end;
		  end;

	  waitvbl;
	  move(buff2^, Ecran , 63040);
	  move(buff2^, buff1^, 64960);

	end;


  fillchar(ecran, 64000, 0);

{ On n'oublie pas de retourner au mode texte 003h }

  asm
	MOV AX, 003h
	INT 010h
  end;

{ On libère la mémoire }

  Freemem( Buff1 , 64960);
  Freemem( Buff2 , 64960);
end.

