home *** CD-ROM | disk | FTP | other *** search
/ The Fred Fish Collection 1.5 / ffcollection-1-5-1992-11.iso / ff_progs / prog_oth / monopoly.lzh / monopoly_source.LZH / geltools.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-01-04  |  14.7 KB  |  446 lines

  1.  
  2.  
  3.  
  4. /* geltools.c */
  5.  
  6. /* ===========================================================
  7.  
  8. GELTOOLS.C - 
  9.  
  10.    A FILE CONTAINING USEFUL SETUP TOOLS FOR THE ANIMATION SYSTEM
  11.  
  12.  
  13.    author:  Rob Peck, incorporating valuable comments and changes from
  14.        Barry Whitebook and David Lucas.
  15.  
  16. ============================================================== */
  17. #include <exec/types.h>
  18. #include <exec/memory.h>
  19. #include <graphics/gfx.h>
  20. #include <graphics/gels.h>
  21. #include <graphics/clip.h>
  22. #include <graphics/rastport.h>
  23. #include <graphics/view.h>
  24. #include <graphics/gfxbase.h>
  25.  
  26.  
  27. /*************************************************************
  28.  * This file is a collection of tools which are used with the vsprite
  29.  * and bob software.  It contains the following:
  30.  *
  31.  * ReadyGels( *gelsinfo, *rastport );
  32.  * PurgeGels( *gelsinfo );
  33.  *
  34.  * struct VSprite *MakeVSprite(lineheight,*image,*colorset,x,y,
  35.  *    wordwidth,imagedepth,flags);       
  36.  * DeleteVSprite( &VSprite );
  37.  *
  38.  * struct Bob *MakeBob(bitwidth,lineheight,imagedepth,*image,
  39.  *       planePick,planeOnOff,x,y)
  40.  * DeleteBob( &Bob );
  41.  *
  42.  * ReadyGels sets up the defaults of the gel system by initializing the
  43.  * GelsInfo structure you provide.  First it allocates room for and
  44.  * links in lastcolor and nextline. It then uses information in your
  45.  * RastPort structure to establish boundary collision defaults at
  46.  * the outer edges of the raster.  It then links together the GelsInfo
  47.  * and the RastPort which you provide. Next it allocates space for two
  48.  * dummy virtual sprite structures, calls InitGels and SetCollision.
  49.  ! You must already have run LoadView before ReadyGels is called.
  50.  *
  51.  * PurgeGels deallocates all memory which ReadyGels and NewGelList have
  52.  * allocated.  The system will crash if you have not used these
  53.  * routines to allocate the space (you cant deallocate something
  54.  * which you havent allocated in the first place).
  55.  *
  56.  * MakeVSprite allocates enough space for and inits a normal vsprite.
  57.  * DeleteVSprite deallocates the memory it used.
  58.  *
  59.  * MakeBob initializes a standard bob and allocates as much memory as is
  60.  * needed for a normal bob and its vsprite structure, links them together.
  61.  * To find the associated vsprite, look at the back-pointer (see the
  62.  * routine doc itself).
  63.  * DeleteBob deallocates the memory it used.
  64.  *
  65.  * Written by Rob Peck, with thanks to Barry Whitebrook and David Lucas.
  66.  *
  67.  ***************************************************************/
  68.  
  69.  
  70. void border_dummy()
  71.    return; 
  72. }
  73.  
  74. /* Caller passes a pointer to his
  75.  * GelsInfo structure which he wants to init, 
  76.  * along with a pointer to his IVPArgs.
  77.  * Default init places the topmost
  78.  * bottommost etc at the outermost boundaries
  79.  * of callers rastport parameters.
  80.  * Caller can change all this stuff after this routine returns.
  81.  */
  82.  
  83. extern struct RastPort *myRast;
  84.  
  85. struct VSprite *SpriteHead = NULL;
  86. struct VSprite *SpriteTail = NULL;
  87.  
  88. /***************************************************************
  89.  * This routine cannot be run until the first LoadView(&view) has been
  90.  * executed.  InitGels works with an already active View, so LoadView
  91.  * must have been run first.
  92.  */
  93.  
  94. ReadyGels(g, r)
  95. struct RastPort *r;
  96. struct GelsInfo *g;
  97. {
  98.    /* Allocate head and tail of list. */
  99.    if ((SpriteHead = (struct VSprite *)AllocMem(sizeof
  100.        (struct VSprite), MEMF_PUBLIC | MEMF_CLEAR)) == 0) {
  101. #ifdef DEBUG
  102.       kprintf("ReadyGels: No memory for sprite head.\n");
  103. #endif
  104.       return(-1);
  105.    }
  106.  
  107.    if ((SpriteTail = (struct VSprite *)AllocMem(sizeof
  108.        (struct VSprite), MEMF_PUBLIC | MEMF_CLEAR)) == 0) {
  109. #ifdef DEBUG
  110.       kprintf("ReadyGels: No memory for sprite tail.\n");
  111. #endif
  112.       return(-1);
  113.    }
  114.  
  115.    /* By setting all bits here, it means that there are NO
  116.       * reserved sprites.  The system can freely use all of the 
  117.       * hardware sprites for its own purposes.  The caller will not be
  118.       * trying to independently use any hardware sprites!
  119.       */
  120.    g->sprRsrvd = -1;
  121.  
  122.    /* The nextline array is used to hold system information about
  123.       * "at which line number on the screen is this hardware sprite
  124.       * again going to become available to be given a new vsprite to
  125.       * display".
  126.       */
  127.    if ((g->nextLine = (WORD *)AllocMem(sizeof(WORD) * 8,
  128.    MEMF_PUBLIC | MEMF_CLEAR)) == NULL) {
  129. #ifdef DEBUG
  130.       kprintf("ReadyGels: No memory for nextline.\n");
  131. #endif
  132.       return(-1);
  133.    }
  134.  
  135.    /* In the lastcolor pointer array, the system will store
  136.       * a pointer to the color definitions most recently used
  137.       * by the system. .... as a reminder, virtual sprites can
  138.       * be assigned to any of the real hardware sprites which
  139.       * may be available at the time.  The vsprite colors will
  140.       * be written into the hardware sprite register set for
  141.       * the hardware sprite to which that vsprite is assigned.
  142.       * This pointer array contains one pointer to the last
  143.       * set of three colors (from the vsprite structure *sprColors)
  144.       * for each hardware sprite.  
  145.       *
  146.    * As the system is scanning to determine which hardware 
  147.       * sprite should next be used to represent a vsprite, it
  148.       * checks the contents of this array.  If a hardware sprite
  149.       * is available and already has been assigned this set of
  150.       * colors, no color assignment is needed, and therefore
  151.       * no color change instructions will be generated for the
  152.       * copper list.
  153.       *
  154.    * If all vsprites use a different set of sprColors, (pointers
  155.       * to sprColors are different for all vsprites), then there
  156.       * is a limit of 4 vsprites on a horizontal line.  If, on
  157.       * the other hand, you define, lets say 8 vsprites, with
  158.       * 1 and 2 having the same sprColors, 3 and 4 the same as
  159.       * each other, 5 and 6 the same as each other, and 7 and 8
  160.       * also having the same vsprite colors, then you will be
  161.       * able to have all 8 vsprites on the same horizontal line.
  162.       *
  163.    * In this case, you will be able to put all 8 vsprites on
  164.       * the same horizontal line.  The reason this helps is that
  165.       * the system hardware shares the color registers between pairs
  166.       * of hardware sprites.  The system thus has enough resources
  167.       * to assign all vsprites to hardware sprites in that there
  168.       * are 4 color-sets for 8 vsprites, exactly matching the 
  169.       * hardware maximum capabilities.
  170.       *
  171.    * Note that lastcolor will not be used for bobs. Just sprites.
  172.       */
  173.    if ((g->lastColor = (WORD **)AllocMem(sizeof(LONG) * 8,
  174.    MEMF_PUBLIC | MEMF_CLEAR)) == NULL) {
  175. #ifdef DEBUG
  176.       kprintf("ReadyGels: No memory for lastcolor.\n");
  177. #endif
  178.       return(-1);
  179.    }
  180.  
  181.    /* This is a table of pointers to the routines which should
  182.       * be performed when DoCollision senses a collision.  This
  183.       * declaration may not be necessary for a basic vsprite with
  184.       * no collision detection implemented, but then it makes for
  185.       * a complete example.
  186.       */
  187.    if ((g->collHandler = (struct collTable *)AllocMem(sizeof(struct
  188.        collTable), MEMF_PUBLIC | MEMF_CLEAR)) == NULL) {
  189. #ifdef DEBUG
  190.       kprintf("ReadyGels: No memory for collHandler.\n");
  191. #endif
  192.       return(-1);
  193.    }
  194.  
  195.    /* When any part of the object touches or passes across
  196.       * this boundary, it will cause the boundary collision
  197.       * routine to be called.  This is at smash[0] in the
  198.       * collision handler table and is called only if
  199.       * DoCollision is called.
  200.       */
  201.    g->leftmost = 0;
  202.    g->rightmost = r->BitMap->BytesPerRow * 8 - 1;
  203.    g->topmost = 0;
  204.    g->bottommost = r->BitMap->Rows - 1;
  205.  
  206.    r->GelsInfo = g;  /* Link together the two structures */
  207.  
  208.    InitGels(SpriteHead, SpriteTail, g );
  209.  
  210.    /* Pointers initialized to the dummy sprites which will be
  211.       * used by the system to keep track of the animation system.
  212.       */
  213.    SetCollision(0, border_dummy, g);
  214.    WaitTOF();
  215.    return(0);
  216. }
  217.  
  218. /*****************************************************************
  219.  * Use this to get rid of the gels stuff when it is not needed any more.
  220.  * more.  You must have allocated the gels info stuff
  221.  * (use the ReadyGels routine).
  222.  */
  223.  
  224. PurgeGels(g)
  225. struct GelsInfo *g;
  226. {
  227.    if (g->collHandler != NULL)
  228.       FreeMem(g->collHandler, sizeof(struct collTable));
  229.    if (g->lastColor != NULL)
  230.       FreeMem(g->lastColor, sizeof(LONG) * 8);
  231.    if (g->nextLine != NULL)
  232.       FreeMem(g->nextLine, sizeof(WORD) * 8);
  233.    if (g->gelHead != NULL)
  234.       FreeMem(g->gelHead, sizeof(struct VSprite));
  235.    if (g->gelTail != NULL)
  236.       FreeMem(g->gelTail, sizeof(struct VSprite));
  237. }
  238.  
  239. /**************************************************************
  240.  * Because MakeVSprite is called by MakeBob,
  241.  * MakeVSprite only creates the
  242.  * VSprite,it doesn't add it to the system list.
  243.  * The calling routine must
  244.  * do an AddVSprite after it is created.
  245.  */
  246.  
  247. struct VSprite *MakeVSprite(lineheight, image, x, y,
  248. wordwidth, imagedepth, flags)
  249. SHORT lineheight;   /* How tall is this vsprite? */
  250. WORD *image;      /* Where is the vsprite image data, should be
  251.             twice as many words as the value of lineheight */
  252. SHORT x, y;      /* What is its initial onscreen position? */
  253. SHORT wordwidth, imagedepth, flags;
  254. {
  255.    struct VSprite *v;   /* Make a pointer to the vsprite structure which
  256.                this routine dynamically allocates */
  257.  
  258.    if ((v = (struct VSprite *)AllocMem(sizeof(struct VSprite),
  259.    MEMF_PUBLIC | MEMF_CLEAR)) == 0) {
  260. #ifdef DEBUG
  261.       printf("MakeVSprite: Couldn't allocate VSprite.\n");
  262. #endif
  263.       return(0);
  264.    }
  265.  
  266.    v->Flags = flags;   /* Is this a vsprite, not a bob? */
  267.  
  268.    v->Y = y;      /* Establish initial position relative to */
  269.    v->X = x;      /* the Display coordinates. */
  270.  
  271.    v->Height = lineheight;   /* The Caller says how high it is. */
  272.    v->Width = wordwidth; /* A vsprite is always 1 word (16 bits) wide.*/
  273.  
  274.    /* There are two kinds of depth... the depth of the image itself,
  275.       and the depth of the playfield into which it will be drawn.
  276.       The image depth says how much data space will be needed
  277.       to store an image if it's dynamically allocated.
  278.       The playfield depth establishes how much space
  279.       will be needed to save and restore the background when
  280.       a bob is drawn. A vsprite is always 2 planes deep,
  281.       but if it's being used to make a bob, it may be deeper...
  282.       */
  283.  
  284.    v->Depth = imagedepth;
  285.  
  286.    /* Assume that the caller at least has a default boundary
  287.       collision routine...bit 1 of this mask is reserved for
  288.       boundary collision detect during DoCollision(). The only
  289.       collisions reported will be with the borders.
  290.       The caller can change all this later.
  291.       */
  292.  
  293.    v->MeMask = 1;
  294.    v->HitMask = 1;
  295.  
  296.    v->ImageData = image;   /* Caller says where to find the image. */
  297.  
  298.    /* Show system where to find a mask which is a squished down
  299.       * version of the vsprite (allows for fast horizontal border
  300.       * collision detect).
  301.       */
  302.  
  303.    if ((v->BorderLine = (WORD *)AllocMem((sizeof(WORD)*wordwidth),
  304.    MEMF_PUBLIC | MEMF_CLEAR)) == 0) {
  305. #ifdef DEBUG
  306.       kprintf("MakeVSprite: Couldn't allocate BorderLine.\n");
  307. #endif
  308.       return(0);
  309.    }
  310.  
  311.    /* Show system where to find the mask which contains a 1 bit for any
  312.       * position in the object in any plane where there
  313.       * is a 1 bit (all planes OR'ed together).
  314.       */
  315.  
  316.    if ((v->CollMask = (WORD *)AllocMem(sizeof(WORD)*lineheight*wordwidth,
  317.    MEMF_CHIP | MEMF_CLEAR)) == 0) {
  318. #ifdef DEBUG
  319.       kprintf("MakeVSprite: Couldn't allocate CollMask.\n");
  320. #endif
  321.       return(0);
  322.    }
  323.  
  324.  
  325.    /* These aren't used for a VSprite, and MakeBob'll do set up for Bob. */
  326.    v->PlanePick = 0x00;
  327.    v->PlaneOnOff = 0x00;
  328.  
  329.    InitMasks(v);   /* Create the collMask and borderLine */
  330.  
  331.    return(v);
  332. }
  333.  
  334. struct Bob *MakeBob(bitwidth,lineheight,imagedepth,image,
  335. planePick,planeOnOff, x,y, flags)
  336. SHORT bitwidth,lineheight,imagedepth,planePick,planeOnOff,x,y,flags;
  337. WORD *image;
  338. {
  339.    struct Bob *b;
  340.    struct VSprite *v;
  341.    SHORT wordwidth;
  342.  
  343.    wordwidth = (bitwidth+15)/16;
  344.  
  345.    /* Create a vsprite for this bob, it will need to be deallocated
  346.       * later (freed) when this bob gets deleted.
  347.       * Note: No color set for bobs.
  348.       */
  349.    if ((v = MakeVSprite(lineheight, image, NULL, x, y, wordwidth,
  350.    imagedepth, flags)) == 0) {
  351. #ifdef DEBUG
  352.       kprintf("MakeBob: MakeVSprite failed.\n");
  353. #endif
  354.       return(0);
  355.    }
  356.  
  357.    /* Caller selects which bit planes into which the image is drawn. */
  358.    v->PlanePick = planePick;
  359.  
  360.    /* What happens to the bit planes into which the image is not drawn. */
  361.    v->PlaneOnOff = planeOnOff;
  362.  
  363.    if ((b = (struct Bob *)AllocMem(sizeof(struct Bob),
  364.    MEMF_PUBLIC | MEMF_CLEAR)) == 0) {
  365. #ifdef DEBUG
  366.       kprintf("MakeBob: Couldn't allocate bob.\n");
  367. #endif
  368.       return(0);
  369.    }
  370.  
  371.    v->VSBob = b; /* Link together the bob and its vsprite structures */
  372.  
  373.    b->Flags = 0; /* Not part of an animation (BOBISCOMP) and don't keep the
  374.             image present after bob is removed (SAVEBOB) */
  375.  
  376.  
  377.    /* Tell where to save background. Must have enough space for as many
  378.       * bitplanes deep as the display into which everything is
  379.          being drawn.      */
  380.  
  381.    if ((b->SaveBuffer = (WORD *)AllocMem(sizeof(SHORT) * wordwidth
  382.        * lineheight * imagedepth, MEMF_CHIP | MEMF_CLEAR)) == 0) {
  383. #ifdef DEBUG
  384.       kprintf("MakeBob: Couldn't allocate save buffer.\n");
  385. #endif
  386.       return(0);
  387.    }
  388.  
  389.    b->ImageShadow = v->CollMask;
  390.  
  391.    /* Interbob priorities are set such that the earliest defined bobs
  392.       * have the lowest priority, last bob defined is on top.
  393.       */
  394.  
  395.    b->Before = NULL;   /* Let the caller worry about priority later. */
  396.    b->After = NULL;
  397.  
  398.    b->BobVSprite = v;
  399.  
  400.    /* InitMasks does not preset the imageShadow ... caller may elect to
  401.       * use the collMask or to create his own version of a shadow,
  402.       * although it is usually the same.
  403.       */
  404.  
  405.    b->BobComp = NULL;   /* this is not part of an animation */
  406.    b->DBuffer = NULL;   /* this is not double buffered */
  407.  
  408.    /* Return a pointer to this newly created bob for additional caller
  409.       * interaction or for AddBob(b);
  410.       */
  411.    return(b);
  412. }
  413.  
  414. /* Deallocate memory which has been allocated by the routines Makexxx. */
  415. /* Assumes images and imageshadow deallocated elsewhere. */
  416. DeleteGel(v)
  417. struct VSprite *v;
  418. {
  419.    if (v != NULL) {
  420.       if (v->VSBob != NULL) {
  421.          if (v->VSBob->SaveBuffer != NULL) {
  422.             FreeMem(v->VSBob->SaveBuffer, sizeof(SHORT) * v->Width
  423.                 * v->Height * v->Depth);
  424.          }
  425.          if (v->VSBob->DBuffer != NULL) {
  426.             if (v->VSBob->DBuffer->BufBuffer != 0) {
  427.                FreeMem(v->VSBob->DBuffer->BufBuffer,
  428.                sizeof(SHORT) * v->Width * v->Height * v->Depth);
  429.             }
  430.             FreeMem(v->VSBob->DBuffer, sizeof(struct DBufPacket));
  431.          }
  432.          FreeMem( v->VSBob, sizeof(struct Bob));
  433.       }
  434.       if (v->CollMask != NULL) {
  435.          FreeMem(v->CollMask, sizeof(WORD) * v->Height * v->Width);
  436.       }
  437.       if (v->BorderLine != NULL) {
  438.          FreeMem(v->BorderLine, sizeof(WORD) * v->Width);
  439.       }
  440.       FreeMem(v, sizeof(struct VSprite));
  441.    }
  442. }
  443.  
  444.  
  445.