home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus Extra 1996 #3 / AmigaPlus_CD-ROM-EXTRA_Nr.3.bin / spiele-demos / aqua / aqua.c < prev    next >
C/C++ Source or Header  |  1994-04-15  |  20KB  |  694 lines

  1. /* Aqua demo by John Enright.  Graphics (c) Mike Alkan */
  2.  
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <exec/memory.h>
  7. #include <exec/types.h>
  8. #include <graphics/gfx.h>
  9. #include <graphics/gfxbase.h>
  10.  
  11. #include <proto/exec.h>
  12. #include <proto/graphics.h>
  13. #include <proto/intuition.h>
  14.  
  15. #include "GameSmith:GameSmith.h"
  16. #include "GameSmith:include/proto/all_regargs.h"
  17. #include "GameSmith:include/libraries/libptrs.h"
  18.  
  19. #define DISPLAY_SIZE    320                /* lores display resolution horizontal */
  20.  
  21. #define PAGE_SIZE    (DISPLAY_SIZE*4)    /* actual scrollable bitmap size */
  22.  
  23. #define BMDEPTH    4                        /* depth of bitmap (16 color) */
  24. #define BMOFFSET    48            /* buffer amount (in pixels) for anims & display offset */
  25. #define BMWIDTH    (PAGE_SIZE+(BMOFFSET*2))    /* actual width of bitmap */
  26. #define BMHEIGHT    192                    /* height of bitmap.  All of this is visible */
  27.  
  28. #define VS_X            (PAGE_SIZE*10)    /* width of virtual space for object traversal */
  29. #define LEFT_BOUNDS    BMOFFSET            /* left boundary for anim objects */
  30. #define RIGHT_BOUNDS    (VS_X+BMOFFSET)    /* right boundary for anim objects */
  31. #define TOP_BOUNDS    16                    /* top boundary for anim objects */
  32. #define BOTTOM_BOUNDS 184                /* bottom boundary for anim objects */
  33. #define BOTTOM_SPACE    16            /* vertical rows on sea bottom for obj placement */
  34.  
  35. #define ANIM_SPEED    4            /* pixel speed for object movement */
  36.  
  37. #define ANIM_COUNT    22            /* number of objects in each array */
  38.  
  39. #define VB_DELAY        5            /* the fastest objects are allowed to animate */
  40.  
  41. #define FRAME_RATE    1            /* scroll rate in vertical blank intervals */
  42.  
  43. /*-------------------------------------------------------------------------*/
  44. /* Function Prototypes                                                                       */
  45.  
  46. void scroll(void);
  47. int setup(void);
  48. int place_anim_bottom(struct anim_struct *);
  49. int place_cplx_bottom(struct anim_cplx *);
  50. int place_cplx(struct anim_cplx *);
  51. void move_creatures(void);
  52. void move_anim(struct anim_struct *);
  53. void move_cplx(struct anim_cplx *);
  54. void check_bounds(void);
  55. void check_anim_bounds(struct anim_struct *);
  56. void check_cplx_bounds(struct anim_cplx *);
  57. int check_close(void);
  58. void cleanup(void);
  59.  
  60. /*-------------------------------------------------------------------------*/
  61. /* some global variables                                                   */
  62.  
  63. struct Interrupt *scroller=NULL;
  64. unsigned long color[1<<BMDEPTH];    /* color table with 2 to the power of BMDEPTH entries */
  65. int dlist=-1;                            /* display list handle for anims */
  66.  
  67. int rs_offset=0,window,reset=0;
  68.  
  69. /* ---- the anim object array pointers ---- */
  70.  
  71. struct anim_struct *rollcrab=NULL,*coral1=NULL,*coral2=NULL,*coral3=NULL;
  72. struct anim_cplx *fish1=NULL,*fish2=NULL,*fish3=NULL;
  73. struct anim_cplx *aquadino=NULL;
  74.  
  75. /*-------------------------------------------------------------------------*/
  76.  
  77. BitMapHeader bmh;
  78.  
  79. struct loadILBM_struct loadpic =
  80.     {
  81.     "gfx/aqua.pic",    /* ptr to picture name string */
  82.     NULL,                    /* ptr to 1st bitmap */
  83.     NULL,                    /* ptr to 2nd bitmap (if any) */
  84.     color,                /* ptr to color table array */
  85.     (1<<BMDEPTH),        /* # colors in color table */
  86.     NULL,                    /* height of image in pixels (filled by load call) */
  87.     NULL,                    /* width of image in pixels (filled) */
  88.     NULL,                    /* x display offset (filled) */
  89.     NULL,                    /* y display offset (filled) */
  90.     NULL,                    /* pic mode (filled) */
  91.     BMOFFSET/8,            /* x load offset (from left) in bytes */
  92.     0,                        /* y load offset (from top) in rows */
  93.     ILBM_COLOR,            /* flags (fill color table) */
  94.     0xff,                    /* bitplane fill mask */
  95.     0xff,                    /* bitplane load mask */
  96.     &bmh                    /* address of BitMapHeader to fill */
  97.     };
  98.  
  99. unsigned short copper_list[]= {
  100.     UC_NOSPRITES,                        /* turn off sprite DMA */
  101.     UC_END                                /* end custom copper list */
  102.     };
  103.  
  104. struct copper_struct copper = 
  105.     {
  106.     copper_list,
  107.     NULL,
  108.     NULL
  109.     };
  110.  
  111. struct gs_viewport vp =
  112.     {
  113.     NULL,                                    /* ptr to next viewport */
  114.     color,                                /* ptr to color table */
  115.     (1<<BMDEPTH),                        /* number of colors in table */
  116.     &copper,                                /* ptr to user copper list */
  117.     BMHEIGHT,DISPLAY_SIZE,BMDEPTH,BMHEIGHT,BMWIDTH, /* height, width, depth, bmheight, bmwidth */
  118.     0,0,                                    /* top & left viewport offsets */
  119.     BMOFFSET,0,                            /* X & Y bitmap offsets */
  120.     GSVP_ALLOCBM,                        /* flags (allocate bitmaps) */
  121.     NULL,NULL,                            /* 2.xx & above compatibility stuff */
  122.     NULL,NULL,                            /* bitmap pointers */
  123.     NULL,                                    /* future expansion */
  124.     0,0,0,0                                /* display clip (MinX,MinY,MaxX,MaxY) */
  125.     };
  126.  
  127. struct display_struct display =
  128.     {
  129.     NULL,                                    /* ptr to previous display view */
  130.     NULL,NULL,                            /* 2.xx & above compatibility stuff */
  131.     0,0,                                    /* X and Y display offsets (1.3 style) */
  132.     0,                                        /* display mode ID */
  133.     GSV_DOUBLE|GSV_SCROLLABLE,        /* flags (scrollable double buffered) */
  134.     &vp,                                    /* ptr to 1st viewport */
  135.     NULL                                    /* future expansion */
  136.     };
  137.  
  138. /***************************************************************************/
  139.  
  140. main(argc,argv)
  141. int argc;
  142. char *argv[];
  143.  
  144. {
  145.     int err,end=0;
  146.  
  147.     if (gs_open_libs(DOS|GRAPHICS,0))    /* open AmigaDOS libs, latest versions */
  148.         exit(01);                    /* if can't open libs, abort */
  149.     if (err=setup())                /* if couldn't get set up... abort program */
  150.         {
  151.         printf("\nSetup error: %d\n",err);
  152.         gs_close_libs();            /* close all libraries */
  153.         exit(02);
  154.         }
  155.     Forbid();                        /* take over the entire machine */
  156.     while (!end)                    /* this shows off speed */
  157.         {
  158.         move_creatures();            /* animate everything */
  159.         end=check_close();        /* end when user hits left mouse button */
  160.         }
  161.     Permit();                        /* OK, let other things run while we clean up */
  162.     cleanup();                        /* close & deallocate everything */
  163.     gs_close_libs();                /* close all libraries */
  164. }
  165.  
  166. /***************************************************************************/
  167. /*
  168.     This is the scroll handler which runs as a vertical blank server routine
  169.     and handles scrolling of the bitmap.  This is the reason for its ultra-
  170.     smooth performance, regardless of what the animation system is doing.
  171.  
  172.     The "__interrupt" is a SAS convention used to make sure that the function
  173.     does NOT do stack checking.  The "__saveds" is also a SAS convention, and
  174.     loads the near data pointer at the beginning of the function.
  175.  
  176. */
  177.  
  178. void __interrupt __saveds scroll()
  179.  
  180. {
  181.     int stick,x=0,diff,velocity=1,shift=0;
  182.     static int x_offset=0,dir_right=1,flop=0;
  183.  
  184.     flop++;
  185.     if (flop < FRAME_RATE)            /* check against frame rate */
  186.         return;                            /* if not time to scroll, abort */
  187.     flop=0;
  188.     stick = _gs_joystick(1);        /* poll joystick */
  189.     if (stick & (JOY_LEFT|JOY_RIGHT|JOY_BUTTON1))
  190.         {                                    /* if joystick value we're concerned with */
  191.         velocity*=3;                    /* increase velocity */
  192.         if (stick & JOY_BUTTON1)    /* button holds display */
  193.             velocity=0;
  194.         if (stick & JOY_LEFT)
  195.             x=-velocity;
  196.         else if (stick & JOY_RIGHT)
  197.             x=velocity;
  198.         }
  199.     else
  200.         {
  201.         if (dir_right)        /* if scrolling right */
  202.             {
  203.             x=velocity;
  204.             }
  205.         else                    /* else scrolll left */
  206.             {
  207.             x=-velocity;
  208.             }
  209.         }
  210.     x_offset+=x;
  211.     if ((x_offset + DISPLAY_SIZE) >= VS_X)        /* check against scroll boundaries */
  212.         {                                                    /* don't go past virtual space used by anims */
  213.         dir_right=0;
  214.         x_offset=VS_X-DISPLAY_SIZE;;
  215.         x=0;
  216.         }
  217.     else if (x_offset < 0)
  218.         {
  219.         dir_right=1;
  220.         x_offset=0;
  221.         x=0;
  222.         }
  223.     if (x)
  224.         {
  225.         diff=vp.xoff+x-BMOFFSET;
  226.         if (diff < 0)                                    /* if past beginning of actual bitmap */
  227.             {
  228.             x=(PAGE_SIZE-DISPLAY_SIZE)+x;            /* shift to end of bitmap & keep scrolling */
  229.             shift=1;                                        /* this provides a seemless transition, and */
  230.             }                                                /* gives the illusion of an infinite horizon */
  231.         else if (((diff-velocity) < 0))            /* early warning system. :) */
  232.             {                                                /* notify main program of upcoming bitmap shift */
  233.             if ((x_offset-velocity) > 0)
  234.                 {
  235.                 rs_offset-=PAGE_SIZE-DISPLAY_SIZE;
  236.                 window=PAGE_SIZE-DISPLAY_SIZE;    /* adjust real space window */
  237.                 reset=1;                                    /* flag to reset bitmap pointers */
  238.                 }
  239.             }
  240.         else if (diff >= (PAGE_SIZE-DISPLAY_SIZE))
  241.             {
  242.             x=-((PAGE_SIZE-DISPLAY_SIZE)-x);
  243.             shift=1;
  244.             }
  245.         else if ((diff+velocity) >= (PAGE_SIZE-DISPLAY_SIZE))
  246.             {                                                /* notify main program of upcoming bitmap shift */
  247.             if ((x_offset+velocity+DISPLAY_SIZE) < VS_X)
  248.                 {
  249.                 rs_offset+=PAGE_SIZE-DISPLAY_SIZE;
  250.                 window=0;                                /* adjust real space window */
  251.                 reset=1;                                    /* flag to reset bitmap pointers */
  252.                 }
  253.             }
  254.         if (!shift)
  255.             gs_rs_window(dlist,diff,0);            /* scroll real space window over bitmap */
  256.         gs_scroll_vp(&display,0,x,0,1);            /* scroll the display during next VB */
  257.         }
  258. }
  259.  
  260. /***************************************************************************/
  261. /*
  262.     This function creates the display, loads the background picture, loads
  263.     all anim objects, allocates a display list for the animation system,
  264.     adds all objects to the list, draws the objects in the display, shows
  265.     the GDS display, and then installs the scroller.
  266. */
  267.  
  268. int setup()
  269.  
  270. {
  271.     int cnt=0;
  272.     struct anim_load_struct load;
  273.  
  274.     gs_get_ILBM_bm(&loadpic);            /* load color table from picture file */
  275.     #ifdef NTSC_MONITOR_ID
  276.         if (GfxBase->LibNode.lib_Version >= 36)    /* if WB 2.0 or higher */
  277.             {                    /* this defeats mode promotion on AGA machines */
  278.             if (ModeNotAvailable(NTSC_MONITOR_ID))
  279.                 {
  280.                 display.modes = PAL_MONITOR_ID;
  281.                 }
  282.             else
  283.                 {
  284.                 display.modes = NTSC_MONITOR_ID;
  285.                 }
  286.             }
  287.     #endif
  288.     if (gs_create_display(&display))
  289.         {
  290.         return(-1);
  291.         }
  292.     loadpic.bitmap1=vp.bitmap1;        /* tell picture loader where to put picture */
  293.     loadpic.bitmap2=vp.bitmap2;        /* fill both bitmaps with background picture */
  294.     while (cnt < PAGE_SIZE)        /* stagger the picture continously across bitmap width */
  295.         {
  296.         loadpic.loadx=(BMOFFSET+cnt)/8;
  297.         if (gs_loadILBM(&loadpic))
  298.             {
  299.             gs_remove_display(&display);
  300.             return(-2);
  301.             }
  302.         cnt+=bmh.w;                            /* add width of picture to load offset */
  303.         }
  304.     load.flags=ANIMLOAD_NOCOLOR;        /* don't allocate a color table */
  305.     load.cmap_size=8;                        /* number of bits per color value */
  306.     load.array_elements=ANIM_COUNT;    /* number of array elements desired */
  307.     load.filename="anim/rollcrab.anim";    /* name of anim file */
  308.     if (gs_load_anim(&load))            /* load the anim object */
  309.         {
  310.         cleanup();
  311.         return(-3);
  312.         }
  313.     rollcrab=load.anim_ptr.anim;        /* ptr to anim object */
  314.     load.filename="anim/coral1.anim";    /* name of anim file */
  315.     if (gs_load_anim(&load))            /* load the anim object */
  316.         {
  317.         cleanup();
  318.         return(-3);
  319.         }
  320.     coral1=load.anim_ptr.anim;            /* ptr to anim object */
  321.     load.filename="anim/coral2.anim";    /* name of anim file */
  322.     if (gs_load_anim(&load))            /* load the anim object */
  323.         {
  324.         cleanup();
  325.         return(-3);
  326.         }
  327.     coral2=load.anim_ptr.anim;            /* ptr to anim object */
  328.     load.filename="anim/coral3.anim";    /* name of anim file */
  329.     if (gs_load_anim(&load))            /* load the anim object */
  330.         {
  331.         cleanup();
  332.         return(-3);
  333.         }
  334.     coral3=load.anim_ptr.anim;            /* ptr to anim object */
  335.     load.filename="cplx/fish1.cplx";    /* name of anim file */
  336.     if (gs_load_anim(&load))            /* load the anim object */
  337.         {
  338.         cleanup();
  339.         return(-4);
  340.         }
  341.     fish1=load.anim_ptr.cplx;            /* ptr to anim object */
  342.     load.filename="cplx/fish2.cplx";    /* name of anim file */
  343.     if (gs_load_anim(&load))            /* load the anim object */
  344.         {
  345.         cleanup();
  346.         return(-5);
  347.         }
  348.     fish2=load.anim_ptr.cplx;            /* ptr to anim object */
  349.     load.filename="cplx/fish3.cplx";    /* name of anim file */
  350.     if (gs_load_anim(&load))            /* load the anim object */
  351.         {
  352.         cleanup();
  353.         return(-6);
  354.         }
  355.     fish3=load.anim_ptr.cplx;            /* ptr to anim object */
  356.     load.filename="cplx/aquadino.cplx";    /* name of anim file */
  357.     if (gs_load_anim(&load))            /* load the anim object */
  358.         {
  359.         cleanup();
  360.         return(-7);
  361.         }
  362.     aquadino=load.anim_ptr.cplx;            /* ptr to anim object */
  363.     if ((dlist=gs_get_display_list()) < 0)    /* allocate a display list for anims */
  364.         {
  365.         cleanup();
  366.         return(-8);
  367.         }
  368.     gs_init_anim(dlist,vp.bitmap1,vp.bitmap2);    /* tell anim system about bitmaps */
  369.     gs_rs_dim(dlist,DISPLAY_SIZE+(BMOFFSET*2),BMHEIGHT);    /* set new real space dimensions */
  370.             /* define area in which anim objects will be allowed to wander */
  371.     gs_set_anim_bounds(dlist,LEFT_BOUNDS,TOP_BOUNDS,RIGHT_BOUNDS,BOTTOM_BOUNDS);
  372.     if (place_anim_bottom(rollcrab))    /* now place all anim objects in the virtual area */
  373.         {
  374.         cleanup();
  375.         return(-10);
  376.         }
  377.     if (place_anim_bottom(coral1))
  378.         {
  379.         cleanup();
  380.         return(-11);
  381.         }
  382.     if (place_anim_bottom(coral2))
  383.         {
  384.         cleanup();
  385.         return(-12);
  386.         }
  387.     if (place_anim_bottom(coral3))
  388.         {
  389.         cleanup();
  390.         return(-13);
  391.         }
  392.     if (place_cplx_bottom(aquadino))
  393.         {
  394.         cleanup();
  395.         return(-14);
  396.         }
  397.     if (place_cplx(fish1))
  398.         {
  399.         cleanup();
  400.         return(-15);
  401.         }
  402.     if (place_cplx(fish2))
  403.         {
  404.         cleanup();
  405.         return(-16);
  406.         }
  407.     if (place_cplx(fish3))
  408.         {
  409.         cleanup();
  410.         return(-17);
  411.         }
  412.     gs_draw_anims(dlist);                /* actually draw anims in 2nd bitmap */
  413.     check_bounds();                        /* check to see if any need to turn around */
  414.     gs_next_anim_page(dlist);            /* tell animation system to use other bitmap next time */
  415.     gs_show_display(&display,1);        /* show the display */
  416.     gs_flip_display(&display,1);        /* flip to next bitmap page during next vertical blank */
  417.     gs_open_vb_timer();                    /* open the super efficient GDS vertical blank timer */
  418.     gs_vb_timer_reset();
  419.     while (!gs_vb_time());                /* sync gfx with display */
  420.     gs_vb_timer_reset();                    /* reset counter to zero */
  421.     scroller=gs_add_vb_server(&scroll,0);    /* add scroller function to vertical blank server chain */
  422.     if (!scroller)
  423.         {
  424.         cleanup();
  425.         return(-9);
  426.         }
  427.     return(0);                                /* all went well */
  428. }
  429.  
  430. /***************************************************************************/
  431. /*
  432.     Place a simple anim object on the see bottom
  433. */
  434.  
  435. int place_anim_bottom(anim)
  436. struct anim_struct *anim;
  437.  
  438. {
  439.     int cnt;
  440.  
  441.     for (cnt=0; cnt < ANIM_COUNT; cnt++)
  442.         {
  443.         anim[cnt].x = gs_random(VS_X);    /* random X,Y coords */
  444.         anim[cnt].y = gs_random(BOTTOM_SPACE)+(BOTTOM_BOUNDS-BOTTOM_SPACE)-anim[cnt].height;
  445.         anim[cnt].xa = gs_random(ANIM_SPEED) +1;    /* use xa field for object speed */
  446.                                                     /* we can do this since object is not attached to */
  447.                                                     /* anything, and the field would go unused otherwise */
  448.         if (cnt&1)
  449.             {
  450.             anim[cnt].xa=-anim[cnt].xa;
  451.             }
  452.         anim[cnt].prio = anim[cnt].y+anim[cnt].height;    /* obj priority setting */
  453.         if (gs_add_anim(dlist,(struct anim_struct *)&anim[cnt],anim[cnt].x,anim[cnt].y))
  454.             {                                    /* if can't add object to display list */
  455.             return(-1);                        /* return failure */
  456.             }
  457.         gs_set_anim_cell((struct anim_struct *)&anim[cnt],gs_random(anim[cnt].count));
  458.         }
  459.     return(0);
  460. }
  461.  
  462. /***************************************************************************/
  463.  
  464. int place_cplx_bottom(cplx)
  465. struct anim_cplx *cplx;
  466.  
  467. {
  468.     int cnt,seq,x,y;
  469.  
  470.     for (cnt=0; cnt < ANIM_COUNT; cnt++)
  471.         {
  472.         x = gs_random(VS_X);                /* random X,Y coords */
  473.         y = gs_random(BOTTOM_SPACE)+(BOTTOM_BOUNDS-BOTTOM_SPACE)
  474.             -cplx[cnt].height;
  475.         seq=1;
  476.         cplx[cnt].list->xa = gs_random(ANIM_SPEED) +1;    /* use xa field for object speed */
  477.         if (cnt&1)
  478.             {
  479.             seq=0;
  480.             cplx[cnt].list->xa=-cplx[cnt].list->xa;
  481.             }
  482.         if (gs_add_anim_cplx(dlist,(struct anim_cplx *)&cplx[cnt],x,y,seq,y+cplx[cnt].height))
  483.             {                                    /* if can't add object to display list */
  484.             return(-1);                        /* return failure */
  485.             }
  486.         gs_set_cplx_cell((struct anim_cplx *)&cplx[cnt],
  487.             gs_random(cplx[cnt].list->count));
  488.         }
  489.     return(0);
  490. }
  491.  
  492. /***************************************************************************/
  493.  
  494. int place_cplx(cplx)
  495. struct anim_cplx *cplx;
  496.  
  497. {
  498.     int cnt,seq,x,y,pre_y;
  499.  
  500.     pre_y = BOTTOM_BOUNDS-TOP_BOUNDS+12-cplx->height;
  501.     for (cnt=0; cnt < ANIM_COUNT; cnt++)
  502.         {
  503.         x = gs_random(VS_X);                /* random X,Y coords */
  504.         y = gs_random(pre_y)+TOP_BOUNDS;
  505.         seq=1;
  506.         cplx[cnt].list->xa = gs_random(ANIM_SPEED) +1;    /* use xa field for object speed */
  507.         if (cnt&1)
  508.             {
  509.             seq=0;
  510.             cplx[cnt].list->xa=-cplx[cnt].list->xa;
  511.             }
  512.         if (gs_add_anim_cplx(dlist,(struct anim_cplx *)&cplx[cnt],x,y,seq,y+cplx[cnt].height))
  513.             {                                    /* if can't add object to display list */
  514.             return(-1);                        /* return failure */
  515.             }
  516.         gs_set_cplx_cell((struct anim_cplx *)&cplx[cnt],
  517.             gs_random(cplx[cnt].list->count));
  518.         }
  519.     return(0);
  520. }
  521.  
  522. /***************************************************************************/
  523. /*
  524.     This handles movement & animation of all objects.  It also continuously
  525.     redraws all objects in case the bitmap pointers have been reset (see the
  526.     scroll routine).
  527. */
  528.  
  529. void move_creatures()
  530.  
  531. /* move & animate everything */
  532.  
  533. {
  534.     unsigned long time;
  535.  
  536.     if (reset)                                    /* if bitmap pointers being reset */
  537.         {
  538.         reset=0;
  539.         gs_rs_offset(dlist,rs_offset,0);    /* adjust real space offset for anims */
  540.         gs_rs_window(dlist,window,0);        /* adjust real space window over bitmap */
  541.         }
  542.     time = gs_vb_time();                        /* get value of vertical blank timer */
  543.     if (time >= VB_DELAY)                    /* don't go too fast */
  544.         {
  545.         gs_vb_timer_reset();                    /* reset vertical blank timer */
  546.         move_anim(rollcrab);
  547.         move_cplx(aquadino);
  548.         move_cplx(fish1);
  549.         move_cplx(fish2);
  550.         move_cplx(fish3);
  551.         while (display.flags & GSV_FLIP); /* while page not flipped yet */
  552.         gs_draw_anims(dlist);                /* draw them anim objects! */
  553.         gs_flip_display(&display,1);        /* switch to other display, sync */
  554.         gs_next_anim_page(dlist);            /* tell anim sys to use other bitmap */
  555.         check_bounds();                        /* turn around at virtual space bounds */
  556.         }
  557.     else
  558.         {
  559.         while (display.flags & GSV_FLIP); /* while page not flipped yet */
  560.         gs_draw_anims(dlist);                /* draw them anim objects! */
  561.         gs_flip_display(&display,1);        /* switch to other display, sync */
  562.         gs_next_anim_page(dlist);            /* tell anim sys to use other bitmap */
  563.         }
  564. }
  565.  
  566. /***************************************************************************/
  567.  
  568. void move_anim(anim)
  569. struct anim_struct *anim;
  570.  
  571. {
  572.     int cnt;
  573.  
  574.     for (cnt=0; cnt < ANIM_COUNT; cnt++)
  575.         {
  576.         anim[cnt].y+=anim[cnt].xa;
  577.         gs_anim_obj((struct anim_struct *)&anim[cnt],anim[cnt].x,anim[cnt].y);
  578.         }
  579. }
  580.  
  581. /***************************************************************************/
  582.  
  583. void move_cplx(cplx)
  584. struct anim_cplx *cplx;
  585.  
  586. {
  587.     int cnt,x;
  588.  
  589.     for (cnt=0; cnt < ANIM_COUNT; cnt++)
  590.         {
  591.         x=cplx[cnt].anim->x+cplx[cnt].list->xa;    /* move the object */
  592.         gs_anim_cplx((struct anim_cplx *)&cplx[cnt],x,cplx[cnt].anim->y);
  593.         }
  594. }
  595.  
  596. /***************************************************************************/
  597.  
  598. void check_bounds()
  599.  
  600. {
  601.     check_anim_bounds(rollcrab);
  602.     check_cplx_bounds(aquadino);
  603.     check_cplx_bounds(fish1);
  604.     check_cplx_bounds(fish2);
  605.     check_cplx_bounds(fish3);
  606. }
  607.  
  608. /***************************************************************************/
  609. /*
  610.     This function checks against top & bottom boundaries for the rollcrab, and
  611.     reverses direction accordingly.
  612. */
  613.  
  614. void check_anim_bounds(anim)
  615. struct anim_struct *anim;
  616.  
  617. {
  618.     int cnt;
  619.  
  620.     for (cnt=0; cnt < ANIM_COUNT; cnt++)
  621.         {
  622.         if (anim[cnt].flags & (ANIM_BOUNDS_Y1|ANIM_BOUNDS_Y2))
  623.             {
  624.             anim[cnt].xa=-anim[cnt].xa;    /* reverse X direction */
  625.             }
  626.         }
  627. }
  628.  
  629. /***************************************************************************/
  630. /*
  631.     This function checks against left & right boundaries for all other
  632.     creatures, and reverses direction accordingly.
  633. */
  634.  
  635. void check_cplx_bounds(cplx)
  636. struct anim_cplx *cplx;
  637.  
  638. {
  639.     int cnt;
  640.  
  641.     for (cnt=0; cnt < ANIM_COUNT; cnt++)
  642.         {
  643.         if (cplx[cnt].anim->flags & (ANIM_BOUNDS_X1|ANIM_BOUNDS_X2))
  644.             {
  645.             cplx[cnt].list->xa=-cplx[cnt].list->xa;    /* reverse X direction */
  646.             gs_set_cplx_seq((struct anim_cplx *)&cplx[cnt],cplx[cnt].seq^1,
  647.                 cplx[cnt].anim->x,cplx[cnt].anim->y);
  648.             }
  649.         }
  650. }
  651.  
  652. /***************************************************************************/
  653.  
  654. int check_close()
  655.  
  656. /* check for left mouse button click */
  657.  
  658. {
  659.     if (gs_joystick(0) & JOY_BUTTON1)
  660.         return(1);
  661.     return(0);
  662. }
  663.  
  664. /***************************************************************************/
  665.  
  666. void cleanup()
  667.  
  668. /* release all resources and memory */
  669.  
  670. {
  671.     gs_close_vb_timer();
  672.     if (dlist > -1)
  673.         gs_free_display_list(dlist);
  674.     if (scroller)
  675.         gs_remove_vb_server(scroller);
  676.     if (rollcrab)
  677.         gs_free_anim(rollcrab,ANIM_COUNT);
  678.     if (coral1)
  679.         gs_free_anim(coral1,ANIM_COUNT);
  680.     if (coral2)
  681.         gs_free_anim(coral2,ANIM_COUNT);
  682.     if (coral3)
  683.         gs_free_anim(coral3,ANIM_COUNT);
  684.     if (fish1)
  685.         gs_free_cplx(fish1,ANIM_COUNT);
  686.     if (fish2)
  687.         gs_free_cplx(fish2,ANIM_COUNT);
  688.     if (fish3)
  689.         gs_free_cplx(fish3,ANIM_COUNT);
  690.     if (aquadino)
  691.         gs_free_cplx(aquadino,ANIM_COUNT);
  692.     gs_remove_display(&display);
  693. }
  694.