home *** CD-ROM | disk | FTP | other *** search
/ Global Amiga Experience / globalamigaexperience.iso / compressed / development / gamesmithdemos.lha / gdsdemos / bubble / bubble_blank.c < prev    next >
C/C++ Source or Header  |  1994-11-14  |  14KB  |  441 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <exec/memory.h>
  5. #include <exec/types.h>
  6. #include <graphics/gfx.h>
  7. #include <graphics/gfxbase.h>
  8.  
  9. #include <proto/exec.h>
  10. #include <proto/graphics.h>
  11.  
  12. #include "GameSmith:GameSmith.h"
  13. #include "GameSmith:include/libraries/libptrs.h"
  14. #include "bubble.h"
  15.  
  16. /*-------------------------------------------------------------------------*/
  17. /* Function Prototypes                                                      */
  18.  
  19. void parser(int,char **);
  20. int setup(void);
  21. void move_image(void);
  22. void check_bounds(void);
  23. void collision(struct anim_struct *,struct anim_struct *,
  24.      struct collision_struct *,struct collision_struct *);
  25. int check_close(void);
  26. void cleanup(void);
  27. void free_arrays(void);
  28.  
  29. /*-------------------------------------------------------------------------*/
  30. /* some global variables                                                   */
  31.  
  32. int bubble_cnt,swidth,sheight,smode,delay=0,random_x=11,random_y=9;
  33. int *x=NULL,*y=NULL,*speedx=NULL,*speedy=NULL,*reset=NULL,*last=NULL;
  34. int dlist;                        /* display list handle for anims */
  35.  
  36. struct BitMap *bm3=NULL;
  37.  
  38. struct anim_struct *bubble;
  39.  
  40. /*-------------------------------------------------------------------------*/
  41.  
  42. struct gs_viewport vp =
  43.    {
  44.    NULL,                           /* ptr to next viewport */
  45.    NULL,                           /* ptr to color table */
  46.    0,                              /* number of colors in table */
  47.    NULL,                           /* ptr to user copper list */
  48.    0,0,0,0,0,                     /* height, width, depth, bmheight, bmwidth */
  49.    0,0,                           /* top & left viewport offsets */
  50.    0,0,                           /* X & Y bitmap offsets */
  51.    GSVP_ALLOCBM,                  /* flags (alloc bitmaps) */
  52.    NULL,NULL,                     /* 2.xx & above compatibility stuff */
  53.    NULL,NULL,                     /* bitmap pointers */
  54.    NULL,                           /* future expansion */
  55.    0,0,0,0                        /* display clip (use nominal) */
  56.    };
  57.  
  58. struct display_struct bubble_display =
  59.    {
  60.    NULL,                           /* ptr to previous display view */
  61.    NULL,NULL,                     /* 2.xx & above compatibility stuff */
  62.    0,0,                           /* X and Y display offsets */
  63.    0,                              /* display mode ID */
  64.    4,4,                           /* sprite priorities (sprites in front of playfields) */
  65.    GSV_DOUBLE,                     /* flags */
  66.    &vp,                           /* ptr to 1st viewport */
  67.    NULL                           /* future expansion */
  68.    };
  69.  
  70. /***************************************************************************/
  71.  
  72. main(argc,argv)
  73. int argc;
  74. char *argv[];
  75.  
  76. {
  77.    int err,end=0;
  78.  
  79.    if (argc < 2)
  80.       {
  81.       printf("\nUSAGE: bubbles [number of bubbles] [HIRES] [SUPER] [VB delay intervals] [X speed] [Y speed]\n");
  82.       exit(01);
  83.       }
  84.    if (gs_open_libs(DOS|GRAPHICS,0))   /* open AmigaDOS libs */
  85.       exit(01);               /* if can't open libs, abort */
  86.    parser(argc,argv);         /* parse command line args */
  87.    if (err=setup())            /* if couldn't get set up... abort program */
  88.       {
  89.       printf("\nSetup error: %d\n",err);
  90.       gs_close_libs();         /* close all libraries */
  91.       exit(02);
  92.       }
  93.    Forbid();                  /* take over the entire machine */
  94.    while (!end)               /* this shows off speed */
  95.       {
  96.       move_image();            /* move them bubbles around */
  97.       end=check_close();      /* end when user hits left mouse button */
  98.       }
  99.    Permit();                  /* OK, let other things run while we clean up */
  100.    cleanup();                  /* close & deallocate everything */
  101.    gs_close_libs();            /* close all libraries */
  102. }
  103.  
  104. /***************************************************************************/
  105.  
  106. void parser(argc,argv)
  107. int argc;
  108. char *argv[];
  109.  
  110. {
  111.    bubble_cnt=atoi(argv[1]);   /* # anims to place on the screen */
  112.    swidth=320;                  /* default width & height */
  113.    sheight=200;
  114. //   smode=0;                     /* default mode of lores no lace */
  115.    smode=NTSC_MONITOR_ID;
  116.    if (argc >= 3)
  117.       {
  118.       if (!(stricmp(argv[2],"HIRES")))   /* check for hires spec */
  119.          {
  120.          swidth=640;
  121.          sheight=400;
  122.          if (GfxBase->LibNode.lib_Version >= 36)
  123.             {
  124.             if (ModeNotAvailable(DBLNTSCHIRESFF_KEY))
  125.                smode=HIRES|LACE;
  126.             else
  127.                smode=DBLNTSCHIRESFF_KEY;
  128.             }
  129.          else
  130.             smode=HIRES|LACE;
  131.          }
  132.       else if (!(stricmp(argv[2],"SUPER")))   /* check for superhires */
  133.          {
  134.          if (GfxBase->LibNode.lib_Version >= 36)
  135.             {
  136.             if (ModeNotAvailable(SUPER72_MONITOR_ID | SUPERLACE_KEY))
  137.                {
  138.                swidth=640;
  139.                sheight=400;
  140.                smode=HIRES|LACE;
  141.                }
  142.             else
  143.                {
  144.                smode=SUPER72_MONITOR_ID | SUPERLACE_KEY;
  145.                swidth=800;
  146.                sheight=600;
  147.                }
  148.             }
  149.          else
  150.             {
  151.             swidth=640;
  152.             sheight=400;
  153.             smode=HIRES|LACE;
  154.             }
  155.          }
  156.       }
  157.    if (argc >= 4)
  158.       {
  159.       delay=atoi(argv[3]);      /* delay value in vertical blank intervals */
  160.       }
  161.    if (argc >= 5)               /* new random X speed range */
  162.       {
  163.       random_x=atoi(argv[4]);
  164.       if (random_x < 2)
  165.          random_x=2;
  166.       }
  167.    if (argc >= 6)               /* new random Y speed range */
  168.       {
  169.       random_y=atoi(argv[5]);
  170.       if (random_y < 2)
  171.          random_y=2;
  172.       }
  173. }
  174.  
  175. /***************************************************************************/
  176.  
  177. int setup()
  178.  
  179. {
  180.    int cnt,depth=0;
  181.    struct blit_struct *img;
  182.    struct anim_load_struct load;
  183.  
  184.    if (!(x=(int *)malloc(bubble_cnt*sizeof(int))))
  185.       return(-1);
  186.    if (!(y=(int *)malloc(bubble_cnt*sizeof(int))))
  187.       {
  188.       free_arrays();
  189.       return(-1);
  190.       }
  191.    if (!(speedx=(int *)malloc(bubble_cnt*sizeof(int))))
  192.       {
  193.       free_arrays();
  194.       return(-1);
  195.       }
  196.    if (!(speedy=(int *)malloc(bubble_cnt*sizeof(int))))
  197.       {
  198.       free_arrays();
  199.       return(-1);
  200.       }
  201.    if (!(last=(int *)malloc(bubble_cnt*sizeof(int))))
  202.       {
  203.       free_arrays();
  204.       return(-1);
  205.       }
  206.    if (!(reset=(int *)malloc(bubble_cnt*sizeof(int))))
  207.       {
  208.       free_arrays();
  209.       return(-1);
  210.       }
  211.    load.filename="bubble";            /* name of anim file */
  212.    load.cmap_size=8;                  /* number of bits per color value */
  213.    load.array_elements=bubble_cnt;   /* number of array elements desired */
  214.    load.flags=0L;                     /* no special load flags */
  215.    if (gs_load_anim(&load))         /* load the anim object */
  216.       {
  217.       free_arrays();
  218.       return(-1);
  219.       }
  220.    bubble=load.anim_ptr.anim;         /* ptr to bubble anim */
  221.    if (load.type)                     /* make sure it's an anim type */
  222.       {
  223.       FreeMem(load.cmap,load.cmap_entries*sizeof(long));
  224.       free_arrays();
  225.       if (load.type = 1)
  226.          gs_free_cplx((struct anim_cplx *)bubble,bubble_cnt);
  227.       return(-2);
  228.       }
  229.    img = bubble[0].list;            /* ptr to 1st image in anim sequence */
  230.    while (img)                        /* find max depth of anim */
  231.       {
  232.       if (img->depth > depth)
  233.          depth = img->depth;
  234.       if (img->next == img)         /* avoid infinite loop */
  235.          img=NULL;                  /* if single shot anim */
  236.       else
  237.          img=img->next;
  238.       }
  239.    vp.height = sheight;               /* set up display dimensions */
  240.    vp.width = swidth;
  241.    vp.depth = depth;
  242.    vp.bmheight = sheight;
  243.    vp.bmwidth = swidth;
  244.    bubble_display.modes = smode;
  245.    vp.num_colors=load.cmap_entries;
  246.    vp.color_table=load.cmap;         /* addr of color table */
  247.    if (gs_create_display(&bubble_display))
  248.       {
  249.       FreeMem(load.cmap,load.cmap_entries*sizeof(long));
  250.       free_arrays();
  251.       gs_free_anim(bubble,bubble_cnt);
  252.       return(-2);
  253.       }
  254.    FreeMem(load.cmap,load.cmap_entries*sizeof(long));   /* done with color table */
  255.    if ((dlist=gs_get_display_list()) < 0)   /* allocate a display list for anims */
  256.       {
  257.       free_arrays();
  258.       gs_free_anim(bubble,bubble_cnt);
  259.       return(-3);
  260.       }
  261.    bm3=gs_get_bitmap(vp.depth,vp.bmwidth,vp.bmheight,0);
  262.    gs_init_anim(dlist,vp.bitmap1,vp.bitmap2,bm3);   /* tell anim system about bitmaps */
  263.    gs_set_anim_bounds(dlist,0,0,swidth-1,sheight-1);   /* set bounds for anim objects */
  264.    gs_set_collision(dlist,&collision);   /* set ptr to collision handler */
  265.    for (cnt=0; cnt < bubble_cnt; cnt++)
  266.       {                              /* add all bubbles to a display list */
  267.       reset[cnt]=0;
  268.       last[cnt]=-1;
  269.       x[cnt] = gs_random(swidth);   /* random X,Y coords */
  270.       y[cnt] = gs_random(sheight);
  271.       while ((speedx[cnt] = gs_random(random_x)) == 0);
  272.       while ((speedy[cnt] = gs_random(random_y)) == 0);
  273.       if (cnt&1)
  274.          {
  275.          speedx[cnt]=-speedx[cnt];
  276.          speedy[cnt]=-speedy[cnt];
  277.          }
  278.       if (bm3)                        /* if restore bitmap */
  279.          {
  280.          bubble[cnt].flags|=ANIM_SAVE_BG;   /* use fastest display method (next to simple copy) */
  281.          if (bubble[cnt].flags & ANIM_CLEAR)
  282.             bubble[cnt].flags ^= ANIM_CLEAR;
  283.          if (bubble[cnt].flags & ANIM_COPY)
  284.             bubble[cnt].flags ^= ANIM_COPY;
  285.          }
  286.       if (gs_add_anim(dlist,(struct anim_struct *)&bubble[cnt],x[cnt],y[cnt]))
  287.          {
  288.          cleanup();                  /* release everything */
  289.          return(-4);                  /* return failure */
  290.          }
  291.       gs_set_anim_cell((struct anim_struct *)&bubble[cnt],gs_random(bubble[cnt].count));
  292.       }
  293.    gs_draw_anims(dlist);
  294.    check_bounds();
  295.    gs_next_anim_page(dlist);
  296.    gs_show_display(&bubble_display,1);
  297.    gs_flip_display(&bubble_display,1);
  298.    gs_open_vb_timer();
  299.    return(0);
  300. }
  301.  
  302. /***************************************************************************/
  303.  
  304. void move_image()
  305.  
  306. /* move and animate the graphic objects on the screen */
  307.  
  308. {
  309.    int cnt;
  310.  
  311.    if (gs_vb_time() < delay)
  312.       return;
  313.    gs_vb_timer_reset();
  314.    for (cnt=0; cnt < bubble_cnt; cnt++)
  315.       {
  316.       x[cnt]+=speedx[cnt];            /* move the object */
  317.       y[cnt]+=speedy[cnt];
  318.       gs_anim_obj((struct anim_struct *)&bubble[cnt],x[cnt],y[cnt]);
  319.       if (reset[cnt])               /* since anim doesn't loop, must reset */
  320.          {                           /* the sequence in the event of collision */
  321.          reset[cnt]=0;               /* start at 1st cell in anim sequence */
  322.          gs_set_anim_cell((struct anim_struct *)&bubble[cnt],0);
  323.          }
  324.       if (!bubble[cnt].collide)      /* if not colliding, clear last ptr */
  325.          last[cnt]=-1;
  326.       }
  327.    while (bubble_display.flags & GSV_FLIP);   /* while page not flipped yet */
  328.    gs_draw_anims(dlist);            /* draw them anim objects! */
  329.    check_bounds();                  /* bounce off of outer bitmap bounds */
  330.    gs_next_anim_page(dlist);         /* tell anim sys to use other bitmap */
  331.    gs_flip_display(&bubble_display,1);   /* switch to other display, sync */
  332. }
  333.  
  334. /***************************************************************************/
  335.  
  336. void check_bounds()
  337.  
  338. {
  339.    int cnt;
  340.  
  341.    for (cnt=0; cnt < bubble_cnt; cnt++)
  342.       {
  343.       if (bubble[cnt].flags & (ANIM_BOUNDS_X1|ANIM_BOUNDS_X2))
  344.          {
  345.          x[cnt]=bubble[cnt].x;   /* keep track of current location */
  346.          speedx[cnt]=-speedx[cnt];   /* reverse X direction */
  347.          reset[cnt]=1;            /* make bubble warp */
  348.          last[cnt]=-1;            /* no colliding */
  349.          }
  350.       if (bubble[cnt].flags & (ANIM_BOUNDS_Y1|ANIM_BOUNDS_Y2))
  351.          {
  352.          y[cnt]=bubble[cnt].y;
  353.          speedy[cnt]=-speedy[cnt];   /* reverse Y direction */
  354.          reset[cnt]=1;
  355.          last[cnt]=-1;
  356.          }
  357.       }
  358. }
  359.  
  360. /***************************************************************************/
  361.  
  362. int check_close()
  363.  
  364. /* check for user input */
  365.  
  366. {
  367.    if (gs_joystick(0) & (JOY_BUTTON1|JOY_BUTTON2))
  368.       return(1);
  369.    return(0);
  370. }
  371.  
  372. /***************************************************************************/
  373.  
  374. void collision(anim1,anim2,coll1,coll2)
  375. struct anim_struct *anim1;
  376. struct anim_struct *anim2;
  377. struct collision_struct *coll1;
  378. struct collision_struct *coll2;
  379.  
  380. /*
  381.  
  382. This is the collision handler which makes the bubbles "bounce" off of
  383. each other.
  384.  
  385. */
  386.  
  387. {
  388.    int temp;
  389.  
  390.    if (last[anim1->array_num] != anim2->array_num)      /* if not same object */
  391.       {
  392.       last[anim1->array_num] = anim2->array_num;      /* remember last collision */
  393.       last[anim2->array_num] = anim1->array_num;
  394.       reset[anim1->array_num]=1;                        /* reset anim cell */
  395.       reset[anim2->array_num]=1;
  396.       temp=speedy[anim2->array_num];                  /* swap values */
  397.       speedy[anim2->array_num]=speedy[anim1->array_num];
  398.       speedy[anim1->array_num]=temp;
  399.       temp=speedx[anim2->array_num];
  400.       speedx[anim2->array_num]=speedx[anim1->array_num];
  401.       speedx[anim1->array_num]=temp;
  402.       }
  403. }
  404.  
  405. /***************************************************************************/
  406.  
  407. void cleanup()
  408.  
  409. /* release all resources and memory */
  410.  
  411. {
  412.    free_arrays();
  413.    gs_free_anim(bubble,bubble_cnt);
  414.    gs_remove_display(&bubble_display);
  415.    gs_free_display_list(dlist);
  416.    gs_close_vb_timer();
  417. }
  418.  
  419. /***************************************************************************/
  420.  
  421. void free_arrays()
  422.  
  423. /* release memory used by control arrays */
  424.  
  425. {
  426.    if (x)
  427.       free(x);
  428.    if (y)
  429.       free(y);
  430.    if (speedx)
  431.       free(speedx);
  432.    if (speedy)
  433.       free(speedy);
  434.    if (last)
  435.       free(last);
  436.    if (reset)
  437.       free(reset);
  438.    if (bm3)
  439.       gs_free_bitmap(bm3);
  440. }
  441.