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