home *** CD-ROM | disk | FTP | other *** search
Text File | 1999-02-08 | 66.9 KB | 2,307 lines | [TEXT/CWIE] |
- ///--------------------------------------------------------------------------------------
- // SpriteWorld.c
- //
- // Portions are copyright: © 1991-94 Tony Myles, All rights reserved worldwide.
- //
- // Description: implementation of the sprite world architecture
- ///--------------------------------------------------------------------------------------
-
-
- #ifndef __SWCOMMON__
- #include "SWCommonHeaders.h"
- #endif
-
- #ifndef __QUICKDRAW__
- #include <QuickDraw.h>
- #endif
-
- #ifndef __MEMORY__
- #include <Memory.h>
- #endif
-
- #ifndef __GESTALT__
- #include <Gestalt.h>
- #endif
-
- #ifndef __TIMER__
- #include <Timer.h>
- #endif
-
- #ifndef __SPRITEWORLDUTILS__
- #include "SpriteWorldUtils.h"
- #endif
-
- #ifndef __SPRITEWORLD__
- #include "SpriteWorld.h"
- #endif
-
- #ifndef __SPRITELAYER__
- #include "SpriteLayer.h"
- #endif
-
- #ifndef __SPRITE__
- #include "Sprite.h"
- #endif
-
- #ifndef __SPRITEFRAME__
- #include "SpriteFrame.h"
- #endif
-
- #ifndef __BLITPIXIE__
- #include "BlitPixie.h"
- #endif
-
- #ifndef __RETRACE__
- #include <Retrace.h>
- #endif
-
- #ifndef __SCROLLING__
- #include "Scrolling.h"
- #endif
-
- #ifndef __TILING__
- #include "Tiling.h"
- #endif
-
-
- SInt8 gSWmmuMode;
- short gProcessorType; //
- RgnHandle gCollisionSectRgn = NULL; /// Initialized by SWEnterSpriteWorld
- RgnHandle gCollisionSpareRgn = NULL; //
- SpritePtr gCurrentSpriteBeingDrawn = NULL;
- SpriteWorldPtr gCleanUpSpriteWorldP = NULL;
-
-
- ///--------------------------------------------------------------------------------------
- // SWEnterSpriteWorld
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC OSErr SWEnterSpriteWorld(void)
- {
- OSErr err = noErr;
-
- gSWmmuMode = GetMMUMode();
-
- if ( !SWHasSystem7() )
- {
- err = kSystemTooOldErr;
- }
-
- SWGetProcessorType(&gProcessorType);
-
- if (gCollisionSectRgn == NULL && gCollisionSpareRgn == NULL)
- {
- gCollisionSectRgn = NewRgn();
- gCollisionSpareRgn = NewRgn();
- }
- else
- {
- err = kAlreadyCalledErr;
- }
-
- SWSetStickyIfError( err );
- return err;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWCreateSpriteWorld
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC OSErr SWCreateSpriteWorld(
- GDHandle mainGDH,
- SpriteWorldPtr *spriteWorldP,
- FramePtr windowFrameP,
- FramePtr backFrameP,
- FramePtr workFrameP,
- short maxDepth)
- {
- OSErr err;
- SpriteWorldPtr tempSpriteWorldP;
- PixMapHandle basePixMap;
-
-
- err = noErr;
- *spriteWorldP = NULL;
-
- tempSpriteWorldP = (SpriteWorldPtr)NewPtrClear((Size)sizeof(SpriteWorldRec));
- if (tempSpriteWorldP == NULL)
- err = MemError();
-
- if (err == noErr)
- {
- // Create the deadSpriteLayerP, but don't add it to the linked layer list
- err = SWCreateSpriteLayer(&tempSpriteWorldP->deadSpriteLayerP);
- if (err != noErr)
- DisposePtr((Ptr)tempSpriteWorldP);
- }
-
- if (err == noErr)
- {
- basePixMap = (**mainGDH).gdPMap;
- if ( maxDepth == 0 || (**basePixMap).pixelSize <= maxDepth )
- {
- tempSpriteWorldP->pixelDepth = (**basePixMap).pixelSize;
- }
- else
- {
- tempSpriteWorldP->pixelDepth = maxDepth;
- }
-
- tempSpriteWorldP->headSpriteLayerP = NULL;
- tempSpriteWorldP->tailSpriteLayerP = NULL;
-
- tempSpriteWorldP->mainSWGDH = mainGDH;
- tempSpriteWorldP->windowFrameP = windowFrameP;
- tempSpriteWorldP->extraBackFrameP = NULL;
- tempSpriteWorldP->backFrameP = backFrameP;
- tempSpriteWorldP->workFrameP = workFrameP;
- tempSpriteWorldP->offscreenDrawProc = SWStdWorldDrawProc;
- tempSpriteWorldP->screenDrawProc = SWStdWorldDrawProc;
- tempSpriteWorldP->doubleRectDrawProc = NULL;
- tempSpriteWorldP->postEraseCallBack = NULL;
- tempSpriteWorldP->postDrawCallBack = NULL;
- tempSpriteWorldP->windRect = windowFrameP->frameRect;
- tempSpriteWorldP->backRect = backFrameP->frameRect;
- tempSpriteWorldP->originalWindRect = windowFrameP->frameRect;
- tempSpriteWorldP->originalBackRect = backFrameP->frameRect;
-
- tempSpriteWorldP->headUpdateRectP = NULL;
-
- tempSpriteWorldP->scrollRectMoveBounds.left = 0;
- tempSpriteWorldP->scrollRectMoveBounds.top = 0;
- tempSpriteWorldP->scrollRectMoveBounds.right = 32767;
- tempSpriteWorldP->scrollRectMoveBounds.bottom = 32767;
- tempSpriteWorldP->horizScrollRectOffset = 0;
- tempSpriteWorldP->vertScrollRectOffset = 0;
- tempSpriteWorldP->horizScrollDelta = 0;
- tempSpriteWorldP->vertScrollDelta = 0;
- tempSpriteWorldP->worldMoveProc = NULL;
-
- // Make sure visScrollRect is at 0,0 top-left corner
- tempSpriteWorldP->visScrollRect = windowFrameP->frameRect;
- OffsetRect(&tempSpriteWorldP->visScrollRect,
- -tempSpriteWorldP->visScrollRect.left,
- -tempSpriteWorldP->visScrollRect.top);
- tempSpriteWorldP->offscreenScrollRect = tempSpriteWorldP->visScrollRect;
- tempSpriteWorldP->oldVisScrollRect = tempSpriteWorldP->visScrollRect;
-
- tempSpriteWorldP->tileLayerArray = NULL;
- tempSpriteWorldP->tilingCache = NULL;
- tempSpriteWorldP->changedTiles = NULL;
- tempSpriteWorldP->tilingIsInitialized = false;
- tempSpriteWorldP->tilingIsOn = false;
- tempSpriteWorldP->numTilesChanged = 0;
- tempSpriteWorldP->tileChangeProc = NULL;
- tempSpriteWorldP->tileRectDrawProc = SWDrawTilesInRect;
- tempSpriteWorldP->tileMaskDrawProc = SWStdSpriteDrawProc;
- tempSpriteWorldP->partialMaskDrawProc = SWStdSpriteDrawProc;
-
- tempSpriteWorldP->frameHasOccurred = false;
- tempSpriteWorldP->fpsTimeInterval = 0L;
-
- tempSpriteWorldP->lastMicroseconds.hi = 0L;
- tempSpriteWorldP->lastMicroseconds.lo = 0L;
- tempSpriteWorldP->runningTimeCount = 0L;
-
- tempSpriteWorldP->vblTaskRec.hasVBLFired = true;
- tempSpriteWorldP->usingVBL = false;
-
- SWClearStickyError();
-
- *spriteWorldP = tempSpriteWorldP;
- }
-
- return err;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWCreateSpriteWorldFromWindow
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC OSErr SWCreateSpriteWorldFromWindow(
- SpriteWorldPtr* spriteWorldP,
- CWindowPtr srcWindowP,
- Rect* worldRectP,
- Rect* offscreenRectP,
- short maxDepth)
- {
- OSErr err = noErr;
- FramePtr windowFrameP, backFrameP, workFrameP;
- Rect tempRect, globalRect, windRect;
- GDHandle mainGDH;
- PixMapHandle basePixMap;
- short depth;
-
-
- *spriteWorldP = NULL;
- windowFrameP = backFrameP = workFrameP = NULL;
-
- SetPort( (WindowPtr)srcWindowP );
-
- windRect = (worldRectP == NULL) ? srcWindowP->portRect : *worldRectP;
-
- globalRect = windRect;
- LocalToGlobal((Point *)&globalRect.top);
- LocalToGlobal((Point *)&globalRect.bottom);
-
-
- mainGDH = GetMaxDevice( &globalRect );
- SetGDevice( mainGDH );
- basePixMap = (**mainGDH).gdPMap;
- if ( maxDepth == 0 || (**basePixMap).pixelSize <= maxDepth )
- {
- depth = (**basePixMap).pixelSize;
- }
- else
- {
- depth = maxDepth;
- }
-
- if ( srcWindowP->portVersion < (short)0xC000 )
- {
- err = kNotCWindowErr;
- }
-
- // If a custom offscreenRect has been requested, use it instead.
- if (offscreenRectP == NULL)
- tempRect = windRect;
- else
- tempRect = *offscreenRectP;
-
- // offset Rect to (0,0) for back and work frames
- OffsetRect(&tempRect, -tempRect.left, -tempRect.top);
-
- if (err == noErr)
- {
- // create window frame
- err = SWCreateWindowFrame(&windowFrameP, &windRect, tempRect.bottom);
- }
-
- if (err == noErr)
- {
- // create back drop frame
- err = SWCreateFrame(mainGDH, &backFrameP, &tempRect, depth);
- }
-
- if (err == noErr)
- {
- // create work frame
- err = SWCreateFrame(mainGDH, &workFrameP, &tempRect, depth);
- }
-
-
- if (err == noErr)
- {
- // create sprite world
- err = SWCreateSpriteWorld(mainGDH, spriteWorldP, windowFrameP,
- backFrameP, workFrameP, maxDepth);
- }
-
- if (err != noErr)
- {
- // an error occurred so dispose of anything we managed to create
-
- if (windowFrameP != NULL)
- {
- SWDisposeWindowFrame(&windowFrameP);
- }
-
- if (backFrameP != NULL)
- {
- SWDisposeFrame(&backFrameP);
- }
-
- if (workFrameP != NULL)
- {
- SWDisposeFrame(&workFrameP);
- }
- }
-
- SWSetStickyIfError( err );
- return err;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWDisposeSpriteWorld
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWDisposeSpriteWorld(
- SpriteWorldPtr *spriteWorldPP)
- {
- SpriteWorldPtr spriteWorldP = *spriteWorldPP;
- SpriteLayerPtr curLayerP;
- SpritePtr curSpriteP;
-
-
- if (spriteWorldP != NULL)
- {
- SWUnlockSpriteWorld(spriteWorldP);
-
- while ((curLayerP = SWGetNextSpriteLayer(spriteWorldP, NULL)) != NULL)
- {
- // dispose of each sprite in the layer
- while ((curSpriteP = SWGetNextSprite(curLayerP, NULL)) != NULL)
- {
- SWRemoveSprite(curSpriteP);
- SWDisposeSprite(&curSpriteP);
- }
-
- // dispose of each layer in the spriteWorld
- SWRemoveSpriteLayer(spriteWorldP, curLayerP);
- SWDisposeSpriteLayer(&curLayerP);
- }
-
- SWDisposeAllSpritesInLayer(spriteWorldP->deadSpriteLayerP);
- SWDisposeSpriteLayer(&spriteWorldP->deadSpriteLayerP);
-
- SWDisposeFrame(&spriteWorldP->backFrameP);
- SWDisposeFrame(&spriteWorldP->workFrameP);
- SWDisposeFrame(&spriteWorldP->extraBackFrameP);
-
- SWDisposeWindowFrame(&spriteWorldP->windowFrameP);
-
- SWExitTiling(spriteWorldP);
- SWSyncSpriteWorldToVBL(spriteWorldP, false);
-
- DisposePtr((Ptr)spriteWorldP);
- *spriteWorldPP = NULL; // Set original pointer to NULL
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWExitSpriteWorld
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWExitSpriteWorld(void)
- {
- if (gCollisionSectRgn != NULL)
- DisposeRgn(gCollisionSectRgn);
- if (gCollisionSpareRgn != NULL)
- DisposeRgn(gCollisionSpareRgn);
-
- gCollisionSectRgn = NULL;
- gCollisionSpareRgn = NULL;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWAddSpriteLayer
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWAddSpriteLayer(
- SpriteWorldPtr spriteWorldP,
- SpriteLayerPtr newSpriteLayerP)
- {
- SpriteLayerPtr tailSpriteLayerP = spriteWorldP->tailSpriteLayerP;
-
- SW_ASSERT(spriteWorldP != NULL);
-
- if (tailSpriteLayerP != NULL)
- tailSpriteLayerP->nextSpriteLayerP = newSpriteLayerP;
- else
- spriteWorldP->headSpriteLayerP = newSpriteLayerP;
-
- newSpriteLayerP->prevSpriteLayerP = tailSpriteLayerP;
- newSpriteLayerP->nextSpriteLayerP = NULL;
-
- // make the new layer the tail
- spriteWorldP->tailSpriteLayerP = newSpriteLayerP;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWRemoveSpriteLayer
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWRemoveSpriteLayer(
- SpriteWorldPtr spriteWorldP,
- SpriteLayerPtr oldSpriteLayerP)
- {
- SW_ASSERT(spriteWorldP != NULL);
-
- // is there a next layer?
- if (oldSpriteLayerP->nextSpriteLayerP != NULL)
- {
- // link the next layer to the prev layer
- oldSpriteLayerP->nextSpriteLayerP->prevSpriteLayerP = oldSpriteLayerP->prevSpriteLayerP;
- }
- else
- {
- // make the prev layer the tail
- spriteWorldP->tailSpriteLayerP = oldSpriteLayerP->prevSpriteLayerP;
- }
-
- // is there a prev layer?
- if (oldSpriteLayerP->prevSpriteLayerP != NULL)
- {
- // link the prev layer to the next layer
- oldSpriteLayerP->prevSpriteLayerP->nextSpriteLayerP = oldSpriteLayerP->nextSpriteLayerP;
- }
- else
- {
- // make the next layer the head
- spriteWorldP->headSpriteLayerP = oldSpriteLayerP->nextSpriteLayerP;
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWSwapSpriteLayer
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWSwapSpriteLayer(
- SpriteWorldPtr spriteWorldP,
- SpriteLayerPtr srcSpriteLayerP,
- SpriteLayerPtr dstSpriteLayerP)
- {
- register SpriteLayerPtr swapSpriteLayerP;
-
- SW_ASSERT(spriteWorldP != NULL);
-
- // adjacent Layers are a special case
-
- if ( srcSpriteLayerP->nextSpriteLayerP == dstSpriteLayerP ||
- dstSpriteLayerP->nextSpriteLayerP == srcSpriteLayerP )
- {
- if ( srcSpriteLayerP->nextSpriteLayerP == dstSpriteLayerP )
- {
- if ( srcSpriteLayerP->prevSpriteLayerP != NULL )
- (srcSpriteLayerP->prevSpriteLayerP)->nextSpriteLayerP = dstSpriteLayerP;
- if ( dstSpriteLayerP->nextSpriteLayerP != NULL )
- (dstSpriteLayerP->nextSpriteLayerP)->prevSpriteLayerP = srcSpriteLayerP;
-
- dstSpriteLayerP->prevSpriteLayerP = srcSpriteLayerP->prevSpriteLayerP;
- srcSpriteLayerP->nextSpriteLayerP = dstSpriteLayerP->nextSpriteLayerP;
-
- dstSpriteLayerP->nextSpriteLayerP = srcSpriteLayerP;
- srcSpriteLayerP->prevSpriteLayerP = dstSpriteLayerP;
- }
- else
- {
- if ( dstSpriteLayerP->prevSpriteLayerP != NULL )
- (dstSpriteLayerP->prevSpriteLayerP)->nextSpriteLayerP = srcSpriteLayerP;
- if ( srcSpriteLayerP->nextSpriteLayerP != NULL )
- (srcSpriteLayerP->nextSpriteLayerP)->prevSpriteLayerP = dstSpriteLayerP;
-
- srcSpriteLayerP->prevSpriteLayerP = dstSpriteLayerP->prevSpriteLayerP;
- dstSpriteLayerP->nextSpriteLayerP = srcSpriteLayerP->nextSpriteLayerP;
-
- srcSpriteLayerP->nextSpriteLayerP = dstSpriteLayerP;
- dstSpriteLayerP->prevSpriteLayerP = srcSpriteLayerP;
- }
- }
- else
- {
- if ( srcSpriteLayerP->prevSpriteLayerP != NULL &&
- dstSpriteLayerP->prevSpriteLayerP != NULL )
- {
- swapSpriteLayerP = (srcSpriteLayerP->prevSpriteLayerP)->nextSpriteLayerP;
- (srcSpriteLayerP->prevSpriteLayerP)->nextSpriteLayerP =
- (dstSpriteLayerP->prevSpriteLayerP)->nextSpriteLayerP;
- (dstSpriteLayerP->prevSpriteLayerP)->nextSpriteLayerP = swapSpriteLayerP;
- }
-
- if ( srcSpriteLayerP->nextSpriteLayerP != NULL &&
- dstSpriteLayerP->nextSpriteLayerP != NULL )
- {
- swapSpriteLayerP = (srcSpriteLayerP->nextSpriteLayerP)->prevSpriteLayerP;
- (srcSpriteLayerP->nextSpriteLayerP)->prevSpriteLayerP =
- (dstSpriteLayerP->nextSpriteLayerP)->prevSpriteLayerP;
- (dstSpriteLayerP->nextSpriteLayerP)->prevSpriteLayerP = swapSpriteLayerP;
- }
- swapSpriteLayerP = srcSpriteLayerP->nextSpriteLayerP;
- srcSpriteLayerP->nextSpriteLayerP = dstSpriteLayerP->nextSpriteLayerP;
- dstSpriteLayerP->nextSpriteLayerP = swapSpriteLayerP;
-
- swapSpriteLayerP = srcSpriteLayerP->prevSpriteLayerP;
- srcSpriteLayerP->prevSpriteLayerP = dstSpriteLayerP->prevSpriteLayerP;
- dstSpriteLayerP->prevSpriteLayerP = swapSpriteLayerP;
- }
-
- if (srcSpriteLayerP->nextSpriteLayerP == NULL)
- {
- spriteWorldP->tailSpriteLayerP = srcSpriteLayerP;
- }
- else if (srcSpriteLayerP->prevSpriteLayerP == NULL)
- {
- spriteWorldP->headSpriteLayerP = srcSpriteLayerP;
- }
-
- if (dstSpriteLayerP->nextSpriteLayerP == NULL)
- {
- spriteWorldP->tailSpriteLayerP = dstSpriteLayerP;
- }
- else if (dstSpriteLayerP->prevSpriteLayerP == NULL)
- {
- spriteWorldP->headSpriteLayerP = dstSpriteLayerP;
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWGetNextSpriteLayer
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC SpriteLayerPtr SWGetNextSpriteLayer(
- SpriteWorldPtr spriteWorldP,
- SpriteLayerPtr curSpriteLayerP)
- {
- SW_ASSERT(spriteWorldP != NULL);
-
- return (curSpriteLayerP == NULL) ?
- spriteWorldP->headSpriteLayerP :
- curSpriteLayerP->nextSpriteLayerP;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWLockSpriteWorld
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWLockSpriteWorld(
- SpriteWorldPtr spriteWorldP)
- {
- SpriteLayerPtr curSpriteLayerP;
-
- SW_ASSERT(spriteWorldP != NULL);
-
- SWLockWindowFrame(spriteWorldP->windowFrameP);
- SWLockFrame(spriteWorldP->workFrameP);
- SWLockFrame(spriteWorldP->backFrameP);
- if (spriteWorldP->extraBackFrameP != NULL)
- SWLockFrame(spriteWorldP->extraBackFrameP);
-
- SWLockTiles(spriteWorldP);
-
- curSpriteLayerP = spriteWorldP->headSpriteLayerP;
-
- while (curSpriteLayerP != NULL)
- {
- SWLockSpriteLayer(curSpriteLayerP);
-
- curSpriteLayerP = curSpriteLayerP->nextSpriteLayerP;
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWUnlockSpriteWorld
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWUnlockSpriteWorld(
- SpriteWorldPtr spriteWorldP)
- {
- SpriteLayerPtr curSpriteLayerP;
-
- SW_ASSERT(spriteWorldP != NULL);
-
- SWUnlockWindowFrame(spriteWorldP->windowFrameP);
- SWUnlockFrame(spriteWorldP->backFrameP);
- SWUnlockFrame(spriteWorldP->workFrameP);
- if (spriteWorldP->extraBackFrameP != NULL)
- SWUnlockFrame(spriteWorldP->extraBackFrameP);
-
- SWUnlockTiles(spriteWorldP);
-
- curSpriteLayerP = spriteWorldP->headSpriteLayerP;
-
- while (curSpriteLayerP != NULL)
- {
- SWUnlockSpriteLayer(curSpriteLayerP);
-
- curSpriteLayerP = curSpriteLayerP->nextSpriteLayerP;
- }
- }
-
-
- #pragma mark -
- ///--------------------------------------------------------------------------------------
- // SWSetPortToBackground
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWSetPortToBackground(
- SpriteWorldPtr spriteWorldP)
- {
- SW_ASSERT(spriteWorldP != NULL);
- SW_ASSERT(spriteWorldP->backFrameP->isFrameLocked);
-
- if ( spriteWorldP->backFrameP->isFrameLocked )
- SetGWorld(spriteWorldP->backFrameP->framePort, nil);
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWSetPortToWorkArea
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWSetPortToWorkArea(
- SpriteWorldPtr spriteWorldP)
- {
- SW_ASSERT(spriteWorldP != NULL);
- SW_ASSERT(spriteWorldP->workFrameP->isFrameLocked);
-
- if ( spriteWorldP->workFrameP->isFrameLocked )
- SetGWorld(spriteWorldP->workFrameP->framePort, nil);
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWSetPortToWindow
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWSetPortToWindow(
- SpriteWorldPtr spriteWorldP)
- {
- SW_ASSERT(spriteWorldP != NULL);
-
- SetGWorld(spriteWorldP->windowFrameP->framePort, nil);
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWSetSpriteWorldOffscreenDrawProc
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC OSErr SWSetSpriteWorldOffscreenDrawProc(
- SpriteWorldPtr spriteWorldP,
- DrawProcPtr drawProc)
- {
- OSErr err = noErr;
-
- SW_ASSERT(spriteWorldP != NULL);
-
- if (spriteWorldP->pixelDepth != 8)
- {
- if ( drawProc == BlitPixie8BitRectDrawProc ||
- drawProc == BP8BitInterlacedRectDrawProc )
- err = kWrongDepthErr;
- }
-
- if ( err == noErr )
- spriteWorldP->offscreenDrawProc = drawProc;
-
- SWSetStickyIfError( err );
- return err;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWSetSpriteWorldScreenDrawProc
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC OSErr SWSetSpriteWorldScreenDrawProc(
- SpriteWorldPtr spriteWorldP,
- DrawProcPtr drawProc)
- {
- OSErr err = noErr;
-
- SW_ASSERT(spriteWorldP != NULL);
-
- if (drawProc == NULL)
- err = kNilParameterErr;
-
- if ( (*spriteWorldP->windowFrameP->framePort->portPixMap)->pixelSize != 8 ||
- (*spriteWorldP->windowFrameP->framePort->portPixMap)->pixelSize !=
- spriteWorldP->pixelDepth )
- {
- if ( drawProc == BlitPixie8BitRectDrawProc ||
- drawProc == BP8BitInterlacedRectDrawProc )
- err = kWrongDepthErr;
- }
-
- if ( err == noErr )
- spriteWorldP->screenDrawProc = drawProc;
-
- SWSetStickyIfError( err );
- return err;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWSetPostEraseCallBack
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWSetPostEraseCallBack(
- SpriteWorldPtr spriteWorldP,
- CallBackPtr callBack)
- {
- spriteWorldP->postEraseCallBack = callBack;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWSetPostDrawCallBack
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWSetPostDrawCallBack(
- SpriteWorldPtr spriteWorldP,
- CallBackPtr callBack)
- {
- spriteWorldP->postDrawCallBack = callBack;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWStdWorldDrawProc
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWStdWorldDrawProc(
- FramePtr srcFrameP,
- FramePtr dstFrameP,
- Rect* srcRect,
- Rect* dstRect)
- {
- Rect srcCopyBitsRect = *srcRect;
- Rect dstCopyBitsRect = *dstRect;
-
-
- // clip off the top
- if (dstCopyBitsRect.top < dstFrameP->frameRect.top)
- {
- srcCopyBitsRect.top += dstFrameP->frameRect.top - dstCopyBitsRect.top;
- dstCopyBitsRect.top = dstFrameP->frameRect.top;
- if (dstCopyBitsRect.top >= dstCopyBitsRect.bottom) return;
- }
- // clip off the bottom
- if (dstCopyBitsRect.bottom > dstFrameP->frameRect.bottom)
- {
- srcCopyBitsRect.bottom -= dstCopyBitsRect.bottom - dstFrameP->frameRect.bottom;
- dstCopyBitsRect.bottom = dstFrameP->frameRect.bottom;
- if (dstCopyBitsRect.bottom <= dstCopyBitsRect.top) return;
- }
- // clip off the left
- if (dstCopyBitsRect.left < dstFrameP->frameRect.left)
- {
- srcCopyBitsRect.left += dstFrameP->frameRect.left - dstCopyBitsRect.left;
- dstCopyBitsRect.left = dstFrameP->frameRect.left;
- if (dstCopyBitsRect.left >= dstCopyBitsRect.right)
- return;
- }
- // clip off the right
- if (dstCopyBitsRect.right > dstFrameP->frameRect.right)
- {
- srcCopyBitsRect.right -= dstCopyBitsRect.right - dstFrameP->frameRect.right;
- dstCopyBitsRect.right = dstFrameP->frameRect.right;
- if (dstCopyBitsRect.right <= dstCopyBitsRect.left) return;
- }
-
- CopyBits( (BitMap*)srcFrameP->framePix,
- (BitMap*)dstFrameP->framePix,
- &srcCopyBitsRect,
- &dstCopyBitsRect,
- srcCopy, NULL);
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWCopyBackgroundToWorkArea
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWCopyBackgroundToWorkArea(
- SpriteWorldPtr spriteWorldP)
- {
- GWorldPtr holdGWorld;
- GDHandle holdGDH;
-
- SW_ASSERT(spriteWorldP != NULL);
- SW_ASSERT(spriteWorldP->backFrameP->isFrameLocked);
- SW_ASSERT(spriteWorldP->workFrameP->isFrameLocked);
-
- GetGWorld( &holdGWorld, &holdGDH );
-
- // Copy the background frame into the work area
-
- SetGWorld(spriteWorldP->workFrameP->framePort, nil);
- (*spriteWorldP->offscreenDrawProc)(spriteWorldP->backFrameP,
- spriteWorldP->workFrameP,
- &spriteWorldP->backFrameP->frameRect,
- &spriteWorldP->workFrameP->frameRect);
-
- SetGWorld( holdGWorld, holdGDH );
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWChangeWorldRect
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC OSErr SWChangeWorldRect(
- SpriteWorldPtr spriteWorldP,
- Rect* newWorldRectP,
- Boolean changeOffscreenAreas)
- {
- Rect oldWindRect;
- short hChange, vChange;
- OSErr err = noErr;
-
- SW_ASSERT(spriteWorldP != NULL && newWorldRectP != NULL);
-
- // Report error if newWorldRectP is larger than the size of the offscreen areas
- if ( SW_RECT_WIDTH((*newWorldRectP)) > SW_RECT_WIDTH(spriteWorldP->originalBackRect) ||
- SW_RECT_HEIGHT((*newWorldRectP)) > SW_RECT_HEIGHT(spriteWorldP->originalBackRect) )
- {
- err = kOutOfRangeErr;
- }
-
-
- if (err == noErr)
- {
- // Now we calculate the difference in size of old and new windRect
- oldWindRect = spriteWorldP->windRect;
- hChange = (oldWindRect.right - oldWindRect.left) -
- (newWorldRectP->right - newWorldRectP->left);
- vChange = (oldWindRect.bottom - oldWindRect.top) -
- (newWorldRectP->bottom - newWorldRectP->top);
-
- // Change the windRect
- spriteWorldP->windRect = *newWorldRectP;
-
- // Resize the visScrollRect
- SWResizeVisScrollRect(spriteWorldP,
- newWorldRectP->right - newWorldRectP->left,
- newWorldRectP->bottom - newWorldRectP->top);
-
- if (changeOffscreenAreas)
- {
- // Make offscreen areas think they are the same size as the new windRect
- spriteWorldP->workFrameP->frameRect.bottom -= vChange;
- spriteWorldP->workFrameP->frameRect.right -= hChange;
- spriteWorldP->backFrameP->frameRect.bottom -= vChange;
- spriteWorldP->backFrameP->frameRect.right -= hChange;
-
- // Update backRect as well
- spriteWorldP->backRect.bottom -= vChange;
- spriteWorldP->backRect.right -= hChange;
- }
-
- // Recalculate blitter data based on new windRect position
- SWWindowMoved(spriteWorldP);
- }
-
- return err;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWRestoreWorldRect
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWRestoreWorldRect(SpriteWorldPtr spriteWorldP)
- {
- Rect originalWindRect = spriteWorldP->originalWindRect;
-
- SW_ASSERT(spriteWorldP != NULL);
-
- // Restore everything to its original size
- spriteWorldP->windRect = originalWindRect;
- spriteWorldP->workFrameP->frameRect = spriteWorldP->originalBackRect;
- spriteWorldP->backFrameP->frameRect = spriteWorldP->originalBackRect;
- spriteWorldP->backRect = spriteWorldP->originalBackRect;
-
- // Resize the visScrollRect to match the originalWindRect
- SWResizeVisScrollRect(spriteWorldP,
- originalWindRect.right - originalWindRect.left,
- originalWindRect.bottom - originalWindRect.top);
-
- // Recalculate blitter data based on new windRect position
- SWWindowMoved(spriteWorldP);
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWWindowMoved
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWWindowMoved(SpriteWorldPtr spriteWorldP)
- {
- GDHandle theGDH,
- holdGDH;
- GWorldPtr holdGWorld;
- Rect worldRect,
- globalWorldRect,
- screenRect;
- short depth;
- long curScanLine;
- Point globalOffset;
-
- SW_ASSERT(spriteWorldP != NULL);
- SW_ASSERT(spriteWorldP->windowFrameP->isFrameLocked);
-
- GetGWorld( &holdGWorld, &holdGDH );
-
- SWSetPortToWindow( spriteWorldP );
- theGDH = spriteWorldP->mainSWGDH;
-
- worldRect = spriteWorldP->windRect;
- globalWorldRect = worldRect;
- screenRect = (*theGDH)->gdRect;
- LocalToGlobal( &(topLeft(globalWorldRect)) );
- LocalToGlobal( &(botRight(globalWorldRect)) );
- globalOffset = topLeft(globalWorldRect);
-
- // Clip worldRect with screenRect
- if (globalWorldRect.top < screenRect.top)
- globalWorldRect.top = screenRect.top;
- if (globalWorldRect.bottom > screenRect.bottom)
- globalWorldRect.bottom = screenRect.bottom;
- if (globalWorldRect.left < screenRect.left)
- globalWorldRect.left = screenRect.left;
- if (globalWorldRect.right > screenRect.right)
- globalWorldRect.right = screenRect.right;
-
- // Convert global rect back to local rect
- GlobalToLocal( &(topLeft(globalWorldRect)) );
- GlobalToLocal( &(botRight(globalWorldRect)) );
-
- spriteWorldP->windowFrameP->frameRect = globalWorldRect;
-
-
- // cache frameRowBytes for use by our blitter routine
-
- spriteWorldP->windowFrameP->frameRowBytes =
- (**spriteWorldP->windowFrameP->framePort->portPixMap).rowBytes & 0x7FFF;
-
- depth = (**(**theGDH).gdPMap).pixelSize;
-
- // align on long word boundary
- spriteWorldP->windowFrameP->rightAlignFactor =
- ((sizeof(long) * kBitsPerByte) / depth) - 1;
- spriteWorldP->windowFrameP->leftAlignFactor =
- ~(spriteWorldP->windowFrameP->rightAlignFactor);
-
-
- // set the worldRectOffset
- spriteWorldP->windowFrameP->worldRectOffset = 0;
-
- if (depth < 8)
- {
- short roundOff;
-
- roundOff = 8/depth;
- spriteWorldP->windowFrameP->worldRectOffset =
- (globalOffset.h - worldRect.left) -
- (((globalOffset.h - worldRect.left)/roundOff)*roundOff);
- }
-
- // set up an array of offsets to the scan lines
- for (curScanLine = 0; curScanLine < spriteWorldP->windowFrameP->numScanLines; curScanLine++)
- {
- spriteWorldP->windowFrameP->scanLinePtrArray[curScanLine] =
- ((curScanLine+(globalOffset.v - worldRect.top) ) *
- spriteWorldP->windowFrameP->frameRowBytes) +
- (globalOffset.h - worldRect.left)*4/(32/depth);
- }
-
- SetGWorld( holdGWorld, holdGDH );
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWWindowFrameMoved
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWWindowFrameMoved(
- FramePtr windowFrameP,
- Rect *frameRect)
- {
- GDHandle theGDH,
- holdGDH;
- GWorldPtr theGWorld,
- holdGWorld;
- Rect worldRect,
- globalWorldRect,
- screenRect;
- short depth;
- long curScanLine;
- Point globalOffset;
-
- SW_ASSERT(windowFrameP != NULL);
- SW_ASSERT(windowFrameP->isFrameLocked);
-
- GetGWorld( &holdGWorld, &holdGDH );
-
- SetGWorld(windowFrameP->framePort, nil);
- GetGWorld(&theGWorld, &theGDH); // Get the GDH
-
- worldRect = *frameRect;
- globalWorldRect = *frameRect;
- screenRect = (*theGDH)->gdRect;
- LocalToGlobal( &(topLeft(globalWorldRect)) );
- LocalToGlobal( &(botRight(globalWorldRect)) );
- globalOffset = topLeft(globalWorldRect);
-
- // Clip worldRect with screenRect
- if (globalWorldRect.top < screenRect.top)
- globalWorldRect.top = screenRect.top;
- if (globalWorldRect.bottom > screenRect.bottom)
- globalWorldRect.bottom = screenRect.bottom;
- if (globalWorldRect.left < screenRect.left)
- globalWorldRect.left = screenRect.left;
- if (globalWorldRect.right > screenRect.right)
- globalWorldRect.right = screenRect.right;
-
- // Convert global rect back to local rect
- GlobalToLocal( &(topLeft(globalWorldRect)) );
- GlobalToLocal( &(botRight(globalWorldRect)) );
-
- windowFrameP->frameRect = globalWorldRect;
-
-
- // cache frameRowBytes for use by our blitter routine
- windowFrameP->frameRowBytes = (**windowFrameP->framePort->portPixMap).rowBytes & 0x7FFF;
- depth = (**(**theGDH).gdPMap).pixelSize;
-
- // align to long boundary
- windowFrameP->rightAlignFactor = ((sizeof(long) * kBitsPerByte) / depth) - 1;
- windowFrameP->leftAlignFactor = ~(windowFrameP->rightAlignFactor);
-
- // set the worldRectOffset
- windowFrameP->worldRectOffset = 0;
-
- if (depth < 8)
- {
- short roundOff;
-
- roundOff = 8/depth;
- windowFrameP->worldRectOffset = (globalOffset.h - worldRect.left) -
- (((globalOffset.h - worldRect.left)/roundOff)*roundOff);
- }
-
- // set up an array of offsets to the scan lines
- for (curScanLine = 0; curScanLine < windowFrameP->numScanLines; curScanLine++)
- {
- windowFrameP->scanLinePtrArray[curScanLine] =
- ((curScanLine+(globalOffset.v - worldRect.top) ) *
- windowFrameP->frameRowBytes) + (globalOffset.h - worldRect.left)*4/(32/depth);
- }
-
- SetGWorld( holdGWorld, holdGDH );
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWUpdateWindow
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWUpdateWindow(
- SpriteWorldPtr spriteWorldP)
- {
- GWorldPtr holdGWorld;
- GDHandle holdGDH;
-
- SW_ASSERT(spriteWorldP != NULL);
- SW_ASSERT(spriteWorldP->workFrameP->isFrameLocked);
- SW_ASSERT(spriteWorldP->windowFrameP->isFrameLocked);
-
- GetGWorld( &holdGWorld, &holdGDH );
-
- SetGWorld(spriteWorldP->windowFrameP->framePort, nil);
- spriteWorldP->numTilesChanged = 0;
-
- if ( spriteWorldP->usingVBL )
- {
- spriteWorldP->vblTaskRec.hasVBLFired = false;
- while ( !spriteWorldP->vblTaskRec.hasVBLFired )
- {}
- }
-
- (*spriteWorldP->screenDrawProc)(spriteWorldP->workFrameP,
- spriteWorldP->windowFrameP,
- &spriteWorldP->visScrollRect,
- &spriteWorldP->windowFrameP->frameRect);
-
- SetGWorld( holdGWorld, holdGDH );
- }
-
-
- #pragma mark -
- ///--------------------------------------------------------------------------------------
- // SWUpdateSpriteWorld
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWUpdateSpriteWorld(
- SpriteWorldPtr spriteWorldP,
- Boolean updateWindow)
- {
- UpdateRectStructPtr curRectStructP,
- nextRectStructP;
- register SpriteLayerPtr curSpriteLayerP;
- register SpritePtr curSpriteP;
- Rect tempRect;
- GWorldPtr holdGWorld;
- GDHandle holdGDH;
- short curTileLayer;
-
- SW_ASSERT(spriteWorldP != NULL);
- SW_ASSERT(spriteWorldP->backFrameP->isFrameLocked);
- SW_ASSERT(spriteWorldP->workFrameP->isFrameLocked);
- SW_ASSERT(spriteWorldP->windowFrameP->isFrameLocked);
-
- GetGWorld( &holdGWorld, &holdGDH );
-
-
- // Copy the background into the work area
- SetGWorld(spriteWorldP->workFrameP->framePort, nil);
- (*spriteWorldP->offscreenDrawProc)(spriteWorldP->backFrameP,
- spriteWorldP->workFrameP,
- &spriteWorldP->backFrameP->frameRect,
- &spriteWorldP->workFrameP->frameRect);
-
- // Call the postEraseCallBack
- if (spriteWorldP->postEraseCallBack != NULL)
- (*spriteWorldP->postEraseCallBack)(spriteWorldP);
-
-
- // Build the current frame of the animation in the work area
-
- curSpriteLayerP = spriteWorldP->headSpriteLayerP;
- curTileLayer = 0;
-
- // iterate through the layers in this world
- while (curSpriteLayerP != NULL)
- {
- curSpriteP = curSpriteLayerP->headSpriteP;
-
- if (curSpriteLayerP->tileLayer > curTileLayer)
- curTileLayer = curSpriteLayerP->tileLayer;
-
- // iterate through the sprites in this layer
- while (curSpriteP != NULL)
- {
- SW_ASSERT(curSpriteP->curFrameP->isFrameLocked);
-
- curSpriteP->tileDepth = curTileLayer;
-
- if (curSpriteP->isVisible)
- {
- gCurrentSpriteBeingDrawn = curSpriteP;
-
- // draw the sprite in the work area
- (*curSpriteP->frameDrawProc)(curSpriteP->curFrameP,
- spriteWorldP->workFrameP,
- &curSpriteP->curFrameP->frameRect,
- &curSpriteP->destFrameRect);
-
- gCurrentSpriteBeingDrawn = NULL;
-
- if (spriteWorldP->tilingIsOn &&
- curSpriteP->tileDepth <= spriteWorldP->lastActiveTileLayer)
- {
- tempRect = curSpriteP->destFrameRect;
-
- // Clip tempRect to visScrollRect
- if (tempRect.left < spriteWorldP->visScrollRect.left)
- tempRect.left = spriteWorldP->visScrollRect.left;
- if (tempRect.right > spriteWorldP->visScrollRect.right)
- tempRect.right = spriteWorldP->visScrollRect.right;
- if (tempRect.top < spriteWorldP->visScrollRect.top)
- tempRect.top = spriteWorldP->visScrollRect.top;
- if (tempRect.bottom > spriteWorldP->visScrollRect.bottom)
- tempRect.bottom = spriteWorldP->visScrollRect.bottom;
-
- SWDrawTilesAboveSprite(spriteWorldP, &tempRect, curSpriteP->tileDepth);
- }
-
- }
-
- // set the delta and last rect to the current rect
- curSpriteP->deltaFrameRect = curSpriteP->destFrameRect;
- curSpriteP->oldFrameRect = curSpriteP->destFrameRect;
-
- // this sprite no longer needs to be drawn
- curSpriteP->needsToBeDrawn = false;
- curSpriteP->needsToBeErased = false;
-
- curSpriteP = curSpriteP->nextSpriteP;
- }
-
- curSpriteLayerP = curSpriteLayerP->nextSpriteLayerP;
- }
-
-
- // Call the postDrawCallBack
- if (spriteWorldP->postDrawCallBack != NULL)
- (*spriteWorldP->postDrawCallBack)(spriteWorldP);
-
-
- // Copy the work area into the window
- if (updateWindow)
- {
- SetGWorld(spriteWorldP->windowFrameP->framePort, nil);
-
- if ( spriteWorldP->usingVBL )
- {
- spriteWorldP->vblTaskRec.hasVBLFired = false;
- while ( !spriteWorldP->vblTaskRec.hasVBLFired )
- {}
- }
-
- (*spriteWorldP->screenDrawProc)(spriteWorldP->workFrameP,
- spriteWorldP->windowFrameP,
- &spriteWorldP->visScrollRect,
- &spriteWorldP->windowFrameP->frameRect);
- }
-
-
- // dispose of flagged background rects
- nextRectStructP = spriteWorldP->headUpdateRectP;
- while ( nextRectStructP != NULL )
- {
- curRectStructP = nextRectStructP;
- nextRectStructP = curRectStructP->nextRectStructP;
- DisposePtr( (Ptr)curRectStructP );
- }
- spriteWorldP->headUpdateRectP = NULL;
-
- spriteWorldP->numTilesChanged = 0;
-
- SetGWorld( holdGWorld, holdGDH );
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWProcessSpriteWorld
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWProcessSpriteWorld(
- SpriteWorldPtr spriteWorldP)
- {
- UnsignedWide curMicroseconds;
- register unsigned long millisecDifference;
- register SpriteLayerPtr curSpriteLayerP;
- register SpritePtr curSpriteP, nextSpriteP;
- register FramePtr newFrameP;
-
- SW_ASSERT(spriteWorldP != NULL);
-
- Microseconds( &curMicroseconds );
- // has hi long has rolled over?
- if ( curMicroseconds.hi > spriteWorldP->lastMicroseconds.hi )
- {
- millisecDifference =
- (0xffffffff - (spriteWorldP->lastMicroseconds.lo - curMicroseconds.lo))/1000;
- }
- else
- {
- millisecDifference = (curMicroseconds.lo - spriteWorldP->lastMicroseconds.lo)/1000;
- }
- if ( millisecDifference > 0 )
- {
- spriteWorldP->runningTimeCount += millisecDifference;
- spriteWorldP->lastMicroseconds.lo = curMicroseconds.lo;
- spriteWorldP->lastMicroseconds.hi = curMicroseconds.hi;
- }
-
- if ( (spriteWorldP->runningTimeCount - spriteWorldP->timeOfLastFrame >=
- spriteWorldP->fpsTimeInterval) )
- {
- spriteWorldP->frameHasOccurred = true;
- spriteWorldP->timeOfLastFrame = spriteWorldP->runningTimeCount;
- }
- else
- {
- spriteWorldP->frameHasOccurred = false;
- return;
- }
-
- if ( spriteWorldP->deadSpriteLayerP->headSpriteP != NULL )
- {
- SWFindSpritesToBeRemoved( spriteWorldP );
- }
-
- // Call the tileChangeProc, if there is one
- if (spriteWorldP->tileChangeProc != NULL)
- {
- (*spriteWorldP->tileChangeProc)(spriteWorldP);
- }
-
- curSpriteLayerP = spriteWorldP->headSpriteLayerP;
-
- // iterate through the layers in this world
- while (curSpriteLayerP != NULL)
- {
- if (!curSpriteLayerP->isPaused)
- {
- curSpriteP = curSpriteLayerP->headSpriteP;
-
- // iterate through the sprites in this layer
- while (curSpriteP != NULL)
- {
- SW_ASSERT(curSpriteP->curFrameP->isFrameLocked);
- nextSpriteP = curSpriteP->nextSpriteP;
-
- // is it time to advance the sprite’s frame?
- if ( curSpriteP->frameTimeInterval >= 0 &&
- (spriteWorldP->runningTimeCount - curSpriteP->timeOfLastFrameChange >
- curSpriteP->frameTimeInterval) )
- {
- register long currentFrameIndex;
-
-
- curSpriteP->timeOfLastFrameChange = spriteWorldP->runningTimeCount;
-
- currentFrameIndex = curSpriteP->curFrameIndex;
- currentFrameIndex += curSpriteP->frameAdvance;
-
- if (currentFrameIndex < curSpriteP->firstFrameIndex)
- {
- if (curSpriteP->frameAdvanceMode == kSWWrapAroundMode)
- {
- // wrap to the last frame
- currentFrameIndex = curSpriteP->lastFrameIndex;
- }
- else // curSpriteP->frameAdvanceMode == kSWPatrollingMode
- {
- // change direction and set index to what it should be
- curSpriteP->frameAdvance = -curSpriteP->frameAdvance;
- currentFrameIndex += curSpriteP->frameAdvance;
- currentFrameIndex += curSpriteP->frameAdvance;
- }
- }
- else if (currentFrameIndex > curSpriteP->lastFrameIndex)
- {
- if (curSpriteP->frameAdvanceMode == kSWWrapAroundMode)
- {
- // wrap to the first frame
- currentFrameIndex = curSpriteP->firstFrameIndex;
- }
- else // curSpriteP->frameAdvanceMode == kSWPatrollingMode
- {
- // change direction and set index to what it should be
- curSpriteP->frameAdvance = -curSpriteP->frameAdvance;
- currentFrameIndex += curSpriteP->frameAdvance;
- currentFrameIndex += curSpriteP->frameAdvance;
- }
- }
-
- curSpriteP->curFrameIndex = currentFrameIndex;
-
-
- // is there a frame callback?
- if (curSpriteP->frameChangeProc != NULL)
- {
- // get new frame
- newFrameP = curSpriteP->frameArray[currentFrameIndex];
-
- // call it
- (*curSpriteP->frameChangeProc)(curSpriteP, newFrameP,
- &curSpriteP->curFrameIndex);
-
- // make sure the new frame index is in range
- if (curSpriteP->curFrameIndex < 0)
- {
- curSpriteP->curFrameIndex = 0;
- }
- else if (curSpriteP->curFrameIndex >= curSpriteP->maxFrames)
- {
- curSpriteP->curFrameIndex = curSpriteP->maxFrames - 1;
- }
- }
-
- // change the frame
- newFrameP = curSpriteP->frameArray[curSpriteP->curFrameIndex];
-
- // has the frame actually changed?
- if (curSpriteP->curFrameP != newFrameP)
- {
- SWSetCurrentFrameIndex(curSpriteP, curSpriteP->curFrameIndex);
- }
- }
-
- // is it time to move the sprite?
- if ( curSpriteP->moveTimeInterval >= 0 &&
- (spriteWorldP->runningTimeCount - curSpriteP->timeOfLastMove) >
- curSpriteP->moveTimeInterval )
- {
- curSpriteP->timeOfLastMove = spriteWorldP->runningTimeCount;
-
- // is there a movement callback?
- if (curSpriteP->spriteMoveProc != NULL)
- {
- (*curSpriteP->spriteMoveProc)(curSpriteP);
- }
- }
- curSpriteP = nextSpriteP;
- }
- }
- curSpriteLayerP = curSpriteLayerP->nextSpriteLayerP;
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWAnimateSpriteWorld
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWAnimateSpriteWorld(
- SpriteWorldPtr spriteWorldP)
- {
- UpdateRectStructPtr curRectStructP,
- nextRectStructP;
- register SpriteLayerPtr curSpriteLayerP;
- register SpritePtr curSpriteP;
- SpritePtr headActiveSpriteP = NULL; // Tail of active sprite list
- SpritePtr headIdleSpriteP = NULL; // Tail of idle sprite list
- SpritePtr curActiveSpriteP = NULL;
- SpritePtr curIdleSpriteP = NULL;
- Rect screenDestRect;
- Rect *changedRectP;
- short index, curTileLayer;
-
- SW_ASSERT(spriteWorldP != NULL);
- SW_ASSERT(spriteWorldP->backFrameP->isFrameLocked);
- SW_ASSERT(spriteWorldP->workFrameP->isFrameLocked);
- SW_ASSERT(spriteWorldP->windowFrameP->isFrameLocked);
-
- if (!spriteWorldP->frameHasOccurred)
- return;
-
- // Add the deadSpriteLayer if there are any Sprites in it.
- if ( spriteWorldP->deadSpriteLayerP->headSpriteP != NULL )
- {
- SWAddSpriteLayer(spriteWorldP, spriteWorldP->deadSpriteLayerP);
- }
-
- // the current port should be the one in which we are drawing
- SetGWorld(spriteWorldP->workFrameP->framePort, nil);
-
- //-----------------erase the sprites--------------------
-
- curSpriteLayerP = spriteWorldP->headSpriteLayerP;
- curTileLayer = 0;
-
- // iterate through the layers in this world
- while (curSpriteLayerP != NULL)
- {
- curSpriteP = curSpriteLayerP->headSpriteP;
-
- if (curSpriteLayerP->tileLayer > curTileLayer)
- curTileLayer = curSpriteLayerP->tileLayer;
-
- // iterate through the sprites in this layer
- while (curSpriteP != NULL)
- {
- SW_ASSERT(curSpriteP->curFrameP->isFrameLocked);
- curSpriteP->tileDepth = curTileLayer;
-
- if ((curSpriteP->needsToBeDrawn && curSpriteP->isVisible) ||
- (curSpriteP->needsToBeErased && !curSpriteP->isVisible))
- {
- // Add sprite to active sprite list
- if (headActiveSpriteP == NULL)
- headActiveSpriteP = curSpriteP;
-
- if (curActiveSpriteP != NULL)
- curActiveSpriteP->nextActiveSpriteP = curSpriteP;
-
- curActiveSpriteP = curSpriteP;
-
- // union last rect and current rect
- // this way is much faster than UnionRect
- curSpriteP->deltaFrameRect.top =
- SW_MIN(curSpriteP->oldFrameRect.top, curSpriteP->destFrameRect.top);
- curSpriteP->deltaFrameRect.left =
- SW_MIN(curSpriteP->oldFrameRect.left, curSpriteP->destFrameRect.left);
- curSpriteP->deltaFrameRect.bottom =
- SW_MAX(curSpriteP->oldFrameRect.bottom, curSpriteP->destFrameRect.bottom);
- curSpriteP->deltaFrameRect.right =
- SW_MAX(curSpriteP->oldFrameRect.right, curSpriteP->destFrameRect.right);
- {
- short temp;
-
- // align the left edge to long word boundary
- curSpriteP->deltaFrameRect.left &=
- (spriteWorldP->workFrameP->leftAlignFactor);
-
- // align the right edge to long word boundary
- temp = curSpriteP->deltaFrameRect.right &
- spriteWorldP->workFrameP->rightAlignFactor;
- if (temp != 0)
- {
- curSpriteP->deltaFrameRect.right +=
- (spriteWorldP->workFrameP->rightAlignFactor + 1) - temp;
- }
-
- // align the left edge to long word boundary
- curSpriteP->oldFrameRect.left &=
- (spriteWorldP->workFrameP->leftAlignFactor);
-
- // align the right edge to long word boundary
- temp = curSpriteP->oldFrameRect.right &
- spriteWorldP->workFrameP->rightAlignFactor;
- if (temp != 0)
- {
- curSpriteP->oldFrameRect.right +=
- (spriteWorldP->workFrameP->rightAlignFactor + 1) - temp;
- }
- }
-
- // copy the back drop piece
- (*spriteWorldP->offscreenDrawProc)(
- spriteWorldP->backFrameP,
- spriteWorldP->workFrameP,
- &curSpriteP->oldFrameRect,
- &curSpriteP->oldFrameRect);
- }
- else if (curSpriteP->isVisible)
- {
- // Add sprite to idle sprite list
- if (headIdleSpriteP == NULL)
- headIdleSpriteP = curSpriteP;
-
- if (curIdleSpriteP != NULL)
- curIdleSpriteP->nextIdleSpriteP = curSpriteP;
-
- curIdleSpriteP = curSpriteP;
- }
-
- curSpriteP = curSpriteP->nextSpriteP;
- }
-
- curSpriteLayerP = curSpriteLayerP->nextSpriteLayerP;
- }
-
- if (curActiveSpriteP != NULL)
- curActiveSpriteP->nextActiveSpriteP = NULL;
-
- if (curIdleSpriteP != NULL)
- curIdleSpriteP->nextIdleSpriteP = NULL;
-
-
- // update flagged background rects
- curRectStructP = spriteWorldP->headUpdateRectP;
- while ( curRectStructP != NULL )
- {
- (*spriteWorldP->offscreenDrawProc)(
- spriteWorldP->backFrameP,
- spriteWorldP->workFrameP,
- &curRectStructP->updateRect,
- &curRectStructP->updateRect);
- curRectStructP = curRectStructP->nextRectStructP;
- }
-
- // Redraw idle sprites that were erased by a tile
- if (spriteWorldP->numTilesChanged > 0)
- SWCheckIdleSpritesWithTiles(spriteWorldP, headIdleSpriteP);
-
- // Redraw idle sprites that were erased by an updateRect
- if (spriteWorldP->headUpdateRectP != NULL)
- SWCheckIdleSpritesWithRects(spriteWorldP, headIdleSpriteP);
-
- // Call the postEraseCallBack
- if (spriteWorldP->postEraseCallBack != NULL)
- (*spriteWorldP->postEraseCallBack)(spriteWorldP);
-
-
- //-----------------draw the sprites--------------------
-
- curSpriteLayerP = spriteWorldP->headSpriteLayerP;
-
- // iterate through the layers in this world
- while (curSpriteLayerP != NULL)
- {
- curSpriteP = curSpriteLayerP->headSpriteP;
-
- // iterate through the sprites in this layer
- while (curSpriteP != NULL)
- {
- if (curSpriteP->isVisible)
- {
- if (curSpriteP->needsToBeDrawn)
- {
- gCurrentSpriteBeingDrawn = curSpriteP;
-
- // draw the sprite in the work area
- (*curSpriteP->frameDrawProc)(
- curSpriteP->curFrameP,
- spriteWorldP->workFrameP,
- &curSpriteP->curFrameP->frameRect,
- &curSpriteP->destFrameRect);
-
- gCurrentSpriteBeingDrawn = NULL;
-
- if (spriteWorldP->tilingIsOn &&
- curSpriteP->tileDepth <= spriteWorldP->lastActiveTileLayer)
- {
- screenDestRect = curSpriteP->destFrameRect;
-
- // Clip screenDestRect to visScrollRect
- if (screenDestRect.left < spriteWorldP->visScrollRect.left)
- screenDestRect.left = spriteWorldP->visScrollRect.left;
- if (screenDestRect.right > spriteWorldP->visScrollRect.right)
- screenDestRect.right = spriteWorldP->visScrollRect.right;
- if (screenDestRect.top < spriteWorldP->visScrollRect.top)
- screenDestRect.top = spriteWorldP->visScrollRect.top;
- if (screenDestRect.bottom > spriteWorldP->visScrollRect.bottom)
- screenDestRect.bottom = spriteWorldP->visScrollRect.bottom;
-
- SWDrawTilesAboveSprite(spriteWorldP, &screenDestRect, curSpriteP->tileDepth);
- }
- }
- else
- {
- SWCheckIdleSpriteOverlap(spriteWorldP, curSpriteP, headActiveSpriteP);
- }
- }
-
- curSpriteP = curSpriteP->nextSpriteP;
- }
-
- curSpriteLayerP = curSpriteLayerP->nextSpriteLayerP;
- }
-
-
- // Call the postDrawCallBack
- if (spriteWorldP->postDrawCallBack != NULL)
- (*spriteWorldP->postDrawCallBack)(spriteWorldP);
-
-
- //-----------------update the screen--------------------
-
- // the current port should be the one in which we are drawing
- SetGWorld(spriteWorldP->windowFrameP->framePort, nil);
-
- // wait for the VBL
- if ( spriteWorldP->usingVBL )
- {
- spriteWorldP->vblTaskRec.hasVBLFired = false;
- while ( !spriteWorldP->vblTaskRec.hasVBLFired )
- {}
- }
-
- curSpriteP = headActiveSpriteP;
-
- // Has a custom worldRect been used? (If so, sprites need offsetting)
- if (spriteWorldP->windRect.left || spriteWorldP->windRect.top)
- {
- // update flagged background rects
- curRectStructP = spriteWorldP->headUpdateRectP;
- while ( curRectStructP != NULL )
- {
- screenDestRect = curRectStructP->updateRect;
- screenDestRect.left += spriteWorldP->windRect.left;
- screenDestRect.right += spriteWorldP->windRect.left;
- screenDestRect.top += spriteWorldP->windRect.top;
- screenDestRect.bottom += spriteWorldP->windRect.top;
- (*spriteWorldP->screenDrawProc)(
- spriteWorldP->workFrameP,
- spriteWorldP->windowFrameP,
- &curRectStructP->updateRect,
- &screenDestRect);
- curRectStructP = curRectStructP->nextRectStructP;
- }
-
- // Update on screen the tiles that have changed
- changedRectP = spriteWorldP->changedTiles;
- for (index = 0; index < spriteWorldP->numTilesChanged; index++, changedRectP++)
- {
- screenDestRect = *changedRectP;
-
- // offset dest rect for screen
- screenDestRect.left += spriteWorldP->windRect.left;
- screenDestRect.right += spriteWorldP->windRect.left;
- screenDestRect.top += spriteWorldP->windRect.top;
- screenDestRect.bottom += spriteWorldP->windRect.top;
-
- (*spriteWorldP->screenDrawProc)(spriteWorldP->workFrameP,
- spriteWorldP->windowFrameP, changedRectP, &screenDestRect);
- }
-
-
- // update the sprites on the screen
- while (curSpriteP != NULL)
- {
- // offset the sprite's delta rect for the screen
- screenDestRect = curSpriteP->deltaFrameRect;
-
- screenDestRect.left += spriteWorldP->windRect.left;
- screenDestRect.right += spriteWorldP->windRect.left;
- screenDestRect.top += spriteWorldP->windRect.top;
- screenDestRect.bottom += spriteWorldP->windRect.top;
-
- (*spriteWorldP->screenDrawProc)(
- spriteWorldP->workFrameP,
- spriteWorldP->windowFrameP,
- &curSpriteP->deltaFrameRect,
- &screenDestRect);
-
-
- // set the delta and last rect to the current rect
- curSpriteP->deltaFrameRect = curSpriteP->destFrameRect;
- curSpriteP->oldFrameRect = curSpriteP->destFrameRect;
-
- // this sprite no longer needs to be drawn
- curSpriteP->needsToBeDrawn = false;
- curSpriteP->needsToBeErased = false;
-
- curSpriteP = curSpriteP->nextActiveSpriteP;
- }
- }
- else
- {
- // update flagged background rects
- curRectStructP = spriteWorldP->headUpdateRectP;
- while ( curRectStructP != NULL )
- {
- (*spriteWorldP->screenDrawProc)(
- spriteWorldP->workFrameP,
- spriteWorldP->windowFrameP,
- &curRectStructP->updateRect,
- &curRectStructP->updateRect);
- curRectStructP = curRectStructP->nextRectStructP;
- }
-
- // Update on screen the tiles that have changed
- changedRectP = spriteWorldP->changedTiles;
- for (index = 0; index < spriteWorldP->numTilesChanged; index++, changedRectP++)
- {
- (*spriteWorldP->screenDrawProc)(spriteWorldP->workFrameP,
- spriteWorldP->windowFrameP, changedRectP, changedRectP);
- }
-
-
- // update the sprites on the screen
- while (curSpriteP != NULL)
- {
- (*spriteWorldP->screenDrawProc)(
- spriteWorldP->workFrameP,
- spriteWorldP->windowFrameP,
- &curSpriteP->deltaFrameRect,
- &curSpriteP->deltaFrameRect);
-
-
- // set the delta and last rect to the current rect
- curSpriteP->deltaFrameRect = curSpriteP->destFrameRect;
- curSpriteP->oldFrameRect = curSpriteP->destFrameRect;
-
- // this sprite no longer needs to be drawn
- curSpriteP->needsToBeDrawn = false;
- curSpriteP->needsToBeErased = false;
-
- curSpriteP = curSpriteP->nextActiveSpriteP;
- }
- }
-
- // dispose of flagged background rects
- nextRectStructP = spriteWorldP->headUpdateRectP;
- while ( nextRectStructP != NULL )
- {
- curRectStructP = nextRectStructP;
- nextRectStructP = curRectStructP->nextRectStructP;
- DisposePtr( (Ptr)curRectStructP );
- }
- spriteWorldP->headUpdateRectP = NULL;
-
- spriteWorldP->numTilesChanged = 0;
-
- // Remove the deadSpriteLayer if we added it earlier.
- if ( spriteWorldP->deadSpriteLayerP->headSpriteP != NULL )
- {
- SWRemoveSpriteLayer(spriteWorldP, spriteWorldP->deadSpriteLayerP);
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWCheckIdleSpriteOverlap
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWCheckIdleSpriteOverlap(
- SpriteWorldPtr spriteWorldP,
- register SpritePtr idleSpriteP,
- SpritePtr headActiveSpriteP)
- {
- register SpritePtr activeSpriteP = headActiveSpriteP;
- Rect srcSectRect, dstSectRect;
-
- // iterate through the active sprites
- while (activeSpriteP != NULL)
- {
- // do the sprites overlap?
- if ((idleSpriteP->oldFrameRect.top < activeSpriteP->deltaFrameRect.bottom) &&
- (idleSpriteP->oldFrameRect.bottom > activeSpriteP->deltaFrameRect.top) &&
- (idleSpriteP->oldFrameRect.left < activeSpriteP->deltaFrameRect.right) &&
- (idleSpriteP->oldFrameRect.right > activeSpriteP->deltaFrameRect.left))
- {
- // calculate the intersection between the idle sprite's destination
- // rect, and the active sprite's delta rect
- dstSectRect.left =
- SW_MAX(idleSpriteP->destFrameRect.left, activeSpriteP->deltaFrameRect.left);
- dstSectRect.top =
- SW_MAX(idleSpriteP->destFrameRect.top, activeSpriteP->deltaFrameRect.top);
- dstSectRect.right =
- SW_MIN(idleSpriteP->destFrameRect.right, activeSpriteP->deltaFrameRect.right);
- dstSectRect.bottom =
- SW_MIN(idleSpriteP->destFrameRect.bottom, activeSpriteP->deltaFrameRect.bottom);
-
- srcSectRect = idleSpriteP->curFrameP->frameRect;
-
- srcSectRect.left += (dstSectRect.left - idleSpriteP->destFrameRect.left);
- srcSectRect.top += (dstSectRect.top - idleSpriteP->destFrameRect.top);
- srcSectRect.right -= (idleSpriteP->destFrameRect.right - dstSectRect.right);
- srcSectRect.bottom -= (idleSpriteP->destFrameRect.bottom - dstSectRect.bottom);
-
-
- // copy a piece of the sprite image onto the workFrame
-
- gCurrentSpriteBeingDrawn = idleSpriteP;
-
- (*idleSpriteP->frameDrawProc)(
- idleSpriteP->curFrameP,
- spriteWorldP->workFrameP,
- &srcSectRect,
- &dstSectRect);
-
-
- gCurrentSpriteBeingDrawn = NULL;
-
- if (spriteWorldP->tilingIsOn &&
- idleSpriteP->tileDepth <= spriteWorldP->lastActiveTileLayer)
- {
- // Clip dstSectRect to visScrollRect
- if (dstSectRect.left < spriteWorldP->visScrollRect.left)
- dstSectRect.left = spriteWorldP->visScrollRect.left;
- if (dstSectRect.right > spriteWorldP->visScrollRect.right)
- dstSectRect.right = spriteWorldP->visScrollRect.right;
- if (dstSectRect.top < spriteWorldP->visScrollRect.top)
- dstSectRect.top = spriteWorldP->visScrollRect.top;
- if (dstSectRect.bottom > spriteWorldP->visScrollRect.bottom)
- dstSectRect.bottom = spriteWorldP->visScrollRect.bottom;
-
- SWDrawTilesAboveSprite(spriteWorldP, &dstSectRect, idleSpriteP->tileDepth);
- }
- }
-
- activeSpriteP = activeSpriteP->nextActiveSpriteP;
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWCheckIdleSpritesWithTiles - redraw sprites erased by tiles that changed
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWCheckIdleSpritesWithTiles(
- SpriteWorldPtr spriteWorldP,
- SpritePtr headIdleSpriteP)
- {
- Rect srcSectRect, dstSectRect;
- register SpritePtr idleSpriteP;
- short srcHorizOffset;
- short srcVertOffset;
- Rect *changedRectP;
- short index;
-
-
- // Cycle through the changedTiles array of rects
- changedRectP = spriteWorldP->changedTiles;
- for (index = 0; index < spriteWorldP->numTilesChanged; index++, changedRectP++)
- {
- idleSpriteP = headIdleSpriteP;
-
- // iterate through the idle sprites
- while (idleSpriteP != NULL)
- {
- // does the idle sprite overlap the changedRect?
- if ((idleSpriteP->oldFrameRect.top < changedRectP->bottom) &&
- (idleSpriteP->oldFrameRect.bottom > changedRectP->top) &&
- (idleSpriteP->oldFrameRect.left < changedRectP->right) &&
- (idleSpriteP->oldFrameRect.right > changedRectP->left))
- {
- // calculate the intersection between the idle
- // sprite's rect and the changedRectP
- dstSectRect.left =
- SW_MAX(idleSpriteP->oldFrameRect.left, changedRectP->left);
- dstSectRect.top =
- SW_MAX(idleSpriteP->oldFrameRect.top, changedRectP->top);
- dstSectRect.right =
- SW_MIN(idleSpriteP->oldFrameRect.right, changedRectP->right);
- dstSectRect.bottom =
- SW_MIN(idleSpriteP->oldFrameRect.bottom, changedRectP->bottom);
-
- // Calculate the source rect
- srcSectRect = dstSectRect;
-
- srcHorizOffset = idleSpriteP->curFrameP->frameRect.left;
- srcVertOffset = idleSpriteP->curFrameP->frameRect.top;
-
- srcSectRect.left -= (idleSpriteP->oldFrameRect.left - srcHorizOffset);
- srcSectRect.right -= (idleSpriteP->oldFrameRect.left - srcHorizOffset);
- srcSectRect.top -= (idleSpriteP->oldFrameRect.top - srcVertOffset);
- srcSectRect.bottom -= (idleSpriteP->oldFrameRect.top - srcVertOffset);
-
- // Copy a piece of the sprite image onto the back drop piece
-
- gCurrentSpriteBeingDrawn = idleSpriteP;
-
- (*idleSpriteP->frameDrawProc)(
- idleSpriteP->curFrameP,
- spriteWorldP->workFrameP,
- &srcSectRect,
- &dstSectRect);
-
- gCurrentSpriteBeingDrawn = NULL;
-
- if (spriteWorldP->tilingIsOn &&
- idleSpriteP->tileDepth <= spriteWorldP->lastActiveTileLayer)
- {
- dstSectRect.top += spriteWorldP->vertScrollRectOffset;
- dstSectRect.bottom += spriteWorldP->vertScrollRectOffset;
- dstSectRect.left += spriteWorldP->horizScrollRectOffset;
- dstSectRect.right += spriteWorldP->horizScrollRectOffset;
- SWDrawTilesAboveSprite(spriteWorldP, &dstSectRect, idleSpriteP->tileDepth);
- }
- }
-
- idleSpriteP = idleSpriteP->nextIdleSpriteP;
- }
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWCheckIdleSpritesWithRects - redraw sprites erased by updateRects
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWCheckIdleSpritesWithRects(
- SpriteWorldPtr spriteWorldP,
- SpritePtr headIdleSpriteP)
- {
- UpdateRectStructPtr curRectStructP;
- register SpritePtr idleSpriteP;
- Rect srcSectRect, dstSectRect;
- short srcHorizOffset;
- short srcVertOffset;
- Rect *changedRectP;
-
-
- curRectStructP = spriteWorldP->headUpdateRectP;
-
- while (curRectStructP != NULL)
- {
- changedRectP = &curRectStructP->updateRect;
- idleSpriteP = headIdleSpriteP;
-
- // iterate through the idle sprites
- while (idleSpriteP != NULL)
- {
- // does the idle sprite overlap the changedRect?
- if ((idleSpriteP->oldFrameRect.top < changedRectP->bottom) &&
- (idleSpriteP->oldFrameRect.bottom > changedRectP->top) &&
- (idleSpriteP->oldFrameRect.left < changedRectP->right) &&
- (idleSpriteP->oldFrameRect.right > changedRectP->left))
- {
- // calculate the intersection between the idle
- // sprite's rect and the changedRectP
- dstSectRect.left =
- SW_MAX(idleSpriteP->oldFrameRect.left, changedRectP->left);
- dstSectRect.top =
- SW_MAX(idleSpriteP->oldFrameRect.top, changedRectP->top);
- dstSectRect.right =
- SW_MIN(idleSpriteP->oldFrameRect.right, changedRectP->right);
- dstSectRect.bottom =
- SW_MIN(idleSpriteP->oldFrameRect.bottom, changedRectP->bottom);
-
- // Calculate the source rect
- srcSectRect = dstSectRect;
-
- srcHorizOffset = idleSpriteP->curFrameP->frameRect.left;
- srcVertOffset = idleSpriteP->curFrameP->frameRect.top;
-
- srcSectRect.left -= (idleSpriteP->oldFrameRect.left - srcHorizOffset);
- srcSectRect.right -= (idleSpriteP->oldFrameRect.left - srcHorizOffset);
- srcSectRect.top -= (idleSpriteP->oldFrameRect.top - srcVertOffset);
- srcSectRect.bottom -= (idleSpriteP->oldFrameRect.top - srcVertOffset);
-
- // Copy a piece of the sprite image onto the back drop piece
-
- gCurrentSpriteBeingDrawn = idleSpriteP;
-
- (*idleSpriteP->frameDrawProc)(
- idleSpriteP->curFrameP,
- spriteWorldP->workFrameP,
- &srcSectRect,
- &dstSectRect);
-
- gCurrentSpriteBeingDrawn = NULL;
-
- if (spriteWorldP->tilingIsOn &&
- idleSpriteP->tileDepth <= spriteWorldP->lastActiveTileLayer)
- {
- dstSectRect.top += spriteWorldP->vertScrollRectOffset;
- dstSectRect.bottom += spriteWorldP->vertScrollRectOffset;
- dstSectRect.left += spriteWorldP->horizScrollRectOffset;
- dstSectRect.right += spriteWorldP->horizScrollRectOffset;
- SWDrawTilesAboveSprite(spriteWorldP, &dstSectRect, idleSpriteP->tileDepth);
- }
- }
-
- idleSpriteP = idleSpriteP->nextIdleSpriteP;
- }
-
- curRectStructP = curRectStructP->nextRectStructP;
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWFindSpritesToBeRemoved
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWFindSpritesToBeRemoved(
- SpriteWorldPtr spriteWorldP )
- {
- SpritePtr curSpriteP, nextSpriteP;
-
- curSpriteP = spriteWorldP->deadSpriteLayerP->headSpriteP;
-
- // iterate through the sprites in the deadSpriteLayerP
- while (curSpriteP != NULL)
- {
- nextSpriteP = curSpriteP->nextSpriteP;
-
- // all the Sprites here should need removing...
- SW_ASSERT(curSpriteP->spriteRemoval != kSWDontRemoveSprite);
-
- // has this sprite been erased by SWAnimate?
- if (curSpriteP->needsToBeErased == false)
- {
- // if so, we can safely remove it from its layer
- SWRemoveSprite(curSpriteP);
-
- // do we want to dispose of this sprite too?
- if (curSpriteP->spriteRemoval == kSWRemoveAndDisposeSprite)
- SWDisposeSprite(&curSpriteP);
- else
- curSpriteP->spriteRemoval = kSWDontRemoveSprite; // We're done
- }
-
- curSpriteP = nextSpriteP;
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWFlagRectAsChanged
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC OSErr SWFlagRectAsChanged(
- SpriteWorldPtr spriteWorldP,
- Rect* theChangedRect)
- {
- UpdateRectStructPtr curRectStructP,
- newUpdateRectP;
- short temp;
- OSErr err = noErr;
-
- // align the left edge to long word boundary
- theChangedRect->left &= (spriteWorldP->workFrameP->leftAlignFactor);
-
- // align the right edge to long word boundary
- temp = theChangedRect->right & spriteWorldP->workFrameP->rightAlignFactor;
- if (temp != 0)
- {
- theChangedRect->right += (spriteWorldP->workFrameP->rightAlignFactor + 1) - temp;
- }
-
- newUpdateRectP = (UpdateRectStructPtr)NewPtr(sizeof(UpdateRectStruct));
- if ( newUpdateRectP != NULL )
- {
- newUpdateRectP->updateRect = *theChangedRect;
- newUpdateRectP->nextRectStructP = NULL;
-
- if ( spriteWorldP->headUpdateRectP == NULL )
- {
- spriteWorldP->headUpdateRectP = newUpdateRectP;
- }
- else
- {
- curRectStructP = spriteWorldP->headUpdateRectP;
- while ( curRectStructP->nextRectStructP != NULL )
- {
- curRectStructP = curRectStructP->nextRectStructP;
- }
- curRectStructP->nextRectStructP = newUpdateRectP;
- }
- }
- else
- {
- err = MemError();
- }
-
- return err;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWFlagScrollingRectAsChanged - same as SWFlagRectAsChanged, minus alignment code
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC OSErr SWFlagScrollingRectAsChanged(
- SpriteWorldPtr spriteWorldP,
- Rect* theChangedRect)
- {
- UpdateRectStructPtr curRectStructP,
- newUpdateRectP;
- OSErr err = noErr;
-
-
- newUpdateRectP = (UpdateRectStructPtr)NewPtr(sizeof(UpdateRectStruct));
- if ( newUpdateRectP != NULL )
- {
- newUpdateRectP->updateRect = *theChangedRect;
- newUpdateRectP->nextRectStructP = NULL;
-
- if ( spriteWorldP->headUpdateRectP == NULL )
- {
- spriteWorldP->headUpdateRectP = newUpdateRectP;
- }
- else
- {
- curRectStructP = spriteWorldP->headUpdateRectP;
- while ( curRectStructP->nextRectStructP != NULL )
- {
- curRectStructP = curRectStructP->nextRectStructP;
- }
- curRectStructP->nextRectStructP = newUpdateRectP;
- }
- }
- else
- {
- err = MemError();
- }
-
- return err;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWSetSpriteWorldMaxFPS
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWSetSpriteWorldMaxFPS(
- SpriteWorldPtr spriteWorldP,
- short framesPerSec)
- {
- SW_ASSERT(spriteWorldP != NULL);
-
- // is framesPerSec a valid value?
- if (framesPerSec > 0 && framesPerSec <= 1000 )
- {
- spriteWorldP->fpsTimeInterval = 1000/framesPerSec;
- }
- // framesPerSec is an "ignore it" value.
- else
- {
- spriteWorldP->fpsTimeInterval = 0;
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWSyncSpriteWorldToVBL
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC OSErr SWSyncSpriteWorldToVBL(
- SpriteWorldPtr spriteWorldP,
- Boolean syncingOn)
- {
- OSErr err = noErr;
- AuxDCEHandle mainDCE;
-
- SW_ASSERT(spriteWorldP != NULL);
-
- if ( syncingOn )
- {
- if ( !spriteWorldP->usingVBL )
- {
- *((VBLUPP*)&spriteWorldP->vblTaskRec.myVBLTask.vblAddr) =
- NewVBLProc((ProcPtr)SWVBLTask);
- spriteWorldP->vblTaskRec.myVBLTask.qType = vType;
- spriteWorldP->vblTaskRec.myVBLTask.vblCount = 1;
- spriteWorldP->vblTaskRec.hasVBLFired = false;
-
- // insert the task into the VBL queue
- mainDCE = (AuxDCEHandle)GetDCtlEntry((**spriteWorldP->mainSWGDH).gdRefNum);
- err = SlotVInstall( (QElemPtr) &spriteWorldP->vblTaskRec.myVBLTask,
- (**mainDCE).dCtlSlot );
- if ( err == noErr )
- {
- spriteWorldP->usingVBL = true;
- }
- }
- }
- else
- {
- if ( spriteWorldP->usingVBL )
- {
- mainDCE = (AuxDCEHandle)GetDCtlEntry((**spriteWorldP->mainSWGDH).gdRefNum);
- err = SlotVRemove( (QElemPtr) &spriteWorldP->vblTaskRec.myVBLTask,
- (**mainDCE).dCtlSlot );
- spriteWorldP->vblTaskRec.hasVBLFired = true;
- spriteWorldP->usingVBL = false;
- DisposeRoutineDescriptor(spriteWorldP->vblTaskRec.myVBLTask.vblAddr);
- }
- }
-
- SWSetStickyIfError( err );
- return err;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWVBLTask
- ///--------------------------------------------------------------------------------------
-
- #if !GENERATINGCFM
- extern VBLTaskRecPtr GetVBLRec(void)
- = 0x2008; /* MOVE.L A0,D0 */
- #endif
-
- #if GENERATINGCFM
- void SWVBLTask(VBLTaskRecPtr vblTaskPtr)
- {
- vblTaskPtr->hasVBLFired = true;
-
- // Reset vblCount so that this procedure executes again
- vblTaskPtr->myVBLTask.vblCount = 1;
- }
- #else
- void SWVBLTask( void )
- {
- VBLTaskRecPtr vblTaskPtr;
-
- vblTaskPtr = (VBLTaskRecPtr) GetVBLRec();
- vblTaskPtr->hasVBLFired = true;
-
- // Reset vblCount so that this procedure executes again
- vblTaskPtr->myVBLTask.vblCount = 1;
- }
- #endif
-
-
- ///--------------------------------------------------------------------------------------
- // SWSetCleanUpSpriteWorld - call this if you want FatalError() or SWAssertFail() to call
- // SWSyncSpriteWorldToVBL with a value of false for your SpriteWorld before it calls
- // ExitToShell. You pass a pointer to the SpriteWorld you want to be "cleaned up".
- ///--------------------------------------------------------------------------------------
-
- void SWSetCleanUpSpriteWorld(SpriteWorldPtr spriteWorldP)
- {
- gCleanUpSpriteWorldP = spriteWorldP;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWGetSpriteWorldVersion
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC unsigned long SWGetSpriteWorldVersion(void)
- {
- return 0x02200000;
- }
-