/******************************
 * Amoeba Wars V.2            *
 * (c) Copyright Larry Roux   *
 * Too Hip! Software          *
 ******************************/
#include <osbind.h>

#define TRUE 1
#define FALSE 0
#define M_ON 257
#define M_OFF 256
#define MU_MESAG 0x0010
#define MU_BUTTON 0x0002
#define MU_KEYBD 0x0001
#define MU_TIMER 0x0020
#define WM_REDRAW 20

int handle;

int	xdesk,ydesk,hdesk,wdesk;
int	xwork,ywork,hwork,wwork;

int gl_wchar,gl_hchar,gl_wbox,gl_hbox;

int	hidden;

int	contrl[12];
int	intin[128];
int	ptsin[128];
int	intout[128];
int	ptsout[128];

int work_in[11];
int work_out[57];

 long addr;
 int picpalette[16],pic_rez;
 int savepal[16];
 long *place;
 int chart[18][28];
 int mx,my;
 int colx,rowy;
 int colx2,rowy2;
 int pl_num,cur_turn;
 int loopcolor=2;
 char *redscore="0 0";
 char *greenscore="0 0";
 int score[4];
 int quit;
 int life_count;
 int level;
 char fs_path[32]="A:\*.SAV";
 char fs_select[16]="AMOEBA.SAV";
 char fs_copy[64];
 int life_limit;

open_vwork()
{
int i;
	for(i=0;i<10;work_in[i++]=1);
	work_in[10]=2;
	v_opnvwk(work_in,&handle,work_out);
}

hide_mouse()
{
	if(! hidden){
		graf_mouse(M_OFF,0x0L);
		hidden=TRUE;
	}
}

show_mouse()
{
	if(hidden){
        graf_mouse(0,0x0L);
		graf_mouse(M_ON,0x0L);
		hidden=FALSE;
	}
}

set_clip(clhandle,x,y,w,h)
int clhandle,x,y,w,h;
{
int clip[4];
	clip[0]=x;
	clip[1]=y;
	clip[2]=x+w;
	clip[3]=y+h;
	vs_clip(clhandle,1,clip);
}

/******************************************************
 * draw the screen                                    *
 ******************************************************/

draw_title(baddr)
long *baddr;
{
int x;
  hide_mouse();
  Setpalette(picpalette);  /* set colors to new palette      */

   for(x=0;x<8000;x++){    /* move from pic in mem to screen */
    *(baddr++) = *(place++);
   }
   
    place-=8000;           /* reset the screen pointer       */
  do_score();
  show_mouse();  
}

/**********************************************************
 *  Load the screen into memory                           *
 **********************************************************/

morestuff()
{
  int fd=0;
  int i;
    /* save the old palette:                    */
    for(i=0;i<16;i++) savepal[i] = Setcolor(i,-1);
    addr=Physbase();

    fd=Fopen("AMOEBA.PI2",0);
    if (fd < 0)
     {
      form_alert(0,"[3][Cannot find AMOEBA.PI2!][oh no!]");
      exit(0);
     }
    Fread(fd,2L,pic_rez);
    Fread(fd,32L,picpalette);
    Fread(fd,32000L,place);
    Fclose(fd);

    draw_title(addr);
  
}



chk_res()
{
    int fm_button;
    
    if (work_out[13] !=4)
    {
    fm_button = form_alert(0,"[3][Switch to MED|Resolution|and Restart][OK]");
    return(0);
    }
   return(1);
}

do_dots()
{
 int count,count2;
 int modrow,truecol,truerow;
  
  hide_mouse();
  for(count=1;count<18;count++)
   {
    for(count2=1;count2<28;count2++)
     {
      if(chart[count][count2])
       {
        modrow= count2%2;
        if(modrow)
         {
          truecol=14+((count-1)*26);
         }
         else
          {
           truecol=27+((count-1)*26);
          }
          truerow=4+((count2-1)*6);
          vsf_interior(handle,1);
          vsf_color(handle,chart[count][count2]);
          if(chart[count][count2]==1)
           {
            vsf_color(handle,0);
           }
          v_contourfill(handle,truecol,truerow,-1);
         }
        }
       }
     show_mouse();
}

get_hex()
{
 int event,keycode;
 int butdown=0;
 int ret;
 char msgbuff[16];
 int chosex,chosey;
 int truecol,truerow,modrow;

   do {
	event = evnt_multi(MU_MESAG | MU_BUTTON | MU_KEYBD | MU_TIMER,
			1,1,butdown,
			0,0,0,0,0,
			0,0,0,0,0,
			msgbuff,200,0,&mx,&my,&ret,&ret,&keycode,&ret);

	wind_update(TRUE);
	
	if (event & MU_MESAG)
	  switch (msgbuff[0]) 
	   {
        case WM_REDRAW:
	    hide_mouse();
        draw_title(addr);
        show_mouse();
	    break;
       } /* switch (msgbuff[0]) */

	 if (event & MU_BUTTON) 
	  {
       if(butdown) butdown=FALSE;
       else butdown=TRUE;
	 
	   if((!butdown) && (mx<453) && (my<170))
	    {
	     mx-=3;
         chosex=(mx/13)+1;
         colx=chosex/2;
         if(chosex%2)
          {
           colx+=1;
           rowy=(my/12)+1;
	       rowy+=rowy-1;
          }
         else
          {
           chosey=my-6;
           rowy=((chosey/12)+1)*2;
          }
          fill_it();              
	    }
	   }
	 if(cur_turn==2)
	  {        
        modrow=rowy2%2;
        if(modrow)
         {
          truecol=14+((colx2-1)*26);
         }
         else
          {
           truecol=27+((colx2-1)*26);
          }
          truerow=4+((rowy2-1)*6);
	    vsf_color(handle,loopcolor);
        v_contourfill(handle,truecol,truerow,-1);
        loopcolor++;
        if(loopcolor==4) loopcolor=2;
      }
      if((event & MU_BUTTON) && (mx>464) && (my>156) && (mx< 535)
             && (my<172) && (!butdown))
        {
         save_it();
        }
     if((event & MU_BUTTON) && (mx>551) && (my>178) && (mx< 622)
             && (my<194) && (!butdown))
        {
         load_it();
        }
     if((event & MU_BUTTON) && (mx>551) && (my>156) && (mx<622)
             && (my<172) && (!butdown))
       {
        quit=2;
       } 
     if((score[2]<1) || (score[3]<1))
      {
       quit=1;
      }
	 wind_update(FALSE);
    }while(!quit);
                
}

fill_it()
{
   if(cur_turn==1)
    {
     if(chart[colx][rowy]==pl_num)
      {
       colx2=colx;
       rowy2=rowy;
       cur_turn=2;
      }
      return;
     }
    if((colx2==colx) && (rowy2==rowy) && (cur_turn==2)) 
     {
      cur_turn=1;
     }
    if((cur_turn==2) && (chart[colx][rowy]==0) &&
       (((rowy==rowy2-2) && (colx==colx2)) ||
        ((rowy==rowy2+2) && (colx==colx2)) || 
        ((rowy==rowy2-1) && (colx==colx2-1) && (rowy2%2)) ||
        ((rowy==rowy2+1) && (colx==colx2-1) && (rowy2%2)) ||
        ((rowy==rowy2-1) && (colx==colx2+1) && (!(rowy2%2))) ||
        ((rowy==rowy2+1) && (colx==colx2+1) && (!(rowy2%2))) ||
        ((rowy==rowy2-1) && (colx==colx2)) ||
        ((rowy==rowy2+1) && (colx==colx2))))
     {
      cur_turn=1;
      chart[colx2][rowy2]=0;
      chart[colx][rowy]=pl_num;
        pl_num++;
        if(pl_num==4) 
         {
          pl_num=2;
         }
        else
         {
		  life_count++;
		  
          if(life_count==life_limit) 
           {
            do_life();
            life_count=2;
           }
         }
      }
    draw_title(addr);
    do_dots();
}     

do_life()
{
 int chart2[18][28];
 int xx,yy,zz;
 int adj_count[4];
 int friends,enemys;
 int me, you;
 int flaga;
 int mult[7];
 

 for(xx=1;xx<18;xx++)
  {
   for(yy=1;yy<28;yy++)
    {
     chart2[xx][yy]=chart[xx][yy];
    }
  }

 for(xx=1;xx<18;xx++)
  {
   for(yy=1;yy<28;yy++)
    {
     if(chart[xx][yy] > 1)
      {
       for(zz=1;zz<7;zz++)
        {
         mult[zz]=0;
        }
       adj_count[2]=0;
       adj_count[3]=0;
       me=chart[xx][yy];
       if(me==2) { you=3; }
       else { you=2; }

       if((yy>2) && (chart[xx][yy-2]))  /* up */
        {
         adj_count[chart[xx][yy-2]]++;
         mult[1]=1;
        }
       if((yy<16) && (chart[xx][yy+2])) /* down */
        {
         adj_count[chart[xx][yy+2]]++;
         mult[2]=1;
        }
       if((yy>1) && (chart[xx][yy-1])) /* angle */
        {
         adj_count[chart[xx][yy-1]]++;
         mult[3]=1;
        }
       if((yy<17) && (chart[xx][yy+1])) /* angle */
        {
         adj_count[chart[xx][yy+1]]++;
         mult[4]=1;
        }
       if((yy%2) && (xx>1) && (yy>1) && (chart[xx-1][yy-1]))
        {
         adj_count[chart[xx-1][yy-1]]++;
         mult[5]=1;
        }
       if((yy%2) && (yy<17) && (xx>1) && (chart[xx-1][yy+1]))
        {
         adj_count[chart[xx-1][yy+1]]++;
         mult[6]=1;
        }
       if((!(yy%2)) && (yy>1) && (xx<27) && (chart[xx+1][yy-1]))
        {
         adj_count[chart[xx+1][yy-1]]++;
         mult[5]=2;
        }
       if((!(yy%2)) && (xx<17) && (yy<27) && (chart[xx+1][yy+1]))
        {
         adj_count[chart[xx+1][yy+1]]++;
         mult[6]=2;
        }
       /* die */
       if(chart[xx][yy]==2)
        {
         friends=adj_count[2];
         enemys=adj_count[3];
        }
       else
        {
         friends=adj_count[3];
         enemys=adj_count[2];
        }
       flaga=0;
       if((friends+enemys==6) && (rnd(100)<75))
        { 
	     flaga=1;
		}
          
       if((friends+enemys==5) && (rnd(100)<50))
        { 
         flaga=1;
        }
       if((friends+enemys==4) && (rnd(100)<25))
        { 
         flaga=1; 
        }
       if((friends+enemys==3) && (rnd(100)<10))
        { 
         flaga=1; 
        }
       if((friends+enemys==1) && (rnd(100)<5))
        { 
         flaga=1; 
        }
       if((friends+enemys==0) && (rnd(100)<10))
        { 
         flaga=1; 
        }
       if(flaga)
        {
         score[me]--;
         chart2[xx][yy]=0;
        }
       /* absorb */
      flaga=0;
      if((friends==0) && (enemys==2) && (rnd(100)<5))
        {
         flaga=1;
        }
      if((friends==0) && (enemys==3) && (rnd(100)<20))
        {
         flaga=1;
        }
      if((friends==0) && (enemys==4) && (rnd(100)<50))
        {
         flaga=1;
        }
      if((friends==0) && (enemys==5) && (rnd(100)<70))
        {
         flaga=1;
        }
       if((friends==1) && (enemys==2) && (rnd(100)<10))
        {
         flaga=1;
        }
       if((friends==1) && (enemys==3) && (rnd(100)<30))
        {
         flaga=1;
        }
       if((friends==1) && (enemys==4) && (rnd(100)<75))
        {
         flaga=1;
        }  
       if((friends==2) && (enemys==3) && (rnd(100)<10))
        {
         flaga=1;
        } 
       if((friends==3) && (enemys==2) && (rnd(100)<5))
        {
         flaga=1;
        }
       if(flaga)
        {
         score[me]--;
         score[you]++;
         chart2[xx][yy]=you;
        }
       /* multiply */  
       flaga=0;
       if((friends==1) && (enemys<4) && (rnd(100)<10))
        {
         flaga=1;
        }
       if((friends==2) && (enemys<4) && (rnd(100)<30))
        {
         flaga=1;
        } 
       if((friends==3) && (enemys<3) && (rnd(100)<60))
        {
         flaga=1;
        }
       if((friends==4) && (enemys<2) && (rnd(100)<20))
        {
         flaga=1;
        }
       if((friends==5) && (enemys==0) && (rnd(100)<10))
        {
         flaga=1;
        }          
       if(flaga)
        {
         zz=0;
       if(yy<3) mult[1]=1;
       if(yy>25) mult[2]=1;
       if(yy<2) mult[3]=1;
       if(yy>26) mult[4]=1;
       if((mult[5]==1) && ((xx<2) || (yy<2))) mult[5]=1;
       if((mult[6]==1) && ((xx<2) || (yy>26))) mult[6]=1;
       if((mult[5]==2) && ((xx>16) || (yy<2))) mult[5]=1;
       if((mult[6]==2) && ((xx>16) || (yy>26))) mult[6]=1;
         do
          {
           zz++;
          }while(mult[zz]);
         if((zz==1) && (chart2[xx][yy-2]==0))
          {
           score[me]++;
           chart2[xx][yy-2]=me;
          }
         if((zz==2) && (chart2[xx][yy+2]==0))
          {
           score[me]++;
           chart2[xx][yy+2]=me;
          }
         if((zz==3) && (chart2[xx][yy-1]==0))
          {
           score[me]++;
           chart2[xx][yy-1]=me;
          }
         if((zz==4) && (chart2[xx][yy+1]==0))
          {
           score[me]++;
           chart2[xx][yy+1]=me;
          } 
         if((zz==5) && (mult[5]==1) && (chart2[xx-1][yy-1]==0))
          {
           score[me]++;
           chart2[xx-1][yy-1]=me;
          }
         if((zz==6) && (mult[6]==1) && (chart2[xx-1][yy+1]==0))
          {
           score[me]++;
           chart2[xx-1][yy+1]=me;
          }
         if((zz==5) && (mult[5]==2) && (chart2[xx+1][yy-1]==0))
          {
           score[me]++;
           chart2[xx+1][yy-1]=me;
          }
         if((zz==6) && (mult[6]==2) && (chart2[xx+1][yy+1]==0))
          {
           score[me]++;
           chart2[xx+1][yy+1]=me;
          } 
        }                                          
      }
    }
  }

 for(xx=1;xx<18;xx++)
  {
   for(yy=1;yy<28;yy++)
    {
     chart[xx][yy]=chart2[xx][yy];
    }
  }
}

do_fsel()
{
int fs_button,
    nut;
long i;
char filename[64];
char *temp;

    fsel_input(fs_path,fs_select,&fs_button);
    if (fs_button)
     {
      i=strlen(fs_path);
	  temp=fs_path+(i-1);
      while((*temp != '*') && (*temp != '\\') && (temp >= fs_path))
       temp--;
       temp++;
       *temp=0;
	  return(1);
     }
    return(0);
} 

get_fname()
{
  char *temp;
  int success;
  long i;
  
     success=do_fsel();
     if(success)
      {
       strcpy(fs_copy,fs_path);
	   i=strlen(fs_copy);
	   temp=fs_copy+(i-1);
	   while((*temp != '\\') && (temp >= fs_copy))
	   temp--;
	   temp++;
	   *temp=0;
	   strcat(fs_copy,fs_select);
       return(1);
	  }
 return(0);
}


load_it()
{
 int fd;
 int x,y;
 char temp;
 int inone,intwo;
 int fsuc;

   fsuc=get_fname();
   if(!fsuc) 
    {
     draw_title(addr);
     do_dots();
     return;
    }
   fd=Fopen(fs_copy,2);
   if (fd < 0)  /* Can't open List of files */
    { 
     form_alert(1,"[0][CANT OPEN SAVE FILE][uh oh]");
     draw_title();
     do_dots();
     return;
    }
    Fread(fd,1L,&temp);
    inone=temp;
    Fread(fd,1L,&temp);
    intwo=temp;
    if((inone != 76) || (intwo != 82))
     {
      Fclose(fd);
      form_alert(1,"[1][That file is not an|AMOEBA save file][oops!]");
      draw_title(addr);
      do_dots();
      return;
     }
    Fread(fd,1L,&temp);
    pl_num=temp;
    score[2]=0;
    score[3]=0;
    for(x=1;x<18;x++)
     {
      for(y=1;y<28;y++)
       {
        Fread(fd,1L,&temp);
        chart[x][y]=temp;
        if(temp) score[temp]++;
       }
     }
    Fclose(fd);
    draw_title(addr);
    do_dots();
} 

save_it()
{
 int fd;
 int x,y;
 char temp;
 int fsuc;

   fsuc=get_fname();
   if(!fsuc)     
    {
     draw_title(addr);
     do_dots();
     return;
    }
   fd=Fcreate(fs_copy,0);
   if (fd < 0)  /* Can't open List of files */
    { 
     form_alert(1,"[0][CANT CREATE SAVE FILE][uh oh]");
     draw_title();
     do_dots();
     return;
    }
    temp=76;
    Fwrite(fd,1L,&temp);
    temp=82;
    Fwrite(fd,1L,&temp);

    temp=pl_num;
    Fwrite(fd,1L,&temp);
    /* save score here */
    for(x=1;x<18;x++)
     {
      for(y=1;y<28;y++)
       {
        temp=chart[x][y];
        Fwrite(fd,1L,&temp);
       }
     }
    Fclose(fd);
    draw_title(addr);
    do_dots();
}   

do_score()
{
 int charw,charh,cellw,cellh;
 int rvar,numb;
 
 rvar=score[2]/10;
 redscore[0]=rvar+16;
 redscore[2]=(score[2]-(rvar*10))+16;
 rvar=score[3]/10;
 greenscore[0]=rvar+16;
 greenscore[2]=(score[3]-(rvar*10))+16;
 vst_point(handle,10,&charw,&charh,&cellw,&cellh);
 vswr_mode(handle,2);  
 vst_effects(handle,1);
 vst_color(handle,2);
 v_gtext(handle,539,51,greenscore);
 vst_color(handle,3);
 v_gtext(handle,540,50,greenscore);
 vst_color(handle,3);
 v_gtext(handle,539,91,redscore);
 vst_color(handle,2);
 v_gtext(handle,540,90,redscore);

 vst_color(handle,0);
 for(numb=1;numb<life_count;numb++)
  {
   v_gtext(handle,510+(numb*10),104,"-");
  }
 vst_color(handle,0);
 v_gtext(handle,520,165-(pl_num*12),"---->");
}
 
rnd(n) /* Random number from... */
  int n; /* 1 to n*/
  {
        int rmnd = 0, mask = 0x000002;
        --n;
        do
          {
                while (mask <= n) mask <<= 1;
                mask -= 1;
                rmnd = Random() & mask; /* Mask off upper bits */
          } /* If still too large... */
        while (rmnd > n); /* try again */
        return(rmnd+1); /* Return results */
}
 
do_win()
{
 if(score[3]<1)
  {
   form_alert(1,"[1][RED Player Wins!|Congratulations!][Amoeba]");
  }
 if(score[2]<1)
  {
   form_alert(1,"[1][GREEN Player Wins!|Congratulations!][Amoeba]");
  }
}

get_level()
{
 level=form_alert(1,"[0][Choose Level of Play][Low|Med|High]");
}

do_walls()
{
 int loop;
 
 if(level==1)
  {
     score[2]=4;
     score[3]=4;
 
     chart[5][13]=3;
     chart[5][14]=3;
     chart[6][13]=3;
     chart[5][12]=3;
     chart[12][13]=2;
     chart[12][14]=2;
     chart[12][12]=2;
     chart[13][13]=2;
     for(loop=5;loop<25;loop+=2)
      {
       chart[4][loop]=1;
       chart[14][loop]=1;
      }
     for(loop=4;loop<15;loop++)
      {
       chart[loop][5]=1;
       if(loop < 14) chart[loop][4]=1;
       chart[loop][23]=1;
       if(loop < 14) chart[loop][24]=1;
      }
     /* the chart is 17 by 27 */
   }
 if(level==2)
  {
     score[2]=7;
     score[3]=7;
 
     chart[5][13]=3;
     chart[5][14]=3;
     chart[6][13]=3;
     chart[5][12]=3;
     chart[5][15]=3;
     chart[5][16]=3;
     chart[6][15]=3;
     chart[12][13]=2;
     chart[12][14]=2;
     chart[12][12]=2;
     chart[13][13]=2;
     chart[12][15]=2;
     chart[12][16]=2;
     chart[13][15]=2;
     for(loop=1;loop<29;loop+=2)
      {
       chart[4][loop]=1;
       chart[14][loop]=1;
      }

   }
  if(level==3)
   {    
     score[2]=14;
     score[3]=14;
  
     chart[1][4]=3;
     chart[2][3]=3;
     chart[2][4]=3;
     chart[1][6]=3;
     chart[2][7]=3;
     chart[2][5]=3;
     chart[2][6]=3;
     chart[16][21]=3;
     chart[16][23]=3;
     chart[16][20]=3;
     chart[17][21]=3;
     chart[16][22]=3;
     chart[17][23]=3;
     chart[16][24]=3;
     chart[2][21]=2;
     chart[2][22]=2;
     chart[2][23]=2;
     chart[1][22]=2;
     chart[1][24]=2;
     chart[2][25]=2;
     chart[2][24]=2;
     chart[16][4]=2;
     chart[16][5]=2;
     chart[16][6]=2;
     chart[16][7]=2;
     chart[16][8]=2;
     chart[17][5]=2;
     chart[17][7]=2;
    }
}

main()
{	
 int reschk;
 int count,count2;
 int xx,yy;

	appl_init();
	handle=graf_handle(&gl_wchar,&gl_hchar,&gl_wbox,&gl_hbox);
    /* set up space to hold screen info     */
	place=(long *) Malloc(32000L);
    open_vwork();
    reschk=chk_res();
    quit=0;

    do
    {
     for(xx=1;xx<18;xx++)
      {
       for(yy=1;yy<28;yy++)
        {
         chart[xx][yy]=0;
        }
      }
     life_count=2;

      if(reschk)
       {
        pl_num=3;
        cur_turn=1;
        if (!quit) morestuff(); 
        if (quit) draw_title(addr);
        quit=0;
        get_level();
        if(level==1) life_limit=3;
        if(level==2) life_limit=5;
        if(level==3) life_limit=7;
        do_walls();
        draw_title(addr);
        do_dots();
        get_hex();
       }
       if(quit==1)
        {
         do_win();
         quit=0;
        }
      quit=form_alert(2,"[1][Do you really want to Quit?][Restart|Quit]");
      }while(quit<2);
     Mfree(place);
}
