home *** CD-ROM | disk | FTP | other *** search
- /* :ts=8 bk=0
- *
- * anim.c: Animation drivers.
- *
- * Leo L. Schwab 8710.2 (415) 456-3960
- */
- #include <exec/types.h>
- #include <exec/lists.h>
- #include <exec/memory.h>
- #include <graphics/rastport.h>
- #include "marketroid.h"
-
- extern struct object ob_grunt; /* Special case for movement */
- extern struct BitMap *sbm;
-
- struct BitMap *getxpmap();
- struct List guys;
- static int opened;
- int leftbound, rightbound, topbound, bottombound;
-
- struct obcontrol *
- addobject (ob, pri, dir, x, y)
- register struct object *ob;
- int pri, dir, x, y;
- {
- register struct obcontrol *oc;
-
- if (!(oc = AllocMem ((long) sizeof (*oc), MEMF_CLEAR)))
- return (0);
-
- oc -> node.ln_Pri = pri;
- oc -> ob = ob;
- oc -> x = x;
- oc -> y = y;
- oc -> frame = 0;
- oc -> delay = 1;
-
- if (oc->x + ob->width > rightbound ||
- oc->x < leftbound ||
- oc->y + ob->height > bottombound ||
- oc->y < topbound)
- oc -> flags |= OFFSCREEN;
-
- setdir (oc, dir);
- Enqueue (&guys, oc);
- return (oc);
- }
-
- removeobject (oc)
- register struct obcontrol *oc;
- {
- register struct object *ob = oc -> ob;
- register struct BitMap *bm;
-
- /* Pull it out of the list */
- Remove (oc);
-
- /* Erase the image from the screen */
- if (!(oc -> flags & OFFSCREEN))
- BltBitMap (ob -> bitmap, 0L, 0L,
- sbm, (long) oc -> x, (long) oc -> y,
- (long) ob -> width, (long) ob -> height,
- 0L, 0xffL, NULL);
-
- /* Free dynamically allocated stuff */
- if (bm = (struct BitMap *) oc -> node.ln_Name) {
- if (bm -> Planes[0])
- FreeRaster (bm -> Planes[0],
- (long) ob->width, bm->Rows * 4L);
- FreeMem (bm, (long) sizeof (*bm));
- }
- FreeMem (oc, (long) sizeof (*oc));
- }
-
- deleteallof (ob)
- register struct object *ob;
- {
- register struct obcontrol *oc;
-
- oc = (struct obcontrol *) guys.lh_Head;
- while (oc -> node.ln_Succ) {
- oc = (struct obcontrol *) oc -> node.ln_Succ;
- if (((struct obcontrol *) oc -> node.ln_Pred) -> ob == ob)
- removeobject (oc -> node.ln_Pred);
- }
- }
-
- setdir (oc, dir)
- register struct obcontrol *oc;
- int dir;
- {
- switch (dir) {
- case UP:
- oc -> dx = 0;
- oc -> dy = -(oc -> ob -> incr);
- oc -> xoff = oc->ob->upx;
- oc -> yoff = oc->ob->upy;
- break;
-
- case DOWN:
- oc -> dx = 0;
- oc -> dy = oc -> ob -> incr;
- oc -> xoff = oc->ob->downx;
- oc -> yoff = oc->ob->downy;
- break;
-
- case LEFT:
- oc -> dy = 0;
- oc -> dx = -2 * oc->ob->incr;
- oc -> xoff = oc->ob->leftx;
- oc -> yoff = oc->ob->lefty;
- break;
-
- case RIGHT:
- oc -> dy = 0;
- oc -> dx = 2 * oc->ob->incr;
- oc -> xoff = oc->ob->rightx;
- oc -> yoff = oc->ob->righty;
- break;
- }
- oc -> dir = dir;
- }
-
- setbounds (lb, rb, tb, bb)
- {
- leftbound = lb;
- rightbound = rb;
- topbound = tb;
- bottombound = bb;
- }
-
- setexplode (oc)
- register struct obcontrol *oc;
- {
- oc -> flags |= EXPLODING;
- oc -> dir = 1;
- oc -> frame = 0;
- oc -> delay = 1;
- }
-
- cls (rp)
- struct RastPort *rp;
- {
- register BYTE pensav = rp -> FgPen;
-
- SetAPen (rp, 0L);
- RectFill (rp, (long) leftbound, (long) topbound,
- rightbound - 1L, bottombound - 1L);
- SetAPen (rp, (long) pensav);
- }
-
- animate ()
- {
- register struct obcontrol *oc;
-
- for (oc = (struct obcontrol *) guys.lh_Head;
- oc -> node.ln_Succ;
- oc = (struct obcontrol *) oc -> node.ln_Succ) {
- if (!--(oc->delay)) {
- /* Countdown ran out, update image */
- moveobject (oc);
- if (oc -> flags & EXPLODING)
- /* Special mod. for exploding stuff */
- oc -> delay = 2;
- else if (oc -> ob == &ob_grunt)
- /* Grunts move randomly */
- oc -> delay = rnd (oc->ob->framerate) +
- oc -> ob -> framerate;
- else
- oc -> delay = oc -> ob -> framerate;
- }
- }
- }
-
- moveobject (oc)
- register struct obcontrol *oc;
- {
- register struct object *ob = oc -> ob;
- long ex, ey, sizx, sizy;
- long yoff;
-
- yoff = oc -> yoff;
- if (oc -> flags & FREEZE) /* Don't move it, just draw it */
- goto frozen; /* Up yours, Djikstra :-) */
-
- if (oc -> flags & EXPLODING) {
- explode (oc);
- return;
- }
-
- switch (oc -> dir) {
- case UP:
- oc -> y += oc -> dy;
- ex = oc -> x;
- ey = oc -> y + ob -> height;
- sizx = ob -> width;
- sizy = -oc -> dy;
- break;
-
- case DOWN:
- ex = oc -> x;
- ey = oc -> y;
- sizx = ob -> width;
- sizy = oc -> dy;
- oc -> y += oc -> dy;
- break;
-
- case LEFT:
- oc -> x += oc -> dx;
- ex = oc -> x + ob -> width;
- ey = oc -> y;
- sizx = -oc -> dx;
- sizy = ob -> height;
- break;
-
- case RIGHT:
- ex = oc -> x;
- ey = oc -> y;
- sizx = oc -> dx;
- sizy = ob -> height;
- oc -> x += oc -> dx;
- break;
- }
-
- /*
- * This next 'if' is tricky. If the object wanders off the screen
- * in any way, we mark it as OFFSCREEN and don't render it. If,
- * during the last animation pass, it was onscreen, we erase it at
- * it's last known position.
- */
- if (oc->x + ob->width > rightbound ||
- oc->x < leftbound ||
- oc->y + ob->height > bottombound ||
- oc->y < topbound) {
- if (!(oc -> flags & OFFSCREEN))
- BltBitMap
- (ob -> bitmap, 0L, 0L,
- sbm, (long) oc->x - oc->dx, (long) oc->y - oc->dy,
- (long) ob -> width, (long) ob -> height,
- 0L, 0xffL, NULL);
- oc -> flags |= OFFSCREEN;
- return;
- }
-
- /* Do erasure only if it really moved and was onscreen last time */
- if (sizx && sizy && !(oc->flags & OFFSCREEN))
- BltBitMap (ob -> bitmap, 0L, 0L, sbm, ex, ey, sizx, sizy,
- 0L, 0xffL, NULL);
-
- /* Calculate new frame, if multiframed object */
- if (ob -> animseq)
- yoff += (ob -> animseq)[oc -> frame];
-
- frozen:
- /* Draw new guy */
- BltBitMap (ob -> bitmap, (long) oc -> xoff, yoff,
- sbm, (long) oc -> x, (long) oc -> y,
- (long) ob -> width, (long) ob -> height,
- 0xc0L, 0xffL, NULL);
-
- if (++oc -> frame >= ob -> nframes)
- oc -> frame = 0;
- oc -> flags &= ~OFFSCREEN;
- }
-
- explode (oc)
- register struct obcontrol *oc;
- {
- /* Pray.... */
- register struct object *ob = oc -> ob;
- register struct BitMap *bm;
- register long y, by, high;
- UWORD bpr;
-
- if (oc -> frame < 0 || oc -> flags & OFFSCREEN)
- return;
-
- if (!oc -> node.ln_Name)
- /* No explosion bitmap has been allocated, go get one. */
- if (!(oc -> node.ln_Name = (char *) getxpmap (oc)))
- die ("Explosion allocation failed.\n");
- bm = (struct BitMap *) oc -> node.ln_Name;
-
- /* Clear previous instance of explosion from screen */
- high = oc -> frame * (ob -> height - 1) + 1;
- y = oc->y - high/2 + ob->height/2;
- if (y < topbound) {
- by = -(y - topbound);
- high -= by;
- y = topbound;
- } else
- by = 0;
-
- if (y + high >= bottombound)
- high -= y + high - bottombound;
-
- BltBitMap (bm, 0L, by,
- sbm, (long) oc -> x, y,
- (long) ob -> width, high,
- 0x20L, 0xffL, NULL);
-
- /* Clear intermediate bitmap */
- BltBitMap (ob -> bitmap, 0L, 0L,
- bm, 0L, 0L,
- (long) ob -> width, (long) ob -> height * 10L,
- 0L, 0xffL, NULL);
-
- /* Check to see if explosion is done */
- if ((oc->frame += oc->dir) > 10 || oc->frame < 1) {
- oc -> frame = -1;
- return;
- }
-
- /* Expand image vertically by raping intermediate BitMap */
- bpr = bm -> BytesPerRow;
- bm -> BytesPerRow *= oc -> frame; /* Make it look wider */
- BltBitMap (ob -> bitmap, (long) oc -> xoff, (long) oc -> yoff,
- bm, 0L, 0L,
- (long) ob -> width, (long) ob -> height,
- 0xc0L, 0xffL, NULL);
-
- /*
- * We have vertically expanded the bitmap. We now copy it into
- * the main screen bitmap.
- */
- bm -> BytesPerRow = bpr; /* Fix it */
- high = oc -> frame * (ob -> height - 1) + 1;
- y = oc->y - high/2 + ob->height/2;
- if (y < topbound) {
- by = -(y - topbound);
- high -= by;
- y = topbound;
- } else
- by = 0;
-
- if (y + high >= bottombound)
- high -= y + high - bottombound;
-
- BltBitMap (bm, 0L, by,
- sbm, (long) oc -> x, y,
- (long) ob -> width, high,
- 0xe0L, 0xffL, NULL);
- }
-
- struct BitMap *
- getxpmap (oc)
- register struct obcontrol *oc;
- {
- register struct object *ob = oc -> ob;
- register struct BitMap *bm;
- register UWORD *planes;
- int high;
-
- high = ob -> height * 10;
-
- if (!(planes = AllocRaster ((long) ob -> width, high * 4L)))
- return (0);
-
- if (!(bm = AllocMem ((long) sizeof (*bm), NULL)))
- return (0);
-
- InitBitMap (bm, 4L, (long) ob -> width, (long) high);
- high *= bm -> BytesPerRow >> 1;
- bm -> Planes[0] = (PLANEPTR) planes;
- bm -> Planes[1] = (PLANEPTR) (planes + high);
- bm -> Planes[2] = (PLANEPTR) (planes + high + high);
- bm -> Planes[3] = (PLANEPTR) (planes + high + high + high);
-
- /* Clear this intermediate bitmap */
- BltBitMap (ob -> bitmap, 0L, 0L,
- bm, 0L, 0L,
- (long) ob -> width, ob -> height * 10L,
- 0L, 0xffL, NULL);
-
- /* Return on-screen object to known state */
- if (oc -> dir > 0) /* Only if exploding positively */
- BltBitMap (ob->bitmap, (long) oc -> xoff, (long) oc -> yoff,
- sbm, (long) oc -> x, (long) oc -> y,
- (long) ob -> width, (long) ob -> height,
- 0xc0L, 0xffL, NULL);
-
- return (bm);
- }
-
-
- /* Housekeeping */
- openanim ()
- {
- NewList (&guys);
- opened = 1;
- }
-
- closeanim ()
- {
- register struct obcontrol *oc;
- register struct BitMap *bm;
- int high;
-
- if (!opened)
- return;
-
- while (oc = RemHead (&guys)) {
- if (bm = (struct BitMap *) oc -> node.ln_Name) {
- if (bm -> Planes[0])
- /*- - - - - - - - - - - - - - -*/
- FreeRaster (bm -> Planes[0], (long) oc->ob->width, oc->ob->height * 10 * 4L);
- /*- - - - - - - - - - - - - - -*/
- FreeMem (bm, (long) sizeof (*bm));
- }
- FreeMem (oc, (long) sizeof (*oc));
- }
- }
-