home *** CD-ROM | disk | FTP | other *** search
Text File | 1999-01-12 | 86.0 KB | 2,675 lines | [TEXT/CWIE] |
- ///--------------------------------------------------------------------------------------
- // Scrolling.c
- //
- // By: Vern Jensen
- //
- // Created: 8/29/95
- //
- // Description: Routines for making fast scrolling games with SpriteWorld
- ///--------------------------------------------------------------------------------------
-
-
-
- #ifndef __QUICKDRAW__
- #include <QuickDraw.h>
- #endif
-
- #ifndef __MEMORY__
- #include <Memory.h>
- #endif
-
- #ifndef __GESTALT__
- #include <Gestalt.h>
- #endif
-
- #ifndef __SPRITEWORLD__
- #include "SpriteWorld.h"
- #endif
-
- #ifndef __SPRITEWORLDUTILS__
- #include "SpriteWorldUtils.h"
- #endif
-
- #ifndef __BLITPIXIE__
- #include "BlitPixie.h"
- #endif
-
- #ifndef __SCROLLING__
- #include "Scrolling.h"
- #endif
-
- #ifndef __TILING__
- #include "Tiling.h"
- #endif
-
-
- extern SpritePtr gCurrentSpriteBeingDrawn;
-
-
- ///--------------------------------------------------------------------------------------
- // SWUpdateScrollingWindow
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWUpdateScrollingWindow(
- 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);
-
- if ( spriteWorldP->usingVBL )
- {
- spriteWorldP->vblTaskRec.hasVBLFired = false;
- while ( !spriteWorldP->vblTaskRec.hasVBLFired )
- {}
- }
-
- // Copy visScrollRect to window
- SWWrapWorldToScreen(spriteWorldP);
-
- SetGWorld( holdGWorld, holdGDH );
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWUpdateScrollingSpriteWorld - should be called at the beginning of
- // a scrolling animation, so that idle sprites are set up correctly.
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWUpdateScrollingSpriteWorld(
- SpriteWorldPtr spriteWorldP,
- Boolean updateWindow)
- {
- UpdateRectStructPtr curRectStructP,
- nextRectStructP;
- register SpriteLayerPtr curSpriteLayerP;
- register SpritePtr curSpriteP;
- short curTileLayer;
- Rect *visScrollRectP = &spriteWorldP->visScrollRect;
- Rect srcFrameRect, tempDstRect;
- GWorldPtr saveGWorld;
- GDHandle saveGDH;
-
- SW_ASSERT(spriteWorldP != NULL);
- SW_ASSERT(spriteWorldP->backFrameP->isFrameLocked);
- SW_ASSERT(spriteWorldP->workFrameP->isFrameLocked);
- SW_ASSERT(spriteWorldP->windowFrameP->isFrameLocked);
-
- GetGWorld( &saveGWorld, &saveGDH );
-
- // 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)
- {
- curSpriteP->destOffscreenRect = curSpriteP->destFrameRect;
- srcFrameRect = curSpriteP->curFrameP->frameRect;
-
-
- // Clip the sprite's destOffscreenRect with visScrollRect
- // We use the destOffscreenRect both for drawing and erasing later
- if (curSpriteP->destOffscreenRect.top < visScrollRectP->top)
- {
- srcFrameRect.top += visScrollRectP->top -
- curSpriteP->destOffscreenRect.top;
- curSpriteP->destOffscreenRect.top = visScrollRectP->top;
- }
-
- if (curSpriteP->destOffscreenRect.bottom > visScrollRectP->bottom)
- {
- srcFrameRect.bottom += visScrollRectP->bottom -
- curSpriteP->destOffscreenRect.bottom;
- curSpriteP->destOffscreenRect.bottom = visScrollRectP->bottom;
- }
-
- if (curSpriteP->destOffscreenRect.left < visScrollRectP->left)
- {
- srcFrameRect.left += visScrollRectP->left -
- curSpriteP->destOffscreenRect.left;
- curSpriteP->destOffscreenRect.left = visScrollRectP->left;
- }
-
- if (curSpriteP->destOffscreenRect.right > visScrollRectP->right)
- {
- srcFrameRect.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) );
-
-
- // Is sprite visible on the screen?
- if (curSpriteP->destRectIsVisible)
- {
- // 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;
-
- gCurrentSpriteBeingDrawn = curSpriteP;
-
- // Draw the sprite in the work area
- SWDrawWrappedSprite(curSpriteP, spriteWorldP->workFrameP,
- &srcFrameRect, &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);
- }
- }
- }
-
- // Set last rect to current rect
- curSpriteP->oldFrameRect = curSpriteP->destFrameRect;
- curSpriteP->oldOffscreenRect = curSpriteP->destOffscreenRect;
- curSpriteP->oldRectIsVisible = curSpriteP->destRectIsVisible;
-
- curSpriteP->needsToBeDrawn = false;
- curSpriteP->needsToBeErased = false;
-
- curSpriteP = curSpriteP->nextSpriteP;
- }
-
- curSpriteLayerP = curSpriteLayerP->nextSpriteLayerP;
- }
-
- spriteWorldP->oldVisScrollRect = spriteWorldP->visScrollRect;
-
-
- // Call the postDrawCallBack
- if (spriteWorldP->postDrawCallBack != NULL)
- (*spriteWorldP->postDrawCallBack)(spriteWorldP);
-
-
- // Copy the work area to the window
- if (updateWindow)
- {
- SetGWorld(spriteWorldP->windowFrameP->framePort, nil);
-
- if (spriteWorldP->usingVBL)
- {
- spriteWorldP->vblTaskRec.hasVBLFired = false;
- while ( !spriteWorldP->vblTaskRec.hasVBLFired )
- {}
- }
-
- // Copy visScrollRect to window
- 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;
-
- SetGWorld( saveGWorld, saveGDH );
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWProcessScrollingSpriteWorld
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWProcessScrollingSpriteWorld(
- SpriteWorldPtr spriteWorldP)
- {
-
- // Process the sprites
- SWProcessSpriteWorld(spriteWorldP);
- if ( !spriteWorldP->frameHasOccurred )
- {
- return;
- }
-
-
- // 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);
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWAnimateScrollingSpriteWorld
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWAnimateScrollingSpriteWorld(
- 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;
-
- SW_ASSERT(spriteWorldP != NULL);
- SW_ASSERT(spriteWorldP->backFrameP->isFrameLocked);
- SW_ASSERT(spriteWorldP->workFrameP->isFrameLocked);
- SW_ASSERT(spriteWorldP->windowFrameP->isFrameLocked);
-
- if (!spriteWorldP->frameHasOccurred)
- return;
-
-
- hScrollDelta = visScrollRectP->left - spriteWorldP->oldVisScrollRect.left;
- vScrollDelta = visScrollRectP->top - spriteWorldP->oldVisScrollRect.top;
-
-
- // Add the deadSpriteLayer if there are any Sprites in it.
- if ( spriteWorldP->deadSpriteLayerP->headSpriteP != NULL )
- {
- SWAddSpriteLayer(spriteWorldP, spriteWorldP->deadSpriteLayerP);
- }
-
-
- // 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);
- }
-
-
- // 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 &&
- (curSpriteP->destFrameRect.left < visScrollRectP->left) &&
- (curSpriteP->destFrameRect.right > spriteWorldP->oldVisScrollRect.left)) ||
- (hScrollDelta < 0 &&
- (curSpriteP->destFrameRect.left < spriteWorldP->oldVisScrollRect.right) &&
- (curSpriteP->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 &&
- (curSpriteP->destFrameRect.top < visScrollRectP->top) &&
- (curSpriteP->destFrameRect.bottom > spriteWorldP->oldVisScrollRect.top)) ||
- (vScrollDelta < 0 &&
- (curSpriteP->destFrameRect.top < spriteWorldP->oldVisScrollRect.bottom) &&
- (curSpriteP->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);
- }
- }
- }
-
- // Set last rect to current rect
- curSpriteP->oldFrameRect = curSpriteP->destFrameRect;
- curSpriteP->oldOffscreenRect = curSpriteP->destOffscreenRect;
- curSpriteP->oldRectIsVisible = curSpriteP->destRectIsVisible;
-
- curSpriteP->needsToBeDrawn = false;
- curSpriteP->needsToBeErased = false;
-
- 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);
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWFastAnimateScrollingSpriteWorld - essentially the same as SWAnimateScrollingSpriteWorld,
- // except that this only updates that sprites/tiles that have moved or changed, by calling
- // SWWrapRectToScreen. All code that handles updating tiles/sprites while scrolling has
- // been removed. (Three parts: the part that draws new tiles, the part that erases idle
- // sprites leaving the visScrollRect, and the part that draws idle sprites entering it.)
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWFastAnimateScrollingSpriteWorld(
- 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;
- Rect *changedRectP;
- short hScrollDelta, vScrollDelta, curTileLayer, index;
-
- SW_ASSERT(spriteWorldP != NULL);
- SW_ASSERT(spriteWorldP->backFrameP->isFrameLocked);
- SW_ASSERT(spriteWorldP->workFrameP->isFrameLocked);
- SW_ASSERT(spriteWorldP->windowFrameP->isFrameLocked);
-
- if (!spriteWorldP->frameHasOccurred)
- return;
-
-
- hScrollDelta = visScrollRectP->left - spriteWorldP->oldVisScrollRect.left;
- vScrollDelta = visScrollRectP->top - spriteWorldP->oldVisScrollRect.top;
- if (hScrollDelta || vScrollDelta)
- {
- // We let this function do everything when scrolling
- SWAnimateScrollingSpriteWorld(spriteWorldP);
- return;
- }
-
-
- // Add the deadSpriteLayer if there are any Sprites in it.
- if ( spriteWorldP->deadSpriteLayerP->headSpriteP != NULL )
- {
- SWAddSpriteLayer(spriteWorldP, spriteWorldP->deadSpriteLayerP);
- }
-
-
- //-----------------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);
- }
-
-
- // 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
- {
- // 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;
-
-
- // 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);
- }
- }
- }
-
- // Set last rect to current rect
- curSpriteP->oldFrameRect = curSpriteP->destFrameRect;
- curSpriteP->oldOffscreenRect = curSpriteP->destOffscreenRect;
- curSpriteP->oldRectIsVisible = curSpriteP->destRectIsVisible;
-
- curSpriteP->needsToBeDrawn = false;
- curSpriteP->needsToBeErased = false;
-
- 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 )
- {}
- }
-
-
- //
- /// --------------BEGIN NEW CODE---------------
- //
-
-
- // update flagged background rects
- curRectStructP = spriteWorldP->headUpdateRectP;
- while ( curRectStructP != NULL )
- {
- SWWrapRectToScreen(spriteWorldP, &curRectStructP->updateRect);
- curRectStructP = curRectStructP->nextRectStructP;
- }
-
- // Update on screen the tiles that have changed
- changedRectP = spriteWorldP->changedTiles;
- for (index = 0; index < spriteWorldP->numTilesChanged; index++, changedRectP++)
- {
- SWWrapRectToScreen(spriteWorldP, changedRectP);
- }
-
-
- // update the sprites on the screen
- curSpriteP = headActiveSpriteP;
- while (curSpriteP != NULL)
- {
- SWWrapRectToScreen(spriteWorldP, &curSpriteP->deltaFrameRect);
- curSpriteP->deltaFrameRect = curSpriteP->destFrameRect;
- curSpriteP = curSpriteP->nextActiveSpriteP;
- }
-
- //
- /// --------------END NEW CODE---------------
- //
-
-
- // 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);
- }
- }
-
-
- #pragma mark -
- ///--------------------------------------------------------------------------------------
- // SWDrawWrappedSprite - wraps image in dest area. For drawing sprites, not erasing,
- // since source rect stays the same.
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWDrawWrappedSprite(
- SpritePtr srcSpriteP,
- FramePtr dstFrameP,
- Rect* srcRect,
- Rect* dstRect)
- {
- Rect tempDstRect;
-
-
- // Draw main image //
- (*srcSpriteP->frameDrawProc)(srcSpriteP->curFrameP, dstFrameP, srcRect, dstRect);
-
-
- // Wrap to top //
- if (dstRect->bottom > dstFrameP->frameRect.bottom)
- {
- tempDstRect.top = dstRect->top - dstFrameP->frameRect.bottom;
- tempDstRect.bottom = dstRect->bottom - dstFrameP->frameRect.bottom;
- tempDstRect.left = dstRect->left;
- tempDstRect.right = dstRect->right;
-
- (*srcSpriteP->frameDrawProc)(srcSpriteP->curFrameP, dstFrameP,
- srcRect, &tempDstRect);
-
-
- // Wrap to upper left or right corner //
- if (dstRect->right > dstFrameP->frameRect.right)
- {
- tempDstRect.left -= dstFrameP->frameRect.right;
- tempDstRect.right -= dstFrameP->frameRect.right;
-
- (*srcSpriteP->frameDrawProc)(srcSpriteP->curFrameP, dstFrameP,
- srcRect, &tempDstRect);
- }
- else if (dstRect->left < dstFrameP->frameRect.left)
- {
- tempDstRect.left += dstFrameP->frameRect.right;
- tempDstRect.right += dstFrameP->frameRect.right;
-
- (*srcSpriteP->frameDrawProc)(srcSpriteP->curFrameP, dstFrameP,
- srcRect, &tempDstRect);
- }
- }
-
- // Wrap to left or right side //
- if (dstRect->right > dstFrameP->frameRect.right)
- {
- tempDstRect.top = dstRect->top;
- tempDstRect.bottom = dstRect->bottom;
- tempDstRect.left = dstRect->left - dstFrameP->frameRect.right;
- tempDstRect.right = dstRect->right - dstFrameP->frameRect.right;
-
- (*srcSpriteP->frameDrawProc)(srcSpriteP->curFrameP, dstFrameP,
- srcRect, &tempDstRect);
- }
- else if (dstRect->left < dstFrameP->frameRect.left)
- {
- tempDstRect.top = dstRect->top;
- tempDstRect.bottom = dstRect->bottom;
- tempDstRect.left = dstRect->left + dstFrameP->frameRect.right;
- tempDstRect.right = dstRect->right + dstFrameP->frameRect.right;
-
- (*srcSpriteP->frameDrawProc)(srcSpriteP->curFrameP, dstFrameP,
- srcRect, &tempDstRect);
- }
-
-
- // Wrap to bottom //
- if (dstRect->top < dstFrameP->frameRect.top)
- {
- tempDstRect.top = dstRect->top + dstFrameP->frameRect.bottom;
- tempDstRect.bottom = dstRect->bottom + dstFrameP->frameRect.bottom;
- tempDstRect.left = dstRect->left;
- tempDstRect.right = dstRect->right;
-
- (*srcSpriteP->frameDrawProc)(srcSpriteP->curFrameP, dstFrameP,
- srcRect, &tempDstRect);
-
- // Wrap to lower left or right corner //
- if (dstRect->right > dstFrameP->frameRect.right)
- {
- tempDstRect.left -= dstFrameP->frameRect.right;
- tempDstRect.right -= dstFrameP->frameRect.right;
-
- (*srcSpriteP->frameDrawProc)(srcSpriteP->curFrameP, dstFrameP,
- srcRect, &tempDstRect);
- }
- else if (dstRect->left < dstFrameP->frameRect.left)
- {
- tempDstRect.left += dstFrameP->frameRect.right;
- tempDstRect.right += dstFrameP->frameRect.right;
-
- (*srcSpriteP->frameDrawProc)(srcSpriteP->curFrameP, dstFrameP,
- srcRect, &tempDstRect);
- }
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWEraseWrappedSprite - erases a wrapped sprite from the work area
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWEraseWrappedSprite(
- SpriteWorldPtr spriteWorldP,
- Rect* dstRect)
- {
- Rect tempDstRect;
- FramePtr srcFrameP = spriteWorldP->backFrameP;
- FramePtr dstFrameP = spriteWorldP->workFrameP;
-
-
- // Draw main image //
- (*spriteWorldP->offscreenDrawProc)(srcFrameP, dstFrameP, dstRect, dstRect);
-
-
- // Wrap to top //
- if (dstRect->bottom > dstFrameP->frameRect.bottom)
- {
- tempDstRect.top = dstRect->top - dstFrameP->frameRect.bottom;
- tempDstRect.bottom = dstRect->bottom - dstFrameP->frameRect.bottom;
- tempDstRect.left = dstRect->left;
- tempDstRect.right = dstRect->right;
-
- (*spriteWorldP->offscreenDrawProc)(srcFrameP, dstFrameP,
- &tempDstRect, &tempDstRect);
-
- // Wrap to upper left or right corner //
- if (dstRect->right > dstFrameP->frameRect.right)
- {
- tempDstRect.left -= dstFrameP->frameRect.right;
- tempDstRect.right -= dstFrameP->frameRect.right;
-
- (*spriteWorldP->offscreenDrawProc)(srcFrameP, dstFrameP,
- &tempDstRect, &tempDstRect);
- }
- else if (dstRect->left < dstFrameP->frameRect.left)
- {
- tempDstRect.left += dstFrameP->frameRect.right;
- tempDstRect.right += dstFrameP->frameRect.right;
-
- (*spriteWorldP->offscreenDrawProc)(srcFrameP, dstFrameP,
- &tempDstRect, &tempDstRect);
- }
- }
-
- // Wrap to left or right side //
- if (dstRect->right > dstFrameP->frameRect.right)
- {
- tempDstRect.top = dstRect->top;
- tempDstRect.bottom = dstRect->bottom;
- tempDstRect.left = dstRect->left - dstFrameP->frameRect.right;
- tempDstRect.right = dstRect->right - dstFrameP->frameRect.right;
-
- (*spriteWorldP->offscreenDrawProc)(srcFrameP, dstFrameP,
- &tempDstRect, &tempDstRect);
- }
- else if (dstRect->left < dstFrameP->frameRect.left)
- {
- tempDstRect.top = dstRect->top;
- tempDstRect.bottom = dstRect->bottom;
- tempDstRect.left = dstRect->left + dstFrameP->frameRect.right;
- tempDstRect.right = dstRect->right + dstFrameP->frameRect.right;
-
- (*spriteWorldP->offscreenDrawProc)(srcFrameP, dstFrameP,
- &tempDstRect, &tempDstRect);
- }
-
-
- // Wrap to bottom //
- if (dstRect->top < dstFrameP->frameRect.top)
- {
- tempDstRect.top = dstRect->top + dstFrameP->frameRect.bottom;
- tempDstRect.bottom = dstRect->bottom + dstFrameP->frameRect.bottom;
- tempDstRect.left = dstRect->left;
- tempDstRect.right = dstRect->right;
-
- (*spriteWorldP->offscreenDrawProc)(srcFrameP, dstFrameP,
- &tempDstRect, &tempDstRect);
-
- // Wrap to lower left or right corner //
- if (dstRect->right > dstFrameP->frameRect.right)
- {
- tempDstRect.left -= dstFrameP->frameRect.right;
- tempDstRect.right -= dstFrameP->frameRect.right;
-
- (*spriteWorldP->offscreenDrawProc)(srcFrameP, dstFrameP,
- &tempDstRect, &tempDstRect);
- }
- else if (dstRect->left < dstFrameP->frameRect.left)
- {
- tempDstRect.left += dstFrameP->frameRect.right;
- tempDstRect.right += dstFrameP->frameRect.right;
-
- (*spriteWorldP->offscreenDrawProc)(srcFrameP, dstFrameP,
- &tempDstRect, &tempDstRect);
- }
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWWrapWorldToScreen - copy source rect to dest rect. Assumes they are the same
- // size, and that dstRect will fit within the bounds of the dstFrameP. Used for
- // copying the work area to the screen, with the ability of "wrapping" the source
- // rect around the work area.
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWWrapWorldToScreen(
- SpriteWorldPtr spriteWorldP)
- {
- FramePtr srcFrameP = spriteWorldP->workFrameP;
- FramePtr dstFrameP = spriteWorldP->windowFrameP;
-
- // We can always add code to clip dstRect later if we want.
- // Just make sure to clip it before clipping srcRect.
- Rect srcRect = spriteWorldP->offscreenScrollRect;
- Rect dstRect = spriteWorldP->windRect;
- Rect srcRectA, srcRectB, dstRectA, dstRectB;
-
- // Size of area that was clipped in source rect
- short topClip=0, rightClip=0, bottomClip=0, leftClip=0;
-
-
- // Clip the source rect, and save what we clipped for wrapping later //
-
- // clip off the top
- if (srcRect.top < srcFrameP->frameRect.top)
- {
- topClip = srcFrameP->frameRect.top - srcRect.top;
- srcRect.top += topClip;
- }
-
- // clip off the bottom
- if (srcRect.bottom > srcFrameP->frameRect.bottom)
- {
- bottomClip = srcRect.bottom - srcFrameP->frameRect.bottom;
- srcRect.bottom -= bottomClip;
- }
-
- // clip off the left
- if (srcRect.left < srcFrameP->frameRect.left)
- {
- leftClip = srcFrameP->frameRect.left - srcRect.left;
- srcRect.left += leftClip;
- }
-
- // clip off the right
- if (srcRect.right > srcFrameP->frameRect.right)
- {
- rightClip = srcRect.right - srcFrameP->frameRect.right;
- srcRect.right -= rightClip;
- }
-
-
- // Here we do the wrapping and drawing //
-
- // Draw top section //
-
- if (topClip)
- {
- // Calculate top piece //
-
- // Wrap source rect to bottom side
- srcRectA.right = srcRect.right; // Copy clipped source rect
- srcRectA.left = srcRect.left;
- srcRectA.bottom = srcFrameP->frameRect.bottom;
- srcRectA.top = srcFrameP->frameRect.bottom - topClip;
-
- // Position dest rect at top side
- dstRectA.top = dstRect.top;
- dstRectA.bottom = dstRect.top + topClip;
- dstRectA.left = dstRect.left + leftClip;
- dstRectA.right = dstRect.right - rightClip;
-
-
- if (leftClip) // Calculate top-left piece
- {
- // Wrap source rect to lower-right corner
- srcRectB.bottom = srcFrameP->frameRect.bottom;
- srcRectB.right = srcFrameP->frameRect.right;
- srcRectB.top = srcFrameP->frameRect.bottom - topClip;
- srcRectB.left = srcFrameP->frameRect.right - leftClip;
-
- // Position dest rect at top-left corner
- dstRectB.left = dstRect.left;
- dstRectB.top = dstRect.top;
- dstRectB.right = dstRect.left + leftClip;
- dstRectB.bottom = dstRect.top + topClip;
-
- if (spriteWorldP->doubleRectDrawProc != NULL)
- {
- // RectB is passed first, since it is to the left of rectA
- (*spriteWorldP->doubleRectDrawProc)(srcFrameP, dstFrameP,
- &srcRectB, &dstRectB, &srcRectA, &dstRectA);
- }
- else
- {
- (*spriteWorldP->screenDrawProc)(srcFrameP, dstFrameP, &srcRectB, &dstRectB);
- (*spriteWorldP->screenDrawProc)(srcFrameP, dstFrameP, &srcRectA, &dstRectA);
- }
- }
- else if (rightClip) // Calculate top-right piece
- {
- // Wrap source rect to lower-left corner
- srcRectB.bottom = srcFrameP->frameRect.bottom;
- srcRectB.left = srcFrameP->frameRect.left;
- srcRectB.right = srcFrameP->frameRect.left + rightClip;
- srcRectB.top = srcFrameP->frameRect.bottom - topClip;
-
- // Position dest rect at top-right corner
- dstRectB.top = dstRect.top;
- dstRectB.right = dstRect.right;
- dstRectB.bottom = dstRect.top + topClip;
- dstRectB.left = dstRect.right - rightClip;
-
- if (spriteWorldP->doubleRectDrawProc != NULL)
- {
- (*spriteWorldP->doubleRectDrawProc)(srcFrameP, dstFrameP,
- &srcRectA, &dstRectA, &srcRectB, &dstRectB);
- }
- else
- {
- (*spriteWorldP->screenDrawProc)(srcFrameP, dstFrameP, &srcRectA, &dstRectA);
- (*spriteWorldP->screenDrawProc)(srcFrameP, dstFrameP, &srcRectB, &dstRectB);
- }
- }
- else
- {
- // Draw just the top rect
- (*spriteWorldP->screenDrawProc)(srcFrameP, dstFrameP, &srcRectA, &dstRectA);
- }
- }
-
-
- // Draw middle section //
-
- // Calculate main middle piece (not wrapped)
- dstRectA.left = dstRect.left + leftClip;
- dstRectA.top = dstRect.top + topClip;
- dstRectA.right = dstRect.right - rightClip;
- dstRectA.bottom = dstRect.bottom - bottomClip;
-
-
- if (leftClip) // Draw left piece
- {
- // Wrap source rect to right side
- srcRectB.top = srcRect.top; // Copy clipped source rect
- srcRectB.bottom = srcRect.bottom;
- srcRectB.right = srcFrameP->frameRect.right;
- srcRectB.left = srcFrameP->frameRect.right - leftClip;
-
- // Position dest rect at left side
- dstRectB.left = dstRect.left;
- dstRectB.right = dstRect.left + leftClip;
- dstRectB.top = dstRect.top + topClip;
- dstRectB.bottom = dstRect.bottom - bottomClip;
-
- if (spriteWorldP->doubleRectDrawProc != NULL)
- {
- // RectB is passed first, since it is to the left of rectA
- (*spriteWorldP->doubleRectDrawProc)(srcFrameP, dstFrameP,
- &srcRectB, &dstRectB, &srcRect, &dstRectA);
- }
- else
- {
- (*spriteWorldP->screenDrawProc)(srcFrameP, dstFrameP, &srcRectB, &dstRectB);
- (*spriteWorldP->screenDrawProc)(srcFrameP, dstFrameP, &srcRect, &dstRectA);
- }
- }
- else if (rightClip) // Draw right piece
- {
- // Wrap source rect to left side
- srcRectB.top = srcRect.top; // Copy clipped source rect
- srcRectB.bottom = srcRect.bottom;
- srcRectB.left = srcFrameP->frameRect.left;
- srcRectB.right = srcFrameP->frameRect.left + rightClip;
-
- // Position dest rect at right side
- dstRectB.right = dstRect.right;
- dstRectB.left = dstRect.right - rightClip;
- dstRectB.top = dstRect.top + topClip;
- dstRectB.bottom = dstRect.bottom - bottomClip;
-
- if (spriteWorldP->doubleRectDrawProc != NULL)
- {
- (*spriteWorldP->doubleRectDrawProc)(srcFrameP, dstFrameP,
- &srcRect, &dstRectA, &srcRectB, &dstRectB);
- }
- else
- {
- (*spriteWorldP->screenDrawProc)(srcFrameP, dstFrameP, &srcRect, &dstRectA);
- (*spriteWorldP->screenDrawProc)(srcFrameP, dstFrameP, &srcRectB, &dstRectB);
- }
- }
- else
- {
- // Draw just the middle piece
- (*spriteWorldP->screenDrawProc)(srcFrameP, dstFrameP, &srcRect, &dstRectA);
- }
-
-
- // Draw bottom section //
-
- if (bottomClip)
- {
- // Calculate bottom piece //
-
- // Wrap source rect to top side
- srcRectA.right = srcRect.right; // Copy clipped source rect
- srcRectA.left = srcRect.left;
- srcRectA.top = srcFrameP->frameRect.top;
- srcRectA.bottom = srcFrameP->frameRect.top + bottomClip;
-
- // Position dest rect at bottom side
- dstRectA.bottom = dstRect.bottom;
- dstRectA.top = dstRect.bottom - bottomClip;
- dstRectA.left = dstRect.left + leftClip;
- dstRectA.right = dstRect.right - rightClip;
-
-
- if (leftClip) // Draw bottom-left piece
- {
- // Wrap source rect to upper-right corner
- srcRectB.top = srcFrameP->frameRect.top;
- srcRectB.right = srcFrameP->frameRect.right;
- srcRectB.bottom = srcFrameP->frameRect.top + bottomClip;
- srcRectB.left = srcFrameP->frameRect.right - leftClip;
-
- // Position dest rect at bottom-left corner
- dstRectB.bottom = dstRect.bottom;
- dstRectB.left = dstRect.left;
- dstRectB.top = dstRect.bottom - bottomClip;
- dstRectB.right = dstRect.left + leftClip;
-
- if (spriteWorldP->doubleRectDrawProc != NULL)
- {
- // RectB is passed first, since it is to the left of rectA
- (*spriteWorldP->doubleRectDrawProc)(srcFrameP, dstFrameP,
- &srcRectB, &dstRectB, &srcRectA, &dstRectA);
- }
- else
- {
- (*spriteWorldP->screenDrawProc)(srcFrameP, dstFrameP, &srcRectB, &dstRectB);
- (*spriteWorldP->screenDrawProc)(srcFrameP, dstFrameP, &srcRectA, &dstRectA);
- }
- }
- else if (rightClip) // Draw bottom-right piece
- {
- // Wrap source rect to upper-left corner
- srcRectB.top = srcFrameP->frameRect.top;
- srcRectB.left = srcFrameP->frameRect.left;
- srcRectB.bottom = srcFrameP->frameRect.top + bottomClip;
- srcRectB.right = srcFrameP->frameRect.left + rightClip;
-
- // Position dest rect at bottom-right corner
- dstRectB.bottom = dstRect.bottom;
- dstRectB.right = dstRect.right;
- dstRectB.top = dstRect.bottom - bottomClip;
- dstRectB.left = dstRect.right - rightClip;
-
- if (spriteWorldP->doubleRectDrawProc != NULL)
- {
- (*spriteWorldP->doubleRectDrawProc)(srcFrameP, dstFrameP,
- &srcRectA, &dstRectA, &srcRectB, &dstRectB);
- }
- else
- {
- (*spriteWorldP->screenDrawProc)(srcFrameP, dstFrameP, &srcRectA, &dstRectA);
- (*spriteWorldP->screenDrawProc)(srcFrameP, dstFrameP, &srcRectB, &dstRectB);
- }
- }
- else
- {
- // Draw just the bottom clip
- (*spriteWorldP->screenDrawProc)(srcFrameP, dstFrameP, &srcRectA, &dstRectA);
- }
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWWrapRectToScreen - essentially the same as SWWrapWorldToScreen, except with some
- // extra code at the beginning to calculate the dstRect based on the srcRect, and clip it.
- // Used by SWFastAnimateScrollingSpriteWorld.
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWWrapRectToScreen(
- SpriteWorldPtr spriteWorldP,
- Rect *srcRectP)
- {
- FramePtr srcFrameP = spriteWorldP->workFrameP;
- FramePtr dstFrameP = spriteWorldP->windowFrameP;
- Rect srcRect, dstRect, srcRectA, srcRectB, dstRectA, dstRectB;
- short topClip=0, rightClip=0, bottomClip=0, leftClip=0;
-
- srcRect = *srcRectP;
-
- // dstRect = srcRect - spriteWorldP->visScrollRect + spriteWorldP->windRect;
- dstRect = srcRect;
- dstRect.top -= spriteWorldP->visScrollRect.top;
- dstRect.bottom -= spriteWorldP->visScrollRect.top;
- dstRect.left -= spriteWorldP->visScrollRect.left;
- dstRect.right -= spriteWorldP->visScrollRect.left;
- dstRect.top += spriteWorldP->windRect.top;
- dstRect.bottom += spriteWorldP->windRect.top;
- dstRect.left += spriteWorldP->windRect.left;
- dstRect.right += spriteWorldP->windRect.left;
-
- // Clip dstRect
- if (dstRect.top < spriteWorldP->windRect.top)
- {
- srcRect.top += spriteWorldP->windRect.top - dstRect.top;
- dstRect.top = spriteWorldP->windRect.top;
- }
-
- if (dstRect.bottom > spriteWorldP->windRect.bottom)
- {
- srcRect.bottom += spriteWorldP->windRect.bottom - dstRect.bottom;
- dstRect.bottom = spriteWorldP->windRect.bottom;
- }
-
- if (dstRect.left < spriteWorldP->windRect.left)
- {
- srcRect.left += spriteWorldP->windRect.left - dstRect.left;
- dstRect.left = spriteWorldP->windRect.left;
- }
-
- if (dstRect.right > spriteWorldP->windRect.right)
- {
- srcRect.right += spriteWorldP->windRect.right - dstRect.right;
- dstRect.right = spriteWorldP->windRect.right;
- }
-
- // Make sure rect is visible
- if ( (dstRect.right <= dstRect.left) || (dstRect.bottom <= dstRect.top) )
- return;
-
- // Make the srcRect local to the offscreen area
- srcRect.top -= spriteWorldP->vertScrollRectOffset;
- srcRect.bottom -= spriteWorldP->vertScrollRectOffset;
- srcRect.left -= spriteWorldP->horizScrollRectOffset;
- srcRect.right -= spriteWorldP->horizScrollRectOffset;
-
-
- // Clip the source rect, and save what we clipped for wrapping later //
-
- // clip off the top
- if (srcRect.top < srcFrameP->frameRect.top)
- {
- topClip = srcFrameP->frameRect.top - srcRect.top;
- srcRect.top += topClip;
- }
-
- // clip off the bottom
- if (srcRect.bottom > srcFrameP->frameRect.bottom)
- {
- bottomClip = srcRect.bottom - srcFrameP->frameRect.bottom;
- srcRect.bottom -= bottomClip;
- }
-
- // clip off the left
- if (srcRect.left < srcFrameP->frameRect.left)
- {
- leftClip = srcFrameP->frameRect.left - srcRect.left;
- srcRect.left += leftClip;
- }
-
- // clip off the right
- if (srcRect.right > srcFrameP->frameRect.right)
- {
- rightClip = srcRect.right - srcFrameP->frameRect.right;
- srcRect.right -= rightClip;
- }
-
-
- // Here we do the wrapping and drawing //
-
- // Draw top section //
-
- if (topClip)
- {
- // Calculate top piece //
-
- // Wrap source rect to bottom side
- srcRectA.right = srcRect.right; // Copy clipped source rect
- srcRectA.left = srcRect.left;
- srcRectA.bottom = srcFrameP->frameRect.bottom;
- srcRectA.top = srcFrameP->frameRect.bottom - topClip;
-
- // Position dest rect at top side
- dstRectA.top = dstRect.top;
- dstRectA.bottom = dstRect.top + topClip;
- dstRectA.left = dstRect.left + leftClip;
- dstRectA.right = dstRect.right - rightClip;
-
-
- if (leftClip) // Calculate top-left piece
- {
- // Wrap source rect to lower-right corner
- srcRectB.bottom = srcFrameP->frameRect.bottom;
- srcRectB.right = srcFrameP->frameRect.right;
- srcRectB.top = srcFrameP->frameRect.bottom - topClip;
- srcRectB.left = srcFrameP->frameRect.right - leftClip;
-
- // Position dest rect at top-left corner
- dstRectB.left = dstRect.left;
- dstRectB.top = dstRect.top;
- dstRectB.right = dstRect.left + leftClip;
- dstRectB.bottom = dstRect.top + topClip;
-
- if (spriteWorldP->doubleRectDrawProc != NULL)
- {
- // RectB is passed first, since it is to the left of rectA
- (*spriteWorldP->doubleRectDrawProc)(srcFrameP, dstFrameP,
- &srcRectB, &dstRectB, &srcRectA, &dstRectA);
- }
- else
- {
- (*spriteWorldP->screenDrawProc)(srcFrameP, dstFrameP, &srcRectB, &dstRectB);
- (*spriteWorldP->screenDrawProc)(srcFrameP, dstFrameP, &srcRectA, &dstRectA);
- }
- }
- else if (rightClip) // Calculate top-right piece
- {
- // Wrap source rect to lower-left corner
- srcRectB.bottom = srcFrameP->frameRect.bottom;
- srcRectB.left = srcFrameP->frameRect.left;
- srcRectB.right = srcFrameP->frameRect.left + rightClip;
- srcRectB.top = srcFrameP->frameRect.bottom - topClip;
-
- // Position dest rect at top-right corner
- dstRectB.top = dstRect.top;
- dstRectB.right = dstRect.right;
- dstRectB.bottom = dstRect.top + topClip;
- dstRectB.left = dstRect.right - rightClip;
-
- if (spriteWorldP->doubleRectDrawProc != NULL)
- {
- (*spriteWorldP->doubleRectDrawProc)(srcFrameP, dstFrameP,
- &srcRectA, &dstRectA, &srcRectB, &dstRectB);
- }
- else
- {
- (*spriteWorldP->screenDrawProc)(srcFrameP, dstFrameP, &srcRectA, &dstRectA);
- (*spriteWorldP->screenDrawProc)(srcFrameP, dstFrameP, &srcRectB, &dstRectB);
- }
- }
- else
- {
- // Draw just the top rect
- (*spriteWorldP->screenDrawProc)(srcFrameP, dstFrameP, &srcRectA, &dstRectA);
- }
- }
-
-
- // Draw middle section //
-
- // Calculate main middle piece (not wrapped)
- dstRectA.left = dstRect.left + leftClip;
- dstRectA.top = dstRect.top + topClip;
- dstRectA.right = dstRect.right - rightClip;
- dstRectA.bottom = dstRect.bottom - bottomClip;
-
-
- if (leftClip) // Draw left piece
- {
- // Wrap source rect to right side
- srcRectB.top = srcRect.top; // Copy clipped source rect
- srcRectB.bottom = srcRect.bottom;
- srcRectB.right = srcFrameP->frameRect.right;
- srcRectB.left = srcFrameP->frameRect.right - leftClip;
-
- // Position dest rect at left side
- dstRectB.left = dstRect.left;
- dstRectB.right = dstRect.left + leftClip;
- dstRectB.top = dstRect.top + topClip;
- dstRectB.bottom = dstRect.bottom - bottomClip;
-
- if (spriteWorldP->doubleRectDrawProc != NULL)
- {
- // RectB is passed first, since it is to the left of rectA
- (*spriteWorldP->doubleRectDrawProc)(srcFrameP, dstFrameP,
- &srcRectB, &dstRectB, &srcRect, &dstRectA);
- }
- else
- {
- (*spriteWorldP->screenDrawProc)(srcFrameP, dstFrameP, &srcRectB, &dstRectB);
- (*spriteWorldP->screenDrawProc)(srcFrameP, dstFrameP, &srcRect, &dstRectA);
- }
- }
- else if (rightClip) // Draw right piece
- {
- // Wrap source rect to left side
- srcRectB.top = srcRect.top; // Copy clipped source rect
- srcRectB.bottom = srcRect.bottom;
- srcRectB.left = srcFrameP->frameRect.left;
- srcRectB.right = srcFrameP->frameRect.left + rightClip;
-
- // Position dest rect at right side
- dstRectB.right = dstRect.right;
- dstRectB.left = dstRect.right - rightClip;
- dstRectB.top = dstRect.top + topClip;
- dstRectB.bottom = dstRect.bottom - bottomClip;
-
- if (spriteWorldP->doubleRectDrawProc != NULL)
- {
- (*spriteWorldP->doubleRectDrawProc)(srcFrameP, dstFrameP,
- &srcRect, &dstRectA, &srcRectB, &dstRectB);
- }
- else
- {
- (*spriteWorldP->screenDrawProc)(srcFrameP, dstFrameP, &srcRect, &dstRectA);
- (*spriteWorldP->screenDrawProc)(srcFrameP, dstFrameP, &srcRectB, &dstRectB);
- }
- }
- else
- {
- // Draw just the middle piece
- (*spriteWorldP->screenDrawProc)(srcFrameP, dstFrameP, &srcRect, &dstRectA);
- }
-
-
- // Draw bottom section //
-
- if (bottomClip)
- {
- // Calculate bottom piece //
-
- // Wrap source rect to top side
- srcRectA.right = srcRect.right; // Copy clipped source rect
- srcRectA.left = srcRect.left;
- srcRectA.top = srcFrameP->frameRect.top;
- srcRectA.bottom = srcFrameP->frameRect.top + bottomClip;
-
- // Position dest rect at bottom side
- dstRectA.bottom = dstRect.bottom;
- dstRectA.top = dstRect.bottom - bottomClip;
- dstRectA.left = dstRect.left + leftClip;
- dstRectA.right = dstRect.right - rightClip;
-
-
- if (leftClip) // Draw bottom-left piece
- {
- // Wrap source rect to upper-right corner
- srcRectB.top = srcFrameP->frameRect.top;
- srcRectB.right = srcFrameP->frameRect.right;
- srcRectB.bottom = srcFrameP->frameRect.top + bottomClip;
- srcRectB.left = srcFrameP->frameRect.right - leftClip;
-
- // Position dest rect at bottom-left corner
- dstRectB.bottom = dstRect.bottom;
- dstRectB.left = dstRect.left;
- dstRectB.top = dstRect.bottom - bottomClip;
- dstRectB.right = dstRect.left + leftClip;
-
- if (spriteWorldP->doubleRectDrawProc != NULL)
- {
- // RectB is passed first, since it is to the left of rectA
- (*spriteWorldP->doubleRectDrawProc)(srcFrameP, dstFrameP,
- &srcRectB, &dstRectB, &srcRectA, &dstRectA);
- }
- else
- {
- (*spriteWorldP->screenDrawProc)(srcFrameP, dstFrameP, &srcRectB, &dstRectB);
- (*spriteWorldP->screenDrawProc)(srcFrameP, dstFrameP, &srcRectA, &dstRectA);
- }
- }
- else if (rightClip) // Draw bottom-right piece
- {
- // Wrap source rect to upper-left corner
- srcRectB.top = srcFrameP->frameRect.top;
- srcRectB.left = srcFrameP->frameRect.left;
- srcRectB.bottom = srcFrameP->frameRect.top + bottomClip;
- srcRectB.right = srcFrameP->frameRect.left + rightClip;
-
- // Position dest rect at bottom-right corner
- dstRectB.bottom = dstRect.bottom;
- dstRectB.right = dstRect.right;
- dstRectB.top = dstRect.bottom - bottomClip;
- dstRectB.left = dstRect.right - rightClip;
-
- if (spriteWorldP->doubleRectDrawProc != NULL)
- {
- (*spriteWorldP->doubleRectDrawProc)(srcFrameP, dstFrameP,
- &srcRectA, &dstRectA, &srcRectB, &dstRectB);
- }
- else
- {
- (*spriteWorldP->screenDrawProc)(srcFrameP, dstFrameP, &srcRectA, &dstRectA);
- (*spriteWorldP->screenDrawProc)(srcFrameP, dstFrameP, &srcRectB, &dstRectB);
- }
- }
- else
- {
- // Draw just the bottom clip
- (*spriteWorldP->screenDrawProc)(srcFrameP, dstFrameP, &srcRectA, &dstRectA);
- }
- }
- }
-
-
-
- ///--------------------------------------------------------------------------------------
- // SWCheckWrappedIdleSpriteOverlap - same as SWCheckIdleSpriteOverlap,
- // but for scrolling SpriteWorlds.
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWCheckWrappedIdleSpriteOverlap(
- SpriteWorldPtr spriteWorldP,
- register SpritePtr idleSpriteP,
- SpritePtr headActiveSpriteP)
- {
- Rect *visScrollRectP = &spriteWorldP->visScrollRect;
- 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);
-
- // Clip the sprite's dstSectRect with visScrollRect
- if (dstSectRect.top < visScrollRectP->top)
- dstSectRect.top = visScrollRectP->top;
- if (dstSectRect.bottom > visScrollRectP->bottom)
- dstSectRect.bottom = visScrollRectP->bottom;
- if (dstSectRect.left < visScrollRectP->left)
- dstSectRect.left = visScrollRectP->left;
- if (dstSectRect.right > visScrollRectP->right)
- dstSectRect.right = visScrollRectP->right;
-
- // Calculate the source rect
- 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);
-
-
- // Make the sprite's dest rect local to the offscreen area
- dstSectRect.top -= spriteWorldP->vertScrollRectOffset;
- dstSectRect.bottom -= spriteWorldP->vertScrollRectOffset;
- dstSectRect.left -= spriteWorldP->horizScrollRectOffset;
- dstSectRect.right -= spriteWorldP->horizScrollRectOffset;
-
- gCurrentSpriteBeingDrawn = idleSpriteP;
-
- // Copy a piece of the sprite image onto the back drop piece
- SWDrawWrappedSprite(idleSpriteP, 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);
- }
- }
-
- activeSpriteP = activeSpriteP->nextActiveSpriteP;
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWCheckWrappedIdleSpritesWithTiles - redraw sprites erased by tiles that changed
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWCheckWrappedIdleSpritesWithTiles(
- SpriteWorldPtr spriteWorldP,
- SpritePtr headIdleSpriteP)
- {
- Rect *visScrollRectP = &spriteWorldP->visScrollRect;
- Rect srcSectRect, dstSectRect;
- register SpritePtr idleSpriteP;
- 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 old
- // 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);
-
- // Clip the sprite's dstSectRect with visScrollRect
- if (dstSectRect.top < visScrollRectP->top)
- dstSectRect.top = visScrollRectP->top;
- if (dstSectRect.bottom > visScrollRectP->bottom)
- dstSectRect.bottom = visScrollRectP->bottom;
- if (dstSectRect.left < visScrollRectP->left)
- dstSectRect.left = visScrollRectP->left;
- if (dstSectRect.right > visScrollRectP->right)
- dstSectRect.right = visScrollRectP->right;
-
- // Calculate the source rect
- srcSectRect = idleSpriteP->curFrameP->frameRect;
-
- srcSectRect.left += (dstSectRect.left - idleSpriteP->oldFrameRect.left);
- srcSectRect.top += (dstSectRect.top - idleSpriteP->oldFrameRect.top);
- srcSectRect.right -= (idleSpriteP->oldFrameRect.right - dstSectRect.right);
- srcSectRect.bottom -= (idleSpriteP->oldFrameRect.bottom - dstSectRect.bottom);
-
-
- // Make the sprite's dest rect local to the offscreen area
- dstSectRect.top -= spriteWorldP->vertScrollRectOffset;
- dstSectRect.bottom -= spriteWorldP->vertScrollRectOffset;
- dstSectRect.left -= spriteWorldP->horizScrollRectOffset;
- dstSectRect.right -= spriteWorldP->horizScrollRectOffset;
-
- gCurrentSpriteBeingDrawn = idleSpriteP;
-
- // Copy a piece of the sprite image onto the back drop piece
- SWDrawWrappedSprite(idleSpriteP, 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;
- }
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWCheckWrappedIdleSpritesWithRects - redraw sprites erased by updateRects
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWCheckWrappedIdleSpritesWithRects(
- SpriteWorldPtr spriteWorldP,
- SpritePtr headIdleSpriteP)
- {
- UpdateRectStructPtr curRectStructP;
- register SpritePtr idleSpriteP;
- Rect *visScrollRectP = &spriteWorldP->visScrollRect;
- Rect srcSectRect, dstSectRect;
- 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 old
- // 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);
-
- // Clip the sprite's dstSectRect with visScrollRect
- if (dstSectRect.top < visScrollRectP->top)
- dstSectRect.top = visScrollRectP->top;
- if (dstSectRect.bottom > visScrollRectP->bottom)
- dstSectRect.bottom = visScrollRectP->bottom;
- if (dstSectRect.left < visScrollRectP->left)
- dstSectRect.left = visScrollRectP->left;
- if (dstSectRect.right > visScrollRectP->right)
- dstSectRect.right = visScrollRectP->right;
-
- // Calculate the source rect
- srcSectRect = idleSpriteP->curFrameP->frameRect;
-
- srcSectRect.left += (dstSectRect.left - idleSpriteP->oldFrameRect.left);
- srcSectRect.top += (dstSectRect.top - idleSpriteP->oldFrameRect.top);
- srcSectRect.right -= (idleSpriteP->oldFrameRect.right - dstSectRect.right);
- srcSectRect.bottom -= (idleSpriteP->oldFrameRect.bottom - dstSectRect.bottom);
-
-
- // Make the sprite's dest rect local to the offscreen area
- dstSectRect.top -= spriteWorldP->vertScrollRectOffset;
- dstSectRect.bottom -= spriteWorldP->vertScrollRectOffset;
- dstSectRect.left -= spriteWorldP->horizScrollRectOffset;
- dstSectRect.right -= spriteWorldP->horizScrollRectOffset;
-
- gCurrentSpriteBeingDrawn = idleSpriteP;
-
- // Copy a piece of the sprite image onto the back drop piece
- SWDrawWrappedSprite(idleSpriteP, 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;
- }
- }
-
-
- #pragma mark -
- ///--------------------------------------------------------------------------------------
- // SWSetScrollingWorldMoveBounds
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWSetScrollingWorldMoveBounds(
- SpriteWorldPtr spriteWorldP,
- Rect* scrollRectMoveBounds)
- {
- spriteWorldP->scrollRectMoveBounds = *scrollRectMoveBounds;
-
- // Make sure the visScrollRect is still within its bounds
- SWMoveVisScrollRect(spriteWorldP,
- spriteWorldP->visScrollRect.left,
- spriteWorldP->visScrollRect.top);
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWSetScrollingWorldMoveProc
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWSetScrollingWorldMoveProc(
- SpriteWorldPtr spriteWorldP,
- WorldMoveProcPtr worldMoveProcP,
- SpritePtr followSpriteP)
- {
- spriteWorldP->worldMoveProc = worldMoveProcP;
- spriteWorldP->followSpriteP = followSpriteP;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWSetDoubleRectDrawProc
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWSetDoubleRectDrawProc(
- SpriteWorldPtr spriteWorldP,
- DoubleDrawProcPtr drawProc)
- {
- spriteWorldP->doubleRectDrawProc = drawProc;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWSetSpriteWorldScrollDelta
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWSetSpriteWorldScrollDelta(
- SpriteWorldPtr spriteWorldP,
- short horizDelta,
- short vertDelta)
- {
- spriteWorldP->horizScrollDelta = horizDelta;
- spriteWorldP->vertScrollDelta = vertDelta;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWMoveVisScrollRect - move visScrollRect to an absolute vertical and
- // horizontal location
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWMoveVisScrollRect(
- SpriteWorldPtr spriteWorldP,
- short horizPos,
- short vertPos)
- {
- short width, height;
-
- height = spriteWorldP->visScrollRect.bottom - spriteWorldP->visScrollRect.top;
- width = spriteWorldP->visScrollRect.right - spriteWorldP->visScrollRect.left;
-
-
- // Move visScrollRect and keep within moveBounds //
-
-
- // Move vertically
- if ((long)vertPos < spriteWorldP->scrollRectMoveBounds.top)
- {
- spriteWorldP->visScrollRect.top = spriteWorldP->scrollRectMoveBounds.top;
- spriteWorldP->visScrollRect.bottom = spriteWorldP->visScrollRect.top + height;
- }
- else if ((long)vertPos + height > spriteWorldP->scrollRectMoveBounds.bottom)
- {
- spriteWorldP->visScrollRect.bottom = spriteWorldP->scrollRectMoveBounds.bottom;
- spriteWorldP->visScrollRect.top = spriteWorldP->visScrollRect.bottom - height;
- }
- else
- {
- spriteWorldP->visScrollRect.top = vertPos;
- spriteWorldP->visScrollRect.bottom = vertPos + height;
- }
-
-
- // Move horizontally
- if ((long)horizPos < spriteWorldP->scrollRectMoveBounds.left)
- {
- spriteWorldP->visScrollRect.left = spriteWorldP->scrollRectMoveBounds.left;
- spriteWorldP->visScrollRect.right = spriteWorldP->visScrollRect.left + width;
- }
- else if ((long)horizPos + width > spriteWorldP->scrollRectMoveBounds.right)
- {
- spriteWorldP->visScrollRect.right = spriteWorldP->scrollRectMoveBounds.right;
- spriteWorldP->visScrollRect.left = spriteWorldP->visScrollRect.right - width;
- }
- else
- {
- spriteWorldP->visScrollRect.left = horizPos;
- spriteWorldP->visScrollRect.right = horizPos + width;
- }
-
-
- SWCalculateOffscreenScrollRect(spriteWorldP);
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWOffsetVisScrollRect - move visScrollRect to an absolute vertical and
- // horizontal location, while keeping within the bounds of scrollRectMoveBounds
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWOffsetVisScrollRect(
- SpriteWorldPtr spriteWorldP,
- short horizOffset,
- short vertOffset)
- {
- // Move visScrollRect and keep within moveBounds //
-
- // Move vertically
- if ((long)spriteWorldP->visScrollRect.top + vertOffset <
- spriteWorldP->scrollRectMoveBounds.top)
- {
- spriteWorldP->visScrollRect.bottom -= spriteWorldP->visScrollRect.top -
- spriteWorldP->scrollRectMoveBounds.top;
- spriteWorldP->visScrollRect.top = spriteWorldP->scrollRectMoveBounds.top;
- }
- else if ((long)spriteWorldP->visScrollRect.bottom + vertOffset >
- spriteWorldP->scrollRectMoveBounds.bottom)
- {
- spriteWorldP->visScrollRect.top -= spriteWorldP->visScrollRect.bottom -
- spriteWorldP->scrollRectMoveBounds.bottom;
- spriteWorldP->visScrollRect.bottom = spriteWorldP->scrollRectMoveBounds.bottom;
- }
- else
- {
- spriteWorldP->visScrollRect.top += vertOffset;
- spriteWorldP->visScrollRect.bottom += vertOffset;
- }
-
-
- // Move horizontally
- if ((long)spriteWorldP->visScrollRect.left + horizOffset <
- spriteWorldP->scrollRectMoveBounds.left)
- {
- spriteWorldP->visScrollRect.right -= spriteWorldP->visScrollRect.left -
- spriteWorldP->scrollRectMoveBounds.left;
- spriteWorldP->visScrollRect.left = spriteWorldP->scrollRectMoveBounds.left;
- }
- else if ((long)spriteWorldP->visScrollRect.right + horizOffset >
- spriteWorldP->scrollRectMoveBounds.right)
- {
- spriteWorldP->visScrollRect.left -= spriteWorldP->visScrollRect.right -
- spriteWorldP->scrollRectMoveBounds.right;
- spriteWorldP->visScrollRect.right = spriteWorldP->scrollRectMoveBounds.right;
- }
- else
- {
- spriteWorldP->visScrollRect.left += horizOffset;
- spriteWorldP->visScrollRect.right += horizOffset;
- }
-
-
- SWCalculateOffscreenScrollRect(spriteWorldP);
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWResizeVisScrollRect - make the visScrollRect a new width and height.
- // Used by SWChangeWorldRect. Make sure to call SWUpdateScrollingSpriteWorld after
- // calling this.
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWResizeVisScrollRect(
- SpriteWorldPtr spriteWorldP,
- short width,
- short height)
- {
- // Will expanding it vertically move it past its bounds?
- if ((long)spriteWorldP->visScrollRect.top + height >
- spriteWorldP->scrollRectMoveBounds.bottom)
- {
- spriteWorldP->visScrollRect.bottom = spriteWorldP->scrollRectMoveBounds.bottom;
- spriteWorldP->visScrollRect.top = spriteWorldP->visScrollRect.bottom - height;
- }
- else
- {
- spriteWorldP->visScrollRect.bottom = spriteWorldP->visScrollRect.top + height;
- }
-
-
- // Will expanding it horizontally move it past its bounds?
- if ((long)spriteWorldP->visScrollRect.left + width >
- spriteWorldP->scrollRectMoveBounds.right)
- {
- spriteWorldP->visScrollRect.right = spriteWorldP->scrollRectMoveBounds.right;
- spriteWorldP->visScrollRect.left = spriteWorldP->visScrollRect.right - width;
- }
- else
- {
- spriteWorldP->visScrollRect.right = spriteWorldP->visScrollRect.left + width;
- }
-
- spriteWorldP->oldVisScrollRect = spriteWorldP->visScrollRect;
- SWCalculateOffscreenScrollRect(spriteWorldP);
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWCalculateOffscreenScrollRect (wrap offscreenScrollRect in the work area)
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWCalculateOffscreenScrollRect(
- SpriteWorldPtr spriteWorldP)
- {
- Rect *offscreenScrollRectP = &spriteWorldP->offscreenScrollRect;
- Rect *visScrollRectP = &spriteWorldP->visScrollRect;
-
-
- spriteWorldP->vertScrollRectOffset = spriteWorldP->backRect.bottom *
- (visScrollRectP->top / spriteWorldP->backRect.bottom);
-
- spriteWorldP->horizScrollRectOffset = spriteWorldP->backRect.right *
- (visScrollRectP->left / spriteWorldP->backRect.right);
-
-
- offscreenScrollRectP->top = visScrollRectP->top -
- spriteWorldP->vertScrollRectOffset;
- offscreenScrollRectP->bottom = visScrollRectP->bottom -
- spriteWorldP->vertScrollRectOffset;
- offscreenScrollRectP->left = visScrollRectP->left -
- spriteWorldP->horizScrollRectOffset;
- offscreenScrollRectP->right = visScrollRectP->right -
- spriteWorldP->horizScrollRectOffset;
- }
-
-
-