March 28, 2024, 09:44:22 AM

News:

IonicWind Snippit Manager 2.xx Released!  Install it on a memory stick and take it with you!  With or without IWBasic!


Boris' Quick Life

Started by Steven Picard, November 28, 2006, 08:28:04 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Steven Picard

Here is a neat little app based on Conways Game of Life written with a lot of impressive in-line assembly to make it very speedy. This is from the old forum.

WRITTEN BY BORIS.

'QUICKLIFE.IBA
'quick version of conways game of life
'Boris Burke 12 NOV 2004
createscreen 640,480,8
def buff1[320,240],buff2[320,240]:char
def bptr:pointer
def bpch:word
if place_cells()=chr$(27) then goto exit
generation=0:fps=0
do
   generation=generation+1
   gosub scan_cells
   gosub draw_cells
   writetext 10,10,"Generation "+str$(generation)+" <SPACE> - Pause/Edit. <ESC> - exit. "+str$(fps)+" FPS."
   fps=flip 1
   k$=getkey
   if k$=" " then k$=place_cells()
until k$=chr$(27)
label exit
closescreen
end
sub scan_cells
_asm
      pusha
      mov esi,239               ;init row counter
   next_row:
      mov ecx,319               ;init column counter
   next_column:
      mov ebx,0               ;init cell counter
      mov eax,320               ;elements per row
      mul esi                  ;y index (row counter)
      add eax,ecx               ;x index (column counter)
   first_cell:
      sub eax,321               ;point eax to row above minus one column (x-1,y-1)
      cmp [$buff1+eax],byte 1      ;cell occupied?
      jne noadd1
      inc ebx
   noadd1:
      inc eax                  ;next column
      cmp [$buff1+eax],byte 1      ;cell occupied?
      jne noadd2
      inc ebx
   noadd2:
      inc eax                  ;next column
      cmp [$buff1+eax],byte 1      ;cell occupied?
      jne noadd3
      inc ebx
   noadd3:
      add eax,318               ;next row
      cmp [$buff1+eax],byte 1      ;cell occupied?
      jne noadd4
      inc ebx
   noadd4:
      inc eax                  ;next column
      inc eax                  ;and the next (bypass the central x,y cell)
      cmp [$buff1+eax],byte 1      ;cell occupied?
      jne noadd5
      inc ebx
   noadd5:
      add eax,318               ;next row
      cmp [$buff1+eax],byte 1      ;cell occupied?
      jne noadd6
      inc ebx
   noadd6:
      inc eax                  ;next column
      cmp [$buff1+eax],byte 1      ;cell occupied?
      jne noadd7
      inc ebx
   noadd7:
      inc eax                  ;next column
      cmp [$buff1+eax],byte 1      ;cell occupied?
      jne noadd8
      inc ebx
   noadd8:
      sub eax,321               ;point eax to central cell
      cmp ebx, 3
      jne noborn
      mov [$buff2+eax],byte 1      ;central cell born
      jmp nokill
   noborn:
      cmp ebx, 2
      je nokill
      mov [$buff2+eax],byte 0      ;central cell killed
   nokill:
      dec ecx
      jnz next_column            ;loop to next column (x)
      dec esi
      jnz next_row            ;loop to next row (y)
      popa
_endasm
return
endsub
sub place_cells(),string
setcursor frontbuffer,@cscustom,0
gosub draw_cells_mag
flip
gosub draw_cells_mag
do
   fillscreen 0
   select 1
   case ucase$(k$)="F"
      for x=1 to 320
         for y=1 to 240
            buff2[x,y]=rand(0,1)
         next y
      next x
      generation=0
      gosub draw_cells_mag
      flip
   case ucase$(k$)="C"
      for x=1 to 320
         for y=1 to 240
            buff2[x,y]=0
         next y
      next x
      generation=0
      gosub draw_cells_mag
      flip
   case ucase$(k$)="R"
      while keydown 0x13
         for n=1 to 10
            do:x=rand(-10,10)+mousex/2:y=rand(-10,10)+mousey/2:until buff2[x,y]=0
            buff2[x,y]=1
         next n
         gosub draw_cells_mag
         flip
      endwhile
   endselect
   while mousedown(1)
      buff2[mousex/2,mousey/2]=1
      gosub draw_cells_mag
      flip
   endwhile
   while mousedown(2)
      buff2[mousex/2,mousey/2]=0
      gosub draw_cells_mag
      flip
   endwhile
   gosub draw_cells_mag
   flip
   k$=getkey
until k$=" " or k$=chr$(27)
setcursor frontbuffer,@cscustom,0
fillscreen 0:flip:fillscreen 0:flip
return k$
endsub
sub draw_cells_mag
gosub draw_cells
x=mousex
y=mousey
drawfilledrect x-50,y-50,105,105,0
drawrect x-50,y-50,105,105,200
drawrect x-2,y-2,8,8,200
for yy=-7 to 7
   for xx=-7 to 7
      if buff2[x/2+xx,y/2+yy]=1 then drawfilledrect x+xx*7,y+yy*7,4,4,249
   next xx
next yy
writetext 10,10,"L'mouse -add cell. R'mouse -kill cell. <R> -random. <F> -fill random. <C> -clear. <SPACE> -start."
return
endsub
sub draw_cells
fillscreen 0
lockbuffer
pbuffer=getbufferpointer
pitch=getbufferpitch
def ptemp:pointer
for y=2 to 239
   for x=1 to 319
      if buff2[x,y]>0
         writepixelfast x*2,2*y,0xf9
      endif
      buff1[x,y]=buff2[x,y]
   next x
next y
unlockbuffer
return
endsub