/*

     Milben...

     von Guido Appenzeller - Landessternwarte - 6900 Heidelberg

      Maschienensprache von Guido Appenzeller & Chris Emmerich

     (c) all Rights reserved.

*/

#include <exec/types.h>
#include <functions.h>
#include <stdio.h>
#include <graphics/gfxbase.h>
#include <intuition/intuitionbase.h>
#include <intuition/intuition.h>

#define MAXNUMBER    200

struct IntuitionBase *IntuitionBase;
struct GfxBase       *GfxBase;
struct RastPort      *rp;
UBYTE  *plane0,*plane1;

int   x1,y1;

long x[MAXNUMBER];
long y[MAXNUMBER];
int hunger[MAXNUMBER];
int futter[MAXNUMBER];

int nummer = 200;
int hungertod = 80;
int nachwuchs = 15;
int stoppos   = 3;

int anzahl=1;

int f,t,a,xx,yy;

BYTE  cflag=2;

long mtime;

main(argc,argv)
int   argc;
char  *argv[];
{

if (argc == 1)
{
printf(">>> MultiVirus <<<\n\n  (c) by Guido Appenzeller and Chris Emmerich\n");
printf("\nFormat:  VIRUS [Verzoegerung Anzahl Hunger Nachwuchs StopPos]] [-L]\n");
}
else if ( *argv[1] != 0 )
   {
      for(t=1;t!=argc;t++)
         {
            if(*argv[t]=='-') cflag = ( *(++argv[t])!='L' );
            else
               {
                  if( t == 1 ) mtime = atol( argv[1] );
                  if( t == 2 ) nummer = atoi( argv[2] );
                  if( t == 3 ) hungertod = atoi( argv[3] );
                  if( t == 4 ) nachwuchs = atoi( argv[4] );
                  if( t == 5 ) stoppos   = atoi( argv[5] );
               }
         }
   }

if (nummer > MAXNUMBER-2 ) nummer = MAXNUMBER-2;

/* --- Intuition und Graphics oeffnen                 --- */

if((IntuitionBase = (struct IntuitionBase *)
                  OpenLibrary("intuition.library",0L)) == NULL )
{  printf("Intuition nicht gefunden !\n");
   exit(FALSE);           }

if((GfxBase = (struct GfxBase *)
                  OpenLibrary("graphics.library",0L)) == NULL )
{  printf("Grafix-Library nicht gefunden !\n");
   CloseLibrary(IntuitionBase);
   exit(FALSE);           }



/* --- Initialisieren -------------------------- */

rp = &( IntuitionBase->ActiveScreen->RastPort );
plane0 = rp->BitMap->Planes[0];
plane1 = rp->BitMap->Planes[1];
x[0] = 320; y[0] = 128; hunger[0] = 100; futter[0] = 0;

Delay(mtime);

/* --- Bewegen ------------------------------------- */

while( (IntuitionBase->ActiveScreen->MouseX) != stoppos )
{
   for(t=0;t<anzahl;t++)
   {
   SetAPen(rp,0L);
   WritePixel(rp,x[t],y[t]);
   xx = x[t];yy = y[t];
   a = rand();
   x1=x[t];y1=y[t];
#asm
      movem.l  d0-d7/a0-a6,-(sp)

      clr.w    d0
      clr.w    _f
      move.w   _xx,d0
      move.w   _yy,d1
      addq.w   #1,d0
      jsr      ReadPixel
      subq.b   #1,d3
      bne      links
      move.w   #1,_a
      bset     #0,_f+1
      bra      Weg1

links move.w   _xx,d0
      move.w   _yy,d1
      subq.w   #1,d0
      jsr      ReadPixel
      subq.b   #1,d3
      bne      hoch
      move.w   #2,_a
      bset     #0,_f+1
      bra      Weg1

hoch  move.w   _xx,d0
      move.w   _yy,d1
      subq.w   #1,d1
      jsr      ReadPixel
      subq.b   #1,d3
      bne      runte
      move.w   #4,_a
      bset     #0,_f+1
      bra      Weg1

runte move.w   _xx,d0
      move.w   _yy,d1
      addq.w   #1,d1
      jsr      ReadPixel
      subq.b   #1,d3
      bne      Weg1
      move.w   #8,_a
      bset     #0,_f+1

Weg1  btst     #0,_a+1
      beq      Weg2
      add.w    #1,_xx
Weg2  btst     #1,_a+1
      beq      Weg3
      sub.w    #1,_xx
Weg3  btst     #2,_a+1
      beq      Weg4
      sub.w    #1,_yy
Weg4  btst     #3,_a+1
      beq      WegEn
      add.w    #1,_yy

WegEn tst.w    _yy
      bpl      OM
      clr.w    _f
OM    cmp.w    #$100,_yy
      bne      ON
      clr.w    _f
ON    and.w    #$ff,_yy
      tst.w    _xx
      bpl      OL
      move.w   #639,_xx
      clr.w    _f
OL    cmp.w    #640,_xx
      bmi      OK
      clr.w    _xx
      clr.w    _f
OK    move.w   _xx,d0
      move.w   _yy,d1
      jsr      ReadPixel
      move.b   d3,d4
      clr.b    d3
      tst.b    d4
      beq      Blue
      move.b   _cflag,d3
Blue  move.w   _x1,d0
      move.w   _y1,d1
      jsr      WritePixel
      movem.l  (sp)+,d0-d7/a0-a6
#endasm
   x[t]=xx; y[t]=yy;
   SetAPen(rp,3L);
   WritePixel(rp,x[t],y[t]);

   if( f ) { hunger[t]=hungertod; futter[t]++;}
   if( anzahl-1 )
      {
         if ( !--hunger[t] )
            {
               SetAPen(rp,2L); WritePixel(rp,x[t],y[t]);
               hunger[t]=hunger[--anzahl];
               futter[t]=futter[anzahl];
               x[t]=x[anzahl]; y[t]=y[anzahl];
            }
      }
   if( ( nummer-2 != anzahl ) && ( futter[t] > nachwuchs ) )
      {
         x[anzahl]=x[t];
         y[anzahl]=y[t];
         hunger[anzahl]=hungertod;
         futter[anzahl++]=0;
         futter[t]=0;
      }
   }
   if(anzahl<2) Delay(1L);
}

/* --- Programmende ------------------------- */

CloseLibrary(GfxBase);
CloseLibrary(IntuitionBase);

exit(TRUE);

}


/* - - - - Eigenes WritePixel() x=d0,y=d1,Plane=a0 640/200 Screen -  */
#asm

WritePixel

      move.l   _plane0,a0
      move.l   _plane1,a1
      move.w   d0,d2
      lsr.w    #3,d0
      mulu     #80,d1
      add.w    d0,d1
      eor.w    #7,d2
      btst     #0,d3
      beq      hier1
      bset     d2,(a0,d1)
hier1 btst     #1,d3
      beq      hier2
      bset     d2,(a1,d1)
hier2 rts

ReadPixel

      clr.l    d3
      move.l   _plane0,a0
      move.l   _plane1,a1
      move.w   d0,d2
      lsr.w    #3,d0
      mulu     #80,d1
      add.w    d0,d1
      eor.w    #7,d2
      btst     d2,(a0,d1)
      beq      hier3
      bset     #0,d3
hier3 btst     d2,(a1,d1)
      beq      hier4
      bset     #1,d3
hier4 rts

#endasm
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

