home *** CD-ROM | disk | FTP | other *** search
-
-
-
- /* geltools.c */
-
- /* ===========================================================
-
- GELTOOLS.C -
-
- A FILE CONTAINING USEFUL SETUP TOOLS FOR THE ANIMATION SYSTEM
-
-
- author: Rob Peck, incorporating valuable comments and changes from
- Barry Whitebook and David Lucas.
-
- ============================================================== */
- #include <exec/types.h>
- #include <exec/memory.h>
- #include <graphics/gfx.h>
- #include <graphics/gels.h>
- #include <graphics/clip.h>
- #include <graphics/rastport.h>
- #include <graphics/view.h>
- #include <graphics/gfxbase.h>
-
-
- /*************************************************************
- * This file is a collection of tools which are used with the vsprite
- * and bob software. It contains the following:
- *
- * ReadyGels( *gelsinfo, *rastport );
- * PurgeGels( *gelsinfo );
- *
- * struct VSprite *MakeVSprite(lineheight,*image,*colorset,x,y,
- * wordwidth,imagedepth,flags);
- * DeleteVSprite( &VSprite );
- *
- * struct Bob *MakeBob(bitwidth,lineheight,imagedepth,*image,
- * planePick,planeOnOff,x,y)
- * DeleteBob( &Bob );
- *
- * ReadyGels sets up the defaults of the gel system by initializing the
- * GelsInfo structure you provide. First it allocates room for and
- * links in lastcolor and nextline. It then uses information in your
- * RastPort structure to establish boundary collision defaults at
- * the outer edges of the raster. It then links together the GelsInfo
- * and the RastPort which you provide. Next it allocates space for two
- * dummy virtual sprite structures, calls InitGels and SetCollision.
- ! You must already have run LoadView before ReadyGels is called.
- *
- * PurgeGels deallocates all memory which ReadyGels and NewGelList have
- * allocated. The system will crash if you have not used these
- * routines to allocate the space (you cant deallocate something
- * which you havent allocated in the first place).
- *
- * MakeVSprite allocates enough space for and inits a normal vsprite.
- * DeleteVSprite deallocates the memory it used.
- *
- * MakeBob initializes a standard bob and allocates as much memory as is
- * needed for a normal bob and its vsprite structure, links them together.
- * To find the associated vsprite, look at the back-pointer (see the
- * routine doc itself).
- * DeleteBob deallocates the memory it used.
- *
- * Written by Rob Peck, with thanks to Barry Whitebrook and David Lucas.
- *
- ***************************************************************/
-
-
- void border_dummy()
- {
- return;
- }
-
- /* Caller passes a pointer to his
- * GelsInfo structure which he wants to init,
- * along with a pointer to his IVPArgs.
- * Default init places the topmost
- * bottommost etc at the outermost boundaries
- * of callers rastport parameters.
- * Caller can change all this stuff after this routine returns.
- */
-
- extern struct RastPort *myRast;
-
- struct VSprite *SpriteHead = NULL;
- struct VSprite *SpriteTail = NULL;
-
- /***************************************************************
- * This routine cannot be run until the first LoadView(&view) has been
- * executed. InitGels works with an already active View, so LoadView
- * must have been run first.
- */
-
- ReadyGels(g, r)
- struct RastPort *r;
- struct GelsInfo *g;
- {
- /* Allocate head and tail of list. */
- if ((SpriteHead = (struct VSprite *)AllocMem(sizeof
- (struct VSprite), MEMF_PUBLIC | MEMF_CLEAR)) == 0) {
- #ifdef DEBUG
- kprintf("ReadyGels: No memory for sprite head.\n");
- #endif
- return(-1);
- }
-
- if ((SpriteTail = (struct VSprite *)AllocMem(sizeof
- (struct VSprite), MEMF_PUBLIC | MEMF_CLEAR)) == 0) {
- #ifdef DEBUG
- kprintf("ReadyGels: No memory for sprite tail.\n");
- #endif
- return(-1);
- }
-
- /* By setting all bits here, it means that there are NO
- * reserved sprites. The system can freely use all of the
- * hardware sprites for its own purposes. The caller will not be
- * trying to independently use any hardware sprites!
- */
- g->sprRsrvd = -1;
-
- /* The nextline array is used to hold system information about
- * "at which line number on the screen is this hardware sprite
- * again going to become available to be given a new vsprite to
- * display".
- */
- if ((g->nextLine = (WORD *)AllocMem(sizeof(WORD) * 8,
- MEMF_PUBLIC | MEMF_CLEAR)) == NULL) {
- #ifdef DEBUG
- kprintf("ReadyGels: No memory for nextline.\n");
- #endif
- return(-1);
- }
-
- /* In the lastcolor pointer array, the system will store
- * a pointer to the color definitions most recently used
- * by the system. .... as a reminder, virtual sprites can
- * be assigned to any of the real hardware sprites which
- * may be available at the time. The vsprite colors will
- * be written into the hardware sprite register set for
- * the hardware sprite to which that vsprite is assigned.
- * This pointer array contains one pointer to the last
- * set of three colors (from the vsprite structure *sprColors)
- * for each hardware sprite.
- *
- * As the system is scanning to determine which hardware
- * sprite should next be used to represent a vsprite, it
- * checks the contents of this array. If a hardware sprite
- * is available and already has been assigned this set of
- * colors, no color assignment is needed, and therefore
- * no color change instructions will be generated for the
- * copper list.
- *
- * If all vsprites use a different set of sprColors, (pointers
- * to sprColors are different for all vsprites), then there
- * is a limit of 4 vsprites on a horizontal line. If, on
- * the other hand, you define, lets say 8 vsprites, with
- * 1 and 2 having the same sprColors, 3 and 4 the same as
- * each other, 5 and 6 the same as each other, and 7 and 8
- * also having the same vsprite colors, then you will be
- * able to have all 8 vsprites on the same horizontal line.
- *
- * In this case, you will be able to put all 8 vsprites on
- * the same horizontal line. The reason this helps is that
- * the system hardware shares the color registers between pairs
- * of hardware sprites. The system thus has enough resources
- * to assign all vsprites to hardware sprites in that there
- * are 4 color-sets for 8 vsprites, exactly matching the
- * hardware maximum capabilities.
- *
- * Note that lastcolor will not be used for bobs. Just sprites.
- */
- if ((g->lastColor = (WORD **)AllocMem(sizeof(LONG) * 8,
- MEMF_PUBLIC | MEMF_CLEAR)) == NULL) {
- #ifdef DEBUG
- kprintf("ReadyGels: No memory for lastcolor.\n");
- #endif
- return(-1);
- }
-
- /* This is a table of pointers to the routines which should
- * be performed when DoCollision senses a collision. This
- * declaration may not be necessary for a basic vsprite with
- * no collision detection implemented, but then it makes for
- * a complete example.
- */
- if ((g->collHandler = (struct collTable *)AllocMem(sizeof(struct
- collTable), MEMF_PUBLIC | MEMF_CLEAR)) == NULL) {
- #ifdef DEBUG
- kprintf("ReadyGels: No memory for collHandler.\n");
- #endif
- return(-1);
- }
-
- /* When any part of the object touches or passes across
- * this boundary, it will cause the boundary collision
- * routine to be called. This is at smash[0] in the
- * collision handler table and is called only if
- * DoCollision is called.
- */
- g->leftmost = 0;
- g->rightmost = r->BitMap->BytesPerRow * 8 - 1;
- g->topmost = 0;
- g->bottommost = r->BitMap->Rows - 1;
-
- r->GelsInfo = g; /* Link together the two structures */
-
- InitGels(SpriteHead, SpriteTail, g );
-
- /* Pointers initialized to the dummy sprites which will be
- * used by the system to keep track of the animation system.
- */
- SetCollision(0, border_dummy, g);
- WaitTOF();
- return(0);
- }
-
- /*****************************************************************
- * Use this to get rid of the gels stuff when it is not needed any more.
- * more. You must have allocated the gels info stuff
- * (use the ReadyGels routine).
- */
-
- PurgeGels(g)
- struct GelsInfo *g;
- {
- if (g->collHandler != NULL)
- FreeMem(g->collHandler, sizeof(struct collTable));
- if (g->lastColor != NULL)
- FreeMem(g->lastColor, sizeof(LONG) * 8);
- if (g->nextLine != NULL)
- FreeMem(g->nextLine, sizeof(WORD) * 8);
- if (g->gelHead != NULL)
- FreeMem(g->gelHead, sizeof(struct VSprite));
- if (g->gelTail != NULL)
- FreeMem(g->gelTail, sizeof(struct VSprite));
- }
-
- /**************************************************************
- * Because MakeVSprite is called by MakeBob,
- * MakeVSprite only creates the
- * VSprite,it doesn't add it to the system list.
- * The calling routine must
- * do an AddVSprite after it is created.
- */
-
- struct VSprite *MakeVSprite(lineheight, image, x, y,
- wordwidth, imagedepth, flags)
- SHORT lineheight; /* How tall is this vsprite? */
- WORD *image; /* Where is the vsprite image data, should be
- twice as many words as the value of lineheight */
- SHORT x, y; /* What is its initial onscreen position? */
- SHORT wordwidth, imagedepth, flags;
- {
- struct VSprite *v; /* Make a pointer to the vsprite structure which
- this routine dynamically allocates */
-
- if ((v = (struct VSprite *)AllocMem(sizeof(struct VSprite),
- MEMF_PUBLIC | MEMF_CLEAR)) == 0) {
- #ifdef DEBUG
- printf("MakeVSprite: Couldn't allocate VSprite.\n");
- #endif
- return(0);
- }
-
- v->Flags = flags; /* Is this a vsprite, not a bob? */
-
- v->Y = y; /* Establish initial position relative to */
- v->X = x; /* the Display coordinates. */
-
- v->Height = lineheight; /* The Caller says how high it is. */
- v->Width = wordwidth; /* A vsprite is always 1 word (16 bits) wide.*/
-
- /* There are two kinds of depth... the depth of the image itself,
- and the depth of the playfield into which it will be drawn.
- The image depth says how much data space will be needed
- to store an image if it's dynamically allocated.
- The playfield depth establishes how much space
- will be needed to save and restore the background when
- a bob is drawn. A vsprite is always 2 planes deep,
- but if it's being used to make a bob, it may be deeper...
- */
-
- v->Depth = imagedepth;
-
- /* Assume that the caller at least has a default boundary
- collision routine...bit 1 of this mask is reserved for
- boundary collision detect during DoCollision(). The only
- collisions reported will be with the borders.
- The caller can change all this later.
- */
-
- v->MeMask = 1;
- v->HitMask = 1;
-
- v->ImageData = image; /* Caller says where to find the image. */
-
- /* Show system where to find a mask which is a squished down
- * version of the vsprite (allows for fast horizontal border
- * collision detect).
- */
-
- if ((v->BorderLine = (WORD *)AllocMem((sizeof(WORD)*wordwidth),
- MEMF_PUBLIC | MEMF_CLEAR)) == 0) {
- #ifdef DEBUG
- kprintf("MakeVSprite: Couldn't allocate BorderLine.\n");
- #endif
- return(0);
- }
-
- /* Show system where to find the mask which contains a 1 bit for any
- * position in the object in any plane where there
- * is a 1 bit (all planes OR'ed together).
- */
-
- if ((v->CollMask = (WORD *)AllocMem(sizeof(WORD)*lineheight*wordwidth,
- MEMF_CHIP | MEMF_CLEAR)) == 0) {
- #ifdef DEBUG
- kprintf("MakeVSprite: Couldn't allocate CollMask.\n");
- #endif
- return(0);
- }
-
-
- /* These aren't used for a VSprite, and MakeBob'll do set up for Bob. */
- v->PlanePick = 0x00;
- v->PlaneOnOff = 0x00;
-
- InitMasks(v); /* Create the collMask and borderLine */
-
- return(v);
- }
-
- struct Bob *MakeBob(bitwidth,lineheight,imagedepth,image,
- planePick,planeOnOff, x,y, flags)
- SHORT bitwidth,lineheight,imagedepth,planePick,planeOnOff,x,y,flags;
- WORD *image;
- {
- struct Bob *b;
- struct VSprite *v;
- SHORT wordwidth;
-
- wordwidth = (bitwidth+15)/16;
-
- /* Create a vsprite for this bob, it will need to be deallocated
- * later (freed) when this bob gets deleted.
- * Note: No color set for bobs.
- */
- if ((v = MakeVSprite(lineheight, image, NULL, x, y, wordwidth,
- imagedepth, flags)) == 0) {
- #ifdef DEBUG
- kprintf("MakeBob: MakeVSprite failed.\n");
- #endif
- return(0);
- }
-
- /* Caller selects which bit planes into which the image is drawn. */
- v->PlanePick = planePick;
-
- /* What happens to the bit planes into which the image is not drawn. */
- v->PlaneOnOff = planeOnOff;
-
- if ((b = (struct Bob *)AllocMem(sizeof(struct Bob),
- MEMF_PUBLIC | MEMF_CLEAR)) == 0) {
- #ifdef DEBUG
- kprintf("MakeBob: Couldn't allocate bob.\n");
- #endif
- return(0);
- }
-
- v->VSBob = b; /* Link together the bob and its vsprite structures */
-
- b->Flags = 0; /* Not part of an animation (BOBISCOMP) and don't keep the
- image present after bob is removed (SAVEBOB) */
-
-
- /* Tell where to save background. Must have enough space for as many
- * bitplanes deep as the display into which everything is
- being drawn. */
-
- if ((b->SaveBuffer = (WORD *)AllocMem(sizeof(SHORT) * wordwidth
- * lineheight * imagedepth, MEMF_CHIP | MEMF_CLEAR)) == 0) {
- #ifdef DEBUG
- kprintf("MakeBob: Couldn't allocate save buffer.\n");
- #endif
- return(0);
- }
-
- b->ImageShadow = v->CollMask;
-
- /* Interbob priorities are set such that the earliest defined bobs
- * have the lowest priority, last bob defined is on top.
- */
-
- b->Before = NULL; /* Let the caller worry about priority later. */
- b->After = NULL;
-
- b->BobVSprite = v;
-
- /* InitMasks does not preset the imageShadow ... caller may elect to
- * use the collMask or to create his own version of a shadow,
- * although it is usually the same.
- */
-
- b->BobComp = NULL; /* this is not part of an animation */
- b->DBuffer = NULL; /* this is not double buffered */
-
- /* Return a pointer to this newly created bob for additional caller
- * interaction or for AddBob(b);
- */
- return(b);
- }
-
- /* Deallocate memory which has been allocated by the routines Makexxx. */
- /* Assumes images and imageshadow deallocated elsewhere. */
- DeleteGel(v)
- struct VSprite *v;
- {
- if (v != NULL) {
- if (v->VSBob != NULL) {
- if (v->VSBob->SaveBuffer != NULL) {
- FreeMem(v->VSBob->SaveBuffer, sizeof(SHORT) * v->Width
- * v->Height * v->Depth);
- }
- if (v->VSBob->DBuffer != NULL) {
- if (v->VSBob->DBuffer->BufBuffer != 0) {
- FreeMem(v->VSBob->DBuffer->BufBuffer,
- sizeof(SHORT) * v->Width * v->Height * v->Depth);
- }
- FreeMem(v->VSBob->DBuffer, sizeof(struct DBufPacket));
- }
- FreeMem( v->VSBob, sizeof(struct Bob));
- }
- if (v->CollMask != NULL) {
- FreeMem(v->CollMask, sizeof(WORD) * v->Height * v->Width);
- }
- if (v->BorderLine != NULL) {
- FreeMem(v->BorderLine, sizeof(WORD) * v->Width);
- }
- FreeMem(v, sizeof(struct VSprite));
- }
- }
-
-
-