program life; uses crt; const wid=200; ht=100; dots=800; VGA = $a000; ld= 0; lh= 100; ls= 150; hs= 5; type Virtual = Array [1..64000] of byte; { The size of our Virtual Screen } VirtPtr = ^Virtual; { Pointer to the virtual screen } var grid: array [0..wid+1,0..ht+1] of shortint; {dot: array[1..wid*ht,1..2] of byte;} temp: array [0..wid+1,0..ht+1] of boolean; chk: array [0..wid+1,0..ht+1] of boolean; x:integer; y:integer; i:integer; a:boolean; j:integer; k:integer; m:integer; tot:integer; colr:longint; dnum:longint; Virscr : VirtPtr; { Our first Virtual screen } Vaddr : word; { The segment of our virtual screen} Scr_Ofs : Array[0..199] of Word; { Put Pixel } Procedure SetMCGA; BEGIN asm mov ax,0013h int 10h end; END; Procedure SetText; BEGIN asm mov ax,0003h int 10h end; END; Procedure Cls (Where:word;Col : Byte); assembler; { This clears the screen to the specified color } asm push es mov cx, 32000; mov es,[where] xor di,di mov al,[col] mov ah,al rep stosw pop es End; Procedure SetUpVirtual; { This sets up the memory needed for the virtual screen } BEGIN GetMem (VirScr,64000); vaddr := seg (virscr^); END; Procedure DestroyVirtual; { This frees the memory used by the virtual screen } BEGIN FreeMem (VirScr,64000); END; procedure WaitRetrace; assembler; { This waits until you are in a Verticle Retrace } label l1, l2; asm mov dx,3DAh l1: in al,dx and al,08h jnz l1 l2: in al,dx and al,08h jz l2 end; Procedure Pal(ColorNo : Byte; R,G,B : Byte); { This sets the Red, Green and Blue values of a certain color } Begin Port[$3c8] := ColorNo; Port[$3c9] := R; Port[$3c9] := G; Port[$3c9] := B; End; Procedure Putpixel (X,Y : Integer; Col : Byte; where:word); { This puts a pixel on the screen by writing directly to memory. } BEGIN Asm push ds {; Make sure these two go out the } push es {; same they went in } mov ax,[where] mov es,ax {; Point to segment of screen } mov bx,[X] mov dx,[Y] push bx {; and this again for later} mov bx, dx {; bx = dx} mov dh, dl {; dx = dx * 256} xor dl, dl shl bx, 1 shl bx, 1 shl bx, 1 shl bx, 1 shl bx, 1 shl bx, 1 {; bx = bx * 64} add dx, bx {; dx = dx + bx (ie y*320)} pop bx {; get back our x} add bx, dx {; finalise location} mov di, bx {; di = offset } {; es:di = where to go} xor al,al mov ah, [Col] mov es:[di],ah {; move the value in ah to screen point es:[di] } pop es pop ds End; END; procedure flip(source,dest:Word); { This copies the entire screen at "source" to destination } begin asm push ds mov ax, [Dest] mov es, ax { ES = Segment of source } mov ax, [Source] mov ds, ax { DS = Segment of source } xor si, si { SI = 0 Faster then mov si,0 } xor di, di { DI = 0 } mov cx, 32000 rep movsw { Repeat movsw 32000 times } pop ds end; end; {procedure arline(tx,ty,bx,by) begin grid} begin SetupVirtual; SetMCGA; { Start } { vaddr - Virtual Screen VGA - Actual Screen } { randomize; for i:= 1 to dots do begin x:=random(wid-1)+1; y:=random(ht-1)+1; if grid[x,y] = 0 then begin grid[x,y]:=1; dot[dnum,1]:=x; dot[dnum,2]:=y; dnum:=dnum+1; end else begin i:=i-1 end; end; } {for i:= wid div 2 - ld div 2 to wid div 2 -ld div 2 + ld do begin grid[i,ht div 2]:=1; end; for i:= ht div 2- lh div 2 to ht div 2 - lh div 2 + lh do begin grid [wid div 2,i]:=1; end;} {R pentomino Code} {grid[ls+1,hs]:=1; grid[ls+1,hs+1]:=1; grid[ls,hs+1]:=1; grid[ls+1,hs+2]:=1; grid[ls+2,hs]:=1;} {glider gun} grid[ls,hs+5]:=1; grid[ls+1,hs+4]:=1; grid[ls+1,hs+5]:=1; grid[ls+12,hs+1]:=1; grid[ls+13,hs+1]:=1; grid[ls+11,hs+2]:=1; grid[ls+10,hs+3]:=1; grid[ls+10,hs+4]:=1; grid[ls+10,hs+5]:=1; grid[ls+11,hs+6]:=1; grid[ls+12,hs+7]:=1; grid[ls+13,hs+7]:=1; grid[ls+23,hs+4]:=1; grid[ls+24,hs+3]:=1; grid[ls+24,hs+4]:=1; grid[ls+23,hs+8]:=1; grid[ls+24,hs+8]:=1; grid[ls+24,hs+9]:=1; grid[ls+26,hs+5]:=1; grid[ls+26,hs+6]:=1; grid[ls+26,hs+7]:=1; grid[ls+27,hs+5]:=1; grid[ls+27,hs+6]:=1; grid[ls+27,hs+7]:=1; grid[ls+28,hs+6]:=1; grid[ls+34,hs+7]:=1; grid[ls+35,hs+6]:=1; grid[ls+35,hs+7]:=1; for i:= 1 to wid do begin for j:=1 to ht do begin chk[i,j]:=true; end; end; repeat for i:=1 to wid do begin for j:=1 to ht do begin if chk[i,j]=true then begin tot:=-grid[i,j]; for k:=-1 to 1 do begin for m:=-1 to 1 do begin tot:=tot+grid[i+k,j+m]; end; end; if tot<2 then temp[i,j]:=false; if tot=2 then begin if grid[i,j]=1 then temp[i,j]:=true else temp [i,j]:=false; end; if tot=3 then temp[i,j]:=true; if tot>3 then temp[i,j]:=false; end; end; end; {Slow Code ends} {fast code begins} {for i:= 1 to dnum do begin tot:=-grid[dot[i,1],dot[i,2]]; for k:=-1 to 1 do begin for m:=-1 to 1 do begin tot:=tot+grid[dot[i,1]+k,dot[i,2]+m]; end; end; if tot<2 then temp[i,j]:=0; if tot=2 then temp[i,j]:=grid[i,j]; if tot=3 then temp[i,j]:=1; if tot>3 then temp[i,j]:=0; end; {end;} {Unused code for drawing on text screen} {for i:=1 to wid do begin for j:=1 to ht do begin if grid[i,j]=1 then begin gotoxy(i,j); write('o'); end; end; end;} cls(vaddr,0); {cls(vga,0);} for i:=1 to wid do begin for j:=1 to wid do begin chk[i,j]:=false; end; end; {temp[random(wid),random(ht)]:=true;} for i:=1 to wid do begin for j:=1 to ht do begin if grid[i,j]=1 then begin putpixel(i,j,14,vaddr); end; if temp[i,j]=true then grid[i,j]:=1 else grid[i,j]:=0; if temp[i,j]=true then begin for k:=-1 to 1 do begin for m:=-1 to 1 do begin chk[i+k,j+m]:=true; end; end; end; temp[i,j]:=false; end; end; {cls(VGA,1);} flip(vaddr,vga); if keypressed then a:=true; until a=true; setText; DestroyVirtual; end.