home *** CD-ROM | disk | FTP | other *** search
Text File | 1999-01-12 | 32.4 KB | 966 lines | [TEXT/CWIE] |
- ///--------------------------------------------------------------------------------------
- // Multi-Screen Scrolling.c
- //
- // By Vern Jensen. Created 1/1/97
- ///--------------------------------------------------------------------------------------
-
-
- #ifndef __SPRITEWORLD__
- #include "SpriteWorld.h"
- #endif
-
- #ifndef __SPRITEWORLDUTILS__
- #include "SpriteWorldUtils.h"
- #endif
-
- #ifndef __SCROLLING__
- #include "Scrolling.h"
- #endif
-
- #ifndef __TILING__
- #include "Tiling.h"
- #endif
-
- #ifndef __MULTISCREENSCROLLING__
- #include "Multi-Screen Scrolling.h"
- #endif
-
-
- extern SpritePtr gCurrentSpriteBeingDrawn;
-
-
- ///--------------------------------------------------------------------------------------
- // SWSetUpDuplicateSpriteWorld
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWSetUpDuplicateSpriteWorld(
- SpriteWorldPtr masterSpriteWorldP,
- SpriteWorldPtr duplicateSpriteWorldP)
- {
- // Dispose the deadSpriteLayer of the duplicateSpriteWorldP
- SWDisposeSpriteLayer(&duplicateSpriteWorldP->deadSpriteLayerP);
-
- // Share SpriteLayers
- duplicateSpriteWorldP->headSpriteLayerP = masterSpriteWorldP->headSpriteLayerP;
- duplicateSpriteWorldP->tailSpriteLayerP = masterSpriteWorldP->tailSpriteLayerP;
- duplicateSpriteWorldP->deadSpriteLayerP = masterSpriteWorldP->deadSpriteLayerP;
-
- // Copy DrawProc info and scrollRectMoveBounds
- duplicateSpriteWorldP->offscreenDrawProc = masterSpriteWorldP->offscreenDrawProc;
- duplicateSpriteWorldP->screenDrawProc = masterSpriteWorldP->screenDrawProc;
- duplicateSpriteWorldP->doubleRectDrawProc = masterSpriteWorldP->doubleRectDrawProc;
- duplicateSpriteWorldP->scrollRectMoveBounds = masterSpriteWorldP->scrollRectMoveBounds;
-
- // Copy tiling stuff
- duplicateSpriteWorldP->extraBackFrameP = masterSpriteWorldP->extraBackFrameP;
- duplicateSpriteWorldP->tileLayerArray = masterSpriteWorldP->tileLayerArray;
- duplicateSpriteWorldP->lastActiveTileLayer = masterSpriteWorldP->lastActiveTileLayer;
- duplicateSpriteWorldP->tileRectDrawProc = masterSpriteWorldP->tileRectDrawProc;
- duplicateSpriteWorldP->tileFrameArray = masterSpriteWorldP->tileFrameArray;
- duplicateSpriteWorldP->curTileImage = masterSpriteWorldP->curTileImage;
- duplicateSpriteWorldP->maxNumTiles = masterSpriteWorldP->maxNumTiles;
- duplicateSpriteWorldP->tileWidth = masterSpriteWorldP->tileWidth;
- duplicateSpriteWorldP->tileHeight = masterSpriteWorldP->tileHeight;
- duplicateSpriteWorldP->tileMaskDrawProc = masterSpriteWorldP->tileMaskDrawProc;
- duplicateSpriteWorldP->partialMaskDrawProc = masterSpriteWorldP->partialMaskDrawProc;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWDisposeDuplicateSpriteWorld
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWDisposeDuplicateSpriteWorld(
- SpriteWorldPtr spriteWorldP)
- {
- if (spriteWorldP != NULL)
- {
- SWUnlockSpriteWorld(spriteWorldP);
-
- SWDisposeFrame(&spriteWorldP->backFrameP);
- SWDisposeFrame(&spriteWorldP->workFrameP);
- SWDisposeWindowFrame(&spriteWorldP->windowFrameP);
-
- SWExitTilingForDuplicateSpriteWorld(spriteWorldP);
- SWSyncSpriteWorldToVBL(spriteWorldP, false);
-
- DisposePtr((Ptr)spriteWorldP);
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWInitTilingForDuplicateSpriteWorld
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC OSErr SWInitTilingForDuplicateSpriteWorld(
- SpriteWorldPtr spriteWorldP,
- short tileHeight,
- short tileWidth)
- {
- OSErr err = noErr;
- Size arraySize;
- short row, col, numTilingCacheRows, numTilingCacheCols, *tilingCacheData;
-
-
- if (spriteWorldP->tilingIsInitialized)
- {
- err = kTilingAlreadyInitialized;
- }
-
-
- if (err == noErr)
- {
- spriteWorldP->tilingIsOn = true;
- spriteWorldP->tilingIsInitialized = true;
- spriteWorldP->tileHeight = tileHeight;
- spriteWorldP->tileWidth = tileWidth;
-
- numTilingCacheRows = spriteWorldP->backRect.bottom / tileHeight;
- numTilingCacheCols = spriteWorldP->backRect.right / tileWidth;
- spriteWorldP->numTilingCacheRows = numTilingCacheRows;
- spriteWorldP->numTilingCacheCols = numTilingCacheCols;
- }
-
-
- if (err == noErr)
- {
- // Allocate the array of pointers for the tiling Cache
- arraySize = (Size)numTilingCacheRows * sizeof(short*);
- spriteWorldP->tilingCache = (short **)NewPtr(arraySize);
- err = MemError();
-
- if (err == noErr)
- {
- // Allocate memory for the actual data of the tiling Cache
- arraySize = (Size)numTilingCacheRows * numTilingCacheCols * sizeof(short);
- tilingCacheData = (short *)NewPtr(arraySize);
- err = MemError();
-
- // If there was an error, dispose what we already created earlier
- if (err != noErr)
- DisposePtr((Ptr)spriteWorldP->tilingCache);
- }
-
- if (err == noErr)
- {
- // Point each element of the tilingCache array to each row of the data
- for (row = 0; row < numTilingCacheRows; row++)
- spriteWorldP->tilingCache[row] = &tilingCacheData[(long)row * numTilingCacheCols];
-
- // Set all elements to -1 (indicating that each tile needs to be drawn)
- for (row = 0; row < numTilingCacheRows; row++)
- for (col = 0; col < numTilingCacheCols; col++)
- spriteWorldP->tilingCache[row][col] = -1;
- }
- }
-
-
- if (err == noErr)
- {
- // Allocate memory for changedTiles array of rects
- spriteWorldP->changedTilesArraySize = (numTilingCacheRows+1) * (numTilingCacheCols+1);
- arraySize = (Size)(numTilingCacheRows+1) * (numTilingCacheCols+1) * sizeof(Rect);
- spriteWorldP->changedTiles = (Rect *)NewPtr(arraySize);
- err = MemError();
- }
-
-
- SWSetStickyIfError(err);
- return err;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWExitTilingForDuplicateSpriteWorld
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWExitTilingForDuplicateSpriteWorld(
- SpriteWorldPtr spriteWorldP)
- {
- // Was tiling ever initialized?
- if (spriteWorldP->tilingIsInitialized)
- {
- DisposePtr((Ptr)spriteWorldP->changedTiles);
- DisposePtr((Ptr)spriteWorldP->tilingCache[0]); // Dispose the data
- DisposePtr((Ptr)spriteWorldP->tilingCache); // Dispose the array of pointers
-
- spriteWorldP->tilingIsInitialized = false;
- spriteWorldP->tilingIsOn = false;
- }
- }
-
-
- #pragma mark -
- ///--------------------------------------------------------------------------------------
- // SWProcessMultiScreenSpriteWorld
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWProcessMultiScreenSpriteWorld(
- SpriteWorldPtr spriteWorldP)
- {
- // Call the scrolling world move proc
- if (spriteWorldP->worldMoveProc != NULL)
- {
- (*spriteWorldP->worldMoveProc)(spriteWorldP, spriteWorldP->followSpriteP);
- }
-
-
- // Move visScrollRect
- if (spriteWorldP->horizScrollDelta || spriteWorldP->vertScrollDelta)
- {
- SWOffsetVisScrollRect(spriteWorldP,
- spriteWorldP->horizScrollDelta,
- spriteWorldP->vertScrollDelta);
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWAnimateMultiScreenSpriteWorld. The only differences between this function
- // and the normal SWAnimateScrollingSpriteWorld are:
- // A) This function recalculates the oldOffscreenRect each frame, instead of using
- // the value that was stored in the sprite the previous frame.
- // B) The section of code directly below was added.
- // C) The code that assigns the destFrameRect to the oldFrameRect, etc. was moved to
- // SWFinishMultiScreenAnimation where applicable.
- // D) The code at the very beginning of this function that checks the frameHasOccurred
- // variable was removed, since the user has to do this for multi-screen animations.
- // E) The following variables were added to this function:
- // short oldVertScrollRectOffset, oldHorizScrollRectOffset;
- // F) The name was changed. :-)
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWAnimateMultiScreenSpriteWorld(
- 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 *visScrollRectP = &spriteWorldP->visScrollRect;
- Rect tempDstRect, tempSrcRect;
- short hScrollDelta, vScrollDelta, curTileLayer;
- short oldVertScrollRectOffset, oldHorizScrollRectOffset;
-
- SW_ASSERT(spriteWorldP != NULL);
- SW_ASSERT(spriteWorldP->backFrameP->isFrameLocked);
- SW_ASSERT(spriteWorldP->workFrameP->isFrameLocked);
- SW_ASSERT(spriteWorldP->windowFrameP->isFrameLocked);
-
- /////////////////////////////////////////////
- // The code below is new to this function. //
- /////////////////////////////////////////////
-
- oldVertScrollRectOffset = spriteWorldP->backRect.bottom *
- (spriteWorldP->oldVisScrollRect.top / spriteWorldP->backRect.bottom);
-
- oldHorizScrollRectOffset = spriteWorldP->backRect.right *
- (spriteWorldP->oldVisScrollRect.left / spriteWorldP->backRect.right);
-
- /////////////////////////////////////////////
-
-
- // Add the deadSpriteLayer if there are any Sprites in it.
- if ( spriteWorldP->deadSpriteLayerP->headSpriteP != NULL )
- {
- SWAddSpriteLayer(spriteWorldP, spriteWorldP->deadSpriteLayerP);
- }
-
-
- hScrollDelta = visScrollRectP->left - spriteWorldP->oldVisScrollRect.left;
- vScrollDelta = visScrollRectP->top - spriteWorldP->oldVisScrollRect.top;
-
-
- // Update tiles as we scroll if tiling is turned on
- if (spriteWorldP->tilingIsOn)
- {
- // VisScrollRect moved horizontally
- if (hScrollDelta)
- {
- // Get rect of new vertical section to update
- tempDstRect = *visScrollRectP;
-
- // Moved left
- if (hScrollDelta < 0)
- {
- if (tempDstRect.right > spriteWorldP->oldVisScrollRect.left)
- tempDstRect.right = spriteWorldP->oldVisScrollRect.left;
- }
- else // Moved right
- {
- if (tempDstRect.left < spriteWorldP->oldVisScrollRect.right)
- tempDstRect.left = spriteWorldP->oldVisScrollRect.right;
- }
-
- (*spriteWorldP->tileRectDrawProc)(spriteWorldP, &tempDstRect, true);
- SWWrapRectToWorkArea(spriteWorldP, &tempDstRect);
-
-
- // Did VisScrollRect moved diagonally?
- if (vScrollDelta)
- {
- // Get rect of new horizontal section to update
- tempDstRect = spriteWorldP->visScrollRect;
-
- // Moved up
- if (vScrollDelta < 0)
- {
- if (tempDstRect.bottom > spriteWorldP->oldVisScrollRect.top)
- tempDstRect.bottom = spriteWorldP->oldVisScrollRect.top;
- }
- else // Moved down
- {
- if (tempDstRect.top < spriteWorldP->oldVisScrollRect.bottom)
- tempDstRect.top = spriteWorldP->oldVisScrollRect.bottom;
- }
-
- // Clip off the part we've already updated
- if (hScrollDelta < 0)
- {
- if (tempDstRect.left < spriteWorldP->oldVisScrollRect.left)
- tempDstRect.left = spriteWorldP->oldVisScrollRect.left;
- }
- else
- {
- if (tempDstRect.right > spriteWorldP->oldVisScrollRect.right)
- tempDstRect.right = spriteWorldP->oldVisScrollRect.right;
- }
-
- // We pass false here to avoid a bug which occured in the
- // tile optimizing code when updating tiles twice in one frame
- if (tempDstRect.right > tempDstRect.left)
- {
- (*spriteWorldP->tileRectDrawProc)(spriteWorldP, &tempDstRect, false);
- SWWrapRectToWorkArea(spriteWorldP, &tempDstRect);
- }
- }
- } // VisScrollRect moved vertically only
- else if (vScrollDelta)
- {
- // Get rect of new horizontal section to update
- tempDstRect = *visScrollRectP;
-
- // Moved up
- if (vScrollDelta < 0)
- {
- if (tempDstRect.bottom > spriteWorldP->oldVisScrollRect.top)
- tempDstRect.bottom = spriteWorldP->oldVisScrollRect.top;
- }
- else // Moved down
- {
- if (tempDstRect.top < spriteWorldP->oldVisScrollRect.bottom)
- tempDstRect.top = spriteWorldP->oldVisScrollRect.bottom;
- }
-
- (*spriteWorldP->tileRectDrawProc)(spriteWorldP, &tempDstRect, true);
- SWWrapRectToWorkArea(spriteWorldP, &tempDstRect);
- }
- }
-
-
- //-----------------erase the sprites--------------------
-
- // Set the port to the work area so we can draw in it
- SetGWorld(spriteWorldP->workFrameP->framePort, nil);
-
- 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;
-
- // Clip the sprite's destOffscreenRect with visScrollRect.
- if (curSpriteP->isVisible)
- {
- curSpriteP->destOffscreenRect = curSpriteP->destFrameRect;
- curSpriteP->clippedSourceRect = curSpriteP->curFrameP->frameRect;
-
-
- if (curSpriteP->destOffscreenRect.top < visScrollRectP->top)
- {
- curSpriteP->clippedSourceRect.top += visScrollRectP->top -
- curSpriteP->destOffscreenRect.top;
- curSpriteP->destOffscreenRect.top = visScrollRectP->top;
- }
-
- if (curSpriteP->destOffscreenRect.bottom > visScrollRectP->bottom)
- {
- curSpriteP->clippedSourceRect.bottom += visScrollRectP->bottom -
- curSpriteP->destOffscreenRect.bottom;
- curSpriteP->destOffscreenRect.bottom = visScrollRectP->bottom;
- }
-
- if (curSpriteP->destOffscreenRect.left < visScrollRectP->left)
- {
- curSpriteP->clippedSourceRect.left += visScrollRectP->left -
- curSpriteP->destOffscreenRect.left;
- curSpriteP->destOffscreenRect.left = visScrollRectP->left;
- }
-
- if (curSpriteP->destOffscreenRect.right > visScrollRectP->right)
- {
- curSpriteP->clippedSourceRect.right += visScrollRectP->right -
- curSpriteP->destOffscreenRect.right;
- curSpriteP->destOffscreenRect.right = visScrollRectP->right;
- }
-
- curSpriteP->destRectIsVisible =
- (curSpriteP->destOffscreenRect.right >
- curSpriteP->destOffscreenRect.left &&
- curSpriteP->destOffscreenRect.bottom >
- curSpriteP->destOffscreenRect.top);
- }
-
-
-
- // Clip the sprite's oldOffscreenRect with oldVisScrollRect. This section
- // of code is the only difference between SWAnimateMultiScreenSpriteWorld
- // and SWAnimateScrollingSpriteWorld, besides destOffscreenRect not being
- // assigned to oldOffscreenRect at the end of this function, and some code
- // at the very beginning of this function.
-
- curSpriteP->oldOffscreenRect = curSpriteP->oldFrameRect;
-
- if (curSpriteP->oldOffscreenRect.top < spriteWorldP->oldVisScrollRect.top)
- curSpriteP->oldOffscreenRect.top = spriteWorldP->oldVisScrollRect.top;
-
- if (curSpriteP->oldOffscreenRect.bottom > spriteWorldP->oldVisScrollRect.bottom)
- curSpriteP->oldOffscreenRect.bottom = spriteWorldP->oldVisScrollRect.bottom;
-
- if (curSpriteP->oldOffscreenRect.left < spriteWorldP->oldVisScrollRect.left)
- curSpriteP->oldOffscreenRect.left = spriteWorldP->oldVisScrollRect.left;
-
- if (curSpriteP->oldOffscreenRect.right > spriteWorldP->oldVisScrollRect.right)
- curSpriteP->oldOffscreenRect.right = spriteWorldP->oldVisScrollRect.right;
-
- curSpriteP->oldRectIsVisible =
- (curSpriteP->oldOffscreenRect.right >
- curSpriteP->oldOffscreenRect.left &&
- curSpriteP->oldOffscreenRect.bottom >
- curSpriteP->oldOffscreenRect.top);
-
- // Make the sprite's rect local to the offscreen area
- curSpriteP->oldOffscreenRect.top -= oldVertScrollRectOffset;
- curSpriteP->oldOffscreenRect.bottom -= oldVertScrollRectOffset;
- curSpriteP->oldOffscreenRect.left -= oldHorizScrollRectOffset;
- curSpriteP->oldOffscreenRect.right -= oldHorizScrollRectOffset;
-
-
- /////////////////////////////////////////////////////////////////////////
-
-
-
-
-
- // Erase the sprites
- if (curSpriteP->needsToBeDrawn && curSpriteP->isVisible ||
- curSpriteP->needsToBeErased && !curSpriteP->isVisible)
- {
- // Was the sprite visible on the screen last frame?
- if (curSpriteP->oldRectIsVisible)
- {
- // Add sprite to active sprite list
- if (headActiveSpriteP == NULL)
- headActiveSpriteP = curSpriteP;
-
- if (curActiveSpriteP != NULL)
- curActiveSpriteP->nextActiveSpriteP = curSpriteP;
-
- curActiveSpriteP = curSpriteP;
-
- {
- short temp;
-
- // align left edge of oldOffscreenRect for erasing
- curSpriteP->oldOffscreenRect.left &=
- (spriteWorldP->workFrameP->leftAlignFactor);
-
- // align the right edge to long word boundary
- temp = curSpriteP->oldOffscreenRect.right &
- spriteWorldP->workFrameP->rightAlignFactor;
- if (temp != 0)
- {
- curSpriteP->oldOffscreenRect.right +=
- (spriteWorldP->workFrameP->rightAlignFactor + 1) - temp;
- }
-
- // align left edge of oldFrameRect - necessary for
- // deltaFrameRect below, used by idle sprite collision
- 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;
- }
- }
-
- // union last rect and current rect - this is necessary for
- // the proper redrawing of idle sprites
- 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);
-
-
- // Erase the sprite from the work area
- SWEraseWrappedSprite(spriteWorldP, &curSpriteP->oldOffscreenRect);
- }
- else if (curSpriteP->destRectIsVisible) // Sprite will be drawn
- {
- // Add sprite to active sprite list
- if (headActiveSpriteP == NULL)
- headActiveSpriteP = curSpriteP;
-
- if (curActiveSpriteP != NULL)
- curActiveSpriteP->nextActiveSpriteP = curSpriteP;
-
- curActiveSpriteP = curSpriteP;
- }
- }
- else if (curSpriteP->isVisible) // Visible, idle sprites
- {
- if (curSpriteP->oldRectIsVisible)
- {
- // Is idle sprite moving outside the visScrollRect?
- if ((hScrollDelta > 0 &&
- (curIdleSpriteP->destFrameRect.left < visScrollRectP->left) &&
- (curIdleSpriteP->destFrameRect.right > spriteWorldP->oldVisScrollRect.left)) ||
- (hScrollDelta < 0 &&
- (curIdleSpriteP->destFrameRect.left < spriteWorldP->oldVisScrollRect.right) &&
- (curIdleSpriteP->destFrameRect.right > visScrollRectP->right)) )
- {
- // Erase piece of idle sprite outside of visScrollRect
- tempDstRect = curSpriteP->oldFrameRect;
-
- // Get section of sprite outside visScrollRect
- if (hScrollDelta > 0)
- {
- if (tempDstRect.right > visScrollRectP->left)
- tempDstRect.right = visScrollRectP->left;
- }
- else
- {
- if (tempDstRect.left < visScrollRectP->right)
- tempDstRect.left = visScrollRectP->right;
- }
-
- // Clip tempDstRect with oldVisScrollRect
- if (tempDstRect.top < spriteWorldP->oldVisScrollRect.top)
- tempDstRect.top = spriteWorldP->oldVisScrollRect.top;
- if (tempDstRect.bottom > spriteWorldP->oldVisScrollRect.bottom)
- tempDstRect.bottom = spriteWorldP->oldVisScrollRect.bottom;
- if (tempDstRect.left < spriteWorldP->oldVisScrollRect.left)
- tempDstRect.left = spriteWorldP->oldVisScrollRect.left;
- if (tempDstRect.right > spriteWorldP->oldVisScrollRect.right)
- tempDstRect.right = spriteWorldP->oldVisScrollRect.right;
-
- // Make the rect local to the offscreen area
- tempDstRect.top -= spriteWorldP->vertScrollRectOffset;
- tempDstRect.bottom -= spriteWorldP->vertScrollRectOffset;
- tempDstRect.left -= spriteWorldP->horizScrollRectOffset;
- tempDstRect.right -= spriteWorldP->horizScrollRectOffset;
-
- SWEraseWrappedSprite(spriteWorldP, &tempDstRect);
- }
-
- // Is idle sprite moving outside the visScrollRect?
- if ((vScrollDelta > 0 &&
- (curIdleSpriteP->destFrameRect.top < visScrollRectP->top) &&
- (curIdleSpriteP->destFrameRect.bottom > spriteWorldP->oldVisScrollRect.top)) ||
- (vScrollDelta < 0 &&
- (curIdleSpriteP->destFrameRect.top < spriteWorldP->oldVisScrollRect.bottom) &&
- (curIdleSpriteP->destFrameRect.bottom > visScrollRectP->bottom)) )
- {
- // Erase piece of idle sprite outside of visScrollRect
- tempDstRect = curSpriteP->oldFrameRect;
-
- // Get section of sprite outside visScrollRect
- if (vScrollDelta > 0)
- {
- if (tempDstRect.bottom > visScrollRectP->top)
- tempDstRect.bottom = visScrollRectP->top;
- }
- else
- {
- if (tempDstRect.top < visScrollRectP->bottom)
- tempDstRect.top = visScrollRectP->bottom;
- }
-
- // Clip tempDstRect with oldVisScrollRect
- if (tempDstRect.top < spriteWorldP->oldVisScrollRect.top)
- tempDstRect.top = spriteWorldP->oldVisScrollRect.top;
- if (tempDstRect.bottom > spriteWorldP->oldVisScrollRect.bottom)
- tempDstRect.bottom = spriteWorldP->oldVisScrollRect.bottom;
- if (tempDstRect.left < spriteWorldP->oldVisScrollRect.left)
- tempDstRect.left = spriteWorldP->oldVisScrollRect.left;
- if (tempDstRect.right > spriteWorldP->oldVisScrollRect.right)
- tempDstRect.right = spriteWorldP->oldVisScrollRect.right;
-
- // Make the rect local to the offscreen area
- tempDstRect.top -= spriteWorldP->vertScrollRectOffset;
- tempDstRect.bottom -= spriteWorldP->vertScrollRectOffset;
- tempDstRect.left -= spriteWorldP->horizScrollRectOffset;
- tempDstRect.right -= spriteWorldP->horizScrollRectOffset;
-
- SWEraseWrappedSprite(spriteWorldP, &tempDstRect);
- }
- }
-
-
- // Is the idle sprite visible on the screen?
- if (curSpriteP->destRectIsVisible)
- {
- // 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;
-
-
-
- // This section of code iterates through the idle sprite list, drawing the tiny
- // sliver of any idle sprites that have just entered the visScrollRect.
- curIdleSpriteP = headIdleSpriteP;
- while (curIdleSpriteP != NULL)
- {
- // Draw vertical piece of idle sprite if it is coming into the visScrollRect.
- if ((vScrollDelta > 0 &&
- (curIdleSpriteP->destFrameRect.top < visScrollRectP->bottom) &&
- (curIdleSpriteP->destFrameRect.bottom > spriteWorldP->oldVisScrollRect.bottom) ) ||
- (vScrollDelta < 0 &&
- (curIdleSpriteP->destFrameRect.top < spriteWorldP->oldVisScrollRect.top) &&
- (curIdleSpriteP->destFrameRect.bottom > visScrollRectP->top)) )
- {
- tempDstRect = curIdleSpriteP->destOffscreenRect;
- tempSrcRect = curIdleSpriteP->clippedSourceRect;
-
- // Determine whether scrolling up or down, then get
- // section of sprite outside oldVisScrollRect.
- if (vScrollDelta < 0)
- {
- // Scrolling up, so get section above oldVisScrollRect
- if (tempDstRect.bottom > spriteWorldP->oldVisScrollRect.top)
- {
- tempSrcRect.bottom += spriteWorldP->oldVisScrollRect.top -
- tempDstRect.bottom;
- tempDstRect.bottom = spriteWorldP->oldVisScrollRect.top;
- }
- }
- else
- {
- // Scrolling down, so get section below oldVisScrollRect
- if (tempDstRect.top < spriteWorldP->oldVisScrollRect.bottom)
- {
- tempSrcRect.top += spriteWorldP->oldVisScrollRect.bottom -
- tempDstRect.top;
- tempDstRect.top = spriteWorldP->oldVisScrollRect.bottom;
- }
- }
-
- // Make the sprite's rect local to the offscreen area
- tempDstRect.top -= spriteWorldP->vertScrollRectOffset;
- tempDstRect.bottom -= spriteWorldP->vertScrollRectOffset;
- tempDstRect.left -= spriteWorldP->horizScrollRectOffset;
- tempDstRect.right -= spriteWorldP->horizScrollRectOffset;
-
- // Draw the sprite in the work area
- SWDrawWrappedSprite(curIdleSpriteP, spriteWorldP->workFrameP,
- &tempSrcRect, &tempDstRect);
-
- // Draw tiles above sprite
- if (spriteWorldP->tilingIsOn &&
- curIdleSpriteP->tileDepth <= spriteWorldP->lastActiveTileLayer)
- {
- tempDstRect.top += spriteWorldP->vertScrollRectOffset;
- tempDstRect.bottom += spriteWorldP->vertScrollRectOffset;
- tempDstRect.left += spriteWorldP->horizScrollRectOffset;
- tempDstRect.right += spriteWorldP->horizScrollRectOffset;
- SWDrawTilesAboveSprite(spriteWorldP, &tempDstRect, curIdleSpriteP->tileDepth);
- }
- }
-
-
- // Draw horizontal piece of idle sprite if it is coming into the visScrollRect.
- if ((hScrollDelta > 0 &&
- (curIdleSpriteP->destFrameRect.left < visScrollRectP->right) &&
- (curIdleSpriteP->destFrameRect.right > spriteWorldP->oldVisScrollRect.right) ) ||
- (hScrollDelta < 0 &&
- (curIdleSpriteP->destFrameRect.left < spriteWorldP->oldVisScrollRect.left) &&
- (curIdleSpriteP->destFrameRect.right > visScrollRectP->left)) )
- {
- tempDstRect = curIdleSpriteP->destOffscreenRect;
- tempSrcRect = curIdleSpriteP->clippedSourceRect;
-
- // Determine whether scrolling left or right, then get
- // section of sprite outside oldVisScrollRect.
- if (hScrollDelta < 0)
- {
- // Scrolling left, so get section to the left of oldVisScrollRect
- if (tempDstRect.right > spriteWorldP->oldVisScrollRect.left)
- {
- tempSrcRect.right += spriteWorldP->oldVisScrollRect.left -
- tempDstRect.right;
- tempDstRect.right = spriteWorldP->oldVisScrollRect.left;
- }
- }
- else
- {
- // Scrolling right, so get section to the right of oldVisScrollRect
- if (tempDstRect.left < spriteWorldP->oldVisScrollRect.right)
- {
- tempSrcRect.left += spriteWorldP->oldVisScrollRect.right -
- tempDstRect.left;
- tempDstRect.left = spriteWorldP->oldVisScrollRect.right;
- }
- }
-
-
- // Make the sprite's rect local to the offscreen area
- tempDstRect.top -= spriteWorldP->vertScrollRectOffset;
- tempDstRect.bottom -= spriteWorldP->vertScrollRectOffset;
- tempDstRect.left -= spriteWorldP->horizScrollRectOffset;
- tempDstRect.right -= spriteWorldP->horizScrollRectOffset;
-
- // Draw the sprite in the work area
- SWDrawWrappedSprite(curIdleSpriteP, spriteWorldP->workFrameP,
- &tempSrcRect, &tempDstRect);
-
- // Draw tiles above sprite
- if (spriteWorldP->tilingIsOn &&
- curIdleSpriteP->tileDepth <= spriteWorldP->lastActiveTileLayer)
- {
- tempDstRect.top += spriteWorldP->vertScrollRectOffset;
- tempDstRect.bottom += spriteWorldP->vertScrollRectOffset;
- tempDstRect.left += spriteWorldP->horizScrollRectOffset;
- tempDstRect.right += spriteWorldP->horizScrollRectOffset;
- SWDrawTilesAboveSprite(spriteWorldP, &tempDstRect, curIdleSpriteP->tileDepth);
- }
- }
-
- curIdleSpriteP = curIdleSpriteP->nextIdleSpriteP;
- }
-
-
- // update flagged background rects
- curRectStructP = spriteWorldP->headUpdateRectP;
- while ( curRectStructP != NULL )
- {
- tempDstRect = curRectStructP->updateRect;
-
- // Make the rect local to the offscreen area
- tempDstRect.top -= spriteWorldP->vertScrollRectOffset;
- tempDstRect.bottom -= spriteWorldP->vertScrollRectOffset;
- tempDstRect.left -= spriteWorldP->horizScrollRectOffset;
- tempDstRect.right -= spriteWorldP->horizScrollRectOffset;
-
- // We're not really erasing a sprite, just copying while wrapping
- SWEraseWrappedSprite(spriteWorldP, &tempDstRect);
- curRectStructP = curRectStructP->nextRectStructP;
- }
-
- // Redraw idle sprites that were erased by a tile
- if (spriteWorldP->numTilesChanged > 0)
- SWCheckWrappedIdleSpritesWithTiles(spriteWorldP, headIdleSpriteP);
-
- // Redraw idle sprites that were erased by an updateRect
- if (spriteWorldP->headUpdateRectP != NULL)
- SWCheckWrappedIdleSpritesWithRects(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)
- {
- // Make the sprite's rect local to the offscreen area
- curSpriteP->destOffscreenRect.top -= spriteWorldP->vertScrollRectOffset;
- curSpriteP->destOffscreenRect.bottom -= spriteWorldP->vertScrollRectOffset;
- curSpriteP->destOffscreenRect.left -= spriteWorldP->horizScrollRectOffset;
- curSpriteP->destOffscreenRect.right -= spriteWorldP->horizScrollRectOffset;
-
- if (curSpriteP->needsToBeDrawn)
- {
- // Is the sprite visible on the screen?
- if (curSpriteP->destRectIsVisible)
- {
- gCurrentSpriteBeingDrawn = curSpriteP;
-
- // Draw the sprite in the work area
- SWDrawWrappedSprite(curSpriteP, spriteWorldP->workFrameP,
- &curSpriteP->clippedSourceRect,
- &curSpriteP->destOffscreenRect);
-
- gCurrentSpriteBeingDrawn = NULL;
-
- // Draw tiles above sprite
- if (spriteWorldP->tilingIsOn &&
- curSpriteP->tileDepth <= spriteWorldP->lastActiveTileLayer)
- {
- tempDstRect = curSpriteP->destOffscreenRect;
- tempDstRect.top += spriteWorldP->vertScrollRectOffset;
- tempDstRect.bottom += spriteWorldP->vertScrollRectOffset;
- tempDstRect.left += spriteWorldP->horizScrollRectOffset;
- tempDstRect.right += spriteWorldP->horizScrollRectOffset;
- SWDrawTilesAboveSprite(spriteWorldP, &tempDstRect, curSpriteP->tileDepth);
- }
- }
- }
- else
- {
- // Is the idle sprite visible on the screen?
- if (curSpriteP->destRectIsVisible)
- {
- SWCheckWrappedIdleSpriteOverlap(spriteWorldP,
- curSpriteP, headActiveSpriteP);
- }
- }
- }
-
-
- ///
- // This is where a lot of code was removed.
- // (most of it moved to SWFinishMultiScreenAnimation)
- ///
-
-
- curSpriteP = curSpriteP->nextSpriteP;
- }
-
- curSpriteLayerP = curSpriteLayerP->nextSpriteLayerP;
- }
-
- spriteWorldP->oldVisScrollRect = spriteWorldP->visScrollRect;
-
-
- // Call the postDrawCallBack
- if (spriteWorldP->postDrawCallBack != NULL)
- (*spriteWorldP->postDrawCallBack)(spriteWorldP);
-
-
- //-----------------update the screen--------------------
-
- // Set the port to the window
- SetGWorld(spriteWorldP->windowFrameP->framePort, nil);
-
- if (spriteWorldP->usingVBL)
- {
- spriteWorldP->vblTaskRec.hasVBLFired = false;
- while ( !spriteWorldP->vblTaskRec.hasVBLFired )
- {}
- }
-
- // Copy offscreen area to screen while wrapping
- SWWrapWorldToScreen(spriteWorldP);
-
-
- // 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);
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWFinishMultiScreenAnimation
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWFinishMultiScreenAnimation(
- SpriteWorldPtr spriteWorldP)
- {
- register SpriteLayerPtr curSpriteLayerP;
- register SpritePtr curSpriteP;
-
-
- 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)
- {
- // Set last rect to current rect
- curSpriteP->oldFrameRect = curSpriteP->destFrameRect;
-
- curSpriteP->needsToBeDrawn = false;
- curSpriteP->needsToBeErased = false;
-
- curSpriteP = curSpriteP->nextSpriteP;
- }
-
- curSpriteLayerP = curSpriteLayerP->nextSpriteLayerP;
- }
- }
-
-