home *** CD-ROM | disk | FTP | other *** search
Text File | 1997-04-16 | 53.2 KB | 1,698 lines | [TEXT/KAHL] |
- ///--------------------------------------------------------------------------------------
- // 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
-
-
-
- ///--------------------------------------------------------------------------------------
- // SWUpdateScrollingWindow
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWUpdateScrollingWindow(
- SpriteWorldPtr spriteWorldP)
- {
- GWorldPtr holdGWorld;
- GDHandle holdGDH;
-
- SWAssert( spriteWorldP != NULL && spriteWorldP->windowFrameP != NULL );
-
- 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)
- {
- register SpriteLayerPtr curSpriteLayerP;
- register SpritePtr curSpriteP;
- Rect *visScrollRectP = &spriteWorldP->visScrollRect;
- Rect srcFrameRect, tempDstRect;
- GWorldPtr saveGWorld;
- GDHandle saveGDH;
-
- SWAssert( spriteWorldP != NULL && spriteWorldP->workFrameP != NULL );
-
- GetGWorld( &saveGWorld, &saveGDH );
-
- spriteWorldP->numTilesChanged = 0;
-
-
- // Copy the background into the work area
- SetGWorld(spriteWorldP->workFrameP->framePort, nil);
- (*spriteWorldP->offscreenDrawProc)(spriteWorldP->backFrameP,
- spriteWorldP->workFrameP,
- &spriteWorldP->backFrameP->frameRect,
- &spriteWorldP->workFrameP->frameRect);
-
-
-
- // Build the current frame of the animation in the work area
-
- 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)
- {
- curSpriteP->destOffscreenRect = curSpriteP->destFrameRect;
-
- SWAssert( curSpriteP->curFrameP != NULL );
-
- 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;
-
- // Draw the sprite in the work area
- SWDrawWrappedSprite(curSpriteP, spriteWorldP->workFrameP,
- &srcFrameRect, &curSpriteP->destOffscreenRect);
-
- // Draw tiles above sprite
- if (curSpriteP->isUnderTiles && spriteWorldP->tilingIsOn)
- {
- tempDstRect = curSpriteP->destOffscreenRect;
- tempDstRect.top += spriteWorldP->vertScrollRectOffset;
- tempDstRect.bottom += spriteWorldP->vertScrollRectOffset;
- tempDstRect.left += spriteWorldP->horizScrollRectOffset;
- tempDstRect.right += spriteWorldP->horizScrollRectOffset;
- SWDrawTilesAboveSprite(spriteWorldP, &tempDstRect);
- }
- }
- }
- // Set the old rect to the current rect
- curSpriteP->oldOffscreenRect = curSpriteP->destOffscreenRect;
- curSpriteP->oldRectIsVisible = curSpriteP->destRectIsVisible;
-
- curSpriteP = curSpriteP->nextSpriteP;
- }
-
- curSpriteLayerP = curSpriteLayerP->nextSpriteLayerP;
- }
-
- spriteWorldP->oldVisScrollRect = spriteWorldP->visScrollRect;
-
- // 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);
- }
-
- SetGWorld( saveGWorld, saveGDH );
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWProcessScrollingSpriteWorld
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWProcessScrollingSpriteWorld(
- SpriteWorldPtr spriteWorldP)
- {
-
- SWAssert( spriteWorldP != NULL );
-
- // Process the sprites
- SWProcessSpriteWorld(spriteWorldP);
- if ( !spriteWorldP->frameHasOccured )
- {
- 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)
- {
- register SpriteLayerPtr curSpriteLayerP;
- register SpritePtr curSpriteP;
- SpritePtr headActiveSpriteP = NULL; // First active sprite in world
- SpritePtr headIdleSpriteP = NULL; // First idle sprite in world
- SpritePtr curActiveSpriteP = NULL;
- SpritePtr curIdleSpriteP = NULL;
-
- Rect *visScrollRectP = &spriteWorldP->visScrollRect;
- Rect tempDstRect;
-
- SWAssert( spriteWorldP != NULL );
-
- if (!spriteWorldP->frameHasOccured)
- return;
-
-
- // Update tiles as we scroll if tiling routines are turned on
- if (spriteWorldP->tilingIsOn)
- {
- // VisScrollRect moved horizontally
- if (spriteWorldP->oldVisScrollRect.left != spriteWorldP->visScrollRect.left)
- {
- // Get rect of new vertical section to update
- tempDstRect = spriteWorldP->visScrollRect;
-
- // Moved left
- if (tempDstRect.left < spriteWorldP->oldVisScrollRect.left)
- {
- 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;
- }
-
- SWDrawTilesInRect(spriteWorldP, &tempDstRect, true);
- SWWrapRectToWorkArea(spriteWorldP, &tempDstRect);
-
-
- // Did VisScrollRect moved diagonally?
- if (spriteWorldP->oldVisScrollRect.top != spriteWorldP->visScrollRect.top)
- {
- // Get rect of new horizontal section to update
- tempDstRect = spriteWorldP->visScrollRect;
-
- // Moved up
- if (tempDstRect.top < spriteWorldP->oldVisScrollRect.top)
- {
- 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 (tempDstRect.left < spriteWorldP->oldVisScrollRect.left)
- {
- 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)
- {
- SWDrawTilesInRect(spriteWorldP, &tempDstRect, false);
- SWWrapRectToWorkArea(spriteWorldP, &tempDstRect);
- }
- }
- }
- else // VisScrollRect moved vertically only
- if (spriteWorldP->oldVisScrollRect.top != spriteWorldP->visScrollRect.top)
- {
- // Get rect of new horizontal section to update
- tempDstRect = spriteWorldP->visScrollRect;
-
- // Moved up
- if (tempDstRect.top < spriteWorldP->oldVisScrollRect.top)
- {
- 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;
- }
-
- SWDrawTilesInRect(spriteWorldP, &tempDstRect, true);
- SWWrapRectToWorkArea(spriteWorldP, &tempDstRect);
- }
- }
-
-
- //-----------------erase the sprites--------------------
-
- SWAssert( spriteWorldP->workFrameP != NULL );
-
- // Set the port to the work area so we can draw in it
- SetGWorld(spriteWorldP->workFrameP->framePort, nil);
-
- 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)
- {
- // Loop through all visible sprites, whether in visScrollRect or not,
- // and 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)
- {
- if (headActiveSpriteP == NULL)
- headActiveSpriteP = curSpriteP;
-
- if (curActiveSpriteP != NULL)
- curActiveSpriteP->nextActiveSpriteP = curSpriteP;
-
- curActiveSpriteP = curSpriteP;
-
- {
- short temp;
-
- // align the left edge to long word boundary
- // for drawing
- 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 the left edge to long word boundary
- // for SWRedrawErasedIdleSprites
- 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;
- }
- }
-
- // 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 dest sprite rect smaller than old sprite rect?
- if (curSpriteP->oldRectIsVisible)
- {
- if (curSpriteP->destOffscreenRect.right -
- curSpriteP->destOffscreenRect.left <
- curSpriteP->oldOffscreenRect.right -
- curSpriteP->oldOffscreenRect.left)
- {
- // Erase part of idle sprite outside of visScrollRect
- tempDstRect = curSpriteP->oldFrameRect;
-
- // Get section of sprite outside visScrollRect
- if (tempDstRect.left < visScrollRectP->left)
- tempDstRect.right = visScrollRectP->left;
- else
- tempDstRect.left = visScrollRectP->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;
-
- // Erase piece of idle sprite outside of visScrollRect
- SWEraseWrappedSprite(spriteWorldP, &tempDstRect);
- }
-
- if (curSpriteP->destOffscreenRect.bottom -
- curSpriteP->destOffscreenRect.top <
- curSpriteP->oldOffscreenRect.bottom -
- curSpriteP->oldOffscreenRect.top)
- {
- // Erase part of idle sprite outside of visScrollRect
- tempDstRect = curSpriteP->oldFrameRect;
-
- // Get section of sprite outside visScrollRect
- if (tempDstRect.top < visScrollRectP->top)
- tempDstRect.bottom = visScrollRectP->top;
- else
- tempDstRect.top = visScrollRectP->bottom;
-
- // Make the rect local to the offscreen area
- tempDstRect.top -= spriteWorldP->vertScrollRectOffset;
- tempDstRect.bottom -= spriteWorldP->vertScrollRectOffset;
- tempDstRect.left -= spriteWorldP->horizScrollRectOffset;
- tempDstRect.right -= spriteWorldP->horizScrollRectOffset;
-
- // Erase piece of idle sprite outside of visScrollRect
- SWEraseWrappedSprite(spriteWorldP, &tempDstRect);
- }
- }
-
-
- // Is the idle sprite visible on the screen?
- if (curSpriteP->destRectIsVisible)
- {
- // Redraw idle sprite if it is coming into the visScrollRect.
- if (curSpriteP->destOffscreenRect.right -
- curSpriteP->destOffscreenRect.left >
- curSpriteP->oldOffscreenRect.right -
- curSpriteP->oldOffscreenRect.left ||
- curSpriteP->destOffscreenRect.bottom -
- curSpriteP->destOffscreenRect.top >
- curSpriteP->oldOffscreenRect.bottom -
- curSpriteP->oldOffscreenRect.top)
- {
- curSpriteP->needsToBeDrawn = true;
-
- // Add sprite to active sprite list
- if (headActiveSpriteP == NULL)
- headActiveSpriteP = curSpriteP;
-
- if (curActiveSpriteP != NULL)
- curActiveSpriteP->nextActiveSpriteP = curSpriteP;
-
- curActiveSpriteP = curSpriteP;
- }
- else // 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; // Last active sprite in chain
-
- if (curIdleSpriteP != NULL)
- curIdleSpriteP->nextIdleSpriteP = NULL; // Last idle sprite in chain
-
-
- // Redraw idle sprites that were erased when active sprites were erased
- SWRedrawErasedIdleSprites(spriteWorldP, headActiveSpriteP, headIdleSpriteP);
-
-
- // Redraw idle sprites which were erased when the background was changed
- while (spriteWorldP->numTilesChanged > 0)
- SWRedrawIdleSpritesInRect(spriteWorldP, headIdleSpriteP,
- &spriteWorldP->changedTiles[--spriteWorldP->numTilesChanged]);
-
-
-
- //-----------------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)
- {
- // Draw the sprite in the work area
- SWDrawWrappedSprite(curSpriteP, spriteWorldP->workFrameP,
- &curSpriteP->clippedSourceRect,
- &curSpriteP->destOffscreenRect);
-
- // Draw tiles above sprite
- if (curSpriteP->isUnderTiles && spriteWorldP->tilingIsOn)
- {
- tempDstRect = curSpriteP->destOffscreenRect;
- tempDstRect.top += spriteWorldP->vertScrollRectOffset;
- tempDstRect.bottom += spriteWorldP->vertScrollRectOffset;
- tempDstRect.left += spriteWorldP->horizScrollRectOffset;
- tempDstRect.right += spriteWorldP->horizScrollRectOffset;
- SWDrawTilesAboveSprite(spriteWorldP, &tempDstRect);
- }
- }
- }
- 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;
-
-
- //-----------------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);
- }
-
-
- ///--------------------------------------------------------------------------------------
- // 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;
-
- SWAssert( srcSpriteP != NULL && dstFrameP != NULL && srcRect != NULL && dstRect != NULL );
-
- // 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;
-
- SWAssert( spriteWorldP != NULL && dstRect != NULL );
-
- // 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 destRect 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->windowFrameP->frameRect;
- Rect tempSrcRect, tempDstRect;
-
- // Size of area that was clipped in source rect
- short topClip=0, rightClip=0, bottomClip=0, leftClip=0;
-
- SWAssert( spriteWorldP != NULL && srcFrameP != NULL && dstFrameP != NULL );
-
-
- // 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;
- }
-
-
- // Do the wrapping and drawing //
-
- // Draw top section, starting at left and going right //
-
- if (topClip)
- {
- if (leftClip) // Draw top-left piece //
- {
- // Wrap source rect to lower-right corner //
- tempSrcRect.bottom = srcFrameP->frameRect.bottom;
- tempSrcRect.right = srcFrameP->frameRect.right;
- tempSrcRect.top = srcFrameP->frameRect.bottom - topClip;
- tempSrcRect.left = srcFrameP->frameRect.right - leftClip;
-
- // Position dest rect at top-left corner //
- tempDstRect.left = dstRect.left;
- tempDstRect.top = dstRect.top;
- tempDstRect.right = dstRect.left + leftClip;
- tempDstRect.bottom = dstRect.top + topClip;
-
- (*spriteWorldP->screenDrawProc)(srcFrameP, dstFrameP,
- &tempSrcRect, &tempDstRect);
- }
-
-
- // Draw top piece //
-
- // Wrap source rect to bottom side //
- tempSrcRect.right = srcRect.right; // Copy clipped source rect
- tempSrcRect.left = srcRect.left;
- tempSrcRect.bottom = srcFrameP->frameRect.bottom;
- tempSrcRect.top = srcFrameP->frameRect.bottom - topClip;
-
- // Position dest rect at top side //
- tempDstRect.top = dstRect.top;
- tempDstRect.bottom = dstRect.top + topClip;
- tempDstRect.left = dstRect.left + leftClip;
- tempDstRect.right = dstRect.right - rightClip;
-
- (*spriteWorldP->screenDrawProc)(srcFrameP, dstFrameP,
- &tempSrcRect, &tempDstRect);
-
-
- if (rightClip) // Draw top-right piece //
- {
- // Wrap source rect to lower-left corner //
- tempSrcRect.bottom = srcFrameP->frameRect.bottom;
- tempSrcRect.left = srcFrameP->frameRect.left;
- tempSrcRect.right = srcFrameP->frameRect.left + rightClip;
- tempSrcRect.top = srcFrameP->frameRect.bottom - topClip;
-
- // Position dest rect at top-right corner //
- tempDstRect.top = dstRect.top;
- tempDstRect.right = dstRect.right;
- tempDstRect.bottom = dstRect.top + topClip;
- tempDstRect.left = dstRect.right - rightClip;
-
- (*spriteWorldP->screenDrawProc)(srcFrameP, dstFrameP,
- &tempSrcRect, &tempDstRect);
- }
- }
-
-
- // Draw middle section, starting at left and going right //
-
- if (leftClip) // Draw left piece //
- {
- // Wrap source rect to right side //
- tempSrcRect.top = srcRect.top; // Copy clipped source rect
- tempSrcRect.bottom = srcRect.bottom;
- tempSrcRect.right = srcFrameP->frameRect.right;
- tempSrcRect.left = srcFrameP->frameRect.right - leftClip;
-
- // Position dest rect at left side //
- tempDstRect.left = dstRect.left;
- tempDstRect.right = dstRect.left + leftClip;
- tempDstRect.top = dstRect.top + topClip;
- tempDstRect.bottom = dstRect.bottom - bottomClip;
-
- (*spriteWorldP->screenDrawProc)(srcFrameP, dstFrameP,
- &tempSrcRect, &tempDstRect);
- }
-
-
- // Draw main middle piece (not wrapped) //
-
- // Position dest rect at middle //
- tempDstRect.left = dstRect.left + leftClip;
- tempDstRect.top = dstRect.top + topClip;
- tempDstRect.right = dstRect.right - rightClip;
- tempDstRect.bottom = dstRect.bottom - bottomClip;
-
- (*spriteWorldP->screenDrawProc)(srcFrameP, dstFrameP,
- &srcRect, &tempDstRect);
-
-
- if (rightClip) // Draw right piece //
- {
- // Wrap source rect to left side //
- tempSrcRect.top = srcRect.top; // Copy clipped source rect
- tempSrcRect.bottom = srcRect.bottom;
- tempSrcRect.left = srcFrameP->frameRect.left;
- tempSrcRect.right = srcFrameP->frameRect.left + rightClip;
-
- // Position dest rect at right side //
- tempDstRect.right = dstRect.right;
- tempDstRect.left = dstRect.right - rightClip;
- tempDstRect.top = dstRect.top + topClip;
- tempDstRect.bottom = dstRect.bottom - bottomClip;
-
- (*spriteWorldP->screenDrawProc)(srcFrameP, dstFrameP,
- &tempSrcRect, &tempDstRect);
- }
-
-
-
- // Draw bottom section, starting at left and going right //
-
- if (bottomClip)
- {
- if (leftClip) // Draw bottom-left piece //
- {
- // Wrap source rect to upper-right corner //
- tempSrcRect.top = srcFrameP->frameRect.top;
- tempSrcRect.right = srcFrameP->frameRect.right;
- tempSrcRect.bottom = srcFrameP->frameRect.top + bottomClip;
- tempSrcRect.left = srcFrameP->frameRect.right - leftClip;
-
- // Position dest rect at bottom-left corner //
- tempDstRect.bottom = dstRect.bottom;
- tempDstRect.left = dstRect.left;
- tempDstRect.top = dstRect.bottom - bottomClip;
- tempDstRect.right = dstRect.left + leftClip;
-
- (*spriteWorldP->screenDrawProc)(srcFrameP, dstFrameP,
- &tempSrcRect, &tempDstRect);
- }
-
-
- // Draw bottom piece //
-
- // Wrap source rect to top side //
- tempSrcRect.right = srcRect.right; // Copy clipped source rect
- tempSrcRect.left = srcRect.left;
- tempSrcRect.top = srcFrameP->frameRect.top;
- tempSrcRect.bottom = srcFrameP->frameRect.top + bottomClip;
-
- // Position dest rect at bottom side //
- tempDstRect.bottom = dstRect.bottom;
- tempDstRect.top = dstRect.bottom - bottomClip;
- tempDstRect.left = dstRect.left + leftClip;
- tempDstRect.right = dstRect.right - rightClip;
-
- (*spriteWorldP->screenDrawProc)(srcFrameP, dstFrameP,
- &tempSrcRect, &tempDstRect);
-
-
- if (rightClip) // Draw bottom-right piece //
- {
- // Wrap source rect to upper-left corner //
- tempSrcRect.top = srcFrameP->frameRect.top;
- tempSrcRect.left = srcFrameP->frameRect.left;
- tempSrcRect.bottom = srcFrameP->frameRect.top + bottomClip;
- tempSrcRect.right = srcFrameP->frameRect.left + rightClip;
-
- // Position dest rect at bottom-right corner //
- tempDstRect.bottom = dstRect.bottom;
- tempDstRect.right = dstRect.right;
- tempDstRect.top = dstRect.bottom - bottomClip;
- tempDstRect.left = dstRect.right - rightClip;
-
- (*spriteWorldP->screenDrawProc)(srcFrameP, dstFrameP,
- &tempSrcRect, &tempDstRect);
- }
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWCheckWrappedIdleSpriteOverlap - same as SWCheckIdleSpriteOverlap,
- // but for scrolling SpriteWorlds.
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWCheckWrappedIdleSpriteOverlap(
- SpriteWorldPtr spriteWorldP,
- register SpritePtr idleSpriteP,
- SpritePtr headActiveSpriteP)
- {
- Rect *visScrollRectP = &spriteWorldP->visScrollRect;
- register SpriteLayerPtr curSpriteLayerP = spriteWorldP->headSpriteLayerP;
- register SpritePtr curSpriteP = curSpriteLayerP->headSpriteP;
-
- register SpritePtr activeSpriteP = headActiveSpriteP;
- short srcHorizOffset;
- short srcVertOffset;
-
- SWAssert( spriteWorldP != NULL && idleSpriteP != NULL );
-
- // In case the first layer(s) have no sprites
- while (curSpriteP == NULL && activeSpriteP != NULL)
- {
- curSpriteLayerP = curSpriteLayerP->nextSpriteLayerP;
- curSpriteP = curSpriteLayerP->headSpriteP;
- }
-
-
- // iterate through the active sprites
- while (activeSpriteP != NULL)
- {
- // Skip all active sprites above the idle sprite
- while (curSpriteP != activeSpriteP)
- {
- // Have we cycled through all active sprites below the idle sprite?
- if (curSpriteP == idleSpriteP)
- return;
-
-
- curSpriteP = curSpriteP->nextSpriteP;
-
- // Cycle curSpriteP through all the sprite layers
- while (curSpriteP == NULL)
- {
- curSpriteLayerP = curSpriteLayerP->nextSpriteLayerP;
- curSpriteP = curSpriteLayerP->headSpriteP;
- }
- }
-
-
- // do the sprites overlap?
- if ((idleSpriteP->oldFrameRect.top < activeSpriteP->destFrameRect.bottom) &&
- (idleSpriteP->oldFrameRect.bottom > activeSpriteP->destFrameRect.top) &&
- (idleSpriteP->oldFrameRect.left < activeSpriteP->destFrameRect.right) &&
- (idleSpriteP->oldFrameRect.right > activeSpriteP->destFrameRect.left))
- {
- Rect srcSectRect, dstSectRect;
-
- // 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->destFrameRect.left);
- dstSectRect.top =
- SW_MAX(idleSpriteP->destFrameRect.top, activeSpriteP->destFrameRect.top);
- dstSectRect.right =
- SW_MIN(idleSpriteP->destFrameRect.right, activeSpriteP->destFrameRect.right);
- dstSectRect.bottom =
- SW_MIN(idleSpriteP->destFrameRect.bottom, activeSpriteP->destFrameRect.bottom);
-
- // Calculate the source rect
- srcSectRect = dstSectRect;
-
- srcHorizOffset = idleSpriteP->curFrameP->frameRect.left;
- srcVertOffset = idleSpriteP->curFrameP->frameRect.top;
-
- srcSectRect.left -= (idleSpriteP->destFrameRect.left - srcHorizOffset);
- srcSectRect.right -= (idleSpriteP->destFrameRect.left - srcHorizOffset);
- srcSectRect.top -= (idleSpriteP->destFrameRect.top - srcVertOffset);
- srcSectRect.bottom -= (idleSpriteP->destFrameRect.top - srcVertOffset);
-
-
-
- // Clip the sprite's dstSectRect with visScrollRect
-
- if (dstSectRect.top < visScrollRectP->top)
- {
- srcSectRect.top += visScrollRectP->top - dstSectRect.top;
- dstSectRect.top = visScrollRectP->top;
- }
-
- if (dstSectRect.bottom > visScrollRectP->bottom)
- {
- srcSectRect.bottom += visScrollRectP->bottom - dstSectRect.bottom;
- dstSectRect.bottom = visScrollRectP->bottom;
- }
-
- if (dstSectRect.left < visScrollRectP->left)
- {
- srcSectRect.left += visScrollRectP->left - dstSectRect.left;
- dstSectRect.left = visScrollRectP->left;
- }
-
- if (dstSectRect.right > visScrollRectP->right)
- {
- srcSectRect.right += visScrollRectP->right - dstSectRect.right;
- dstSectRect.right = visScrollRectP->right;
- }
-
-
- // 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;
-
- // copy a piece of the sprite image onto the back drop piece
- SWDrawWrappedSprite(idleSpriteP, spriteWorldP->workFrameP,
- &srcSectRect, &dstSectRect);
-
- if (idleSpriteP->isUnderTiles && spriteWorldP->tilingIsOn)
- {
- dstSectRect.top += spriteWorldP->vertScrollRectOffset;
- dstSectRect.bottom += spriteWorldP->vertScrollRectOffset;
- dstSectRect.left += spriteWorldP->horizScrollRectOffset;
- dstSectRect.right += spriteWorldP->horizScrollRectOffset;
- SWDrawTilesAboveSprite(spriteWorldP, &dstSectRect);
- }
- }
-
- activeSpriteP = activeSpriteP->nextActiveSpriteP;
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWRedrawErasedIdleSprites - redraw an idle sprite if it was erased
- // when an active sprite overlapping it was erased.
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWRedrawErasedIdleSprites(
- SpriteWorldPtr spriteWorldP,
- SpritePtr headActiveSpriteP,
- SpritePtr headIdleSpriteP)
- {
- Rect *visScrollRectP = &spriteWorldP->visScrollRect;
- register SpritePtr activeSpriteP;
- register SpritePtr idleSpriteP;
- short srcHorizOffset;
- short srcVertOffset;
-
- SWAssert( spriteWorldP != NULL );
-
- idleSpriteP = headIdleSpriteP;
-
- // iterate through the idle sprites
- while (idleSpriteP != NULL)
- {
- activeSpriteP = headActiveSpriteP;
-
- // iterate through the active sprites
- while (activeSpriteP != NULL)
- {
- // did the sprites overlap?
- if ((idleSpriteP->oldFrameRect.top < activeSpriteP->oldFrameRect.bottom) &&
- (idleSpriteP->oldFrameRect.bottom > activeSpriteP->oldFrameRect.top) &&
- (idleSpriteP->oldFrameRect.left < activeSpriteP->oldFrameRect.right) &&
- (idleSpriteP->oldFrameRect.right > activeSpriteP->oldFrameRect.left))
- {
- Rect srcSectRect, dstSectRect;
-
- // calculate the intersection between the idle sprite's old
- // rect and the active sprite's old rect
- dstSectRect.left =
- SW_MAX(idleSpriteP->oldFrameRect.left, activeSpriteP->oldFrameRect.left);
- dstSectRect.top =
- SW_MAX(idleSpriteP->oldFrameRect.top, activeSpriteP->oldFrameRect.top);
- dstSectRect.right =
- SW_MIN(idleSpriteP->oldFrameRect.right, activeSpriteP->oldFrameRect.right);
- dstSectRect.bottom =
- SW_MIN(idleSpriteP->oldFrameRect.bottom, activeSpriteP->oldFrameRect.bottom);
-
- // Calculate the source rect
- srcSectRect = dstSectRect;
-
- srcHorizOffset = idleSpriteP->curFrameP->frameRect.left;
- srcVertOffset = idleSpriteP->curFrameP->frameRect.top;
-
- srcSectRect.left -= (idleSpriteP->oldFrameRect.left - srcHorizOffset);
- srcSectRect.right -= (idleSpriteP->oldFrameRect.left - srcHorizOffset);
- srcSectRect.top -= (idleSpriteP->oldFrameRect.top - srcVertOffset);
- srcSectRect.bottom -= (idleSpriteP->oldFrameRect.top - srcVertOffset);
-
-
- // Clip the sprite's dstSectRect with visScrollRect
-
- if (dstSectRect.top < visScrollRectP->top)
- {
- srcSectRect.top += visScrollRectP->top - dstSectRect.top;
- dstSectRect.top = visScrollRectP->top;
- }
-
- if (dstSectRect.bottom > visScrollRectP->bottom)
- {
- srcSectRect.bottom += visScrollRectP->bottom - dstSectRect.bottom;
- dstSectRect.bottom = visScrollRectP->bottom;
- }
-
- if (dstSectRect.left < visScrollRectP->left)
- {
- srcSectRect.left += visScrollRectP->left - dstSectRect.left;
- dstSectRect.left = visScrollRectP->left;
- }
-
- if (dstSectRect.right > visScrollRectP->right)
- {
- srcSectRect.right += visScrollRectP->right - dstSectRect.right;
- dstSectRect.right = visScrollRectP->right;
- }
-
-
- // 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;
-
- // copy a piece of the sprite image onto the back drop piece
- SWDrawWrappedSprite(idleSpriteP, spriteWorldP->workFrameP,
- &srcSectRect, &dstSectRect);
-
- if (idleSpriteP->isUnderTiles && spriteWorldP->tilingIsOn)
- {
- dstSectRect.top += spriteWorldP->vertScrollRectOffset;
- dstSectRect.bottom += spriteWorldP->vertScrollRectOffset;
- dstSectRect.left += spriteWorldP->horizScrollRectOffset;
- dstSectRect.right += spriteWorldP->horizScrollRectOffset;
- SWDrawTilesAboveSprite(spriteWorldP, &dstSectRect);
- }
- }
-
- activeSpriteP = activeSpriteP->nextActiveSpriteP;
- }
-
- idleSpriteP = idleSpriteP->nextIdleSpriteP;
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWRedrawIdleSpritesInRect - used by SWAnimateScrollingSpriteWorld
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWRedrawIdleSpritesInRect(
- SpriteWorldPtr spriteWorldP,
- SpritePtr headIdleSpriteP,
- Rect *updateRect)
- {
- Rect *visScrollRectP = &spriteWorldP->visScrollRect;
- register SpritePtr idleSpriteP;
- short srcHorizOffset;
- short srcVertOffset;
-
- SWAssert( spriteWorldP != NULL && updateRect != NULL );
-
- idleSpriteP = headIdleSpriteP;
-
- // iterate through the idle sprites
- while (idleSpriteP != NULL)
- {
- // is the idle sprite in the updateRect?
- if ((idleSpriteP->oldFrameRect.top < updateRect->bottom) &&
- (idleSpriteP->oldFrameRect.bottom > updateRect->top) &&
- (idleSpriteP->oldFrameRect.left < updateRect->right) &&
- (idleSpriteP->oldFrameRect.right > updateRect->left))
- {
- Rect srcSectRect, dstSectRect;
-
- // calculate the intersection between the idle sprite's old
- // rect and the updateRect
- dstSectRect.left =
- SW_MAX(idleSpriteP->oldFrameRect.left, updateRect->left);
- dstSectRect.top =
- SW_MAX(idleSpriteP->oldFrameRect.top, updateRect->top);
- dstSectRect.right =
- SW_MIN(idleSpriteP->oldFrameRect.right, updateRect->right);
- dstSectRect.bottom =
- SW_MIN(idleSpriteP->oldFrameRect.bottom, updateRect->bottom);
-
- // Calculate the source rect
- srcSectRect = dstSectRect;
-
- srcHorizOffset = idleSpriteP->curFrameP->frameRect.left;
- srcVertOffset = idleSpriteP->curFrameP->frameRect.top;
-
- srcSectRect.left -= (idleSpriteP->oldFrameRect.left - srcHorizOffset);
- srcSectRect.right -= (idleSpriteP->oldFrameRect.left - srcHorizOffset);
- srcSectRect.top -= (idleSpriteP->oldFrameRect.top - srcVertOffset);
- srcSectRect.bottom -= (idleSpriteP->oldFrameRect.top - srcVertOffset);
-
-
- // Clip the sprite's dstSectRect with visScrollRect
-
- if (dstSectRect.top < visScrollRectP->top)
- {
- srcSectRect.top += visScrollRectP->top - dstSectRect.top;
- dstSectRect.top = visScrollRectP->top;
- }
-
- if (dstSectRect.bottom > visScrollRectP->bottom)
- {
- srcSectRect.bottom += visScrollRectP->bottom - dstSectRect.bottom;
- dstSectRect.bottom = visScrollRectP->bottom;
- }
-
- if (dstSectRect.left < visScrollRectP->left)
- {
- srcSectRect.left += visScrollRectP->left - dstSectRect.left;
- dstSectRect.left = visScrollRectP->left;
- }
-
- if (dstSectRect.right > visScrollRectP->right)
- {
- srcSectRect.right += visScrollRectP->right - dstSectRect.right;
- dstSectRect.right = visScrollRectP->right;
- }
-
-
- // 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;
-
- // copy a piece of the sprite image onto the back drop piece
- SWDrawWrappedSprite(idleSpriteP, spriteWorldP->workFrameP,
- &srcSectRect, &dstSectRect);
-
- if (idleSpriteP->isUnderTiles && spriteWorldP->tilingIsOn)
- {
- dstSectRect.top += spriteWorldP->vertScrollRectOffset;
- dstSectRect.bottom += spriteWorldP->vertScrollRectOffset;
- dstSectRect.left += spriteWorldP->horizScrollRectOffset;
- dstSectRect.right += spriteWorldP->horizScrollRectOffset;
- SWDrawTilesAboveSprite(spriteWorldP, &dstSectRect);
- }
- }
-
- idleSpriteP = idleSpriteP->nextIdleSpriteP;
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWSetScrollingWorldMoveBounds
- ///--------------------------------------------------------------------------------------
-
-
- SW_FUNC void SWSetScrollingWorldMoveBounds(
- SpriteWorldPtr spriteWorldP,
- Rect* scrollRectMoveBounds)
- {
- SWAssert( spriteWorldP != NULL && scrollRectMoveBounds != NULL );
-
- spriteWorldP->scrollRectMoveBounds = *scrollRectMoveBounds;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWSetScrollingWorldMoveProc
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWSetScrollingWorldMoveProc(
- SpriteWorldPtr spriteWorldP,
- WorldMoveProcPtr worldMoveProcP,
- SpritePtr followSpriteP)
- {
- SWAssert( spriteWorldP != NULL && worldMoveProcP != NULL );
-
- spriteWorldP->worldMoveProc = worldMoveProcP;
- spriteWorldP->followSpriteP = followSpriteP;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWSetSpriteWorldScrollDelta
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWSetSpriteWorldScrollDelta(
- SpriteWorldPtr spriteWorldP,
- short horizDelta,
- short vertDelta)
- {
- SWAssert( spriteWorldP != NULL );
-
- 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;
-
- SWAssert( spriteWorldP != NULL );
-
- 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.bottom -= spriteWorldP->visScrollRect.top -
- spriteWorldP->scrollRectMoveBounds.top;
- spriteWorldP->visScrollRect.top = spriteWorldP->scrollRectMoveBounds.top;
- }
- else if ((long)vertPos + height > spriteWorldP->scrollRectMoveBounds.bottom)
- {
- spriteWorldP->visScrollRect.top -= spriteWorldP->visScrollRect.bottom -
- spriteWorldP->scrollRectMoveBounds.bottom;
- spriteWorldP->visScrollRect.bottom = spriteWorldP->scrollRectMoveBounds.bottom;
- }
- else
- {
- spriteWorldP->visScrollRect.top = vertPos;
- spriteWorldP->visScrollRect.bottom = vertPos + height;
- }
-
-
- // Move horizontally
- if ((long)horizPos < spriteWorldP->scrollRectMoveBounds.left)
- {
- spriteWorldP->visScrollRect.right -= spriteWorldP->visScrollRect.left -
- spriteWorldP->scrollRectMoveBounds.left;
- spriteWorldP->visScrollRect.left = spriteWorldP->scrollRectMoveBounds.left;
- }
- else if ((long)horizPos + width > spriteWorldP->scrollRectMoveBounds.right)
- {
- spriteWorldP->visScrollRect.left -= spriteWorldP->visScrollRect.right -
- spriteWorldP->scrollRectMoveBounds.right;
- spriteWorldP->visScrollRect.right = spriteWorldP->scrollRectMoveBounds.right;
- }
- 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 //
-
- SWAssert( spriteWorldP != NULL );
-
- // 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);
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWCalculateOffscreenScrollRect (wrap offscreenScrollRect in the work area)
- ///--------------------------------------------------------------------------------------
-
-
- SW_FUNC void SWCalculateOffscreenScrollRect(
- SpriteWorldPtr spriteWorldP)
- {
- Rect *offscreenScrollRectP = &spriteWorldP->offscreenScrollRect;
- Rect *visScrollRectP = &spriteWorldP->visScrollRect;
-
- SWAssert( spriteWorldP != NULL );
-
- 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;
- }
-
-
-