/* CONWAY'S GAME OF LIFE 02/12/92 */
/* Programmed by Terry Newton     */
/* 160 by 96 Cells in four colors */
/* Arrays start at $5300          */
/* Link to...                     */
/*  ACECIO.CCC    Ace C functions */
/*  CELLS.OBJ     Generation code */
/*  CMPA400.OBJ   Compress code   */
/*  ENGINE.OBJ    Ace C runtime   */
int  check1;
char *popadr,*denadr;
char *repadr,*dead,*monadr;
char *popcnt,*gencnt;
char inpstr[40];
int  key,esc,esc1,i,j,k,l;
int  func,x,y,err,desc,lock;
int  cr0,cr1,cr2,cr3;
int  creg,hue,intens,cbyte,mono;
int  check2;
main() $(
/* set Sparta RUNLOC */
 if(peek(dpeek(10)+28)==128||
    peek(0x0700)==0x53)
  dpoke(dpeek(10)+61,0x3635);
 popadr=0xA009;denadr=0xA00B;
 repadr=0xA00C;dead=0xA00D;
 monadr=0xA00E;
 if(peek(dead)==127)check1=0;
 if(check1!=1234||check2!=5678) $(
  poke(dpeek(0x2CB4),peek(0x0021)+48);
  mono=0;poke(monadr,0);poke(dead,0);
  dpoke(popadr,0);gencnt=0;
  poke(denadr,40);poke(repadr,20);
  x=80;y=48;desc=0;
  graphics(7);getcols();
 $) else $( check1=0;check2=0; $)
 while(1) $(
  graphics(7+32);setcols();
  poke(752,1);popcnt=dpeek(popadr);
  printf("↰Generation:%-5d Population:%-5d\n",gencnt,popcnt);
  printf(" R  Random Mode   L  Load Colony\n");
  printf(" E  Edit Cells    S  Save Colony\n");
  printf(" C  Continue      P  Parameters");
  func=0;while(func==0) $(
   key=toupper(getkey());
   if(key=='C')func=1;
   if(key=='E')func=2;
   if(key=='R')func=3;
   if(key=='L')func=4;
   if(key=='S')func=5;
   if(key=='P')func=6;
  $)
  if(func==1)contgen();
  if(func==2)editmode();
  if(func==3)randmode();
  if(func==4)load();
  if(func==5)save();
  if(func==6)submenu();
 $)
$)
submenu() $(
 esc=0;while(esc==0) $(
  poke(752,1);
  printf("↰ D  Random Start Density:%-3d\n",peek(denadr));
  printf(" R  Repeats Until Dead  :%-3d\n",peek(repadr));
  printf(" E  Escape When Dead    :");
  if(desc)printf("Y");else printf("N");
  printf("\n C  Colors  ESC Menu   X  DOS");
  func=0;while(func==0) $(
   key=toupper(getkey());
   if(key=='D')func=1;
   if(key=='R')func=2;
   if(key=='E')func=3;
   if(key=='C')func=4;
   if(key=='␛')func=5;
   if(key=='X')func=6;
  $)
  poke(752,0);
  printf("↑ \n↑↑↑→→→→→→→→→→→→→→→→→→→→→→→→→");
  if(func==1) $(
   gets(inpstr);
   i=val(inpstr);poke(denadr,i);
  $) if(func==2) $(
   printf("↓");gets(inpstr);
   i=val(inpstr);poke(repadr,i);
  $) if(func==3) $(
   if(desc)desc=0;else desc=1;
  $) if(func==4) altcols();
  if(func==5)esc=1;
  if(func==6) $(
   poke(752,1);
   printf("↰↓Press RETURN to Exit");
   i=getkey();if(i==155) $(
    check1=1234;check2=5678;
    poke(752,0);printf("↰");exit();
   $)
  $)
 $)
$)
randmode() $(
 graphics(7+16);setcols();
 poke(764,255);
 esc=0;while(esc==0) $(
  randomstart();gencnt=0;
  esc1=0;while(esc1==0) $(
   generate();poke(77,0);
   if(peek(dead))esc1=1;
   key=peek(764);poke(764,255);
   if(key==0x000C)esc1=1;  /* return */
   if(key==0x0021) $(      /* spc */
    key=255;
    while(key==255)key=peek(764);
    poke(764,255); $)
   if(key==0x001C) $( esc=1;esc1=1; $)
   if(esc1==0)gencnt++;
  $)
 $)
$)
contgen() $(
 graphics(7+48);setcols();
 poke(764,255);initialize();
 esc=0;while(esc==0) $(
  generate();poke(77,0);
  key=peek(764);poke(764,255);
  if(desc&&peek(dead))esc=1;
  if(key==0x0021) $(
   key=255;
   while(key==255)key=peek(764);
   poke(764,255); $)
  if(key==0x001C)esc=1;
  if(esc==0)gencnt++;
 $)
$)
save() $(
 poke(752,0);
 printf("↰↓SAVE FILENAME>");
 gets(inpstr);
 if(strlen(inpstr)>0) $(
  normalize(inpstr,"LIF");
  err=open(4,8,0,inpstr);
  if(err<0)errtrap();
  else $(
   cputc(7,4);cputc(cr1,4);
   cputc(cr2,4);cputc(cr3,4);
   cputc(254,4);cputc(cr0,4);
   encode(dpeek(0x0058),3840,4);
   printf(4,"%d\n",gencnt);
   printf(4,"%d\n",popcnt);
  $)
  close(4);
 $)
$)
load() $(
 poke(752,0);
 printf("↰↓LOAD FILENAME>");
 gets(inpstr);poke(752,1);
 if(strlen(inpstr)>0) $(
  normalize(inpstr,"LIF");
  err=open(4,4,0,inpstr);
  if(err<0)errtrap();
  else $(
   i=cgetc(4);cr1=cgetc(4);
   cr2=cgetc(4);cr3=cgetc(4);
   j=cgetc(4);cr0=cgetc(4);
   if(i==7&&j==254) $(
    setcols();
    decode(dpeek(0x0058),3840,4);
    cgets(inpstr,4);gencnt=val(inpstr);
    cgets(inpstr,4);popcnt=val(inpstr);
    dpoke(popadr,popcnt);
   $) else $(
    getcols();
    printf("↰↓Not a CELLS File");
    getkey();
   $)
  $)
  close(4);
 $)
$)
char *byte;
/* get pixel color */
getpix(a,b)
int a,b;
$(
 byte=dpeek(0x0058);
 byte+=y*40;byte+=x/4;
 i=*byte;j=x&3;
 if(j==0)i=i>>6;
 else if(j==1)i=i>>4;
 else if(j==2)i=i>>2;
 i=i&3;return(i);
$)
editmode() $(
 graphics(7+48);setcols();
 k=1;l=0;lock=0;
 esc1=0;while(esc1==0) $(
  if(lock==0)i=getpix(x,y);
  while(peek(764)==255) $(
   if(l<20)color(i);
   else color(k);
   plot(x,y);l++;
   if(l>40) $( l=0;k++;if(k>3)k=1; $)
  $)
  color(i);plot(x,y);
  key=toupper(getkey());
  if(key=='-')y--;
  if(key=='=')y++;
  if(key=='+')x--;
  if(key=='*')x++;
  if(key==' ') $(
   if(i==0)i=1;else i=0;
   if(i==1)popcnt++;else popcnt--;
   color(i);plot(x,y);gencnt=0;
  $)
  if(key=='L') $(
   if(lock==0)lock=1;else lock=0;
  $)
  if(key=='↰') $(
   graphics(7+16);setcols();
   popcnt=0;gencnt=0;
  $)
  if(key=='␛')esc1=1;
  if(key==155)contgen();
  if(x<0)x=159;if(x>159)x=0;
  if(y<0)y=95;if(y>95)y=0;
 $)
 dpoke(popadr,popcnt);
$)
errtrap() $(
 err=abs(err);
 printf("↰↓Error # %d",err);
 getkey();
$)
/* Alter Colors */
altcols() $(
 creg=0;esc=0;
 while(esc==0) $(
  poke(752,1);
  if(creg==0)i=712;else i=707+creg;
  cbyte=peek(i)&254;
  hue=cbyte/16;intens=hue*16;
  intens=(cbyte-intens)&14;
  printf("↰↓   C  Col:%-2d  H  Hue:%-2d  L  Lum:%d",creg,hue,intens);
  printf("\n↓   M  Cell Mode: ");
  if(mono==0)printf("Color");
  else printf("Monochrome");
  key=toupper(getkey());
  if(key=='C') $(
   creg++;if(creg>3)creg=0;
  $) else if(key=='H') $(
   hue++;if(hue>15)hue=0;
  $) else if(key=='L') $(
   intens+=2;if(intens>14)intens=0;
  $) else if(key=='M') $(
   if(mono==0)mono=1;else mono=0;
   poke(monadr,mono);
   if(mono==1) $(
    printf("↰↓Converting...");
    initialize();generate();
   $)
  $) else esc=1;
  if(key=='H'||key=='L') $(
   cbyte=hue*16;cbyte+=intens;
   if(creg==0)i=712;else i=707+creg;
   poke(i,cbyte);
  $)
 $)
 getcols();
$)
getcols() $(
 cr0=peek(712);cr1=peek(708);
 cr2=peek(709);cr3=peek(710);
$)
setcols() $(
 poke(712,cr0);poke(708,cr1);
 poke(709,cr2);poke(710,cr3);
$)
/* ML interface */
generate()     asm 0xA000;
initialize()   asm 0xA003;
randomstart()  asm 0xA006;
encode()       asm 0xA400;
decode()       asm 0xA403;