home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 412.lha / spiders / spiders.c < prev    next >
C/C++ Source or Header  |  1990-09-02  |  12KB  |  379 lines

  1. /************************************************************************/
  2. /*                                                                      */
  3. /*                                   ######################             */
  4. /*      A n t h o n y                      ##  ##  ##                   */
  5. /*                                         ##########                   */
  6. /*              T h y s s e n            ####  ##  ####                 */
  7. /*                                     ####    ##    ####               */
  8. /*                                   ####      ##      ####             */
  9. /*                                                                      */
  10. /************************************************************************/
  11.  
  12. /*
  13. **  Spiders - for AMIGA under lattace C
  14. */
  15.  
  16. #include <stdio.h>
  17. #include <string.h>
  18. #include <intuition/intuition.h>
  19. #include <graphics/gfx.h>
  20. #include <exec/exec.h>
  21. #include <proto/all.h>
  22. #define   BM_SRC   0xC0      /* minterm source only */
  23. #define   BM_DST   0xA0      /* minterm destination only */
  24.  
  25. #include "spiders.h"
  26.  
  27. struct Library       *IntuitionBase = NULL, *GfxBase = NULL;
  28. struct Remember      *Remember = NULL;
  29. struct Screen        *WBScrn = NULL;
  30. struct Window        *Window = NULL;          /* Window pointer */
  31. struct Task          *MyTask = NULL;          /* my tasks address */
  32. struct IntuiMessage  *message;
  33. ULONG                WindowSignal;            /* IDCMP window signal */
  34. int                  WBDepth, WBScrX, WBScrY; /* Screen info */
  35. struct NewWindow     NW = {
  36.         30, 200, 205, 10, 0, 1,               /* position, size and colors */
  37.         CLOSEWINDOW,                          /* IDCMP messages */
  38.         ACTIVATE| SIMPLE_REFRESH| WINDOWDEPTH|
  39.            WINDOWDRAG| WINDOWCLOSE,           /* window flags */
  40.         NULL, NULL,                           /* gadget, checkmark */
  41.         (UBYTE *) " -- Spiders -- ",          /* name of window */
  42.         NULL,NULL,                            /* screen-> , BitMap-> */
  43.         0,0,0,0,                              /* min and max size (disable) */
  44.         WBENCHSCREEN                          /* screen type */
  45.         };
  46.  
  47.  
  48. typedef struct {
  49.   int           x, y;
  50. }               point;
  51.  
  52. typedef enum {
  53.     Sleeping,          /* Waiting to start - off screen */
  54.     Waiting,           /* Comtemplating the decent */
  55.     Decending,         /* Going down screen */
  56.     Landed,            /* Getting a bit of screen */
  57.     Ascending,         /* Going up the screen */
  58.     Munching           /* eating its bit of screen */
  59. } status;
  60.  
  61. static struct {
  62.   point              ulc;               /* upper left corner of spider */
  63.   status             stat;              /* current status of crab */
  64.   int                time;              /* time count down to actions */
  65.   struct RastPort    bitRP;             /* raster port for screen bit */
  66.   struct BitMap      bitBM;             /* bit map for the screen bit */
  67. }                    Spider[NUMBER];    /* spider' state */
  68.  
  69. /* images and masks */
  70. unsigned short chip  SpiderImage[] =
  71. #  include "spiderimage.i"
  72. unsigned short chip  MaskImage[] =
  73. #  include "maskimage.i"
  74.  
  75. struct RastPort      SpiderRP, MaskRP, ScreenRP;      /* RastPorts */
  76. struct BitMap        SpiderBM, MaskBM;                /* BitMaps */
  77.  
  78. #ifdef CBACK
  79. /* Cback.o varibles */
  80. long _stack = 2000;
  81. char *_procname = "spiders";
  82. long _priority = -1;
  83. long _BackGroundIO = 0;
  84. #endif
  85.  
  86.   /* function declarations */
  87. extern void  Init(), OpenLibraries(), SpiderExit(), Cycle();
  88. extern void  HideScrBit(), DrawScrBit(), HideSpider(), DrawSpider();
  89. extern int   TestDown(), RandInt();
  90. extern void  RandInit();
  91.  
  92. void
  93. _main()
  94.   /* I am not using printf's functions so _main() will do */
  95. {
  96.   Init();                              /* set up initial grey crab layer */
  97.  
  98.   for (;;) {                           /* no way out! */
  99.     Cycle();                           /* move the crabs */
  100.   }
  101.   /* NOTREACHED */
  102. }
  103.  
  104. void
  105. Init()
  106. {
  107.   int i, j;
  108.  
  109.   RandInit();
  110.  
  111.   OpenLibraries();        /* open the various system structures */
  112.  
  113.   if( !(Window = OpenWindow( &NW )) )
  114.     SpiderExit();
  115.   WindowSignal = 1<<Window->UserPort->mp_SigBit;
  116.  
  117.   MyTask = FindTask( NULL );
  118.   WBScrn = Window->WScreen;
  119.   WBDepth = 2;                            /* Assume it (for WB pic progs) */
  120.   WBScrX = WBScrn->Width -XSPIDER;
  121.   WBScrY = WBScrn->Height -YSPIDER;
  122.  
  123.   /* grab a copy of the screens raster port */
  124.   memcpy( (char *)&ScreenRP, (char *)&WBScrn->RastPort,
  125.                                        sizeof( struct RastPort ) );
  126.  
  127.   /* define spiders */
  128.   for (i = 0; i < NUMBER; i++) {
  129.     Spider[i].stat = Sleeping;               /* spider is just sleeping */
  130.     Spider[i].time = RandInt(1, SLEEPTIME);
  131.       /* initialise bitmaps */
  132.     InitRastPort( &Spider[i].bitRP );
  133.     Spider[i].bitRP.BitMap = &Spider[i].bitBM;
  134.     InitBitMap( &Spider[i].bitBM, WBDepth, XMASK, YMASK);
  135.     for( j = 0; j < WBDepth; j++ )
  136.       if( !( Spider[i].bitBM.Planes[j] = (PLANEPTR)
  137.            AllocRemember( &Remember, RASSIZE(XMASK, YMASK),
  138.                MEMF_CHIP | MEMF_CLEAR ) ) )
  139.         SpiderExit();
  140.   }
  141.     InitRastPort( &MaskRP );
  142.     MaskRP.BitMap = &MaskBM;
  143.     InitBitMap( &MaskBM, WBDepth, XMASK, YMASK);
  144.     for( j = 0; j < WBDepth; j++ )
  145.       MaskBM.Planes[j] = (PLANEPTR) &MaskImage;
  146.  
  147.     InitRastPort( &SpiderRP );
  148.     SpiderRP.BitMap = &SpiderBM;
  149.     InitBitMap( &SpiderBM, 1, XSPIDER, YSPIDER);
  150.     SpiderBM.Planes[0] = (PLANEPTR) &SpiderImage;
  151. }
  152.  
  153. void
  154. OpenLibraries()
  155. {
  156.   if( ! (IntuitionBase = OpenLibrary( "intuition.library", 0 )) )
  157.     SpiderExit();
  158.   if( ! (GfxBase = OpenLibrary( "graphics.library", 0 )) )
  159.     SpiderExit();
  160. }
  161.  
  162. void
  163. SpiderExit()
  164. /* exit - remove all traces */
  165. {
  166.   FreeRemember( &Remember, TRUE );          /* free all allocated memory */
  167.  
  168.   if( Window )          CloseWindow( Window );
  169.   if( GfxBase )         CloseLibrary( GfxBase );
  170.   if( IntuitionBase )   CloseLibrary(  IntuitionBase );
  171.  
  172.   exit(0);
  173. }
  174.  
  175. void
  176. Cycle()
  177.  /* one motion cycle for all spiders */
  178. {
  179.   int             s;                 /* spider to do */
  180.  
  181.   /* test for window closure */
  182.   if( message = (void *)GetMsg(Window->UserPort) ) {
  183.     ReplyMsg( (void *) message );
  184.     switch( message->Class ) {
  185.       case CLOSEWINDOW : /* window closed message */
  186.         SpiderExit();
  187.     }
  188.   } /* Message test */
  189.  
  190. #if DELAY
  191.   Delay(DELAY);
  192. #endif
  193.  
  194.   for (s = 0; s < NUMBER; s++) {
  195.     switch( Spider[s].stat ) {
  196.       case Sleeping:
  197.         {
  198.           int i, test;
  199.  
  200.           if( --Spider[s].time ) break;     /* spider not yet ready to start */
  201.           do {
  202.             Spider[s].ulc.x = RandInt(0, WBScrX);
  203.             test = TRUE;                    /* assume this position is OK */
  204.             for(i = 0; i < NUMBER; i++)
  205.               if( Spider[i].stat != Sleeping &&
  206.                   Spider[s].ulc.x > Spider[i].ulc.x - XSPIDER &&
  207.                   Spider[i].ulc.x > Spider[s].ulc.x - XSPIDER ) {
  208.                 test = FALSE;   /* spider on screen already in this position */
  209.                 break;
  210.               }
  211.           } while ( !test );    /* repeat search until good position found */
  212.           Spider[s].ulc.y = SCREENTOP;
  213.           Spider[s].stat = Waiting;
  214.           Spider[s].time = WAITTIME;
  215.           DrawSpider(s);
  216.         }
  217.         break;
  218.  
  219.       case Waiting:
  220.           if( Spider[s].time-- )   break;
  221.           Spider[s].stat = Decending;
  222.           break;
  223.  
  224.       case Decending:
  225.         {
  226.           int   y, speed;
  227.  
  228.           y = Spider[s].ulc.y;
  229.           speed = TestDown(s);      /* check on landing or screen bottom */
  230.           y += speed;                /* Decend quickly or stop? */
  231.           if( !speed )
  232.             Spider[s].stat = Landed;
  233.           Spider[s].ulc.y = y;
  234.           DrawSpider(s);            /* don't hide spide to leave ... trail */
  235.         }
  236.         break;
  237.  
  238.       case Landed:
  239.         /* bit of screen already read in testdown() just wait */
  240.         Spider[s].stat = Ascending;
  241.         break;
  242.  
  243.       case Ascending:
  244.         {
  245.           int   y;
  246.  
  247.           y = Spider[s].ulc.y;
  248.           y--;                         /* Ascend at a slow rate */
  249.           if( y < SCREENTOP ) {        /* Spider hit rock bottom */
  250.             y = SCREENTOP;
  251.             Spider[s].stat = Munching;
  252.             Spider[s].time = (YMASK+2) * EATRATE-1;
  253.           }
  254.           HideSpider(s); HideScrBit(s);
  255.           Spider[s].ulc.y = y;
  256.           DrawSpider(s); DrawScrBit(s);
  257.         }
  258.         break;
  259.  
  260.       case Munching:
  261.         if( !Spider[s].time ) {
  262.           /* reinitialize start */
  263.           Spider[s].stat = Sleeping;
  264.           Spider[s].time = RandInt(1, SLEEPTIME);   /* random delay in starting */
  265.           HideSpider(s);
  266.           break;
  267.         }
  268.         if( !(Spider[s].time-- % EATRATE ) ) {       /* eat another bit? */
  269.           HideScrBit(s);
  270.           ScrollRaster( &Spider[s].bitRP, 0, 1, 0, 0, XMASK-1, YMASK-1);
  271.           DrawScrBit(s);
  272.         }
  273.         break;
  274.     }
  275.   }    /* move next spider */
  276. }
  277.  
  278. int
  279. TestDown(s)
  280.   int             s;
  281. /* returns distance to first screen bit below spider */
  282. /* if the Spider is withing SPEED of that piece  */
  283. /* Also gets the actual piece into the bitRP of spider */
  284. {
  285.   int    i, j, size, speed = SPEED;
  286.   UBYTE *bits0, *bits1;
  287.   /* clear out any old image */
  288.   SetRast( &Spider[s].bitRP, 0 );
  289.  
  290.   size = WBScrY - Spider[s].ulc.y;
  291.   if( size > YMASK )    size = YMASK;     /* reduce image size */
  292.   if( size < speed )    speed = size;     /* reduce speed - don't over shoot */
  293.   if( !size )           return 0;         /* oops rock bottom! */
  294.  
  295.   /* get a image from screen */
  296.   ClipBlit( &ScreenRP, Spider[s].ulc.x, Spider[s].ulc.y + YSPIDER,
  297.             &Spider[s].bitRP, 0, 0,
  298.             XMASK, size, BM_SRC);
  299.   /* mask out background */
  300.   ClipBlit( &MaskRP, 0, 0,
  301.             &Spider[s].bitRP, 0, 0,
  302.             XMASK, YMASK, BM_SRC & BM_DST);
  303.  
  304.   /* check the data to find distance to landing on screen bit */
  305.   bits0 = Spider[s].bitBM.Planes[0];
  306.   bits1 = Spider[s].bitBM.Planes[1];
  307.   for (i = 0; i < speed; i++)
  308.     for( j = 0; j < Spider[s].bitBM.BytesPerRow; j++ )
  309.       if( *(bits0++) || *(bits1++) )   /* if a bit in either plane */
  310.         return i;                      /* return distance to screen bit */
  311.  
  312.   return speed;                        /* return speed */
  313. }
  314.  
  315. void
  316. HideScrBit(s)
  317.   int s;
  318.   /* remove screen bit carried */
  319. {
  320.   int  size;
  321.  
  322.   size = WBScrY - Spider[s].ulc.y;
  323.   if( size > YMASK )    size = YMASK;      /* reduce image size */
  324.   if( !size )           return;            /* noting to erase */
  325.  
  326.   ClipBlit( &MaskRP, 0, 0,
  327.             &ScreenRP, Spider[s].ulc.x, Spider[s].ulc.y + YSPIDER,
  328.             XMASK, size, ~BM_SRC & BM_DST);
  329. }
  330.  
  331. void
  332. DrawScrBit(s)
  333.   int s;
  334. /* draw screen bit carried */
  335. {
  336.   int  size;
  337.  
  338.   size = WBScrY - Spider[s].ulc.y;
  339.   if( size > YMASK )    size = YMASK;     /* reduce image size */
  340.   if( !size )           return;           /* no room to draw */
  341.   ClipBlit( &Spider[s].bitRP, 0, 0,
  342.             &ScreenRP, Spider[s].ulc.x, Spider[s].ulc.y + YSPIDER,
  343.             XMASK, size, BM_SRC | BM_DST);
  344. }
  345.  
  346. void
  347. HideSpider(s)
  348.   int    s;
  349. /* over write current spider */
  350. {
  351.   ClipBlit( &SpiderRP, 0, 0,
  352.             &ScreenRP, Spider[s].ulc.x, Spider[s].ulc.y,
  353.             XSPIDER, YSPIDER, 0);
  354. }
  355.  
  356. void
  357. DrawSpider(s)
  358.   int    s;
  359. /* Draw the spider on the screen */
  360. {
  361.   ClipBlit( &SpiderRP, 0, 0,
  362.             &ScreenRP, Spider[s].ulc.x, Spider[s].ulc.y,
  363.             XSPIDER, YSPIDER, BM_SRC);
  364. }
  365.  
  366. void
  367. RandInit()
  368. {
  369.   srand((int)time(NULL));
  370. }
  371.  
  372. int
  373. RandInt(lo, hi)                        /* generate random integer in range */
  374.   int             lo, hi;              /* range lo..hi inclusive */
  375. {
  376.   return lo + (int)( (unsigned)rand() % (hi - lo +1) );
  377. }
  378.  
  379.