home *** CD-ROM | disk | FTP | other *** search
- /* vsprite.final.c, merged with its support files */
-
- /* execute makesimple vsprite.final ; Amiga C 1.1 (Lattice 3.03) */
-
- #include "exec/types.h"
- #include "intuition/intuition.h"
- #include "graphics/sprite.h"
- #include "exec/memory.h"
- #include "graphics/gels.h"
-
- /* ask system to create and manage MAXSP vsprites */
- #define MAXSP 28
-
- /* define possible speeds for vsprites in counts per vblank */
-
- SHORT speed[] = { 1, 2, -1, -2 };
-
- SHORT xmove[MAXSP], ymove[MAXSP];
- /* sprite directions of movement */
- struct VSprite *vsprite[MAXSP]; /* MAXSP simple sprites */
- struct VSprite *vspr; /* pointer to a sprite */
- short maxgot; /* max # of sprites we created */
-
- struct GelsInfo mygelsinfo; /* the window's RastPort needs one
- * of these in order to do VSprites */
-
- struct Window *w; /* pointer to a Window */
- struct RastPort *rp; /* pointer to a RastPort */
- struct Screen *s; /* a pointer to a Screen */
- struct ViewPort *vp; /* pointer to a ViewPort */
-
- struct Window *OpenWindow();
- struct Screen *OpenScreen();
- LONG GfxBase;
- LONG IntuitionBase;
-
- /* 18 words of sprite data = 9 lines of sprite data */
-
- UWORD sprite_data[ ] = {
- 0x0fc3, 0x0000, /* image data line 1*/
- 0x3ff3, 0x0000, /* image data line 2*/
- 0x30c3, 0x0000, /* image data line 3*/
- 0x0000, 0x3c03, /* image data line 4*/
- 0x0000, 0x3fc3, /* image data line 5*/
- 0x0000, 0x03c3, /* image data line 6*/
- 0xc033, 0xc033, /* image data line 7*/
- 0xffc0, 0xffc0, /* image data line 8*/
- 0x3f03, 0x3f03, /* image data line 9*/
- };
- UWORD *sprdata;
-
- void movesprites()
- {
- short i;
-
- for (i=0; i<maxgot; i++)
- {
- vspr = vsprite[i];
-
- vspr->X = xmove[i]+vspr->X;
- vspr->Y = ymove[i]+vspr->Y;
-
- /* move the sprites ... here. */
-
- if(vspr->X >= 300 || vspr->X <= 0) xmove[i]=-xmove[i];
- if(vspr->Y >= 190 || vspr->Y <= 0) ymove[i]=-ymove[i];
-
- }
- SortGList(rp); /* get the list in order */
- DrawGList(rp, vp); /* create the sprite instructions */
-
- MakeScreen(s); /* ask Intuition to pull it all together */
- RethinkDisplay(); /* and to show us what we have now. */
- }
-
-
- #define AZCOLOR 1
- #define WHITECOLOR 2
-
- #define WC WINDOWCLOSE
- #define WS WINDOWSIZING
- #define WDP WINDOWDEPTH
- #define WDR WINDOWDRAG
-
- #define NORMALFLAGS (WC|WS|WDP)
- /* Did not use windowdrag because dont want screen to be moved. */
-
- /* Allow window sizing so user can decrease size of window, then
- * increase it again, thus erasing the background text and more
- * easily see that some vsprites wink out and into existence when
- * too many sprites are on a single horizontal plane and the
- * vsprite machine runs out of sprites to assign.
- */
-
- /* myfont1 specifies characteristics of the default font;
- * this case selects the 80 column font that displays as
- * 40 columns in low resolution mode.
- */
- struct TextAttr myfont1 = { "topaz.font", 8, 0, 0 };
-
- struct NewScreen myscreen1 = {
- 0, 0, /* LeftEdge, TopEdge ... where to put screen */
- 320, 200, /* Width, Height ... size of the screen */
- 5, /* 5 planes Depth, means 2 to the 5th or
- * 32 different colors to choose from once
- * the screen is opened.
- */
- 1, 0, /* DetailPen, BlockPen */
- SPRITES, /* ViewModes ... value of 0 = low resolution */
- CUSTOMSCREEN, /* Type of screen */
- &myfont1, /* Font to be used as default for this screen */
- "32 Color Test", /* DefaultTitle for its title bar */
- NULL, /* screens user-gadgets, always NULL, ignored */
- NULL };
- /* address of custom bitmap for screen,
- * not used in this example
- */
-
-
- struct NewWindow myWindow = {
- 0, /* LeftEdge for window measured in pixels,
- at the current horizontal resolution,
- from the leftmost edge of the Screen */
- 0, /* TopEdge for window is measured in lines
- from the top of the current Screen. */
- 320, 185, /* Width, Height of this window */
- 0, /* DetailPen - what pen number is to be
- used to draw the borders of the window */
- 1, /* BlockPen - what pen number is to be
- used to draw system generated window
- gadgets */
- /* (for DetailPen and BlockPen, the value
- of -1 says "use the default value") */
- CLOSEWINDOW, /* simplesprite program used INTUITICKS also */
- /* IDCMP Flags */
- NORMALFLAGS | GIMMEZEROZERO | ACTIVATE,
- /* Window Flags: (see below for more info) */
- NULL, /* FirstGadget */
- NULL, /* CheckMark */
- "Click Close Gadget To Stop", /* Window title */
- NULL, /* Pointer to Screen if not workbench */
- NULL, /* Pointer to BitMap if a SUPERBITMAP window */
- 320, 10, /* minimum width, minimum height */
- 320, 200, /* maximum width, maximum height */
- CUSTOMSCREEN
- };
-
- #include "graphics/gfxmacros.h"
-
- /* #include "event1.c" */
- /* gets the event handler */
- /* event1.c */
-
- HandleEvent(code)
- LONG code; /* provided by main */
- {
- switch(code)
- {
- case CLOSEWINDOW:
- return(0);
- break;
- case INTUITICKS: /* could have done much faster
- * but what the heck, this is
- * shorter for test purposes
- */
- movesprites(); /* 10 moves per second; test */
- default:
- break;
- }
- return(1);
- }
-
- UWORD mycolortable[] = {
-
- 0x0000, 0x0e30, 0x0fff, 0x0b40, 0x0fb0, 0x0bf0,
- 0x05d0, 0x0ed0, 0x07df, 0x069f, 0x0c0e,
- 0x0f2e, 0x0feb, 0x0c98, 0x0bbb, 0x07df,
-
- 0x0000, 0x0e30, 0x0fff, 0x0b40,
- 0x0fb0, 0x0bf0, 0x05d0, 0x0ed0,
- 0x07df, 0x069f, 0x0c0e, 0x0f2e,
- 0x0feb, 0x0c98, 0x0bbb, 0x07df
- };
-
- /* black, red, white, fire-engine red, orange, yellow,
- lime green, green, aqua, dark blue, purple,
- violet, tan, brown, gray, skyblue, (everything again) */
-
- UWORD colorset0[ ] = { 0x0e30, 0xffff, 0x0b40 }; /* same as colors 17-19 */
- UWORD colorset1[ ] = { 0x0bf0, 0x05d0, 0x0ed0 }; /* 21-23 */
- UWORD colorset2[ ] = { 0x069f, 0x0c0e, 0x0f2e }; /* 25-27 */
- UWORD colorset3[ ] = { 0x0c98, 0x0bbb, 0x07df }; /* 29-31 */
- UWORD *colorset[ ] = {
- colorset0, colorset1,
- colorset2, colorset3 };
- int choice;
- char *numbers[] = { "17","18","19",
- "20","21","22","23",
- "24","25","26","27",
- "28","29","30","31" };
-
- /* #include "ram:purgegels.c" */
- /* purgegels.c */
-
- /*
- * Use this to get rid of the gels stuff when it is not needed any more.
- * You must have allocated the gels info stuff (use the ReadyGels routine).
- */
-
- void 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));
- }
-
-
- /* Deallocate memory which has been allocated by the routines Makexxx. */
- /* Assumes images and imageshadow deallocated elsewhere. */
-
- void 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));
- }
- }
-
- /* end of purgegels.c */
-
- /* #include "ram:readygels.c" */
- /* readygels.c */
-
- struct VSprite *SpriteHead = NULL;
- struct VSprite *SpriteTail = NULL;
-
- void border_dummy() /* a dummy collision routine */
- {
- return;
- }
-
- 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)
- {
- return(-1);
- }
-
- if ((SpriteTail = (struct VSprite *)AllocMem(sizeof
- (struct VSprite), MEMF_PUBLIC | MEMF_CLEAR)) == 0)
- {
- FreeMem(SpriteHead, sizeof(struct VSprite));
- return(-2);
- }
- g->sprRsrvd = 0xFC; /* do not use sprites 0 or 1. */
-
- if ((g->nextLine = (WORD *)AllocMem(sizeof(WORD) * 8,
- MEMF_PUBLIC | MEMF_CLEAR)) == NULL)
- {
- FreeMem(SpriteHead, sizeof(struct VSprite));
- FreeMem(SpriteTail, sizeof(struct VSprite));
- return(-3);
- }
-
- if ((g->lastColor = (WORD **)AllocMem(sizeof(LONG) * 8,
- MEMF_PUBLIC | MEMF_CLEAR)) == NULL)
- {
- FreeMem(g->nextLine,8 * sizeof(WORD));
- FreeMem(SpriteHead, sizeof(struct VSprite));
- FreeMem(SpriteTail, sizeof(struct VSprite));
- return(-4);
- }
-
- /* Next we prepare 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)
- {
- FreeMem(g->lastColor, 8 * sizeof(LONG));
- FreeMem(g->nextLine,8 * sizeof(WORD));
- FreeMem(SpriteHead, sizeof(struct VSprite));
- FreeMem(SpriteTail, sizeof(struct VSprite));
- return(-5);
- }
-
- /* 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); /* a return value of 0 says all ok, any
- * negative value tells you when it failed.
- * (see the listing as to what the routine
- * was trying to do... all failures are
- * due to out of memory conditions).
- */
- }
-
-
- /* end of readygels.c */
-
- /* #include "ram:MakeVSprite.c" */
- /* MakeVSprite.c */
-
- struct VSprite *MakeVSprite(lineheight, image, colorset, 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 */
- WORD *colorset; /* Where is the set of three words which describes
- the colors that this vsprite can take on? */
- 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)
- {
- 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)
- {
- FreeMem(v, sizeof(struct VSprite));
- 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)
- {
- FreeMem(v, sizeof(struct VSprite));
- FreeMem(v->BorderLine, wordwidth * sizeof(WORD));
- return(0);
- }
-
- /* This isn't used for a Bob, just a VSprite. It's where the
- * Caller says where to find the VSprites colors.
- */
- v->SprColors = colorset;
-
- /* 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);
- }
- /* end of MakeVSprite.c */
-
- int main()
- {
- struct IntuiMessage *msg;
- LONG result;
- SHORT k, j, x, y, error;
- UWORD *src, *dest; /* for copying sprite data to RAM */
-
- GfxBase = OpenLibrary("graphics.library",0);
-
- IntuitionBase = OpenLibrary("intuition.library",0);
- /* (error checking left out for brevity here) */
-
- s = OpenScreen(&myscreen1); /* try to open it */
- if(s == 0)
- {
- printf("Can't open myscreen1\n");
- exit(10);
- }
- myWindow.Screen = s; /* say where screen is located */
-
- ShowTitle(s, FALSE); /* Dont let screen be dragged down...*/
-
- w = OpenWindow(&myWindow);
- if(w == 0)
- {
- printf("Window didn't open!\n");
- CloseScreen(s);
- exit(20);
- }
- vp = &(s->ViewPort);
- /* set the colors for this viewport */
-
- LoadRGB4(vp, &mycolortable[0], 32);
- rp = w->RPort;
- /* Now wait for a message to arrive from Intuition
- * (task goes to sleep while waiting for the message)
- */
-
- /* Write Text using sprite colors so that demo can show
- * how the vsprite machine stuffs the colors as it goes
- * down the screen. Thus if using vsprites, user should
- * avoid using the color registers that the vsprites use.
- */
-
- /* Notice also that color numbers 17-19 are untouched.
- * That is because of the sprResrvd=0xFC in ReadyGels.
- * (Doesn't allow the virtual sprite machine to access
- * either sprite 0 or 1... 0 is used by mouse cursor and
- * shares its colors with 1, so I reserved both of them.
- */
-
- for(j=8; j<180; j+=50)
- {
- for(k=0; k<15; k++)
- {
- Move(rp,k*20,j);
- SetAPen(rp,k+17); /* show 17-31 */
- /* 16, 20, 24, 28 are unaffected by vsprites
- * because they are not used by hardware sprites */
-
- Text(rp,numbers[k],2);
- }
- }
- /* *************************************** */
- /* VSPRITE DEMO SECTION */
- /* *************************************** */
-
- /* Allocate CHIP memory to hold the actual sprite data */
- /* (necessary if ever to run on an expanded RAM Amiga) */
-
- sprdata = (UWORD *)AllocMem(36, MEMF_CHIP);
-
- if(sprdata == NULL)
- {
- /* not enough memory for sprite */
- }
- /* now copy the sprite data into the CHIP RAM. */
-
- src = sprite_data;
- dest = sprdata; /* source, destination */
-
- for( j=0; j<18; j++)
- {
- *dest++ = *src++;
- }
-
- choice = 0;
- maxgot = 0;
-
- /* Prepare the GELS system to work with VSPRITE or BOBS */
-
- error = ReadyGels(&mygelsinfo, rp);
-
- for(k=0; k<MAXSP; k++) /* whatever maximum number of vsprites */
- {
- xmove[k]=speed[RangeRand(4)];
- ymove[k]=speed[RangeRand(4)];
-
- /* establish a position for the sprite */
- x = 10 + RangeRand(280);
- y = 10 + RangeRand(170);
-
- /* create a vsprite */
- vsprite[k] = MakeVSprite( 9, sprdata, colorset[choice],
- x, y, 1, 2, VSPRITE);
- /* 9 lines high, using MEMF_CHIP image of a sprite,
- * with a particular set of colors, at an X,Y location
- * 1 word wide, 2 planes deep (all vsprites are 2 deep)
- * and it is a VSPRITE */
-
- if(vsprite[k] == 0)
- {
- break; /* ran out of memory! */
- }
- AddVSprite(vsprite[k], rp);
-
- maxgot++;
-
- choice++; /* choose a different color set */
- if(choice >= 4)
- {
- choice = 0; /* wrap around on colorsets */
- }
- }
- while(1) /* forever */
- {
- WaitTOF();
- movesprites();
-
- result = -1; /* now see if CLOSEWINDOW is waiting */
- msg = (struct IntuiMessage *)GetMsg(w->UserPort);
- if(msg != 0)
- {
- result = HandleEvent(msg->Class);
-
- /* Let Intuition reuse the msg */
- ReplyMsg(msg);
- }
- if(result == 0)
- {
- break; /* got a CLOSEWINDOW */
- }
- }
-
- /* DONE, now cleanup */
-
- /* Free however many vsprites we actually managed to create */
-
- for(k=0; k<maxgot; k++)
- {
- DeleteGel(vsprite[k]);
- }
- /* delete what ReadyGels created */
- PurgeGels(&mygelsinfo);
-
- FreeMem(sprdata, 36); /* free what we allocated. */
-
- CloseWindow(w);
- CloseScreen(s);
- return (0);
- }
-
-
-
-