home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 377a.lha / libraries / graphics / sprite_bob_anim / anim / anim.c < prev    next >
C/C++ Source or Header  |  1980-02-04  |  28KB  |  971 lines

  1. /* Copyright (c) 1990 Commodore-Amiga, Inc.
  2.  *
  3.  * This example is provided in electronic form by Commodore-Amiga, Inc. for
  4.  * use with the 1.3 revisions of the Addison-Wesley Amiga reference manuals. 
  5.  * The 1.3 Addison-Wesley Amiga Reference Manual series contains additional
  6.  * information on the correct usage of the techniques and operating system
  7.  * functions presented in this example.  The source and executable code of
  8.  * this example may only be distributed in free electronic form, via bulletin
  9.  * board or as part of a fully non-commercial and freely redistributable
  10.  * diskette.  Both the source and executable code (including comments) must
  11.  * be included, without modification, in any copy.  This example may not be
  12.  * published in printed form or distributed with any commercial product.
  13.  * However, the programming techniques and support routines set forth in
  14.  * this example may be used in the development of original executable
  15.  * software products for Commodore Amiga computers.
  16.  * All other rights reserved.
  17.  * This example is provided "as-is" and is subject to change; no warranties
  18.  * are made.  All use is at your own risk.  No liability or responsibility
  19.  * is assumed.
  20.  */
  21.  
  22. /* anim.c 19oct89 original code by Dave Lucas.
  23. ** rework by (CATS)
  24. **
  25. ** lattice c 5.04
  26. ** lc -b1 -cfist -v -y anim.c
  27. ** blink FROM LIB:c.o anim.o /animtools/animtools.o LIB LIB:lc.lib TO anim
  28. */
  29. #include <exec/types.h>
  30. #include <intuition/intuition.h>
  31. #include <graphics/gels.h>
  32. #include <exec/memory.h>
  33.  
  34. #include "/animtools/animtools.h"
  35. #include "/animtools/animtools_proto.h"
  36.  
  37. #include <stdlib.h>
  38. #include <stdio.h>
  39. #include <proto/all.h>
  40. int CXBRK(void) { return(0); } /* disable lattice CTRL-C handling */
  41.  
  42. /*--------------------------------------------------------------*/
  43. /*                                                              */
  44. /*--------------------------------------------------------------*/
  45. struct AnimOb *setupBoing(SHORT dbufing);
  46. struct AnimOb *setupMan(SHORT dbufing);
  47. struct AnimOb *setupWorm(SHORT dbufing);
  48.  
  49. WORD anEdgeORoutine(struct AnimOb *anOb);
  50. WORD bounceORoutine(struct AnimOb *anOb);
  51. WORD goInFrontOfHead(struct AnimComp *aComp);
  52. WORD goBehindHead(struct AnimComp *aComp);
  53.  
  54. VOID runAnimation(struct Window *win, SHORT dbufing,
  55.                   struct AnimOb **animKey, struct BitMap **myBitMaps);
  56.  
  57. LONG setupPlanes(struct BitMap *bitMap, LONG depth, LONG width, LONG height);
  58. struct BitMap **setupBitMaps(LONG depth, LONG width, LONG height);
  59. VOID freePlanes(struct BitMap *bitMap, LONG depth, LONG width, LONG height);
  60. VOID freeBitMaps(struct BitMap **myBitMaps,
  61.                     LONG depth, LONG width, LONG height);
  62.  
  63. struct GelsInfo *setupDisplay(struct Window **win,
  64.                               SHORT dbufing, struct BitMap **myBitMaps);
  65. VOID DrawGels(struct Window *win, struct AnimOb **animKey, SHORT dbufing,
  66.               WORD *toggleFrame, struct BitMap **myBitMaps);
  67.  
  68. /*--------------------------------------------------------------*/
  69. /*                                                              */
  70. /*--------------------------------------------------------------*/
  71. #define ANFS    ANFRACSIZE
  72. #define BNFS    (ANFRACSIZE-2)
  73. #define CNFS    (ANFRACSIZE-2)
  74.  
  75. /* These are used for MeMask (1 << ID_xxx) */
  76. #define ID_BORDER 0
  77. #define ID_WRM    3
  78. #define ID_BNG    4
  79. #define ID_MAN    5
  80.  
  81. #define SBMWIDTH  320  /* My screen size constants. */
  82. #define SBMHEIGHT 200
  83. #define SBMDEPTH    4
  84. #define SCRNMODE NULL  /* (HIRES | LACE) for NewScreen, ends up in view.*/
  85.  
  86. #define RBMWIDTH  320  /* My raster size constants. (These CAN differ) */
  87. #define RBMHEIGHT 200
  88. #define RBMDEPTH    4
  89.  
  90. /*--------------------------------------------------------------*/
  91. /*                                                              */
  92. /*--------------------------------------------------------------*/
  93. struct NewScreen ns =
  94.     {
  95.     0, 0, SBMWIDTH, SBMHEIGHT, SBMDEPTH, 0, 0, SCRNMODE,
  96.     CUSTOMSCREEN | SCREENQUIET, NULL, NULL, NULL, NULL
  97.     };
  98.  
  99. /* this is a little window that will let us get a CLOSEWINDOW message */
  100. struct NewWindow nw =
  101.     {
  102.     0, 0, 25, 12, 0, 0, CLOSEWINDOW,
  103.     WINDOWCLOSE | BORDERLESS | RMBTRAP, NULL, NULL, NULL, NULL,
  104.     NULL, 0, 0, SBMWIDTH, SBMHEIGHT-1, CUSTOMSCREEN
  105.     };
  106.  
  107. struct IntuitionBase *IntuitionBase    = NULL;
  108. struct GfxBase         *GfxBase        = NULL;
  109.  
  110. int return_code;
  111.  
  112. /*--------------------------------------------------------------*/
  113. /* constants for the worm sequence.                             */
  114. /*--------------------------------------------------------------*/
  115. #include "image_worm.h"
  116.  
  117. NEWBOB newWrmBob =
  118.     {
  119.     NULL,                /* nb_Image - image is null for sequences    */
  120.                         /*              data comes from NEWANIMSEQ    */
  121.     WRMWWIDTH,            /* nb_WordWidth - width of the bob            */
  122.     WRMHEIGHT,            /* nb_LineHeight - height of the bob        */
  123.     WRMDEPTH,            /* nb_ImageDepth - depth of image data        */
  124.     0x3,                /* nb_PlanePick - planes to put data in        */
  125.     0x0,                /* nb_PlaneOnOff - empty planes to set        */
  126.     SAVEBACK | OVERLAY,    /* nb_BFlags - flags for the bob            */
  127.     0,                    /* nb_DBuf - 1=dbuf, 0=not dbuf                */
  128.     RBMDEPTH,            /* nb_RasDepth - num planes in raster        */
  129.     0,                    /* nb_X - bob x position                    */
  130.     0,                    /* nb_Y - bob y position                    */
  131.     (1L << ID_BORDER),    /* nb_HitMask - hit mask                    */
  132.     (1L << ID_WRM),        /* nb_MeMask - me mask                        */
  133.     };
  134. NEWANIMSEQ newWrmSeq =
  135.     {
  136.     NULL,                /* nas_HeadOb - head object for the seq        */
  137.     (WORD *)WrmImage,    /* nas_Images - array of images                */
  138.     WrmXTranses,        /* nas_Xt - x offsets from central object    */
  139.     WrmYTranses,        /* nas_Yt - y offsets from central object    */
  140.     WrmTimes,            /* nas_Times - timing values for objects    */
  141.     WrmCRoutines,        /* nas_Routines - array of comp routines    */
  142.     0,                    /* nas_CFlags - comp flags                    */
  143.     WRMCOUNT,            /* nas_Count - number of comps in sequence    */
  144.     0,                    /* nas_SingleImage - 1=single image for seq.*/
  145.                         /*                     0=multiple images      */
  146.     };
  147.  
  148. /*--------------------------------------------------------------*/
  149. /* constants for the man sequence.                              */
  150. /*--------------------------------------------------------------*/
  151. #define MANRINGY        -1
  152. #define MANRINGX        36
  153. #define MANHEIGHT        62
  154. #define MANWIDTH        46
  155.  
  156. #define MANTCOUNT        4
  157. #define MANTHEIGHT        34
  158. #define MANTWIDTH        9
  159. #define MANTDEPTH        2
  160. #define MANTWWIDTH        ((MANTWIDTH + 15) / 16)
  161.  
  162. #define MANACOUNT        8
  163. #define MANAHEIGHT        22
  164. #define MANAWIDTH        24
  165. #define MANADEPTH        2
  166. #define MANAWWIDTH        ((MANAWIDTH + 15) / 16)
  167.  
  168. #define MANLCOUNT        8
  169. #define MANLHEIGHT        30
  170. #define MANLWIDTH        26
  171. #define MANLDEPTH        2
  172. #define MANLWWIDTH        ((MANLWIDTH + 15) / 16)
  173.  
  174. #include "image_man.h"
  175.  
  176. NEWBOB newNearLegBob =
  177.     {
  178.     NULL, MANLWWIDTH, MANLHEIGHT, MANLDEPTH, 0x3, 0xC,
  179.     SAVEBACK | OVERLAY, 0, RBMDEPTH, 0,0, (1L<<ID_BORDER), (1L<<ID_MAN),
  180.     };
  181. NEWANIMSEQ newNearLegSeq =
  182.     {
  183.     NULL, (WORD *)manLImage, manLXTranses, manLYTranses, manLTimes,
  184.     manLCRoutines, 0, MANLCOUNT, 0,
  185.     };
  186.  
  187. NEWBOB newFarLegBob =
  188.     {
  189.     NULL, MANLWWIDTH, MANLHEIGHT, MANLDEPTH, 0x3, 0x8,
  190.     SAVEBACK | OVERLAY, 0, RBMDEPTH, 0,0, (1L<<ID_BORDER), (1L<<ID_MAN),
  191.     };
  192. NEWANIMSEQ newFarLegSeq =
  193.     {
  194.     NULL, (WORD *)manLImage, manLXTranses, manLYTranses, manLTimes,
  195.     manLCRoutines, 0, MANLCOUNT, 0,
  196.     };
  197.  
  198. NEWBOB newNearArmBob =
  199.     {
  200.     NULL, MANAWWIDTH, MANAHEIGHT, MANADEPTH, 0x3, 0xC,
  201.     SAVEBACK | OVERLAY, 0, RBMDEPTH, 0,0, (1L<<ID_BORDER), (1L<<ID_MAN),
  202.     };
  203. NEWANIMSEQ newNearArmSeq =
  204.     {
  205.     NULL, (WORD *)manAImage, manAXTranses, manAYTranses, manATimes,
  206.     manACRoutines, 0, MANACOUNT, 0,
  207.     };
  208.  
  209. NEWBOB newFarArmBob =
  210.     {
  211.     NULL, MANAWWIDTH, MANAHEIGHT, MANADEPTH, 0x3, 0x8,
  212.     SAVEBACK | OVERLAY, 0, RBMDEPTH, 0,0, (1L<<ID_BORDER), (1L<<ID_MAN),
  213.     };
  214. NEWANIMSEQ newFarArmSeq =
  215.     {
  216.     NULL, (WORD *)manAImage, manAXTranses, manAYTranses, manATimes,
  217.     manACRoutines, 0, MANACOUNT, 0,
  218.     };
  219.  
  220. NEWBOB newTrunkBob =
  221.     {
  222.     NULL, MANTWWIDTH, MANTHEIGHT, MANTDEPTH, 0x3, 0xC,
  223.     SAVEBACK | OVERLAY, 0, RBMDEPTH, 0,0, (1L<<ID_BORDER), (1L<<ID_MAN),
  224.     };
  225. NEWANIMSEQ newTrunkSeq =
  226.     {
  227.     NULL, (WORD *)manTImage, manTXTranses, manTYTranses, manTTimes,
  228.     manTCRoutines, 0, MANTCOUNT, 0,
  229.     };
  230.  
  231. /*--------------------------------------------------------------*/
  232. /* constants for the boing ball and sattellites.                */
  233. /*--------------------------------------------------------------*/
  234. #define BNG3RINGY        0
  235. #define BNG3RINGX        0
  236. #define BNG3COUNT        6
  237. #define BNG3HEIGHT        25
  238. #define BNG3WIDTH        29
  239. #define BNG3DEPTH        3
  240. #define BNG3WWIDTH        ((BNG3WIDTH + 15) / 16)
  241.  
  242. #define SATCOUNT        16
  243. #define SATHEIGHT        5
  244. #define SATWIDTH        5
  245. #define SATDEPTH        2
  246. #define SATWWIDTH        ((SATWIDTH + 15) / 16)
  247.  
  248. #include "image_boing.h"
  249.  
  250. NEWBOB newBoingBob =
  251.     {
  252.     NULL, BNG3WWIDTH, BNG3HEIGHT, BNG3DEPTH, 0xD, 0x2,
  253.     SAVEBACK | OVERLAY, 0, RBMDEPTH, 0,0, (1L<<ID_BORDER), (1L<<ID_BNG),
  254.     };
  255. NEWANIMSEQ newBoingSeq =
  256.     {
  257.     NULL, (WORD *)boing3Image, boing3XTranses, boing3YTranses,
  258.     boing3Times, boing3CRoutines, 0, BNG3COUNT, 0,
  259.     };
  260.  
  261. NEWBOB newSatABob =
  262.     {
  263.     NULL, SATWWIDTH, SATHEIGHT, SATDEPTH, 0xC, 0x0,
  264.     SAVEBACK | OVERLAY, 0, RBMDEPTH, 0,0, (1L<<ID_BORDER), (1L<<ID_BNG),
  265.     };
  266. NEWANIMSEQ newSatASeq =
  267.     {
  268.     NULL, (WORD *)satImage, satAXTranses, satAYTranses,
  269.     satTimes, satACRoutines, 0, SATCOUNT, 1,
  270.     };
  271. NEWBOB newSatBBob =
  272.     {
  273.     NULL, SATWWIDTH, SATHEIGHT, SATDEPTH, 0xC, 0x3,
  274.     SAVEBACK | OVERLAY, 0, RBMDEPTH, 0,0, (1L<<ID_BORDER), (1L<<ID_BNG),
  275.     };
  276. NEWANIMSEQ newSatBSeq =
  277.     {
  278.     NULL, (WORD *)satImage, satBXTranses, satBYTranses,
  279.     satTimes, satBCRoutines, 0, SATCOUNT, 1,
  280.     };
  281. NEWBOB newSatCBob =
  282.     {
  283.     NULL, SATWWIDTH, SATHEIGHT, SATDEPTH, 0x3, 0x0,
  284.     SAVEBACK | OVERLAY, 0, RBMDEPTH, 0,0, (1L<<ID_BORDER), (1L<<ID_BNG),
  285.     };
  286. NEWANIMSEQ newSatCSeq =
  287.     {
  288.     NULL, (WORD *)satImage, satCXTranses, satCYTranses,
  289.     satTimes, satCCRoutines, 0, SATCOUNT, 1,
  290.     };
  291.  
  292. /*--------------------------------------------------------------*/
  293. /*--------------------------------------------------------------*/
  294. /*                      PROCEDURES                              */
  295. /*--------------------------------------------------------------*/
  296. /*--------------------------------------------------------------*/
  297.  
  298. /*--------------------------------------------------------------
  299. ** setupBoing() - allocate and initialize an object that will
  300. ** display as a boing ball with orbiting sattellites.
  301. **
  302. ** this is an animation object with four animation sequences.
  303. ** (boing and three sattellites.)
  304. ** (note that the sattellites all share the same single image data.)
  305. **
  306. ** return NULL on failure.
  307. */
  308. struct AnimOb *setupBoing(SHORT dbufing)
  309. {
  310. struct AnimOb    *bngOb;
  311. struct AnimComp *bngComp;
  312. struct AnimComp *satAComp;
  313. struct AnimComp *satBComp;
  314. struct AnimComp *satCComp;
  315.  
  316. if (NULL != (bngOb = AllocMem((LONG)sizeof(struct AnimOb), MEMF_CLEAR)))
  317.     {
  318.     bngOb->NextOb        = NULL;
  319.     bngOb->PrevOb        = NULL;
  320.     bngOb->Clock        = 0;
  321.     bngOb->AnY            = 50;
  322.     bngOb->AnX            = 50;
  323.     bngOb->AnOldY        = bngOb->AnY;
  324.     bngOb->AnOldX        = bngOb->AnX;
  325.     bngOb->YVel            = 3 << ANFRACSIZE;
  326.     bngOb->XVel            = 3 << ANFRACSIZE;
  327.     bngOb->YAccel        = 0;
  328.     bngOb->XAccel        = 0;
  329.     bngOb->RingYTrans    = BNG3RINGY << ANFRACSIZE;
  330.     bngOb->RingXTrans    = BNG3RINGX << ANFRACSIZE;
  331.     bngOb->AnimORoutine    = bounceORoutine;
  332.     bngOb->AUserExt        = 0;
  333.  
  334.     newBoingBob.nb_DBuf    = dbufing;
  335.     newBoingSeq.nas_HeadOb = bngOb;
  336.  
  337.     satACRoutines[4]      = goInFrontOfHead;
  338.     satACRoutines[12]      = goBehindHead;
  339.     satBCRoutines[8]      = goInFrontOfHead;
  340.     satBCRoutines[0]      = goBehindHead;
  341.     satCCRoutines[4]      = goInFrontOfHead;
  342.     satCCRoutines[12]     = goBehindHead;
  343.  
  344.     newSatABob.nb_DBuf      = dbufing;
  345.     newSatBBob.nb_DBuf      = dbufing;
  346.     newSatCBob.nb_DBuf      = dbufing;
  347.     newSatASeq.nas_HeadOb = bngOb;
  348.     newSatBSeq.nas_HeadOb = bngOb;
  349.     newSatCSeq.nas_HeadOb = bngOb;
  350.  
  351.     if (NULL != (bngComp = makeSeq(&newBoingBob, &newBoingSeq)))
  352.         {
  353.         bngComp->Flags |= RINGTRIGGER;
  354.         bngOb->HeadComp = bngComp;
  355.  
  356.         if (NULL != (satAComp = makeSeq(&newSatABob, &newSatASeq)))
  357.             {
  358.             bngComp->AnimBob->Before = satAComp->AnimBob;
  359.             satAComp->AnimBob->After = bngComp->AnimBob;
  360.  
  361.             if (NULL != (satBComp = makeSeq(&newSatBBob, &newSatBSeq)))
  362.                 {
  363.                 satAComp->AnimBob->Before = satBComp->AnimBob;
  364.                 satBComp->AnimBob->After = satAComp->AnimBob;
  365.  
  366.                 if (NULL != (satCComp = makeSeq(&newSatCBob, &newSatCSeq)))
  367.                     {
  368.                     satBComp->AnimBob->Before = satCComp->AnimBob;
  369.                     satCComp->AnimBob->After = satBComp->AnimBob;
  370.  
  371.                     bngComp->NextComp  = satAComp;
  372.                     bngComp->PrevComp  = NULL;
  373.  
  374.                     satAComp->NextComp = satBComp;
  375.                     satAComp->PrevComp = bngComp;
  376.  
  377.                     satBComp->NextComp = satCComp;
  378.                     satBComp->PrevComp = satAComp;
  379.  
  380.                     satCComp->NextComp = NULL;
  381.                     satCComp->PrevComp = satBComp;
  382.  
  383.                     return(bngOb);
  384.                     }
  385.                 freeSeq(satBComp,RBMDEPTH);
  386.                 }
  387.             freeSeq(satAComp,RBMDEPTH);
  388.             }
  389.         freeSeq(bngComp,RBMDEPTH);
  390.         }
  391.     FreeMem(bngOb, (LONG)sizeof(struct AnimOb));
  392.     }
  393. return_code = RETURN_WARN;
  394. return(NULL);
  395. }
  396.  
  397. /*--------------------------------------------------------------
  398. ** setupMan() - allocate and initialize an object that will
  399. ** display as a walking man.
  400. **
  401. ** this is an animation object with five animation sequences.
  402. ** (body, two arms and two legs.)
  403. **
  404. ** return NULL on failure.
  405. */
  406. struct AnimOb *setupMan(SHORT dbufing)
  407. {
  408. struct AnimOb *manOb;
  409.  
  410. struct AnimComp *trunkComp;
  411. struct AnimComp *farArmComp;
  412. struct AnimComp *farLegComp;
  413. struct AnimComp *nearArmComp;
  414. struct AnimComp *nearLegComp;
  415.  
  416. if (NULL != (manOb = AllocMem((LONG)sizeof(struct AnimOb), MEMF_CLEAR)))
  417.     {
  418.     manOb->NextOb        = NULL;
  419.     manOb->PrevOb        = NULL;
  420.     manOb->Clock        = 0;
  421.     manOb->AnY            = ((2 * MANHEIGHT) << ANFRACSIZE);
  422.     manOb->AnX            = 0;
  423.     manOb->AnOldY        = manOb->AnY;
  424.     manOb->AnOldX        = manOb->AnX;
  425.     manOb->YVel            = 0;
  426.     manOb->XVel            = 0;
  427.     manOb->YAccel        = 0;
  428.     manOb->XAccel        = 0;
  429.     manOb->RingYTrans    = (MANRINGY << ANFRACSIZE);
  430.     manOb->RingXTrans    = (MANRINGX << ANFRACSIZE);
  431.     manOb->AnimORoutine    = anEdgeORoutine;
  432.     manOb->AUserExt        = 0;
  433.  
  434.     newTrunkBob.nb_DBuf   = dbufing;
  435.     newFarArmBob.nb_DBuf  = dbufing;
  436.     newFarLegBob.nb_DBuf  = dbufing;
  437.     newNearArmBob.nb_DBuf = dbufing;
  438.     newNearLegBob.nb_DBuf = dbufing;
  439.  
  440.     newTrunkSeq.nas_HeadOb   = manOb;
  441.     newFarArmSeq.nas_HeadOb  = manOb;
  442.     newFarLegSeq.nas_HeadOb  = manOb;
  443.     newNearArmSeq.nas_HeadOb = manOb;
  444.     newNearLegSeq.nas_HeadOb = manOb;
  445.  
  446.     if (NULL != (trunkComp = makeSeq(&newTrunkBob, &newTrunkSeq)))
  447.         {
  448.         trunkComp->Flags |= RINGTRIGGER;
  449.  
  450.         if (NULL != (farArmComp = makeSeq(&newFarArmBob, &newFarArmSeq)))
  451.             {
  452.             trunkComp->AnimBob->Before = farArmComp->AnimBob;
  453.             farArmComp->AnimBob->After = trunkComp->AnimBob;
  454.  
  455.             if (NULL != (farLegComp = makeSeq(&newFarLegBob, &newFarLegSeq)))
  456.                 {
  457.                 farArmComp->AnimBob->Before = farLegComp->AnimBob;
  458.                 farLegComp->AnimBob->After = farArmComp->AnimBob;
  459.  
  460.                 if (NULL != (nearArmComp =
  461.                             makeSeq(&newNearArmBob, &newNearArmSeq)))
  462.                     {
  463.                     nearArmComp =
  464.                         nearArmComp->NextSeq->NextSeq->NextSeq->NextSeq;
  465.                     farLegComp->AnimBob->Before = nearArmComp->AnimBob;
  466.                     nearArmComp->AnimBob->After = farLegComp->AnimBob;
  467.  
  468.                     if (NULL != (nearLegComp =
  469.                                     makeSeq(&newNearLegBob, &newNearLegSeq)))
  470.                         {
  471.                         nearLegComp =
  472.                             nearLegComp->NextSeq->NextSeq->NextSeq->NextSeq;
  473.                         nearArmComp->AnimBob->Before = nearLegComp->AnimBob;
  474.                         nearLegComp->AnimBob->After = nearArmComp->AnimBob;
  475.  
  476.                         manOb->HeadComp = trunkComp;
  477.  
  478.                         trunkComp->PrevComp = NULL;
  479.                         trunkComp->NextComp = farArmComp;
  480.  
  481.                         farArmComp->PrevComp = trunkComp;
  482.                         farArmComp->NextComp = farLegComp;
  483.  
  484.                         farLegComp->PrevComp = farArmComp;
  485.                         farLegComp->NextComp = nearArmComp;
  486.  
  487.                         nearArmComp->PrevComp = farLegComp;
  488.                         nearArmComp->NextComp = nearLegComp;
  489.  
  490.                         nearLegComp->PrevComp = nearArmComp;
  491.                         nearLegComp->NextComp = NULL;
  492.  
  493.                         return(manOb);
  494.                         }
  495.                     freeSeq(nearArmComp,RBMDEPTH);
  496.                     }
  497.                 freeSeq(farLegComp,RBMDEPTH);
  498.                 }
  499.             freeSeq(farArmComp,RBMDEPTH);
  500.             }
  501.         freeSeq(trunkComp,RBMDEPTH);
  502.         }
  503.     FreeMem(manOb, (LONG)sizeof(struct AnimOb));
  504.     }
  505. return_code = RETURN_WARN;
  506. return(NULL);
  507. }
  508.  
  509. /*--------------------------------------------------------------
  510. ** setupBoing() - allocate and initialize an object that will
  511. ** display as an inch worm.
  512. **
  513. ** this is an animation object with only one animation sequence.
  514. **
  515. ** return NULL on failure.
  516. */
  517. struct AnimOb *setupWorm(SHORT dbufing)
  518. {
  519. struct AnimOb   *wormOb;
  520. struct AnimComp *wormComp;
  521.  
  522. if (NULL != (wormOb = AllocMem((LONG)sizeof(struct AnimOb), MEMF_CLEAR)))
  523.     {
  524.     wormOb->NextOb         = NULL;
  525.     wormOb->PrevOb         = NULL;
  526.     wormOb->Clock         = 0;
  527.     wormOb->AnY             = ((RBMHEIGHT - WRMHEIGHT - 5) << ANFRACSIZE);
  528.     wormOb->AnX             = (10L << ANFRACSIZE);
  529.     wormOb->AnOldY         = wormOb->AnY;
  530.     wormOb->AnOldX         = wormOb->AnX;
  531.     wormOb->YVel         = 0;
  532.     wormOb->XVel         = 0;
  533.     wormOb->YAccel         = 0;
  534.     wormOb->XAccel         = 0;
  535.     wormOb->RingYTrans     = (WRMRINGY << ANFRACSIZE);
  536.     wormOb->RingXTrans     = (WRMRINGX << ANFRACSIZE);
  537.     wormOb->AnimORoutine = anEdgeORoutine;
  538.     wormOb->AUserExt     = 0;
  539.  
  540.     newWrmBob.nb_DBuf     = dbufing;
  541.     newWrmSeq.nas_HeadOb = wormOb;
  542.  
  543.     if (NULL != (wormComp = makeSeq(&newWrmBob, &newWrmSeq)))
  544.         {
  545.         wormComp->Flags |= RINGTRIGGER;
  546.         wormOb->HeadComp = wormComp;
  547.  
  548.         return(wormOb);
  549.         }
  550.     }
  551. return_code = RETURN_WARN;
  552. return(NULL);
  553. }
  554.  
  555. /*--------------------------------------------------------------
  556. ** This ORoutine makes the Object restart on left edge if it has
  557. ** gone off the right of the screen. If it has gone off the top,
  558. ** it is restarted at the bottom. It is used for the worm and the
  559. ** man. It works for animations that move to the right, and
  560. ** optionally up, ONLY.
  561. */
  562. WORD anEdgeORoutine(struct AnimOb *anOb)
  563. {
  564. struct AnimComp *acptr;
  565. struct AnimComp *seqptr;
  566.  
  567. acptr = anOb->HeadComp;
  568.  
  569. while (acptr)
  570.     {
  571.     seqptr = acptr;
  572.     do    {
  573.         if (seqptr->AnimBob->BobVSprite->Flags & GELGONE)
  574.             {
  575.             seqptr->AnimBob->BobVSprite->Flags &= ~GELGONE;
  576.             anOb->AnX = -10L << ANFRACSIZE;
  577.             if (anOb->AnY <= 0)
  578.                 anOb->AnY = (RBMHEIGHT-60L) << ANFRACSIZE;
  579.             }
  580.         seqptr = seqptr->NextSeq;
  581.         } while (seqptr != acptr && (seqptr));
  582.     acptr = acptr->NextComp;
  583.     }
  584. return(0) ;
  585. }
  586.  
  587. /*--------------------------------------------------------------
  588. ** This ORoutine makes the Object Bounce off Borders.
  589. */
  590. WORD bounceORoutine(struct AnimOb *anOb)
  591. {
  592. SHORT Y;
  593. SHORT X;
  594.  
  595. Y = anOb->AnY >> ANFRACSIZE;
  596. X = anOb->AnX >> ANFRACSIZE;
  597.  
  598. if ((Y<0 && anOb->YVel < 0) ||
  599.     ((Y+anOb->HeadComp->AnimBob->BobVSprite->Height > RBMHEIGHT) &&
  600.      (anOb->YVel > 0)))
  601.     {
  602.     anOb->YVel = -(anOb->YVel);
  603.     }
  604.  
  605. if (((X < 0) && (anOb->XVel < 0)) ||
  606.     ((X + (anOb->HeadComp->AnimBob->BobVSprite->Width << 4) > RBMWIDTH) &&
  607.      (anOb->XVel > 0)))
  608.     {
  609.     anOb->XVel = -(anOb->XVel);
  610.     }
  611. return(0) ;
  612. }
  613.  
  614. /*--------------------------------------------------------------
  615. ** This CRoutine rearranges Bob Before and After pointers in a
  616. ** way that makes the Component passed look like it is in front
  617. ** of its' head component.
  618. ** 
  619. ** Used for Boing satelittes.
  620. ** 
  621. ** So that they go in front of AND behind the boing ball.
  622. */
  623. WORD goInFrontOfHead(struct AnimComp *aComp)
  624. {
  625. /* close up hole */
  626. if (aComp->AnimBob->Before != NULL)
  627.     aComp->AnimBob->Before->After = aComp->AnimBob->After;
  628. if (aComp->AnimBob->After != NULL)
  629.     aComp->AnimBob->After->Before = aComp->AnimBob->Before;
  630.  
  631. /* reinsert */
  632. aComp->AnimBob->Before = aComp->HeadOb->HeadComp->AnimBob->Before;
  633. aComp->AnimBob->After = aComp->HeadOb->HeadComp->AnimBob;
  634. if (aComp->AnimBob->Before != NULL)
  635.     aComp->AnimBob->Before->After = aComp->AnimBob;
  636. aComp->HeadOb->HeadComp->AnimBob->Before = aComp->AnimBob;
  637.  
  638. return(0) ;
  639. }
  640.  
  641. /*--------------------------------------------------------------
  642. ** This CRoutine rearranges Bob Before and After pointers in a
  643. ** way that makes the Component passed look like it is behind
  644. ** its' head component.
  645. */
  646. WORD goBehindHead(struct AnimComp *aComp)
  647. {
  648. if (aComp->AnimBob->Before != NULL)
  649.     aComp->AnimBob->Before->After = aComp->AnimBob->After;
  650. if (aComp->AnimBob->After != NULL)
  651.     aComp->AnimBob->After->Before = aComp->AnimBob->Before;
  652.  
  653. aComp->AnimBob->After = aComp->HeadOb->HeadComp->AnimBob->After;
  654. aComp->AnimBob->Before = aComp->HeadOb->HeadComp->AnimBob;
  655. if (aComp->AnimBob->After != NULL)
  656.     aComp->AnimBob->After->Before = aComp->AnimBob;
  657. aComp->HeadOb->HeadComp->AnimBob->After = aComp->AnimBob;
  658.  
  659. return(0) ;
  660. }
  661.  
  662. /*--------------------------------------------------------------
  663. **
  664. */
  665. VOID runAnimation(struct Window *win,
  666.                   SHORT dbufing,
  667.                   struct AnimOb **animKey,
  668.                   struct BitMap **myBitMaps)
  669. {
  670. struct IntuiMessage  *intuiMsg;
  671. WORD toggleFrame;
  672.  
  673. toggleFrame = 0;
  674.  
  675. /* everything opened, and allocated, and initialized.
  676. ** Now I just hang out, move the gels, tell the system to redraw them,
  677. ** and let the collision and anim routines bounce them about.
  678. */
  679. for (;;)
  680.     {
  681.     /* All the work done here */
  682.     DrawGels(win, animKey, dbufing, &toggleFrame, myBitMaps);
  683.  
  684.     while (intuiMsg = (struct IntuiMessage *)GetMsg(win->UserPort))
  685.         {
  686.         if (intuiMsg->Class == CLOSEWINDOW)
  687.             {
  688.             ReplyMsg((struct Message *)intuiMsg);
  689.             return;
  690.             }
  691.         ReplyMsg((struct Message *)intuiMsg);
  692.         }
  693.     }
  694. }
  695.  
  696. /*---------------------------------------------------------
  697. ** allocate the bit planes for a screen bit map.
  698. */
  699. LONG setupPlanes(struct BitMap *bitMap,
  700.                  LONG depth, LONG width, LONG height)
  701. {
  702. SHORT plane_num ;
  703.  
  704. for (plane_num = 0; plane_num < depth; plane_num++)
  705.     {
  706.     if (NULL != (bitMap->Planes[plane_num] =
  707.                     (PLANEPTR)AllocRaster(width, height)))
  708.         BltClear(bitMap->Planes[plane_num], (width / 8) * height, 1);
  709.     else
  710.         {
  711.         freePlanes(bitMap, depth, width, height);
  712.         return_code = RETURN_WARN;
  713.         return(NULL);
  714.         }
  715.     }
  716. return(TRUE);
  717. }
  718.  
  719. /*---------------------------------------------------------
  720. ** allocate the bit maps for a double buffered screen.
  721. */
  722. struct BitMap **setupBitMaps(LONG depth, LONG width, LONG height)
  723. {
  724. /* this must be static -- it cannot go away when the routine exits. */
  725. static struct BitMap *myBitMaps[2];
  726.  
  727. if (NULL != (myBitMaps[0] =
  728.         (struct BitMap *)AllocMem((LONG)sizeof(struct BitMap), MEMF_CLEAR)))
  729.     {
  730.     if (NULL != (myBitMaps[1] =
  731.         (struct BitMap *)AllocMem((LONG)sizeof(struct BitMap), MEMF_CLEAR)))
  732.         {
  733.         InitBitMap(myBitMaps[0], depth, width, height);
  734.         InitBitMap(myBitMaps[1], depth, width, height);
  735.  
  736.         if (NULL != setupPlanes(myBitMaps[0], depth, width, height))
  737.             {
  738.             if (NULL != setupPlanes(myBitMaps[1], depth, width, height))
  739.                 return(myBitMaps);
  740.  
  741.             freePlanes(myBitMaps[0], depth, width, height);
  742.             }
  743.         FreeMem(myBitMaps[1], (LONG)sizeof(struct BitMap));
  744.         }
  745.     FreeMem(myBitMaps[0], (LONG)sizeof(struct BitMap));
  746.     }
  747. return_code = RETURN_WARN;
  748. return(NULL);
  749. }
  750.  
  751. /*--------------------------------------------------------------
  752. ** free up the memory allocated by setupPlanes().
  753. */
  754. VOID    freePlanes(struct BitMap *bitMap,
  755.                    LONG depth, LONG width, LONG height)
  756. {
  757. SHORT plane_num ;
  758.  
  759. for (plane_num = 0; plane_num < depth; plane_num++)
  760.     {
  761.     if (NULL != bitMap->Planes[plane_num])
  762.         FreeRaster(bitMap->Planes[plane_num], width, height);
  763.     }
  764. }
  765.  
  766. /*--------------------------------------------------------------
  767. ** free up the memory allocated by setupBitMaps().
  768. */
  769. VOID    freeBitMaps(struct BitMap **myBitMaps,
  770.                     LONG depth, LONG width, LONG height)
  771. {
  772. freePlanes(myBitMaps[0], depth, width, height);
  773. freePlanes(myBitMaps[1], depth, width, height);
  774.  
  775. FreeMem(myBitMaps[0], (LONG)sizeof(struct BitMap));
  776. FreeMem(myBitMaps[1], (LONG)sizeof(struct BitMap));
  777. }
  778.  
  779. /*--------------------------------------------------------------
  780. **
  781. */
  782. struct GelsInfo *setupDisplay(struct Window **win,
  783.                               SHORT dbufing,
  784.                               struct BitMap **myBitMaps)
  785. {
  786. struct GelsInfo       *gInfo;
  787. struct Screen       *screen;
  788. struct ViewPort       *vport;
  789. struct RastPort    *rport;
  790.  
  791. if (dbufing)
  792.     {
  793.     /* Screen type. We alloc two BitMaps. See DBLBUF comments. */
  794.     ns.Type |= CUSTOMBITMAP;
  795.     ns.CustomBitMap = myBitMaps[0];
  796.     }
  797.  
  798. if ((screen = (struct Screen *)OpenScreen(&ns)) != NULL)
  799.     {
  800.     vport = &screen->ViewPort;
  801.     rport = &screen->RastPort;
  802.  
  803.     SetRGB4(vport, 0x0, 0x0, 0x0, 0x0); /* Black */
  804.     SetRGB4(vport, 0x1, 0x0, 0x6, 0x0); /* dk green */
  805.     SetRGB4(vport, 0x2, 0x0, 0x9, 0x0); /* med green */
  806.     SetRGB4(vport, 0x3, 0x0, 0xC, 0x0); /* lt green */
  807.     SetRGB4(vport, 0x4, 0x1, 0x1, 0x7); /* dk blue */
  808.     SetRGB4(vport, 0x5, 0x7, 0x0, 0x8); /* dk violet */
  809.     SetRGB4(vport, 0x6, 0x6, 0x6, 0x6); /* dk grey */
  810.     SetRGB4(vport, 0x7, 0x7, 0x1, 0x0); /* dk red */
  811.     SetRGB4(vport, 0x8, 0x3, 0x3, 0xB); /* med blue */
  812.     SetRGB4(vport, 0x9, 0xB, 0x0, 0xC); /* med violet */
  813.     SetRGB4(vport, 0xA, 0x9, 0x9, 0x9); /* med grey */
  814.     SetRGB4(vport, 0xB, 0xB, 0x0, 0x0); /* med red */
  815.     SetRGB4(vport, 0xC, 0x5, 0x5, 0xF); /* lt blue */
  816.     SetRGB4(vport, 0xD, 0xE, 0x0, 0xF); /* lt violet */
  817.     SetRGB4(vport, 0xE, 0xF, 0xF, 0xF); /* lt grey (white) */
  818.     SetRGB4(vport, 0xF, 0xF, 0x0, 0x0); /* lt red */
  819.  
  820.     /* put some stuff in the background, so we can
  821.     ** see that it does not get destroyed.
  822.     */
  823.     SetAPen(rport, 0xA);
  824.     SetDrMd(rport, JAM1);
  825.     Move(rport, 70, 105);
  826.     Text(rport, "Animation Example...", 20);
  827.  
  828.     nw.Screen = screen;
  829.     if ((*win = (struct Window *)OpenWindow(&nw)) != NULL)
  830.         {
  831.         if (dbufing)
  832.             {
  833.             (*win)->WScreen->RastPort.Flags = DBUFFER;
  834.  
  835.             /* copy the rast port data into the alternate rast port */
  836.             (*win)->WScreen->RastPort.BitMap = myBitMaps[1];
  837.             BltBitMapRastPort(myBitMaps[0], 0,0, &(*win)->WScreen->RastPort,
  838.                         0,0, RBMWIDTH, RBMHEIGHT, 0xC0);
  839.             (*win)->WScreen->RastPort.BitMap = myBitMaps[0];
  840.             }
  841.  
  842.         /* set up the gels system.
  843.         ** 0xFC says: when you allocate sprites for me, don't ever use
  844.         ** sprites zero or one. This guarantees that sprite zero, the
  845.         ** intuition pointer, stays intact. Remember sprite one shares
  846.         ** colors with sprite zero.
  847.         */
  848.         if (NULL != (gInfo = setupGelSys(&(*win)->WScreen->RastPort, 0xFC)))
  849.             return(gInfo);
  850.  
  851.         CloseWindow(*win);
  852.         }
  853.     CloseScreen(screen);
  854.     }
  855. return_code = RETURN_WARN;
  856. return(NULL);
  857. }
  858.  
  859. /*--------------------------------------------------------------
  860. ** DrawGels part of loop.
  861. */
  862. VOID DrawGels(struct Window *win,
  863.               struct AnimOb **animKey,
  864.               SHORT dbufing,
  865.               WORD *toggleFrame,
  866.               struct BitMap **myBitMaps)
  867. {
  868. Animate(animKey, &win->WScreen->RastPort);
  869.  
  870. SortGList(&win->WScreen->RastPort);   /* Put the list in order. */
  871. DoCollision(&win->WScreen->RastPort); /* Collision routines may called now */
  872. SortGList(&win->WScreen->RastPort);      /* Put the list in order. */
  873.  
  874. if (dbufing)
  875.     win->WScreen->ViewPort.RasInfo->BitMap = myBitMaps[*toggleFrame];
  876.  
  877. /* Draw 'em. */
  878. DrawGList(&win->WScreen->RastPort, &win->WScreen->ViewPort);
  879.  
  880. if (dbufing)
  881.     {
  882.     MakeScreen(win->WScreen);    /* Tell intuition to do it's stuff. */
  883.     RethinkDisplay();            /* Does a MrgCop & LoadView. */
  884.  
  885.     *toggleFrame ^= 1;
  886.     /* Flip to the next BitMap. */
  887.     win->WScreen->RastPort.BitMap = myBitMaps[*toggleFrame];
  888.     }
  889. else
  890.     WaitTOF();
  891. }
  892.  
  893. /*--------------------------------------------------------------
  894. **
  895. */
  896. VOID main(int argc, char **argv)
  897. {
  898. struct BitMap    **myBitMaps;
  899. struct AnimOb     *boingOb;
  900. struct AnimOb     *wormOb;
  901. struct AnimOb     *manOb;
  902. struct Window     *win;
  903. struct Screen     *screen;
  904. struct GelsInfo     *gInfo;
  905. struct AnimOb     *animKey;
  906. SHORT dbufing;
  907.  
  908. return_code = RETURN_OK; /* a global variable, yech! */
  909.  
  910. printf("Program will run double buffered if there are\n");
  911. printf("any command line arguements.\n");
  912.  
  913. if (argc > 1)
  914.     dbufing = 1;  /* run double buffered when arguements */
  915. else
  916.     dbufing = 0;  /* not double buff */
  917.  
  918. if (NULL == (IntuitionBase = (struct IntuitionBase *)
  919.         OpenLibrary("intuition.library", 33L)))
  920.     return_code = RETURN_FAIL;
  921. else
  922.     {
  923.     if (NULL == (GfxBase = (struct GfxBase *)
  924.             OpenLibrary("graphics.library", 33L)))
  925.         return_code = RETURN_FAIL;
  926.     else
  927.         {
  928.         if ((!dbufing) ||
  929.             (NULL != (myBitMaps=setupBitMaps(RBMDEPTH,RBMWIDTH,RBMHEIGHT))))
  930.             {
  931.             if (NULL != (gInfo = setupDisplay(&win,dbufing,myBitMaps)))
  932.                 {
  933.                 InitAnimate(&animKey);
  934.                 /* Simple sequenced animation. (Boing ball)
  935.                 ** Simple animation using XTrans and YTrans.
  936.                 ** (tiny orbiting satellite)
  937.                 */
  938.                 if (NULL != (boingOb = setupBoing(dbufing)))
  939.                     {
  940.                     AddAnimOb(boingOb, &animKey, &win->WScreen->RastPort);
  941.                     if (NULL != (wormOb = setupWorm(dbufing)))
  942.                         {
  943.                         AddAnimOb(wormOb, &animKey, &win->WScreen->RastPort);
  944.                         if (NULL != (manOb = setupMan(dbufing)))
  945.                             {
  946.                             AddAnimOb(manOb, &animKey,
  947.                                         &win->WScreen->RastPort);
  948.                             runAnimation(win, dbufing, &animKey, myBitMaps);
  949.                             freeOb(manOb, RBMDEPTH);
  950.                             }
  951.                         freeOb(wormOb, RBMDEPTH);
  952.                         }
  953.                     freeOb(boingOb, RBMDEPTH);
  954.                     }
  955.  
  956.                 cleanupGelSys(gInfo, &win->WScreen->RastPort);
  957.                 screen = win->WScreen;
  958.                 CloseWindow(win);
  959.                 CloseScreen(screen);
  960.                 }
  961.  
  962.             if (dbufing)
  963.                 freeBitMaps(myBitMaps, RBMDEPTH, RBMWIDTH, RBMHEIGHT);
  964.             }
  965.         CloseLibrary((struct Library *)GfxBase);
  966.         }
  967.     CloseLibrary((struct Library *)IntuitionBase);
  968.     }
  969. exit(return_code);
  970. }
  971.