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 >
Wrap
C/C++ Source or Header
|
1980-02-04
|
28KB
|
971 lines
/* Copyright (c) 1990 Commodore-Amiga, Inc.
*
* This example is provided in electronic form by Commodore-Amiga, Inc. for
* use with the 1.3 revisions of the Addison-Wesley Amiga reference manuals.
* The 1.3 Addison-Wesley Amiga Reference Manual series contains additional
* information on the correct usage of the techniques and operating system
* functions presented in this example. The source and executable code of
* this example may only be distributed in free electronic form, via bulletin
* board or as part of a fully non-commercial and freely redistributable
* diskette. Both the source and executable code (including comments) must
* be included, without modification, in any copy. This example may not be
* published in printed form or distributed with any commercial product.
* However, the programming techniques and support routines set forth in
* this example may be used in the development of original executable
* software products for Commodore Amiga computers.
* All other rights reserved.
* This example is provided "as-is" and is subject to change; no warranties
* are made. All use is at your own risk. No liability or responsibility
* is assumed.
*/
/* anim.c 19oct89 original code by Dave Lucas.
** rework by (CATS)
**
** lattice c 5.04
** lc -b1 -cfist -v -y anim.c
** blink FROM LIB:c.o anim.o /animtools/animtools.o LIB LIB:lc.lib TO anim
*/
#include <exec/types.h>
#include <intuition/intuition.h>
#include <graphics/gels.h>
#include <exec/memory.h>
#include "/animtools/animtools.h"
#include "/animtools/animtools_proto.h"
#include <stdlib.h>
#include <stdio.h>
#include <proto/all.h>
int CXBRK(void) { return(0); } /* disable lattice CTRL-C handling */
/*--------------------------------------------------------------*/
/* */
/*--------------------------------------------------------------*/
struct AnimOb *setupBoing(SHORT dbufing);
struct AnimOb *setupMan(SHORT dbufing);
struct AnimOb *setupWorm(SHORT dbufing);
WORD anEdgeORoutine(struct AnimOb *anOb);
WORD bounceORoutine(struct AnimOb *anOb);
WORD goInFrontOfHead(struct AnimComp *aComp);
WORD goBehindHead(struct AnimComp *aComp);
VOID runAnimation(struct Window *win, SHORT dbufing,
struct AnimOb **animKey, struct BitMap **myBitMaps);
LONG setupPlanes(struct BitMap *bitMap, LONG depth, LONG width, LONG height);
struct BitMap **setupBitMaps(LONG depth, LONG width, LONG height);
VOID freePlanes(struct BitMap *bitMap, LONG depth, LONG width, LONG height);
VOID freeBitMaps(struct BitMap **myBitMaps,
LONG depth, LONG width, LONG height);
struct GelsInfo *setupDisplay(struct Window **win,
SHORT dbufing, struct BitMap **myBitMaps);
VOID DrawGels(struct Window *win, struct AnimOb **animKey, SHORT dbufing,
WORD *toggleFrame, struct BitMap **myBitMaps);
/*--------------------------------------------------------------*/
/* */
/*--------------------------------------------------------------*/
#define ANFS ANFRACSIZE
#define BNFS (ANFRACSIZE-2)
#define CNFS (ANFRACSIZE-2)
/* These are used for MeMask (1 << ID_xxx) */
#define ID_BORDER 0
#define ID_WRM 3
#define ID_BNG 4
#define ID_MAN 5
#define SBMWIDTH 320 /* My screen size constants. */
#define SBMHEIGHT 200
#define SBMDEPTH 4
#define SCRNMODE NULL /* (HIRES | LACE) for NewScreen, ends up in view.*/
#define RBMWIDTH 320 /* My raster size constants. (These CAN differ) */
#define RBMHEIGHT 200
#define RBMDEPTH 4
/*--------------------------------------------------------------*/
/* */
/*--------------------------------------------------------------*/
struct NewScreen ns =
{
0, 0, SBMWIDTH, SBMHEIGHT, SBMDEPTH, 0, 0, SCRNMODE,
CUSTOMSCREEN | SCREENQUIET, NULL, NULL, NULL, NULL
};
/* this is a little window that will let us get a CLOSEWINDOW message */
struct NewWindow nw =
{
0, 0, 25, 12, 0, 0, CLOSEWINDOW,
WINDOWCLOSE | BORDERLESS | RMBTRAP, NULL, NULL, NULL, NULL,
NULL, 0, 0, SBMWIDTH, SBMHEIGHT-1, CUSTOMSCREEN
};
struct IntuitionBase *IntuitionBase = NULL;
struct GfxBase *GfxBase = NULL;
int return_code;
/*--------------------------------------------------------------*/
/* constants for the worm sequence. */
/*--------------------------------------------------------------*/
#include "image_worm.h"
NEWBOB newWrmBob =
{
NULL, /* nb_Image - image is null for sequences */
/* data comes from NEWANIMSEQ */
WRMWWIDTH, /* nb_WordWidth - width of the bob */
WRMHEIGHT, /* nb_LineHeight - height of the bob */
WRMDEPTH, /* nb_ImageDepth - depth of image data */
0x3, /* nb_PlanePick - planes to put data in */
0x0, /* nb_PlaneOnOff - empty planes to set */
SAVEBACK | OVERLAY, /* nb_BFlags - flags for the bob */
0, /* nb_DBuf - 1=dbuf, 0=not dbuf */
RBMDEPTH, /* nb_RasDepth - num planes in raster */
0, /* nb_X - bob x position */
0, /* nb_Y - bob y position */
(1L << ID_BORDER), /* nb_HitMask - hit mask */
(1L << ID_WRM), /* nb_MeMask - me mask */
};
NEWANIMSEQ newWrmSeq =
{
NULL, /* nas_HeadOb - head object for the seq */
(WORD *)WrmImage, /* nas_Images - array of images */
WrmXTranses, /* nas_Xt - x offsets from central object */
WrmYTranses, /* nas_Yt - y offsets from central object */
WrmTimes, /* nas_Times - timing values for objects */
WrmCRoutines, /* nas_Routines - array of comp routines */
0, /* nas_CFlags - comp flags */
WRMCOUNT, /* nas_Count - number of comps in sequence */
0, /* nas_SingleImage - 1=single image for seq.*/
/* 0=multiple images */
};
/*--------------------------------------------------------------*/
/* constants for the man sequence. */
/*--------------------------------------------------------------*/
#define MANRINGY -1
#define MANRINGX 36
#define MANHEIGHT 62
#define MANWIDTH 46
#define MANTCOUNT 4
#define MANTHEIGHT 34
#define MANTWIDTH 9
#define MANTDEPTH 2
#define MANTWWIDTH ((MANTWIDTH + 15) / 16)
#define MANACOUNT 8
#define MANAHEIGHT 22
#define MANAWIDTH 24
#define MANADEPTH 2
#define MANAWWIDTH ((MANAWIDTH + 15) / 16)
#define MANLCOUNT 8
#define MANLHEIGHT 30
#define MANLWIDTH 26
#define MANLDEPTH 2
#define MANLWWIDTH ((MANLWIDTH + 15) / 16)
#include "image_man.h"
NEWBOB newNearLegBob =
{
NULL, MANLWWIDTH, MANLHEIGHT, MANLDEPTH, 0x3, 0xC,
SAVEBACK | OVERLAY, 0, RBMDEPTH, 0,0, (1L<<ID_BORDER), (1L<<ID_MAN),
};
NEWANIMSEQ newNearLegSeq =
{
NULL, (WORD *)manLImage, manLXTranses, manLYTranses, manLTimes,
manLCRoutines, 0, MANLCOUNT, 0,
};
NEWBOB newFarLegBob =
{
NULL, MANLWWIDTH, MANLHEIGHT, MANLDEPTH, 0x3, 0x8,
SAVEBACK | OVERLAY, 0, RBMDEPTH, 0,0, (1L<<ID_BORDER), (1L<<ID_MAN),
};
NEWANIMSEQ newFarLegSeq =
{
NULL, (WORD *)manLImage, manLXTranses, manLYTranses, manLTimes,
manLCRoutines, 0, MANLCOUNT, 0,
};
NEWBOB newNearArmBob =
{
NULL, MANAWWIDTH, MANAHEIGHT, MANADEPTH, 0x3, 0xC,
SAVEBACK | OVERLAY, 0, RBMDEPTH, 0,0, (1L<<ID_BORDER), (1L<<ID_MAN),
};
NEWANIMSEQ newNearArmSeq =
{
NULL, (WORD *)manAImage, manAXTranses, manAYTranses, manATimes,
manACRoutines, 0, MANACOUNT, 0,
};
NEWBOB newFarArmBob =
{
NULL, MANAWWIDTH, MANAHEIGHT, MANADEPTH, 0x3, 0x8,
SAVEBACK | OVERLAY, 0, RBMDEPTH, 0,0, (1L<<ID_BORDER), (1L<<ID_MAN),
};
NEWANIMSEQ newFarArmSeq =
{
NULL, (WORD *)manAImage, manAXTranses, manAYTranses, manATimes,
manACRoutines, 0, MANACOUNT, 0,
};
NEWBOB newTrunkBob =
{
NULL, MANTWWIDTH, MANTHEIGHT, MANTDEPTH, 0x3, 0xC,
SAVEBACK | OVERLAY, 0, RBMDEPTH, 0,0, (1L<<ID_BORDER), (1L<<ID_MAN),
};
NEWANIMSEQ newTrunkSeq =
{
NULL, (WORD *)manTImage, manTXTranses, manTYTranses, manTTimes,
manTCRoutines, 0, MANTCOUNT, 0,
};
/*--------------------------------------------------------------*/
/* constants for the boing ball and sattellites. */
/*--------------------------------------------------------------*/
#define BNG3RINGY 0
#define BNG3RINGX 0
#define BNG3COUNT 6
#define BNG3HEIGHT 25
#define BNG3WIDTH 29
#define BNG3DEPTH 3
#define BNG3WWIDTH ((BNG3WIDTH + 15) / 16)
#define SATCOUNT 16
#define SATHEIGHT 5
#define SATWIDTH 5
#define SATDEPTH 2
#define SATWWIDTH ((SATWIDTH + 15) / 16)
#include "image_boing.h"
NEWBOB newBoingBob =
{
NULL, BNG3WWIDTH, BNG3HEIGHT, BNG3DEPTH, 0xD, 0x2,
SAVEBACK | OVERLAY, 0, RBMDEPTH, 0,0, (1L<<ID_BORDER), (1L<<ID_BNG),
};
NEWANIMSEQ newBoingSeq =
{
NULL, (WORD *)boing3Image, boing3XTranses, boing3YTranses,
boing3Times, boing3CRoutines, 0, BNG3COUNT, 0,
};
NEWBOB newSatABob =
{
NULL, SATWWIDTH, SATHEIGHT, SATDEPTH, 0xC, 0x0,
SAVEBACK | OVERLAY, 0, RBMDEPTH, 0,0, (1L<<ID_BORDER), (1L<<ID_BNG),
};
NEWANIMSEQ newSatASeq =
{
NULL, (WORD *)satImage, satAXTranses, satAYTranses,
satTimes, satACRoutines, 0, SATCOUNT, 1,
};
NEWBOB newSatBBob =
{
NULL, SATWWIDTH, SATHEIGHT, SATDEPTH, 0xC, 0x3,
SAVEBACK | OVERLAY, 0, RBMDEPTH, 0,0, (1L<<ID_BORDER), (1L<<ID_BNG),
};
NEWANIMSEQ newSatBSeq =
{
NULL, (WORD *)satImage, satBXTranses, satBYTranses,
satTimes, satBCRoutines, 0, SATCOUNT, 1,
};
NEWBOB newSatCBob =
{
NULL, SATWWIDTH, SATHEIGHT, SATDEPTH, 0x3, 0x0,
SAVEBACK | OVERLAY, 0, RBMDEPTH, 0,0, (1L<<ID_BORDER), (1L<<ID_BNG),
};
NEWANIMSEQ newSatCSeq =
{
NULL, (WORD *)satImage, satCXTranses, satCYTranses,
satTimes, satCCRoutines, 0, SATCOUNT, 1,
};
/*--------------------------------------------------------------*/
/*--------------------------------------------------------------*/
/* PROCEDURES */
/*--------------------------------------------------------------*/
/*--------------------------------------------------------------*/
/*--------------------------------------------------------------
** setupBoing() - allocate and initialize an object that will
** display as a boing ball with orbiting sattellites.
**
** this is an animation object with four animation sequences.
** (boing and three sattellites.)
** (note that the sattellites all share the same single image data.)
**
** return NULL on failure.
*/
struct AnimOb *setupBoing(SHORT dbufing)
{
struct AnimOb *bngOb;
struct AnimComp *bngComp;
struct AnimComp *satAComp;
struct AnimComp *satBComp;
struct AnimComp *satCComp;
if (NULL != (bngOb = AllocMem((LONG)sizeof(struct AnimOb), MEMF_CLEAR)))
{
bngOb->NextOb = NULL;
bngOb->PrevOb = NULL;
bngOb->Clock = 0;
bngOb->AnY = 50;
bngOb->AnX = 50;
bngOb->AnOldY = bngOb->AnY;
bngOb->AnOldX = bngOb->AnX;
bngOb->YVel = 3 << ANFRACSIZE;
bngOb->XVel = 3 << ANFRACSIZE;
bngOb->YAccel = 0;
bngOb->XAccel = 0;
bngOb->RingYTrans = BNG3RINGY << ANFRACSIZE;
bngOb->RingXTrans = BNG3RINGX << ANFRACSIZE;
bngOb->AnimORoutine = bounceORoutine;
bngOb->AUserExt = 0;
newBoingBob.nb_DBuf = dbufing;
newBoingSeq.nas_HeadOb = bngOb;
satACRoutines[4] = goInFrontOfHead;
satACRoutines[12] = goBehindHead;
satBCRoutines[8] = goInFrontOfHead;
satBCRoutines[0] = goBehindHead;
satCCRoutines[4] = goInFrontOfHead;
satCCRoutines[12] = goBehindHead;
newSatABob.nb_DBuf = dbufing;
newSatBBob.nb_DBuf = dbufing;
newSatCBob.nb_DBuf = dbufing;
newSatASeq.nas_HeadOb = bngOb;
newSatBSeq.nas_HeadOb = bngOb;
newSatCSeq.nas_HeadOb = bngOb;
if (NULL != (bngComp = makeSeq(&newBoingBob, &newBoingSeq)))
{
bngComp->Flags |= RINGTRIGGER;
bngOb->HeadComp = bngComp;
if (NULL != (satAComp = makeSeq(&newSatABob, &newSatASeq)))
{
bngComp->AnimBob->Before = satAComp->AnimBob;
satAComp->AnimBob->After = bngComp->AnimBob;
if (NULL != (satBComp = makeSeq(&newSatBBob, &newSatBSeq)))
{
satAComp->AnimBob->Before = satBComp->AnimBob;
satBComp->AnimBob->After = satAComp->AnimBob;
if (NULL != (satCComp = makeSeq(&newSatCBob, &newSatCSeq)))
{
satBComp->AnimBob->Before = satCComp->AnimBob;
satCComp->AnimBob->After = satBComp->AnimBob;
bngComp->NextComp = satAComp;
bngComp->PrevComp = NULL;
satAComp->NextComp = satBComp;
satAComp->PrevComp = bngComp;
satBComp->NextComp = satCComp;
satBComp->PrevComp = satAComp;
satCComp->NextComp = NULL;
satCComp->PrevComp = satBComp;
return(bngOb);
}
freeSeq(satBComp,RBMDEPTH);
}
freeSeq(satAComp,RBMDEPTH);
}
freeSeq(bngComp,RBMDEPTH);
}
FreeMem(bngOb, (LONG)sizeof(struct AnimOb));
}
return_code = RETURN_WARN;
return(NULL);
}
/*--------------------------------------------------------------
** setupMan() - allocate and initialize an object that will
** display as a walking man.
**
** this is an animation object with five animation sequences.
** (body, two arms and two legs.)
**
** return NULL on failure.
*/
struct AnimOb *setupMan(SHORT dbufing)
{
struct AnimOb *manOb;
struct AnimComp *trunkComp;
struct AnimComp *farArmComp;
struct AnimComp *farLegComp;
struct AnimComp *nearArmComp;
struct AnimComp *nearLegComp;
if (NULL != (manOb = AllocMem((LONG)sizeof(struct AnimOb), MEMF_CLEAR)))
{
manOb->NextOb = NULL;
manOb->PrevOb = NULL;
manOb->Clock = 0;
manOb->AnY = ((2 * MANHEIGHT) << ANFRACSIZE);
manOb->AnX = 0;
manOb->AnOldY = manOb->AnY;
manOb->AnOldX = manOb->AnX;
manOb->YVel = 0;
manOb->XVel = 0;
manOb->YAccel = 0;
manOb->XAccel = 0;
manOb->RingYTrans = (MANRINGY << ANFRACSIZE);
manOb->RingXTrans = (MANRINGX << ANFRACSIZE);
manOb->AnimORoutine = anEdgeORoutine;
manOb->AUserExt = 0;
newTrunkBob.nb_DBuf = dbufing;
newFarArmBob.nb_DBuf = dbufing;
newFarLegBob.nb_DBuf = dbufing;
newNearArmBob.nb_DBuf = dbufing;
newNearLegBob.nb_DBuf = dbufing;
newTrunkSeq.nas_HeadOb = manOb;
newFarArmSeq.nas_HeadOb = manOb;
newFarLegSeq.nas_HeadOb = manOb;
newNearArmSeq.nas_HeadOb = manOb;
newNearLegSeq.nas_HeadOb = manOb;
if (NULL != (trunkComp = makeSeq(&newTrunkBob, &newTrunkSeq)))
{
trunkComp->Flags |= RINGTRIGGER;
if (NULL != (farArmComp = makeSeq(&newFarArmBob, &newFarArmSeq)))
{
trunkComp->AnimBob->Before = farArmComp->AnimBob;
farArmComp->AnimBob->After = trunkComp->AnimBob;
if (NULL != (farLegComp = makeSeq(&newFarLegBob, &newFarLegSeq)))
{
farArmComp->AnimBob->Before = farLegComp->AnimBob;
farLegComp->AnimBob->After = farArmComp->AnimBob;
if (NULL != (nearArmComp =
makeSeq(&newNearArmBob, &newNearArmSeq)))
{
nearArmComp =
nearArmComp->NextSeq->NextSeq->NextSeq->NextSeq;
farLegComp->AnimBob->Before = nearArmComp->AnimBob;
nearArmComp->AnimBob->After = farLegComp->AnimBob;
if (NULL != (nearLegComp =
makeSeq(&newNearLegBob, &newNearLegSeq)))
{
nearLegComp =
nearLegComp->NextSeq->NextSeq->NextSeq->NextSeq;
nearArmComp->AnimBob->Before = nearLegComp->AnimBob;
nearLegComp->AnimBob->After = nearArmComp->AnimBob;
manOb->HeadComp = trunkComp;
trunkComp->PrevComp = NULL;
trunkComp->NextComp = farArmComp;
farArmComp->PrevComp = trunkComp;
farArmComp->NextComp = farLegComp;
farLegComp->PrevComp = farArmComp;
farLegComp->NextComp = nearArmComp;
nearArmComp->PrevComp = farLegComp;
nearArmComp->NextComp = nearLegComp;
nearLegComp->PrevComp = nearArmComp;
nearLegComp->NextComp = NULL;
return(manOb);
}
freeSeq(nearArmComp,RBMDEPTH);
}
freeSeq(farLegComp,RBMDEPTH);
}
freeSeq(farArmComp,RBMDEPTH);
}
freeSeq(trunkComp,RBMDEPTH);
}
FreeMem(manOb, (LONG)sizeof(struct AnimOb));
}
return_code = RETURN_WARN;
return(NULL);
}
/*--------------------------------------------------------------
** setupBoing() - allocate and initialize an object that will
** display as an inch worm.
**
** this is an animation object with only one animation sequence.
**
** return NULL on failure.
*/
struct AnimOb *setupWorm(SHORT dbufing)
{
struct AnimOb *wormOb;
struct AnimComp *wormComp;
if (NULL != (wormOb = AllocMem((LONG)sizeof(struct AnimOb), MEMF_CLEAR)))
{
wormOb->NextOb = NULL;
wormOb->PrevOb = NULL;
wormOb->Clock = 0;
wormOb->AnY = ((RBMHEIGHT - WRMHEIGHT - 5) << ANFRACSIZE);
wormOb->AnX = (10L << ANFRACSIZE);
wormOb->AnOldY = wormOb->AnY;
wormOb->AnOldX = wormOb->AnX;
wormOb->YVel = 0;
wormOb->XVel = 0;
wormOb->YAccel = 0;
wormOb->XAccel = 0;
wormOb->RingYTrans = (WRMRINGY << ANFRACSIZE);
wormOb->RingXTrans = (WRMRINGX << ANFRACSIZE);
wormOb->AnimORoutine = anEdgeORoutine;
wormOb->AUserExt = 0;
newWrmBob.nb_DBuf = dbufing;
newWrmSeq.nas_HeadOb = wormOb;
if (NULL != (wormComp = makeSeq(&newWrmBob, &newWrmSeq)))
{
wormComp->Flags |= RINGTRIGGER;
wormOb->HeadComp = wormComp;
return(wormOb);
}
}
return_code = RETURN_WARN;
return(NULL);
}
/*--------------------------------------------------------------
** This ORoutine makes the Object restart on left edge if it has
** gone off the right of the screen. If it has gone off the top,
** it is restarted at the bottom. It is used for the worm and the
** man. It works for animations that move to the right, and
** optionally up, ONLY.
*/
WORD anEdgeORoutine(struct AnimOb *anOb)
{
struct AnimComp *acptr;
struct AnimComp *seqptr;
acptr = anOb->HeadComp;
while (acptr)
{
seqptr = acptr;
do {
if (seqptr->AnimBob->BobVSprite->Flags & GELGONE)
{
seqptr->AnimBob->BobVSprite->Flags &= ~GELGONE;
anOb->AnX = -10L << ANFRACSIZE;
if (anOb->AnY <= 0)
anOb->AnY = (RBMHEIGHT-60L) << ANFRACSIZE;
}
seqptr = seqptr->NextSeq;
} while (seqptr != acptr && (seqptr));
acptr = acptr->NextComp;
}
return(0) ;
}
/*--------------------------------------------------------------
** This ORoutine makes the Object Bounce off Borders.
*/
WORD bounceORoutine(struct AnimOb *anOb)
{
SHORT Y;
SHORT X;
Y = anOb->AnY >> ANFRACSIZE;
X = anOb->AnX >> ANFRACSIZE;
if ((Y<0 && anOb->YVel < 0) ||
((Y+anOb->HeadComp->AnimBob->BobVSprite->Height > RBMHEIGHT) &&
(anOb->YVel > 0)))
{
anOb->YVel = -(anOb->YVel);
}
if (((X < 0) && (anOb->XVel < 0)) ||
((X + (anOb->HeadComp->AnimBob->BobVSprite->Width << 4) > RBMWIDTH) &&
(anOb->XVel > 0)))
{
anOb->XVel = -(anOb->XVel);
}
return(0) ;
}
/*--------------------------------------------------------------
** This CRoutine rearranges Bob Before and After pointers in a
** way that makes the Component passed look like it is in front
** of its' head component.
**
** Used for Boing satelittes.
**
** So that they go in front of AND behind the boing ball.
*/
WORD goInFrontOfHead(struct AnimComp *aComp)
{
/* close up hole */
if (aComp->AnimBob->Before != NULL)
aComp->AnimBob->Before->After = aComp->AnimBob->After;
if (aComp->AnimBob->After != NULL)
aComp->AnimBob->After->Before = aComp->AnimBob->Before;
/* reinsert */
aComp->AnimBob->Before = aComp->HeadOb->HeadComp->AnimBob->Before;
aComp->AnimBob->After = aComp->HeadOb->HeadComp->AnimBob;
if (aComp->AnimBob->Before != NULL)
aComp->AnimBob->Before->After = aComp->AnimBob;
aComp->HeadOb->HeadComp->AnimBob->Before = aComp->AnimBob;
return(0) ;
}
/*--------------------------------------------------------------
** This CRoutine rearranges Bob Before and After pointers in a
** way that makes the Component passed look like it is behind
** its' head component.
*/
WORD goBehindHead(struct AnimComp *aComp)
{
if (aComp->AnimBob->Before != NULL)
aComp->AnimBob->Before->After = aComp->AnimBob->After;
if (aComp->AnimBob->After != NULL)
aComp->AnimBob->After->Before = aComp->AnimBob->Before;
aComp->AnimBob->After = aComp->HeadOb->HeadComp->AnimBob->After;
aComp->AnimBob->Before = aComp->HeadOb->HeadComp->AnimBob;
if (aComp->AnimBob->After != NULL)
aComp->AnimBob->After->Before = aComp->AnimBob;
aComp->HeadOb->HeadComp->AnimBob->After = aComp->AnimBob;
return(0) ;
}
/*--------------------------------------------------------------
**
*/
VOID runAnimation(struct Window *win,
SHORT dbufing,
struct AnimOb **animKey,
struct BitMap **myBitMaps)
{
struct IntuiMessage *intuiMsg;
WORD toggleFrame;
toggleFrame = 0;
/* everything opened, and allocated, and initialized.
** Now I just hang out, move the gels, tell the system to redraw them,
** and let the collision and anim routines bounce them about.
*/
for (;;)
{
/* All the work done here */
DrawGels(win, animKey, dbufing, &toggleFrame, myBitMaps);
while (intuiMsg = (struct IntuiMessage *)GetMsg(win->UserPort))
{
if (intuiMsg->Class == CLOSEWINDOW)
{
ReplyMsg((struct Message *)intuiMsg);
return;
}
ReplyMsg((struct Message *)intuiMsg);
}
}
}
/*---------------------------------------------------------
** allocate the bit planes for a screen bit map.
*/
LONG setupPlanes(struct BitMap *bitMap,
LONG depth, LONG width, LONG height)
{
SHORT plane_num ;
for (plane_num = 0; plane_num < depth; plane_num++)
{
if (NULL != (bitMap->Planes[plane_num] =
(PLANEPTR)AllocRaster(width, height)))
BltClear(bitMap->Planes[plane_num], (width / 8) * height, 1);
else
{
freePlanes(bitMap, depth, width, height);
return_code = RETURN_WARN;
return(NULL);
}
}
return(TRUE);
}
/*---------------------------------------------------------
** allocate the bit maps for a double buffered screen.
*/
struct BitMap **setupBitMaps(LONG depth, LONG width, LONG height)
{
/* this must be static -- it cannot go away when the routine exits. */
static struct BitMap *myBitMaps[2];
if (NULL != (myBitMaps[0] =
(struct BitMap *)AllocMem((LONG)sizeof(struct BitMap), MEMF_CLEAR)))
{
if (NULL != (myBitMaps[1] =
(struct BitMap *)AllocMem((LONG)sizeof(struct BitMap), MEMF_CLEAR)))
{
InitBitMap(myBitMaps[0], depth, width, height);
InitBitMap(myBitMaps[1], depth, width, height);
if (NULL != setupPlanes(myBitMaps[0], depth, width, height))
{
if (NULL != setupPlanes(myBitMaps[1], depth, width, height))
return(myBitMaps);
freePlanes(myBitMaps[0], depth, width, height);
}
FreeMem(myBitMaps[1], (LONG)sizeof(struct BitMap));
}
FreeMem(myBitMaps[0], (LONG)sizeof(struct BitMap));
}
return_code = RETURN_WARN;
return(NULL);
}
/*--------------------------------------------------------------
** free up the memory allocated by setupPlanes().
*/
VOID freePlanes(struct BitMap *bitMap,
LONG depth, LONG width, LONG height)
{
SHORT plane_num ;
for (plane_num = 0; plane_num < depth; plane_num++)
{
if (NULL != bitMap->Planes[plane_num])
FreeRaster(bitMap->Planes[plane_num], width, height);
}
}
/*--------------------------------------------------------------
** free up the memory allocated by setupBitMaps().
*/
VOID freeBitMaps(struct BitMap **myBitMaps,
LONG depth, LONG width, LONG height)
{
freePlanes(myBitMaps[0], depth, width, height);
freePlanes(myBitMaps[1], depth, width, height);
FreeMem(myBitMaps[0], (LONG)sizeof(struct BitMap));
FreeMem(myBitMaps[1], (LONG)sizeof(struct BitMap));
}
/*--------------------------------------------------------------
**
*/
struct GelsInfo *setupDisplay(struct Window **win,
SHORT dbufing,
struct BitMap **myBitMaps)
{
struct GelsInfo *gInfo;
struct Screen *screen;
struct ViewPort *vport;
struct RastPort *rport;
if (dbufing)
{
/* Screen type. We alloc two BitMaps. See DBLBUF comments. */
ns.Type |= CUSTOMBITMAP;
ns.CustomBitMap = myBitMaps[0];
}
if ((screen = (struct Screen *)OpenScreen(&ns)) != NULL)
{
vport = &screen->ViewPort;
rport = &screen->RastPort;
SetRGB4(vport, 0x0, 0x0, 0x0, 0x0); /* Black */
SetRGB4(vport, 0x1, 0x0, 0x6, 0x0); /* dk green */
SetRGB4(vport, 0x2, 0x0, 0x9, 0x0); /* med green */
SetRGB4(vport, 0x3, 0x0, 0xC, 0x0); /* lt green */
SetRGB4(vport, 0x4, 0x1, 0x1, 0x7); /* dk blue */
SetRGB4(vport, 0x5, 0x7, 0x0, 0x8); /* dk violet */
SetRGB4(vport, 0x6, 0x6, 0x6, 0x6); /* dk grey */
SetRGB4(vport, 0x7, 0x7, 0x1, 0x0); /* dk red */
SetRGB4(vport, 0x8, 0x3, 0x3, 0xB); /* med blue */
SetRGB4(vport, 0x9, 0xB, 0x0, 0xC); /* med violet */
SetRGB4(vport, 0xA, 0x9, 0x9, 0x9); /* med grey */
SetRGB4(vport, 0xB, 0xB, 0x0, 0x0); /* med red */
SetRGB4(vport, 0xC, 0x5, 0x5, 0xF); /* lt blue */
SetRGB4(vport, 0xD, 0xE, 0x0, 0xF); /* lt violet */
SetRGB4(vport, 0xE, 0xF, 0xF, 0xF); /* lt grey (white) */
SetRGB4(vport, 0xF, 0xF, 0x0, 0x0); /* lt red */
/* put some stuff in the background, so we can
** see that it does not get destroyed.
*/
SetAPen(rport, 0xA);
SetDrMd(rport, JAM1);
Move(rport, 70, 105);
Text(rport, "Animation Example...", 20);
nw.Screen = screen;
if ((*win = (struct Window *)OpenWindow(&nw)) != NULL)
{
if (dbufing)
{
(*win)->WScreen->RastPort.Flags = DBUFFER;
/* copy the rast port data into the alternate rast port */
(*win)->WScreen->RastPort.BitMap = myBitMaps[1];
BltBitMapRastPort(myBitMaps[0], 0,0, &(*win)->WScreen->RastPort,
0,0, RBMWIDTH, RBMHEIGHT, 0xC0);
(*win)->WScreen->RastPort.BitMap = myBitMaps[0];
}
/* set up the gels system.
** 0xFC says: when you allocate sprites for me, don't ever use
** sprites zero or one. This guarantees that sprite zero, the
** intuition pointer, stays intact. Remember sprite one shares
** colors with sprite zero.
*/
if (NULL != (gInfo = setupGelSys(&(*win)->WScreen->RastPort, 0xFC)))
return(gInfo);
CloseWindow(*win);
}
CloseScreen(screen);
}
return_code = RETURN_WARN;
return(NULL);
}
/*--------------------------------------------------------------
** DrawGels part of loop.
*/
VOID DrawGels(struct Window *win,
struct AnimOb **animKey,
SHORT dbufing,
WORD *toggleFrame,
struct BitMap **myBitMaps)
{
Animate(animKey, &win->WScreen->RastPort);
SortGList(&win->WScreen->RastPort); /* Put the list in order. */
DoCollision(&win->WScreen->RastPort); /* Collision routines may called now */
SortGList(&win->WScreen->RastPort); /* Put the list in order. */
if (dbufing)
win->WScreen->ViewPort.RasInfo->BitMap = myBitMaps[*toggleFrame];
/* Draw 'em. */
DrawGList(&win->WScreen->RastPort, &win->WScreen->ViewPort);
if (dbufing)
{
MakeScreen(win->WScreen); /* Tell intuition to do it's stuff. */
RethinkDisplay(); /* Does a MrgCop & LoadView. */
*toggleFrame ^= 1;
/* Flip to the next BitMap. */
win->WScreen->RastPort.BitMap = myBitMaps[*toggleFrame];
}
else
WaitTOF();
}
/*--------------------------------------------------------------
**
*/
VOID main(int argc, char **argv)
{
struct BitMap **myBitMaps;
struct AnimOb *boingOb;
struct AnimOb *wormOb;
struct AnimOb *manOb;
struct Window *win;
struct Screen *screen;
struct GelsInfo *gInfo;
struct AnimOb *animKey;
SHORT dbufing;
return_code = RETURN_OK; /* a global variable, yech! */
printf("Program will run double buffered if there are\n");
printf("any command line arguements.\n");
if (argc > 1)
dbufing = 1; /* run double buffered when arguements */
else
dbufing = 0; /* not double buff */
if (NULL == (IntuitionBase = (struct IntuitionBase *)
OpenLibrary("intuition.library", 33L)))
return_code = RETURN_FAIL;
else
{
if (NULL == (GfxBase = (struct GfxBase *)
OpenLibrary("graphics.library", 33L)))
return_code = RETURN_FAIL;
else
{
if ((!dbufing) ||
(NULL != (myBitMaps=setupBitMaps(RBMDEPTH,RBMWIDTH,RBMHEIGHT))))
{
if (NULL != (gInfo = setupDisplay(&win,dbufing,myBitMaps)))
{
InitAnimate(&animKey);
/* Simple sequenced animation. (Boing ball)
** Simple animation using XTrans and YTrans.
** (tiny orbiting satellite)
*/
if (NULL != (boingOb = setupBoing(dbufing)))
{
AddAnimOb(boingOb, &animKey, &win->WScreen->RastPort);
if (NULL != (wormOb = setupWorm(dbufing)))
{
AddAnimOb(wormOb, &animKey, &win->WScreen->RastPort);
if (NULL != (manOb = setupMan(dbufing)))
{
AddAnimOb(manOb, &animKey,
&win->WScreen->RastPort);
runAnimation(win, dbufing, &animKey, myBitMaps);
freeOb(manOb, RBMDEPTH);
}
freeOb(wormOb, RBMDEPTH);
}
freeOb(boingOb, RBMDEPTH);
}
cleanupGelSys(gInfo, &win->WScreen->RastPort);
screen = win->WScreen;
CloseWindow(win);
CloseScreen(screen);
}
if (dbufing)
freeBitMaps(myBitMaps, RBMDEPTH, RBMWIDTH, RBMHEIGHT);
}
CloseLibrary((struct Library *)GfxBase);
}
CloseLibrary((struct Library *)IntuitionBase);
}
exit(return_code);
}