home *** CD-ROM | disk | FTP | other *** search
Text File | 1999-02-12 | 85.6 KB | 2,918 lines | [TEXT/CWIE] |
- ///--------------------------------------------------------------------------------------
- // Tiling.c
- //
- // By Vern Jensen. SWLoadTile routines by Karl Bunker.
- //
- // Created: 11/15/95
- //
- // Description: Routines to use tiling with SpriteWorld
- ///--------------------------------------------------------------------------------------
-
-
- #ifndef __QUICKDRAW__
- #include <QuickDraw.h>
- #endif
-
- #ifndef __MEMORY__
- #include <Memory.h>
- #endif
-
- #ifndef __SPRITEWORLD__
- #include "SpriteWorld.h"
- #endif
-
- #ifndef __SPRITEFRAME__
- #include "SpriteFrame.h"
- #endif
-
- #ifndef __SPRITEWORLDUTILS__
- #include "SpriteWorldUtils.h"
- #endif
-
- #ifndef __TILING__
- #include "Tiling.h"
- #endif
-
- #ifndef __BLITPIXIE__
- #include "BlitPixie.h"
- #endif
-
-
-
- ///--------------------------------------------------------------------------------------
- // SWInitTiling
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC OSErr SWInitTiling(
- SpriteWorldPtr spriteWorldP,
- short tileHeight,
- short tileWidth,
- short maxNumTiles)
- {
- OSErr err = noErr;
- Size arraySize;
- short tileIndex;
-
- SW_ASSERT(spriteWorldP != NULL);
-
- if (spriteWorldP->tilingIsInitialized)
- {
- err = kTilingAlreadyInitialized;
- }
-
-
- if (err == noErr)
- {
- spriteWorldP->tilingIsOn = true;
- spriteWorldP->tilingIsInitialized = true;
- spriteWorldP->lastActiveTileLayer = 0;
- spriteWorldP->maxNumTiles = maxNumTiles;
- spriteWorldP->tileHeight = tileHeight;
- spriteWorldP->tileWidth = tileWidth;
- }
-
-
- if (err == noErr)
- {
- // Create both tiling cache and changedTiles array of rects
- err = SWInitTilingCache(spriteWorldP);
- }
-
-
- if (err == noErr)
- {
- // Allocate memory for tileFrameArray
- arraySize = (Size)maxNumTiles * sizeof(FramePtr);
- spriteWorldP->tileFrameArray = (FramePtr *)NewPtrClear(arraySize);
- err = MemError();
- }
-
-
- if (err == noErr)
- {
- // Allocate memory for curTileImage array
- arraySize = (Size)maxNumTiles * sizeof(short);
- spriteWorldP->curTileImage = (short *)NewPtr(arraySize);
- err = MemError();
-
- if (err == noErr)
- {
- // Set up values in curTileImage array
- for (tileIndex = 0; tileIndex < maxNumTiles; tileIndex++)
- spriteWorldP->curTileImage[tileIndex] = tileIndex;
- }
- }
-
-
- if (err == noErr)
- {
- // Allocate memory for tileLayerArray
- arraySize = (Size)kNumTileLayers * sizeof(TileMapStructPtr);
- spriteWorldP->tileLayerArray = (TileMapStructPtr *)NewPtrClear(arraySize);
- err = MemError();
- }
-
-
- SWSetStickyIfError(err);
- return err;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWExitTiling
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWExitTiling(
- SpriteWorldPtr spriteWorldP)
- {
- short tileIndex;
-
- SW_ASSERT(spriteWorldP != NULL);
-
- // Was tiling ever initialized?
- if (spriteWorldP->tilingIsInitialized)
- {
- tileIndex = spriteWorldP->maxNumTiles;
- while (tileIndex--)
- {
- SWDisposeTile(spriteWorldP, tileIndex);
- }
-
- DisposePtr((Ptr)spriteWorldP->tileFrameArray);
- DisposePtr((Ptr)spriteWorldP->curTileImage);
- DisposePtr((Ptr)spriteWorldP->tileLayerArray);
- DisposePtr((Ptr)spriteWorldP->changedTiles);
- spriteWorldP->changedTiles = NULL;
-
- DisposePtr((Ptr)spriteWorldP->tilingCache[0]); // Dispose the data
- DisposePtr((Ptr)spriteWorldP->tilingCache); // Dispose the array of pointers
- spriteWorldP->tilingCache = NULL;
-
-
- spriteWorldP->tilingIsInitialized = false;
- spriteWorldP->tilingIsOn = false;
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWInitTilingCache - an internal function; called by SWInitTiling and SWChangeTileSize.
- // Creates both the tiling cache and the changedTiles array of rects.
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC OSErr SWInitTilingCache(
- SpriteWorldPtr spriteWorldP)
- {
- short row, col, numTilingCacheCols, numTilingCacheRows, *tilingCacheData;
- Size arraySize;
- OSErr err = noErr;
-
- // Dispose the old tilingCache if necessary
- if (spriteWorldP->tilingCache != NULL)
- {
- DisposePtr((Ptr)spriteWorldP->tilingCache[0]); // Dispose the data
- DisposePtr((Ptr)spriteWorldP->tilingCache); // Dispose the array of pointers
- }
-
- // Dispose the old changeTiles array of rects if necessary
- if (spriteWorldP->changedTiles != NULL)
- {
- DisposePtr((Ptr)spriteWorldP->changedTiles);
- }
-
- numTilingCacheRows = spriteWorldP->backRect.bottom / spriteWorldP->tileHeight;
- numTilingCacheCols = spriteWorldP->backRect.right / spriteWorldP->tileWidth;
- spriteWorldP->numTilingCacheRows = numTilingCacheRows;
- spriteWorldP->numTilingCacheCols = numTilingCacheCols;
-
-
- // Allocate memory for changedTiles array of rects
- spriteWorldP->changedTilesArraySize = (numTilingCacheRows+1) * (numTilingCacheCols+1);
- arraySize = (Size)(numTilingCacheRows+1) * (numTilingCacheCols+1) * sizeof(Rect);
- spriteWorldP->changedTiles = (Rect *)NewPtr(arraySize);
- err = MemError();
-
-
- if (err == noErr)
- {
- // Allocate the array of pointers for the tiling Cache
- arraySize = (Size)numTilingCacheRows * sizeof(short*);
- spriteWorldP->tilingCache = (short **)NewPtr(arraySize);
- err = MemError();
-
- if (err == noErr)
- {
- // Allocate memory for the actual data of the tiling Cache
- arraySize = (Size)numTilingCacheRows * numTilingCacheCols * sizeof(short);
- tilingCacheData = (short *)NewPtr(arraySize);
- err = MemError();
-
- // If there was an error, dispose what we already created earlier
- if (err != noErr)
- DisposePtr((Ptr)spriteWorldP->tilingCache);
- }
-
- if (err == noErr)
- {
- // Point each element of the tilingCache array to each row of the data
- for (row = 0; row < numTilingCacheRows; row++)
- spriteWorldP->tilingCache[row] = &tilingCacheData[(long)row * numTilingCacheCols];
-
- // Set all elements to -1 (indicating that each tile needs to be drawn)
- for (row = 0; row < numTilingCacheRows; row++)
- for (col = 0; col < numTilingCacheCols; col++)
- spriteWorldP->tilingCache[row][col] = -1;
- }
- }
-
- if (err)
- {
- spriteWorldP->tilingCache = NULL;
- spriteWorldP->changedTiles = NULL;
- }
-
- return err;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWCreateTileMap
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC OSErr SWCreateTileMap(
- TileMapStructPtr *tileMapStructPP,
- short numTileMapRows,
- short numTileMapCols)
- {
- TileMapStructPtr tileMapStructP;
- Size arraySize;
- OSErr err = noErr;
-
-
- // Allocate memory for the TileMapStruct
- tileMapStructP = (TileMapStructPtr)NewPtrClear(sizeof(TileMapStruct));
- err = MemError();
-
- if (err == noErr)
- {
- tileMapStructP->numRows = numTileMapRows;
- tileMapStructP->numCols = numTileMapCols;
-
- // Allocate the array of pointers that point to the data of the TileMap
- arraySize = (Size)numTileMapRows * sizeof(short*);
- tileMapStructP->arrayOfPointersH = NewHandle(arraySize);
- err = MemError();
- }
-
- if (err == noErr)
- {
- // Allocate memory for the actual data of the TileMap
- arraySize = ((Size)numTileMapRows * numTileMapCols + 2) * sizeof(short);
- tileMapStructP->tileMapDataH = NewHandleClear(arraySize);
- err = MemError();
- }
-
- if (err == noErr)
- {
- SWLockTileMap(tileMapStructP);
- }
-
-
- if (err != noErr)
- {
- // Dispose what we created
- if (tileMapStructP != NULL)
- {
- DisposeHandle((Handle)tileMapStructP->arrayOfPointersH);
- DisposeHandle((Handle)tileMapStructP->tileMapDataH);
- DisposePtr((Ptr)tileMapStructP);
- tileMapStructP = NULL;
- }
- }
-
- // Return a pointer to the TileMapStruct in the tileMapStructPP variable
- *tileMapStructPP = tileMapStructP;
-
- SWSetStickyIfError(err);
- return err;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWDisposeTileMap
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWDisposeTileMap(
- TileMapStructPtr *tileMapStructPP)
- {
- TileMapStructPtr myTileMapStructP = *tileMapStructPP;
-
- if (myTileMapStructP != NULL)
- {
- DisposeHandle((Handle)myTileMapStructP->arrayOfPointersH);
- DisposeHandle((Handle)myTileMapStructP->tileMapDataH);
- DisposePtr((Ptr)myTileMapStructP);
- *tileMapStructPP = NULL;
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWLockTileMap
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWLockTileMap(
- TileMapStructPtr tileMapStructP)
- {
- short **arrayOfPointers;
- short *tileMapDataP;
- short row;
-
- SW_ASSERT(tileMapStructP != NULL);
-
- HLockHi(tileMapStructP->arrayOfPointersH);
- HLockHi(tileMapStructP->tileMapDataH);
-
- tileMapDataP = (short*)*tileMapStructP->tileMapDataH;
- arrayOfPointers = (short**)*tileMapStructP->arrayOfPointersH;
-
- // Point each element of the array of pointers to each row of the data
- for (row = 0; row < tileMapStructP->numRows; row++)
- {
- arrayOfPointers[row] = &tileMapDataP[(long)row * tileMapStructP->numCols + 2];
- }
-
- tileMapStructP->tileMap = arrayOfPointers;
- tileMapStructP->isLocked = true;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWUnlockTileMap
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWUnlockTileMap(
- TileMapStructPtr tileMapStructP)
- {
- SW_ASSERT(tileMapStructP != NULL);
-
- HUnlock(tileMapStructP->arrayOfPointersH);
- HUnlock(tileMapStructP->tileMapDataH);
- tileMapStructP->tileMap = NULL;
- tileMapStructP->isLocked = false;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWInstallTileMap
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWInstallTileMap(
- SpriteWorldPtr spriteWorldP,
- TileMapStructPtr tileMapStructP,
- short tileLayer)
- {
- short curLayer;
-
- SW_ASSERT(spriteWorldP != NULL);
- SW_ASSERT(tileLayer < kNumTileLayers);
-
- // Install the TileMap
- spriteWorldP->tileLayerArray[tileLayer] = tileMapStructP;
- spriteWorldP->lastActiveTileLayer = 0;
-
- // Find the last active tile layer
- for (curLayer = 0; curLayer < kNumTileLayers; curLayer++)
- {
- if (spriteWorldP->tileLayerArray[curLayer] != NULL)
- spriteWorldP->lastActiveTileLayer = curLayer;
- }
-
- // Set the appropriate tileRectDrawProc
- if (spriteWorldP->lastActiveTileLayer == 0)
- {
- spriteWorldP->tileRectDrawProc = SWDrawTilesInRect;
- }
- else
- {
- spriteWorldP->tileRectDrawProc = SWDrawTileLayersInRect;
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWLoadTileMap
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC OSErr SWLoadTileMap(
- TileMapStructPtr *tileMapStructPP,
- short resourceID)
- {
- TileMapStructPtr tileMapStructP;
- short *tileMapData;
- Size arraySize;
- OSErr err = noErr;
-
-
- // Allocate memory for the TileMapStruct
- tileMapStructP = (TileMapStructPtr)NewPtrClear(sizeof(TileMapStruct));
- err = MemError();
-
- if (err == noErr)
- {
- // Load the resource
- tileMapStructP->tileMapDataH = Get1Resource('TMAP', resourceID);
-
- if (tileMapStructP->tileMapDataH == NULL)
- err = ResError() ? ResError() : resNotFound;
- }
-
- if (err == noErr)
- {
- DetachResource((Handle)tileMapStructP->tileMapDataH);
-
- tileMapData = (short*)*tileMapStructP->tileMapDataH;
- tileMapStructP->numRows = tileMapData[0];
- tileMapStructP->numCols = tileMapData[1];
-
- // Allocate the array of pointers that point to the data of the TileMap
- arraySize = (Size)tileMapStructP->numRows * sizeof(short*);
- tileMapStructP->arrayOfPointersH = NewHandle(arraySize);
- err = MemError();
- }
-
- if (err == noErr)
- {
- SWLockTileMap(tileMapStructP);
- }
-
-
- if (err != noErr)
- {
- // Dispose what we created
- if (tileMapStructP != NULL)
- {
- DisposeHandle((Handle)tileMapStructP->arrayOfPointersH);
- DisposeHandle((Handle)tileMapStructP->tileMapDataH);
- DisposePtr((Ptr)tileMapStructP);
- tileMapStructP = NULL;
- }
- }
-
- // Return a pointer to the TileMapStruct in the tileMapStructPP variable
- *tileMapStructPP = tileMapStructP;
-
- SWSetStickyIfError(err);
- return err;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWSaveTileMap
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC OSErr SWSaveTileMap(
- TileMapStructPtr tileMapStructP,
- short destResID)
- {
- short tempResID;
- short *tileMapData;
- Handle tempTileMapH;
- OSErr err = noErr;
-
- // Make sure there is a tileMap to save
- if (tileMapStructP == NULL)
- err = kNullTileMapErr;
-
- if (err == noErr)
- {
- // Save numRows & numCols in the first two elements of the tileMapData
- tileMapData = (short*)*tileMapStructP->tileMapDataH;
- tileMapData[0] = tileMapStructP->numRows;
- tileMapData[1] = tileMapStructP->numCols;
-
- // Add the TMAP resource, assigning it a temporary, unused ID
- tempResID = Unique1ID('TMAP');
- AddResource(tileMapStructP->tileMapDataH, 'TMAP', tempResID, "\p");
- err = ResError();
-
- // This call may fix a sporadic problem I've had occasionally that occurs when
- // opening one level, then opening another one, making it larger, saving it, and
- // re-opening it, all without quitting. Unfortunately, I couldn't reproduce it to
- // test this fix.
- if (err == noErr)
- WriteResource(tileMapStructP->tileMapDataH);
- }
-
- if (err == noErr)
- {
- do // Remove any old TMAP resources with destResID
- {
- SetResLoad(false);
- tempTileMapH = Get1Resource('TMAP', destResID);
- SetResLoad(true);
-
- if (tempTileMapH != NULL)
- {
- RemoveResource(tempTileMapH);
-
- // This could happen if the resource is protected
- err = ResError();
- SW_ASSERT(ResError() == noErr);
- }
- else if (ResError() != resNotFound && ResError() != noErr)
- {
- // This could happen if Get1Resource didn't have a free master
- // pointer and there isn't enough memory to allocate a new block
- err = ResError();
- }
- } while (tempTileMapH != NULL);
-
-
- // Change the resource ID to the proper one
- SetResInfo(tileMapStructP->tileMapDataH, destResID, "\p");
-
- // Update file, writing new resource and deleting old one in one step.
- UpdateResFile( CurResFile() );
- DetachResource(tileMapStructP->tileMapDataH);
- }
-
-
- SWSetStickyIfError(err);
- return err;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWResizeTileMap
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC OSErr SWResizeTileMap(
- TileMapStructPtr oldTileMapStructP,
- short numNewTileMapRows,
- short numNewTileMapCols)
- {
- TileMapStruct tempTileMapStruct;
- TileMapStructPtr newTileMapStructP;
- short row, numRowsToCopy, numColsToCopy;
- Size arraySize;
- OSErr err = noErr;
-
- SW_ASSERT(numNewTileMapRows > 0 && numNewTileMapCols > 0);
-
- if (oldTileMapStructP == NULL)
- err = kNullTileMapErr;
-
-
- if (err == noErr)
- {
- // Don't do anything if the TileMap is already the requested size.
- if (oldTileMapStructP->numRows == numNewTileMapRows &&
- oldTileMapStructP->numCols == numNewTileMapCols)
- {
- return noErr;
- }
-
- // Create the new TileMap
- err = SWCreateTileMap(&newTileMapStructP, numNewTileMapRows, numNewTileMapCols);
- }
-
- if (err == noErr)
- {
- if (oldTileMapStructP->isLocked == false)
- SWLockTileMap(oldTileMapStructP);
-
- numRowsToCopy = SW_MIN(oldTileMapStructP->numRows, numNewTileMapRows);
- numColsToCopy = SW_MIN(oldTileMapStructP->numCols, numNewTileMapCols);
-
- // Copy the data from the old TileMap to the new TileMap
- arraySize = (Size)numColsToCopy * sizeof(short);
- for (row = 0; row < numRowsToCopy; row++)
- {
- BlockMoveData(&oldTileMapStructP->tileMap[row][0],
- &newTileMapStructP->tileMap[row][0], arraySize);
- }
-
- // Swap contents of the new and old TileMapStructs
- tempTileMapStruct = *oldTileMapStructP;
- *oldTileMapStructP = *newTileMapStructP;
- *newTileMapStructP = tempTileMapStruct;
-
- // Dispose the newTileMapStruct, which now contains the old TileMap
- SWDisposeTileMap(&newTileMapStructP);
- }
-
-
- SWSetStickyIfError(err);
- return err;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWLoadTileFromCicnResource
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC OSErr SWLoadTileFromCicnResource(
- SpriteWorldPtr spriteWorldP,
- short tileID,
- short cicnID,
- MaskType maskType)
- {
- OSErr err;
- GWorldPtr saveGWorld;
- GDHandle saveGDH;
- FramePtr newFrameP;
- CIconHandle cIconH;
- Rect frameRect;
- Boolean maskIsSolid = false;
-
- SW_ASSERT(spriteWorldP != NULL);
-
- err = noErr;
- newFrameP = NULL;
-
- if ( !spriteWorldP->tilingIsInitialized )
- {
- err = kTilingNotInitialized;
- }
- else if ( tileID < 0 || tileID >= spriteWorldP->maxNumTiles)
- {
- err = kOutOfRangeErr;
- }
-
- if (maskType == kSolidMask)
- {
- maskIsSolid = true;
- maskType = kNoMask;
- }
-
- if ( err == noErr )
- {
- err = SWCreateFrameFromCicnResource(spriteWorldP, &newFrameP, cicnID, maskType);
-
- if ( err == noErr )
- {
- newFrameP->tileMaskIsSolid = maskIsSolid;
-
- // "Fix" the size if the CICN is larger than the tiles are
- if (newFrameP->frameRect.right > spriteWorldP->tileWidth)
- newFrameP->frameRect.right = spriteWorldP->tileWidth;
- if (newFrameP->frameRect.bottom > spriteWorldP->tileHeight)
- newFrameP->frameRect.bottom = spriteWorldP->tileHeight;
-
- cIconH = GetCIcon( cicnID );
-
- if (cIconH != NULL)
- {
- GetGWorld(&saveGWorld, &saveGDH);
-
- HLock((Handle)cIconH);
- frameRect = ((**cIconH).iconPMap.bounds);
- (**cIconH).iconPMap.baseAddr = *(**cIconH).iconData;
- (**cIconH).iconBMap.baseAddr = (Ptr)&((**cIconH).iconMaskData ) +
- ((**cIconH).iconMask.rowBytes * (frameRect.bottom-frameRect.top));
-
- (void)LockPixels( GetGWorldPixMap( newFrameP->framePort ) );
- SetGWorld( newFrameP->framePort, NULL );
- if ( spriteWorldP->pixelDepth > 1 )
- {
- CopyBits( (BitMap*)(&((**cIconH).iconPMap)),
- (BitMap*)*GetGWorldPixMap( newFrameP->framePort ),
- &frameRect, &newFrameP->frameRect, srcCopy, nil);
- }
- else
- {
- CopyBits( (BitMap*)(&((**cIconH).iconBMap)),
- (BitMap*)*GetGWorldPixMap( newFrameP->framePort ),
- &frameRect,
- &newFrameP->frameRect, srcCopy, nil);
- }
- UnlockPixels( GetGWorldPixMap( newFrameP->framePort ) );
- DisposeCIcon( cIconH );
- SetGWorld( saveGWorld, saveGDH );
- }
- else
- {
- err = MemError();
- }
- }
-
- if ( err == noErr )
- {
- // Are we replacing an old tile?
- if (spriteWorldP->tileFrameArray[tileID] != NULL)
- {
- SWDisposeTile( spriteWorldP, tileID );
- }
- spriteWorldP->tileFrameArray[tileID] = newFrameP;
- newFrameP->useCount++;
- }
- }
-
- if ( err != noErr && newFrameP != NULL )
- {
- SWDisposeFrame(&newFrameP);
- }
-
- SWSetStickyIfError(err);
- return err;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWLoadTilesFromPictResource
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC OSErr SWLoadTilesFromPictResource(
- SpriteWorldPtr spriteWorldP,
- short startTileID,
- short endTileID,
- short pictResID,
- short maskResID,
- MaskType maskType,
- short horizBorderWidth,
- short vertBorderHeight)
- {
- OSErr err;
- short tileIndex;
- FramePtr newFrameP;
- GWorldPtr tempPictGWorldP,
- tempMaskGWorldP,
- tempTempMaskGWorldP,
- currentGWorld;
- GDHandle currentGDH;
- Rect currentTileRect;
- short horizOffset,
- vertOffset;
- Boolean allTilesDone,
- maskIsSolid = false;
-
- SW_ASSERT(spriteWorldP != NULL);
-
- err = noErr;
- newFrameP = NULL;
- tempPictGWorldP = NULL;
- tempMaskGWorldP = NULL;
- tempTempMaskGWorldP = NULL;
-
- if ( !spriteWorldP->tilingIsInitialized )
- {
- err = kTilingNotInitialized;
- }
- else if ( startTileID < 0 || endTileID >= spriteWorldP->maxNumTiles)
- {
- err = kOutOfRangeErr;
- }
-
- if (maskType == kSolidMask)
- {
- maskIsSolid = true;
- maskType = kNoMask;
- }
-
- if ( err == noErr )
- {
- err = SWCreateGWorldFromPictResource( spriteWorldP, &tempPictGWorldP, pictResID );
-
- if ( err == noErr && maskType != kNoMask )
- err = SWCreateGWorldFromPictResource( spriteWorldP, &tempMaskGWorldP, maskResID );
-
- if (err == noErr)
- {
- if ( pictResID == maskResID && tempMaskGWorldP != NULL )
- {
- err = SWBlackenGWorld( tempMaskGWorldP );
- }
- }
-
- if ( err == noErr )
- {
- err = SWCreateFrameFromGWorldAndRectStart( &tempTempMaskGWorldP,
- spriteWorldP->tileWidth, spriteWorldP->tileHeight, maskType );
- }
-
- if ( err == noErr )
- {
- SetRect( ¤tTileRect, 0, 0,
- spriteWorldP->tileWidth, spriteWorldP->tileHeight );
- tileIndex = startTileID;
- horizOffset = spriteWorldP->tileWidth + horizBorderWidth;
- vertOffset = spriteWorldP->tileHeight + vertBorderHeight;
-
- allTilesDone = false;
- while( !allTilesDone && err == noErr )
- {
- err = SWCreateFrameFromGWorldAndRectPartial( &newFrameP, tempPictGWorldP,
- tempMaskGWorldP, tempTempMaskGWorldP, ¤tTileRect, maskType);
-
- if ( newFrameP != NULL && err == noErr )
- {
- newFrameP->tileMaskIsSolid = maskIsSolid;
-
- // Are we replacing an old tile?
- if (spriteWorldP->tileFrameArray[tileIndex] != NULL)
- {
- SWDisposeTile( spriteWorldP, tileIndex );
- }
- spriteWorldP->tileFrameArray[tileIndex] = newFrameP;
- newFrameP->useCount++;
-
- tileIndex++;
- if (tileIndex > endTileID )
- {
- allTilesDone = true;
- }
- else
- {
- if (tileIndex >= spriteWorldP->maxNumTiles)
- {
- err = kOutOfRangeErr;
- }
- currentTileRect.left += horizOffset;
- currentTileRect.right += horizOffset;
- if ( currentTileRect.right > tempPictGWorldP->portRect.right )
- {
- currentTileRect.left = 0;
- currentTileRect.right = spriteWorldP->tileWidth;
- currentTileRect.top += vertOffset;
- currentTileRect.bottom += vertOffset;
- if ( currentTileRect.bottom > tempPictGWorldP->portRect.bottom )
- {
- err = kOutOfRangeErr;
- }
- }
- }
- }
- }
-
- if (err == noErr)
- {
- // make a pixel mask
- if ((maskType & kPixelMask) != 0)
- {
- if (spriteWorldP->pixelDepth <= 8)
- {
- GetGWorld( ¤tGWorld, ¤tGDH );
- (void)LockPixels( GetGWorldPixMap(tempMaskGWorldP) );
- SetGWorld(tempMaskGWorldP, nil);
- InvertRect(&tempMaskGWorldP->portRect);
- SetGWorld( currentGWorld, currentGDH );
- UnlockPixels( GetGWorldPixMap(tempMaskGWorldP) );
- }
- }
- else if (tempMaskGWorldP != NULL)
- {
- // If no pixel Mask wanted, dispose
- // of the GWorld we used to make region
- DisposeGWorld( tempMaskGWorldP );
- }
- }
- }
- SWCreateFrameFromGWorldAndRectFinish( tempTempMaskGWorldP );
- }
-
- SWSetStickyIfError(err);
- return err;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWDisposeTile
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWDisposeTile(
- SpriteWorldPtr spriteWorldP,
- short tileID)
- {
- short tileIndex;
- Boolean gWorldStillInUse;
-
- SW_ASSERT(spriteWorldP != NULL);
- SW_ASSERT(spriteWorldP->tilingIsInitialized);
-
- // see if any other tile is using this tile's GWorld
- gWorldStillInUse = false;
- tileIndex = spriteWorldP->maxNumTiles;
- while ( tileIndex-- )
- {
- if ( tileIndex != tileID )
- {
- if ( spriteWorldP->tileFrameArray[tileIndex] != NULL &&
- ((spriteWorldP->tileFrameArray[tileIndex])->framePort ==
- (spriteWorldP->tileFrameArray[tileID])->framePort) )
- {
- gWorldStillInUse = true;
- }
- }
- }
- // set flag that tells SWDisposeFrame whether to dispose of GWorld
- (spriteWorldP->tileFrameArray[tileID])->sharesGWorld = gWorldStillInUse;
-
- (void)SWDisposeFrame( &spriteWorldP->tileFrameArray[tileID] );
- spriteWorldP->tileFrameArray[tileID] = NULL;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWLockTiles
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWLockTiles(
- SpriteWorldPtr spriteWorldP)
- {
- short tileIndex;
-
- SW_ASSERT(spriteWorldP != NULL);
-
- // Tiling might not be initialized if this was called from SWLockSpriteWorld
- if (spriteWorldP->tilingIsInitialized)
- {
- for (tileIndex = 0; tileIndex < spriteWorldP->maxNumTiles; tileIndex++)
- {
- if (spriteWorldP->tileFrameArray[tileIndex] != NULL)
- SWLockFrame(spriteWorldP->tileFrameArray[tileIndex]);
- }
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWUnlockTiles
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWUnlockTiles(
- SpriteWorldPtr spriteWorldP)
- {
- short tileIndex;
-
- SW_ASSERT(spriteWorldP != NULL);
-
- // Tiling might not be initialized if this was called from SWLockSpriteWorld
- if (spriteWorldP->tilingIsInitialized)
- {
- for (tileIndex = 0; tileIndex < spriteWorldP->maxNumTiles; tileIndex++)
- {
- if (spriteWorldP->tileFrameArray[tileIndex] != NULL)
- SWUnlockFrame(spriteWorldP->tileFrameArray[tileIndex]);
- }
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWCreateExtraBackFrame
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC OSErr SWCreateExtraBackFrame(
- SpriteWorldPtr spriteWorldP,
- Rect *frameRect)
- {
- OSErr err = noErr;
-
- SW_ASSERT(spriteWorldP != NULL);
- SW_ASSERT(frameRect->right > frameRect->left && frameRect->bottom > frameRect->top);
-
- if (spriteWorldP->extraBackFrameP != NULL)
- {
- SWDisposeFrame(&spriteWorldP->extraBackFrameP);
- }
-
- // Make sure rect starts at 0,0
- OffsetRect(frameRect, -frameRect->left, -frameRect->top);
-
- err = SWCreateFrame(spriteWorldP->mainSWGDH, &spriteWorldP->extraBackFrameP,
- frameRect, spriteWorldP->pixelDepth);
-
- return err;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWDisposeExtraBackFrame
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWDisposeExtraBackFrame(
- SpriteWorldPtr spriteWorldP)
- {
- SW_ASSERT(spriteWorldP != NULL);
- SWDisposeFrame(&spriteWorldP->extraBackFrameP);
- spriteWorldP->extraBackFrameP = NULL;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWSetPortToExtraBackFrame
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC OSErr SWSetPortToExtraBackFrame(
- SpriteWorldPtr spriteWorldP)
- {
- OSErr err = noErr;
-
- SW_ASSERT(spriteWorldP != NULL);
-
- if ( spriteWorldP->extraBackFrameP == NULL )
- err = kNilFrameErr;
- else if ( spriteWorldP->extraBackFrameP->isFrameLocked == false)
- err = kNotLockedErr;
-
- if (err == noErr)
- SetGWorld(spriteWorldP->extraBackFrameP->framePort, nil);
-
- SWSetStickyIfError( err );
- return err;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWSetTilingOn
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWSetTilingOn(
- SpriteWorldPtr spriteWorldP,
- Boolean tilingIsOn)
- {
- SW_ASSERT(spriteWorldP != NULL);
- spriteWorldP->tilingIsOn = tilingIsOn;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWChangeTileSize
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC OSErr SWChangeTileSize(
- SpriteWorldPtr spriteWorldP,
- short tileHeight,
- short tileWidth)
- {
- OSErr err;
-
- SW_ASSERT(spriteWorldP != NULL);
-
- spriteWorldP->tileHeight = tileHeight;
- spriteWorldP->tileWidth = tileWidth;
-
- // Dispose and rebuild the tiling cache, based on the new tile width & height
- err = SWInitTilingCache(spriteWorldP);
-
- return err;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWSetSpriteLayerUnderTileLayer
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWSetSpriteLayerUnderTileLayer(
- SpriteLayerPtr spriteLayerP,
- short tileLayer)
- {
- SW_ASSERT(spriteLayerP != NULL);
- spriteLayerP->tileLayer = tileLayer;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWSetTileMaskDrawProc
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC OSErr SWSetTileMaskDrawProc(
- SpriteWorldPtr spriteWorldP,
- DrawProcPtr drawProc)
- {
- OSErr err = noErr;
-
- SW_ASSERT(spriteWorldP != NULL);
-
- if (drawProc == BlitPixie8BitPartialMaskDrawProc ||
- drawProc == BP8BitInterlacedPartialMaskDrawProc)
- {
- err = kBadParameterErr;
- }
- else if (spriteWorldP->pixelDepth != 8)
- {
- if (drawProc == BlitPixie8BitMaskDrawProc || drawProc == BP8BitInterlacedMaskDrawProc)
- {
- err = kWrongDepthErr;
- }
- }
-
- if ( err == noErr )
- {
- spriteWorldP->tileMaskDrawProc = drawProc;
- }
-
- SWSetStickyIfError( err );
- return err;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWSetPartialMaskDrawProc
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC OSErr SWSetPartialMaskDrawProc(
- SpriteWorldPtr spriteWorldP,
- DrawProcPtr drawProc)
- {
- OSErr err = noErr;
-
- SW_ASSERT(spriteWorldP != NULL);
-
- if (spriteWorldP->pixelDepth != 8)
- {
- if (drawProc == BlitPixie8BitPartialMaskDrawProc ||
- drawProc == BP8BitInterlacedPartialMaskDrawProc)
- {
- err = kWrongDepthErr;
- }
- }
-
- if ( err == noErr )
- {
- spriteWorldP->partialMaskDrawProc = drawProc;
- }
-
- SWSetStickyIfError( err );
- return err;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWSetTileChangeProc
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWSetTileChangeProc(
- SpriteWorldPtr spriteWorldP,
- TileChangeProcPtr tileChangeProc)
- {
- SW_ASSERT(spriteWorldP != NULL);
- spriteWorldP->tileChangeProc = tileChangeProc;
- }
-
-
- #pragma mark -
- ///--------------------------------------------------------------------------------------
- // SWDrawTilesInBackground
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC OSErr SWDrawTilesInBackground(
- SpriteWorldPtr spriteWorldP)
- {
- GWorldPtr holdGWorld;
- GDHandle holdGDH;
- OSErr err = noErr;
-
- SW_ASSERT(spriteWorldP != NULL);
-
- GetGWorld( &holdGWorld, &holdGDH );
-
- if ( !spriteWorldP->tilingIsInitialized )
- err = kTilingNotInitialized;
-
- if (err == noErr)
- {
- (*spriteWorldP->tileRectDrawProc)(spriteWorldP, &spriteWorldP->visScrollRect, true);
- }
-
- SetGWorld( holdGWorld, holdGDH );
-
- SWSetStickyIfError(err);
- return err;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWDrawTile - sets value in tileMap and draws tile if visible in visScrollRect.
- // The main core of this function is very similar to the inner loop of
- // SWTileDrawLayersInRect, except that this calls SWAddChangedRect, has code to set the
- // tiling cache, and makes sure the tile is visible on screen before drawing it.
- // Oh, and SWDrawTile *sets* the tileID in the tileMap, instead of getting it. :-)
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWDrawTile(
- SpriteWorldPtr spriteWorldP,
- short dstTileLayer,
- short tileRow,
- short tileCol,
- short tileID)
- {
- short row, col, offscreenTileRow, offscreenTileCol, tileLayer;
- Rect* visScrollRectP = &spriteWorldP->visScrollRect;
- Rect* backRectP = &spriteWorldP->backRect;
- short tileHeight = spriteWorldP->tileHeight;
- short tileWidth = spriteWorldP->tileWidth;
- Rect srcRect, dstRect;
- FramePtr tileFrameP;
- Boolean tileClipped, tileHasMask;
-
- // We must have a TileMap installed in the dstTileLayer to draw in it!
- if (spriteWorldP->tileLayerArray[dstTileLayer] == NULL)
- return;
-
- // Check SpriteWorldRec
- SW_ASSERT(spriteWorldP != NULL);
- SW_ASSERT(spriteWorldP->tilingIsInitialized);
- SW_ASSERT(spriteWorldP->tileMaskDrawProc != NULL);
- SW_ASSERT(spriteWorldP->offscreenDrawProc != NULL);
- SW_ASSERT(spriteWorldP->backFrameP->isFrameLocked);
- SW_ASSERT(spriteWorldP->workFrameP->isFrameLocked);
- SW_ASSERT(spriteWorldP->tileLayerArray[dstTileLayer] != NULL);
- SW_ASSERT(spriteWorldP->tileLayerArray[dstTileLayer]->isLocked);
-
- // Check parameters
- SW_ASSERT(dstTileLayer <= spriteWorldP->lastActiveTileLayer);
- SW_ASSERT(tileRow < spriteWorldP->tileLayerArray[dstTileLayer]->numRows);
- SW_ASSERT(tileCol < spriteWorldP->tileLayerArray[dstTileLayer]->numCols);
- SW_ASSERT(tileID < spriteWorldP->maxNumTiles);
-
- SetGWorld(spriteWorldP->backFrameP->framePort, nil);
-
- // Note: we can not return if the tileID is what is already in the TileMap,
- // since tile animation would then not work.
-
-
- // Store the new tileID in the TileMap of the dstTileLayer
- spriteWorldP->tileLayerArray[dstTileLayer]->tileMap[tileRow][tileCol] = tileID;
-
- row = tileRow * tileHeight;
- col = tileCol * tileWidth;
-
- dstRect.bottom = row + tileHeight;
- dstRect.right = col + tileWidth;
-
- // Clip tile dstRect with visScrollRect //
- tileClipped = false;
- if (row < visScrollRectP->top)
- {
- dstRect.top = visScrollRectP->top;
- tileClipped = true;
- }
- else
- dstRect.top = row;
-
- if (col < visScrollRectP->left)
- {
- dstRect.left = visScrollRectP->left;
- tileClipped = true;
- }
- else
- dstRect.left = col;
-
- if (dstRect.bottom > visScrollRectP->bottom)
- {
- dstRect.bottom = visScrollRectP->bottom;
- tileClipped = true;
- }
-
- if (dstRect.right > visScrollRectP->right)
- {
- dstRect.right = visScrollRectP->right;
- tileClipped = true;
- }
-
-
- // Draw tile if visible on screen (in visScrollRect)
- if (dstRect.left < dstRect.right && dstRect.top < dstRect.bottom)
- {
- // Save rect as having been changed
- SWAddChangedRect(spriteWorldP, &dstRect);
-
- // Now get the tileID of this row and col in tileLayer 0
- if (spriteWorldP->tileLayerArray[0] == NULL)
- tileID = -1;
- else
- tileID = spriteWorldP->tileLayerArray[0]->tileMap[tileRow][tileCol];
-
- // Now we redraw all tiles in this location
- if (tileID >= 0)
- {
- tileFrameP = spriteWorldP->tileFrameArray[spriteWorldP->curTileImage[tileID]];
- SW_ASSERT(tileFrameP != NULL);
- SW_ASSERT(tileFrameP->isFrameLocked);
-
- // Determine whether the tile has a mask with background showing through
- tileHasMask = (tileFrameP->maskPort != NULL || tileFrameP->maskRgn != NULL);
- }
- else
- tileHasMask = false;
-
- // Copy a piece from the extraBackFrameP only if there is no tile, or the
- // tile has a mask with background showing through the unmasked part.
- if ( (tileID == -1 || tileHasMask) && spriteWorldP->extraBackFrameP != NULL)
- {
- // There is no tile in this spot, or there is a masked tile and
- // there is an extraBackFrameP, so copy a piece from extraBackFrameP
- // Note: the function below wraps the dstRect for us, and leaves it
- // that way when it returns, so we don't have to wrap it ourselves.
- SWWrapRectFromExtraBackFrame(spriteWorldP, &dstRect);
- }
- else
- {
- // Make the tile's dest rect local to the offscreen area
- dstRect.top -= spriteWorldP->vertScrollRectOffset;
- dstRect.bottom -= spriteWorldP->vertScrollRectOffset;
- dstRect.left -= spriteWorldP->horizScrollRectOffset;
- dstRect.right -= spriteWorldP->horizScrollRectOffset;
-
- // Wrap tile to top or bottom of offscreen area
- if (dstRect.bottom > backRectP->bottom)
- {
- dstRect.top -= backRectP->bottom;
- dstRect.bottom -= backRectP->bottom;
- }
- else if (dstRect.top < backRectP->top)
- {
- dstRect.top += backRectP->bottom;
- dstRect.bottom += backRectP->bottom;
- }
-
- // Wrap tile to left or right side of offscreen area
- if (dstRect.right > backRectP->right)
- {
- dstRect.left -= backRectP->right;
- dstRect.right -= backRectP->right;
- }
- else if (dstRect.left < backRectP->left)
- {
- dstRect.left += backRectP->right;
- dstRect.right += backRectP->right;
- }
- }
-
-
- if (tileID >= 0)
- {
- srcRect = tileFrameP->frameRect;
-
- // Clip new srcRect
- if (row < visScrollRectP->top)
- srcRect.top += visScrollRectP->top - row;
- if (col < visScrollRectP->left)
- srcRect.left += visScrollRectP->left - col;
- if (row + tileHeight > visScrollRectP->bottom)
- srcRect.bottom -= row + tileHeight - visScrollRectP->bottom;
- if (col + tileWidth > visScrollRectP->right)
- srcRect.right -= col + tileWidth - visScrollRectP->right;
-
- if (tileHasMask && spriteWorldP->extraBackFrameP != NULL)
- {
- // The tile has a mask, with background showing through
- (*spriteWorldP->tileMaskDrawProc)(tileFrameP,
- spriteWorldP->backFrameP, &srcRect, &dstRect);
- }
- else
- {
- // The entire tile should be drawn
- (*spriteWorldP->offscreenDrawProc)(tileFrameP,
- spriteWorldP->backFrameP, &srcRect, &dstRect);
- }
- }
-
-
- // Draw tiles in higher layers
- for (tileLayer = 1; tileLayer <= spriteWorldP->lastActiveTileLayer; tileLayer++)
- {
- if (spriteWorldP->tileLayerArray[tileLayer] == NULL)
- continue;
-
- SW_ASSERT(tileRow < spriteWorldP->tileLayerArray[tileLayer]->numRows);
- SW_ASSERT(tileCol < spriteWorldP->tileLayerArray[tileLayer]->numCols);
-
- tileID = spriteWorldP->tileLayerArray[tileLayer]->tileMap[tileRow][tileCol];
- if (tileID < 0)
- continue;
-
- SW_ASSERT(tileID < spriteWorldP->maxNumTiles);
-
- tileFrameP = spriteWorldP->tileFrameArray[spriteWorldP->curTileImage[tileID]];
- SW_ASSERT(tileFrameP != NULL);
- SW_ASSERT(tileFrameP->isFrameLocked);
-
- srcRect = tileFrameP->frameRect;
-
- // Clip new srcRect
- if (row < visScrollRectP->top)
- srcRect.top += visScrollRectP->top - row;
- if (col < visScrollRectP->left)
- srcRect.left += visScrollRectP->left - col;
- if (row + tileHeight > visScrollRectP->bottom)
- srcRect.bottom -= row + tileHeight - visScrollRectP->bottom;
- if (col + tileWidth > visScrollRectP->right)
- srcRect.right -= col + tileWidth - visScrollRectP->right;
-
- // Draw the tile
- if (tileFrameP->maskPort == NULL && tileFrameP->maskRgn == NULL)
- {
- // Tile has no mask
- (*spriteWorldP->offscreenDrawProc)(tileFrameP,
- spriteWorldP->backFrameP, &srcRect, &dstRect);
- }
- else
- {
- // Tile has a mask
- (*spriteWorldP->tileMaskDrawProc)(tileFrameP,
- spriteWorldP->backFrameP, &srcRect, &dstRect);
- }
- }
-
- // Copy tiles from back area to work area
- SetGWorld(spriteWorldP->workFrameP->framePort, nil);
- (*spriteWorldP->offscreenDrawProc)(spriteWorldP->backFrameP,
- spriteWorldP->workFrameP, &dstRect, &dstRect);
-
- // Update tiling cache info only if only one tile layer is used
- if (spriteWorldP->lastActiveTileLayer == 0)
- {
- offscreenTileRow = dstRect.top / spriteWorldP->tileHeight;
- offscreenTileCol = dstRect.left / spriteWorldP->tileWidth;
-
- // Set new tile value in tilingCache
- if (tileClipped || tileID < 0)
- {
- spriteWorldP->tilingCache[offscreenTileRow][offscreenTileCol] = -1;
- }
- else
- {
- spriteWorldP->tilingCache[offscreenTileRow][offscreenTileCol] =
- spriteWorldP->curTileImage[tileID];
- }
- }
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWDrawTilesInRect - draw only one layer of tiles in updateRect of backFrame. Note:
- // The only reason we use this instead of SWDrawTilesLayersInRect is because with this,
- // we can use the tiling cache.
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWDrawTilesInRect(
- SpriteWorldPtr spriteWorldP,
- Rect* updateRectP,
- Boolean optimizingOn)
- {
- short row, col, tileRow, tileCol, tileID;
- short startRow, startCol, stopRow, stopCol;
- short offscreenTileRow, offscreenTileCol;
- Rect srcRect, dstRect;
- FramePtr tileFrameP;
- Boolean tileClipped, tileHasMask;
- Rect* visScrollRectP = &spriteWorldP->visScrollRect;
- Rect* backRectP = &spriteWorldP->backRect;
- Rect updateRect = *updateRectP;
- short tileWidth = spriteWorldP->tileWidth;
- short tileHeight = spriteWorldP->tileHeight;
-
- SW_ASSERT(spriteWorldP != NULL && spriteWorldP->tilingIsInitialized);
- SW_ASSERT(spriteWorldP->tileMaskDrawProc != NULL);
- SW_ASSERT(spriteWorldP->offscreenDrawProc != NULL);
- SW_ASSERT(spriteWorldP->backFrameP->isFrameLocked);
-
- SW_ASSERT(spriteWorldP->tileLayerArray[0] != NULL);
- SW_ASSERT(spriteWorldP->tileLayerArray[0]->isLocked);
-
- SetGWorld(spriteWorldP->backFrameP->framePort, nil);
-
- // Convert pixel row and col into tile row and col
- startRow = updateRect.top / tileHeight;
- startCol = updateRect.left / tileWidth;
- stopRow = (updateRect.bottom-1) / tileHeight;
- stopCol = (updateRect.right-1) / tileWidth;
-
-
- row = startRow * tileHeight;
- for (tileRow = startRow; tileRow <= stopRow; tileRow++, row += tileHeight)
- {
- col = startCol * tileWidth;
- for (tileCol = startCol; tileCol <= stopCol; tileCol++, col += tileWidth)
- {
- if (spriteWorldP->tileLayerArray[0] != NULL)
- {
- SW_ASSERT(tileRow < spriteWorldP->tileLayerArray[0]->numRows);
- SW_ASSERT(tileCol < spriteWorldP->tileLayerArray[0]->numCols);
- }
-
- dstRect.bottom = row + tileHeight;
- dstRect.right = col + tileWidth;
-
- // Is tile completely visible on screen?
- if (row >= visScrollRectP->top && col >= visScrollRectP->left &&
- dstRect.bottom <= visScrollRectP->bottom &&
- dstRect.right <= visScrollRectP->right)
- {
- tileClipped = false;
- }
- else
- {
- tileClipped = true;
- }
-
- // Clip tile dstRect with updateRect //
- if (row < updateRect.top)
- dstRect.top = updateRect.top;
- else
- dstRect.top = row;
-
- if (col < updateRect.left)
- dstRect.left = updateRect.left;
- else
- dstRect.left = col;
-
- if (dstRect.bottom > updateRect.bottom)
- dstRect.bottom = updateRect.bottom;
-
- if (dstRect.right > updateRect.right)
- dstRect.right = updateRect.right;
-
- if (spriteWorldP->tileLayerArray[0] == NULL)
- tileID = -1;
- else
- tileID = spriteWorldP->tileLayerArray[0]->tileMap[tileRow][tileCol];
-
- SW_ASSERT(tileID < spriteWorldP->maxNumTiles);
-
- if (tileID >= 0)
- {
- tileFrameP = spriteWorldP->tileFrameArray[spriteWorldP->curTileImage[tileID]];
- SW_ASSERT(tileFrameP != NULL);
- SW_ASSERT(tileFrameP->isFrameLocked);
-
- // Determine whether the tile has a mask with background showing through
- tileHasMask = (tileFrameP->maskPort != NULL || tileFrameP->maskRgn != NULL);
- }
- else
- tileHasMask = false;
-
- // Copy a piece from the extraBackFrameP only if there is no tile, or the
- // tile has a mask with background showing through the unmasked part.
- if ( (tileID == -1 || tileHasMask) && spriteWorldP->extraBackFrameP != NULL)
- {
- // There is no tile in this spot, or there is a masked tile and
- // there is an extraBackFrameP, so copy a piece from extraBackFrameP
- // Note: the function below wraps the dstRect for us, and leaves it
- // that way when it returns, so we don't have to wrap it ourselves.
- SWWrapRectFromExtraBackFrame(spriteWorldP, &dstRect);
- }
- else
- {
- // Make the tile's dest rect local to the offscreen area
- dstRect.top -= spriteWorldP->vertScrollRectOffset;
- dstRect.bottom -= spriteWorldP->vertScrollRectOffset;
- dstRect.left -= spriteWorldP->horizScrollRectOffset;
- dstRect.right -= spriteWorldP->horizScrollRectOffset;
-
- // Wrap tile to top or bottom of offscreen area
- if (dstRect.bottom > backRectP->bottom)
- {
- dstRect.top -= backRectP->bottom;
- dstRect.bottom -= backRectP->bottom;
- }
- else if (dstRect.top < backRectP->top)
- {
- dstRect.top += backRectP->bottom;
- dstRect.bottom += backRectP->bottom;
- }
-
- // Wrap tile to left or right side of offscreen area
- if (dstRect.right > backRectP->right)
- {
- dstRect.left -= backRectP->right;
- dstRect.right -= backRectP->right;
- }
- else if (dstRect.left < backRectP->left)
- {
- dstRect.left += backRectP->right;
- dstRect.right += backRectP->right;
- }
- }
-
-
- offscreenTileRow = dstRect.top / tileHeight;
- offscreenTileCol = dstRect.left / tileWidth;
-
- if (tileID >= 0)
- {
- srcRect = tileFrameP->frameRect;
-
- // Clip new srcRect
- if (row < updateRect.top)
- srcRect.top += updateRect.top - row;
- if (col < updateRect.left)
- srcRect.left += updateRect.left - col;
- if (row + tileHeight > updateRect.bottom)
- srcRect.bottom -= row + tileHeight - updateRect.bottom;
- if (col + tileWidth > updateRect.right)
- srcRect.right -= col + tileWidth - updateRect.right;
-
- if (tileHasMask && spriteWorldP->extraBackFrameP != NULL)
- {
- // The tile has a mask, with background showing through
- (*spriteWorldP->tileMaskDrawProc)(tileFrameP,
- spriteWorldP->backFrameP, &srcRect, &dstRect);
-
- // Since the background is showing here, set this cache spot to -1
- spriteWorldP->tilingCache[offscreenTileRow][offscreenTileCol] = -1;
- }
- else
- {
- // Save time by not drawing tile if already the same
- if (spriteWorldP->tilingCache[offscreenTileRow][offscreenTileCol] !=
- spriteWorldP->curTileImage[tileID] || !optimizingOn)
- {
- // The entire tile should be drawn
- (*spriteWorldP->offscreenDrawProc)(tileFrameP,
- spriteWorldP->backFrameP, &srcRect, &dstRect);
-
- // Set new tile value in tilingCache
- if (tileClipped)
- {
- spriteWorldP->tilingCache[offscreenTileRow][offscreenTileCol] = -1;
- }
- else
- {
- spriteWorldP->tilingCache[offscreenTileRow][offscreenTileCol] =
- spriteWorldP->curTileImage[tileID];
- }
- }
- }
- }
- else
- {
- // Since no tile is here, this spot in the tiling Cache should be set to -1
- spriteWorldP->tilingCache[offscreenTileRow][offscreenTileCol] = -1;
-
- // Cause assertion failure if tileID is -1 and there is no extraBackFrameP
- SW_ASSERT(spriteWorldP->extraBackFrameP != NULL);
- }
- }
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWDrawTileLayersInRect - draws all tile layers in updateRect of backFrame
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWDrawTileLayersInRect(
- SpriteWorldPtr spriteWorldP,
- Rect* updateRectP,
- Boolean optimizingOn)
- {
- #pragma unused(optimizingOn) // This is used in our sister function, SWDrawTilesInRect
- short row, col, tileRow, tileCol, tileID;
- short startRow, startCol, stopRow, stopCol;
- short tileLayer, startPixelCol;
- Rect srcRect, dstRect;
- FramePtr tileFrameP;
- Rect* visScrollRectP = &spriteWorldP->visScrollRect;
- Rect* backRectP = &spriteWorldP->backRect;
- Rect updateRect = *updateRectP;
- short tileWidth = spriteWorldP->tileWidth;
- short tileHeight = spriteWorldP->tileHeight;
- Boolean tileHasMask;
-
- SW_ASSERT(spriteWorldP != NULL && spriteWorldP->tilingIsInitialized);
- SW_ASSERT(spriteWorldP->tileMaskDrawProc != NULL);
- SW_ASSERT(spriteWorldP->offscreenDrawProc != NULL);
- SW_ASSERT(spriteWorldP->backFrameP->isFrameLocked);
-
- SetGWorld(spriteWorldP->backFrameP->framePort, nil);
-
- // Convert pixel row and col into tile row and col
- startRow = updateRect.top / tileHeight;
- startCol = updateRect.left / tileWidth;
- stopRow = (updateRect.bottom-1) / tileHeight;
- stopCol = (updateRect.right-1) / tileWidth;
-
- startPixelCol = startCol * tileWidth;
-
- row = startRow * tileHeight;
- for (tileRow = startRow; tileRow <= stopRow; tileRow++, row += tileHeight)
- {
- col = startPixelCol;
- for (tileCol = startCol; tileCol <= stopCol; tileCol++, col += tileWidth)
- {
- if (spriteWorldP->tileLayerArray[0] != NULL)
- {
- SW_ASSERT(spriteWorldP->tileLayerArray[0]->isLocked);
- SW_ASSERT(tileRow < spriteWorldP->tileLayerArray[0]->numRows);
- SW_ASSERT(tileCol < spriteWorldP->tileLayerArray[0]->numCols);
- }
-
- dstRect.bottom = row + tileHeight;
- dstRect.right = col + tileWidth;
-
- // Clip tile dstRect with updateRect //
- if (row < updateRect.top)
- dstRect.top = updateRect.top;
- else
- dstRect.top = row;
-
- if (col < updateRect.left)
- dstRect.left = updateRect.left;
- else
- dstRect.left = col;
-
- if (dstRect.bottom > updateRect.bottom)
- dstRect.bottom = updateRect.bottom;
-
- if (dstRect.right > updateRect.right)
- dstRect.right = updateRect.right;
-
- if (spriteWorldP->tileLayerArray[0] == NULL)
- tileID = -1;
- else
- tileID = spriteWorldP->tileLayerArray[0]->tileMap[tileRow][tileCol];
-
- SW_ASSERT(tileID < spriteWorldP->maxNumTiles);
-
- if (tileID >= 0)
- {
- tileFrameP = spriteWorldP->tileFrameArray[spriteWorldP->curTileImage[tileID]];
- SW_ASSERT(tileFrameP != NULL);
- SW_ASSERT(tileFrameP->isFrameLocked);
-
- // Determine whether the tile has a mask with background showing through
- tileHasMask = (tileFrameP->maskPort != NULL || tileFrameP->maskRgn != NULL);
- }
- else
- tileHasMask = false;
-
- // Copy a piece from the extraBackFrameP only if there is no tile, or the
- // tile has a mask with background showing through the unmasked part.
- if ( (tileID == -1 || tileHasMask) && spriteWorldP->extraBackFrameP != NULL)
- {
- // There is no tile in this spot, or there is a masked tile and
- // there is an extraBackFrameP, so copy a piece from extraBackFrameP
- // Note: the function below wraps the dstRect for us, and leaves it
- // that way when it returns, so we don't have to wrap it ourselves.
- SWWrapRectFromExtraBackFrame(spriteWorldP, &dstRect);
- }
- else
- {
- // Make the tile's dest rect local to the offscreen area
- dstRect.top -= spriteWorldP->vertScrollRectOffset;
- dstRect.bottom -= spriteWorldP->vertScrollRectOffset;
- dstRect.left -= spriteWorldP->horizScrollRectOffset;
- dstRect.right -= spriteWorldP->horizScrollRectOffset;
-
- // Wrap tile to top or bottom of offscreen area
- if (dstRect.bottom > backRectP->bottom)
- {
- dstRect.top -= backRectP->bottom;
- dstRect.bottom -= backRectP->bottom;
- }
- else if (dstRect.top < backRectP->top)
- {
- dstRect.top += backRectP->bottom;
- dstRect.bottom += backRectP->bottom;
- }
-
- // Wrap tile to left or right side of offscreen area
- if (dstRect.right > backRectP->right)
- {
- dstRect.left -= backRectP->right;
- dstRect.right -= backRectP->right;
- }
- else if (dstRect.left < backRectP->left)
- {
- dstRect.left += backRectP->right;
- dstRect.right += backRectP->right;
- }
- }
-
-
- if (tileID >= 0)
- {
- srcRect = tileFrameP->frameRect;
-
- // Clip new srcRect
- if (row < updateRect.top)
- srcRect.top += updateRect.top - row;
- if (col < updateRect.left)
- srcRect.left += updateRect.left - col;
- if (row + tileHeight > updateRect.bottom)
- srcRect.bottom -= row + tileHeight - updateRect.bottom;
- if (col + tileWidth > updateRect.right)
- srcRect.right -= col + tileWidth - updateRect.right;
-
- if (tileHasMask && spriteWorldP->extraBackFrameP != NULL)
- {
- // The tile has a mask, with background showing through
- (*spriteWorldP->tileMaskDrawProc)(tileFrameP,
- spriteWorldP->backFrameP, &srcRect, &dstRect);
- }
- else
- {
- // The entire tile should be drawn
- (*spriteWorldP->offscreenDrawProc)(tileFrameP,
- spriteWorldP->backFrameP, &srcRect, &dstRect);
- }
- }
-
-
- // Draw tiles in higher layers
- for (tileLayer = 1; tileLayer <= spriteWorldP->lastActiveTileLayer; tileLayer++)
- {
- if (spriteWorldP->tileLayerArray[tileLayer] == NULL)
- continue;
-
- SW_ASSERT(spriteWorldP->tileLayerArray[tileLayer]->isLocked);
- SW_ASSERT(tileRow < spriteWorldP->tileLayerArray[tileLayer]->numRows);
- SW_ASSERT(tileCol < spriteWorldP->tileLayerArray[tileLayer]->numCols);
-
- tileID = spriteWorldP->tileLayerArray[tileLayer]->tileMap[tileRow][tileCol];
- if (tileID < 0)
- continue;
-
- SW_ASSERT(tileID < spriteWorldP->maxNumTiles);
-
- tileFrameP = spriteWorldP->tileFrameArray[spriteWorldP->curTileImage[tileID]];
- SW_ASSERT(tileFrameP != NULL);
- SW_ASSERT(tileFrameP->isFrameLocked);
-
- srcRect = tileFrameP->frameRect;
-
- // Clip new srcRect
- if (row < updateRect.top)
- srcRect.top += updateRect.top - row;
- if (col < updateRect.left)
- srcRect.left += updateRect.left - col;
- if (row + tileHeight > updateRect.bottom)
- srcRect.bottom -= row + tileHeight - updateRect.bottom;
- if (col + tileWidth > updateRect.right)
- srcRect.right -= col + tileWidth - updateRect.right;
-
- // Draw the tile
- if (tileFrameP->maskPort == NULL && tileFrameP->maskRgn == NULL)
- {
- // Tile has no mask
- (*spriteWorldP->offscreenDrawProc)(tileFrameP,
- spriteWorldP->backFrameP, &srcRect, &dstRect);
- }
- else
- {
- // Tile has a mask
- (*spriteWorldP->tileMaskDrawProc)(tileFrameP,
- spriteWorldP->backFrameP, &srcRect, &dstRect);
- }
- }
- }
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWDrawTilesAboveSprite - draw tiles over sprite using the tiles' masks.
- // Assumes that updateRect fits within the bounds of the tileMap.
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWDrawTilesAboveSprite(
- SpriteWorldPtr spriteWorldP,
- Rect* updateRectP,
- short startLayer)
- {
- Rect* backRectP = &spriteWorldP->backRect;
- Rect updateRect = *updateRectP;
- short tileLayer;
- short tileWidth = spriteWorldP->tileWidth;
- short tileHeight = spriteWorldP->tileHeight;
- short row, col, tileRow, tileCol, tileID;
- short startRow, startCol, stopRow, stopCol;
- short startPixelRow, startPixelCol;
- Rect srcRect, dstRect;
- FramePtr tileFrameP;
-
- SW_ASSERT(spriteWorldP != NULL && spriteWorldP->tilingIsInitialized);
- SW_ASSERT(startLayer >= 0);
-
- // Convert pixel row and col into tile row and col
- startRow = updateRect.top / tileHeight;
- startCol = updateRect.left / tileWidth;
- stopRow = (updateRect.bottom-1) / tileHeight;
- stopCol = (updateRect.right-1) / tileWidth;
-
- startPixelRow = startRow * tileHeight;
- startPixelCol = startCol * tileWidth;
-
- for (tileLayer = startLayer; tileLayer <= spriteWorldP->lastActiveTileLayer; tileLayer++)
- {
- if (spriteWorldP->tileLayerArray[tileLayer] == NULL)
- continue;
-
- row = startPixelRow;
- for (tileRow = startRow; tileRow <= stopRow; tileRow++, row += tileHeight)
- {
- col = startPixelCol;
- for (tileCol = startCol; tileCol <= stopCol; tileCol++, col += tileWidth)
- {
- SW_ASSERT(tileRow < spriteWorldP->tileLayerArray[tileLayer]->numRows);
- SW_ASSERT(tileCol < spriteWorldP->tileLayerArray[tileLayer]->numCols);
-
- tileID = spriteWorldP->tileLayerArray[tileLayer]->tileMap[tileRow][tileCol];
- if (tileID < 0)
- continue;
-
- SW_ASSERT(tileID < spriteWorldP->maxNumTiles);
-
- tileFrameP = spriteWorldP->tileFrameArray[spriteWorldP->curTileImage[tileID]];
- SW_ASSERT(tileFrameP != NULL);
-
- // Skip tiles in the bottom layer that have no mask, and therefore
- // aren't above the sprites, as long as no extraBackFrameP is installed.
- if (tileLayer == 0 && spriteWorldP->extraBackFrameP == NULL &&
- tileFrameP->maskPort == NULL && tileFrameP->maskRgn == NULL &&
- tileFrameP->tileMaskIsSolid == false)
- {
- continue;
- }
-
- srcRect = tileFrameP->frameRect;
- dstRect.bottom = row + tileHeight;
- dstRect.right = col + tileWidth;
-
-
- // Clip tile dstRect with updateRect //
- if (row < updateRect.top)
- {
- dstRect.top = updateRect.top;
- srcRect.top += updateRect.top - row;
- }
- else
- dstRect.top = row;
-
- if (col < updateRect.left)
- {
- dstRect.left = updateRect.left;
- srcRect.left += updateRect.left - col;
- }
- else
- dstRect.left = col;
-
-
- if (dstRect.bottom > updateRect.bottom)
- {
- srcRect.bottom -= dstRect.bottom - updateRect.bottom;
- dstRect.bottom = updateRect.bottom;
- }
-
- if (dstRect.right > updateRect.right)
- {
- srcRect.right -= dstRect.right - updateRect.right;
- dstRect.right = updateRect.right;
- }
-
-
-
- // Make the tile's dest rect local to the offscreen area
- dstRect.top -= spriteWorldP->vertScrollRectOffset;
- dstRect.bottom -= spriteWorldP->vertScrollRectOffset;
- dstRect.left -= spriteWorldP->horizScrollRectOffset;
- dstRect.right -= spriteWorldP->horizScrollRectOffset;
-
- // Wrap tile to top or bottom of offscreen area
- if (dstRect.bottom > backRectP->bottom)
- {
- dstRect.top -= backRectP->bottom;
- dstRect.bottom -= backRectP->bottom;
- }
- else if (dstRect.top < backRectP->top)
- {
- dstRect.top += backRectP->bottom;
- dstRect.bottom += backRectP->bottom;
- }
-
- // Wrap tile to left or right side of offscreen area
- if (dstRect.right > backRectP->right)
- {
- dstRect.left -= backRectP->right;
- dstRect.right -= backRectP->right;
- }
- else if (dstRect.left < backRectP->left)
- {
- dstRect.left += backRectP->right;
- dstRect.right += backRectP->right;
- }
-
- if (tileLayer == 0 && spriteWorldP->extraBackFrameP == NULL)
- {
- // The tile is in the bottom layer
- if (tileFrameP->tileMaskIsSolid)
- {
- // Draw the tile without using a mask
- (*spriteWorldP->offscreenDrawProc)(tileFrameP,
- spriteWorldP->workFrameP, &srcRect, &dstRect);
- }
- else
- {
- // Draw the masked part of the tile
- (*spriteWorldP->partialMaskDrawProc)(tileFrameP,
- spriteWorldP->workFrameP, &srcRect, &dstRect);
- }
- }
- else
- {
- // The tile is in a higher layer, or is in the background layer and
- // an extraBackFrameP is installed, and must be handled differently
- if (tileFrameP->maskPort == NULL && tileFrameP->maskRgn == NULL)
- {
- // Tile has no mask
- (*spriteWorldP->offscreenDrawProc)(tileFrameP,
- spriteWorldP->workFrameP, &srcRect, &dstRect);
- }
- else
- {
- // Tile has a mask
- (*spriteWorldP->tileMaskDrawProc)(tileFrameP,
- spriteWorldP->workFrameP, &srcRect, &dstRect);
- }
- }
- }
- }
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWResetTilingCache
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWResetTilingCache(
- SpriteWorldPtr spriteWorldP)
- {
- short row, col;
-
- SW_ASSERT(spriteWorldP != NULL);
- SW_ASSERT(spriteWorldP->tilingIsInitialized);
-
- // Set all elements to -1 (indicating that each tile needs to be drawn)
- for (row = 0; row < spriteWorldP->numTilingCacheRows; row++)
- {
- for (col = 0; col < spriteWorldP->numTilingCacheCols; col++)
- {
- spriteWorldP->tilingCache[row][col] = -1;
- }
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWAddChangedRect - used by SWDrawTile
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC static void SWAddChangedRect(
- SpriteWorldPtr spriteWorldP,
- Rect *changedRectP)
- {
- short index;
- Rect *changedTileP;
-
- SW_ASSERT(spriteWorldP != NULL && spriteWorldP->tilingIsInitialized);
- SW_ASSERT(changedRectP->top >= 0 && changedRectP->left >= 0 &&
- changedRectP->right > changedRectP->left && changedRectP->bottom > changedRectP->top);
-
- changedTileP = spriteWorldP->changedTiles;
- for ( index = 0; index < spriteWorldP->numTilesChanged; index++, changedTileP++ )
- {
- // check for changedRectP entirely contained by changedTileP
- if ( changedTileP->left <= changedRectP->left &&
- changedTileP->top <= changedRectP->top &&
- changedTileP->right >= changedRectP->right &&
- changedTileP->bottom >= changedRectP->bottom )
- {
- return;
- }
- }
-
- changedTileP = spriteWorldP->changedTiles;
- for ( index = 0; index < spriteWorldP->numTilesChanged; index++, changedTileP++ )
- {
- // check for changedRectP horizontally adjacent to changedTileP
- if ( changedTileP->top == changedRectP->top &&
- changedTileP->bottom == changedRectP->bottom )
- {
- if ( changedRectP->left <= changedTileP->left && // changedRectP is to the left of changedTileP
- changedRectP->right >= changedTileP->left || // or
- changedRectP->left <= changedTileP->right && // changedRectP is to the right of changedTileP
- changedRectP->right >= changedTileP->right )
- {
- changedTileP->left = SW_MIN( changedTileP->left, changedRectP->left );
- changedTileP->right = SW_MAX( changedTileP->right, changedRectP->right );
- return;
- }
- }
-
- // check for changedRectP vertically adjacent to changedTileP
- if ( changedTileP->left == changedRectP->left &&
- changedTileP->right == changedRectP->right )
- {
- if ( changedRectP->top <= changedTileP->top && // changedRectP is above changedTileP
- changedRectP->bottom >= changedTileP->top || // or
- changedRectP->top <= changedTileP->bottom && // changedRectP is below changedTileP
- changedRectP->bottom >= changedTileP->bottom )
- {
- changedTileP->top = SW_MIN( changedTileP->top, changedRectP->top );
- changedTileP->bottom = SW_MAX( changedTileP->bottom, changedRectP->bottom );
- return;
- }
- }
- }
-
- if (spriteWorldP->numTilesChanged < spriteWorldP->changedTilesArraySize)
- {
- spriteWorldP->changedTiles[spriteWorldP->numTilesChanged++] = *changedRectP;
- }
- else
- {
- // This shouldn't ever happen, but if it does, we'll trip our Assert routine.
- SW_ASSERT(0);
- SWFlagRectAsChanged(spriteWorldP, changedRectP);
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWChangeTileImage
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWChangeTileImage(
- SpriteWorldPtr spriteWorldP,
- short tileID,
- short newImage)
- {
- SW_ASSERT(spriteWorldP != NULL && spriteWorldP->tilingIsInitialized);
- SW_ASSERT(tileID < spriteWorldP->maxNumTiles);
- SW_ASSERT(newImage < spriteWorldP->maxNumTiles);
-
- // Set the current image
- spriteWorldP->curTileImage[tileID] = newImage;
-
- // Update the tile image on screen
- SWUpdateTileOnScreen(spriteWorldP, tileID);
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWUpdateTileOnScreen - render new tile image in offscreen areas
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWUpdateTileOnScreen(
- SpriteWorldPtr spriteWorldP,
- short tileID)
- {
- short tileRow, tileCol, tileLayer;
- short startRow, startCol, stopRow, stopCol;
-
- SW_ASSERT(spriteWorldP != NULL && spriteWorldP->tilingIsInitialized);
-
- // Convert pixel row and col into tile row and col
- startRow = spriteWorldP->visScrollRect.top / spriteWorldP->tileHeight;
- startCol = spriteWorldP->visScrollRect.left / spriteWorldP->tileWidth;
- stopRow = (spriteWorldP->visScrollRect.bottom-1) / spriteWorldP->tileHeight;
- stopCol = (spriteWorldP->visScrollRect.right-1) / spriteWorldP->tileWidth;
-
- for (tileLayer = 0; tileLayer <= spriteWorldP->lastActiveTileLayer; tileLayer++)
- {
- if (spriteWorldP->tileLayerArray[tileLayer] == NULL)
- continue;
-
- for (tileRow = startRow; tileRow <= stopRow; tileRow++)
- {
- for (tileCol = startCol; tileCol <= stopCol; tileCol++)
- {
- if (tileID == spriteWorldP->tileLayerArray[tileLayer]->tileMap[tileRow][tileCol])
- SWDrawTile(spriteWorldP, tileLayer, tileRow, tileCol, tileID);
- }
- }
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWResetCurrentTileImages
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWResetCurrentTileImages(
- SpriteWorldPtr spriteWorldP)
- {
- short tileIndex;
-
- SW_ASSERT(spriteWorldP != NULL && spriteWorldP->tilingIsInitialized);
-
- if (spriteWorldP->tilingIsInitialized)
- {
- for (tileIndex = 0; tileIndex < spriteWorldP->maxNumTiles; tileIndex++)
- spriteWorldP->curTileImage[tileIndex] = tileIndex;
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWReturnTileUnderPixel
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC short SWReturnTileUnderPixel(
- SpriteWorldPtr spriteWorldP,
- short tileLayer,
- short pixelCol,
- short pixelRow)
- {
- short row, col;
-
- SW_ASSERT(spriteWorldP != NULL && spriteWorldP->tilingIsInitialized);
- SW_ASSERT(tileLayer < kNumTileLayers);
-
- if (spriteWorldP->tileLayerArray[tileLayer] == NULL)
- return -1; // No tile here, since there is no tileMap!
-
- row = pixelRow / spriteWorldP->tileHeight;
- col = pixelCol / spriteWorldP->tileWidth;
-
- if (row < 0 || row >= spriteWorldP->tileLayerArray[tileLayer]->numRows ||
- col < 0 || col >= spriteWorldP->tileLayerArray[tileLayer]->numCols )
- {
- return -1; // Pixel location is outside TileMap bounds!
- }
- else
- {
- return spriteWorldP->tileLayerArray[tileLayer]->tileMap[row][col];
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWCheckSpriteWithTiles
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC Boolean SWCheckSpriteWithTiles(
- SpriteWorldPtr spriteWorldP,
- SpritePtr srcSpriteP,
- SWTileSearchType searchType,
- Rect *insetRectP,
- short startTileLayer,
- short endTileLayer,
- short firstTileID,
- short lastTileID,
- Boolean fixPosition)
- {
- short row, col, startRow, stopRow, startCol, stopCol;
- TileMapPtr tileMap;
- Rect oldFrameRect, destFrameRect;
- Boolean foundTile = false;
- Boolean rowLoopTest, colLoopTest;
- short temp, tileID, tileLayer, rowIncrement, colIncrement;
-
- SW_ASSERT(spriteWorldP != NULL && spriteWorldP->tilingIsInitialized);
- SW_ASSERT(startTileLayer >= 0 && endTileLayer < kNumTileLayers);
- SW_ASSERT(srcSpriteP != NULL);
-
- oldFrameRect = srcSpriteP->oldFrameRect;
- destFrameRect = srcSpriteP->destFrameRect;
-
- if (insetRectP != NULL)
- {
- oldFrameRect.left += insetRectP->left;
- oldFrameRect.top += insetRectP->top;
- oldFrameRect.right -= insetRectP->right;
- oldFrameRect.bottom -= insetRectP->bottom;
-
- destFrameRect.left += insetRectP->left;
- destFrameRect.top += insetRectP->top;
- destFrameRect.right -= insetRectP->right;
- destFrameRect.bottom -= insetRectP->bottom;
- }
-
- // We must do this so sprites hanging off the top or left side of the TileMap
- // are still handled correctly. (The conversion from pixel to row won't work
- // correctly for negative numbers, so we "fix" the problem here.)
- if (oldFrameRect.top < 0)
- oldFrameRect.top -= spriteWorldP->tileHeight;
- if (oldFrameRect.bottom <= 0)
- oldFrameRect.bottom -= spriteWorldP->tileHeight;
-
- if (oldFrameRect.left <= 0)
- oldFrameRect.left -= spriteWorldP->tileWidth;
- if (oldFrameRect.right <= 0)
- oldFrameRect.right -= spriteWorldP->tileWidth;
-
- if (destFrameRect.left < 0)
- destFrameRect.left -= spriteWorldP->tileWidth;
- if (destFrameRect.right <= 0)
- destFrameRect.right -= spriteWorldP->tileWidth;
-
- if (destFrameRect.top < 0)
- destFrameRect.top -= spriteWorldP->tileHeight;
- if (destFrameRect.bottom <= 0)
- destFrameRect.bottom -= spriteWorldP->tileHeight;
-
-
- // startRow = the tile the oldFrameRect.side was about to run into.
- // stopRow = the tile the destFrameRect.side is currently in.
- // Function returns early if the sprite didn't move over
- // a tile's bounds since last frame.
-
- if (searchType == kSWTopSide)
- {
- startRow = (oldFrameRect.top / spriteWorldP->tileHeight);
- stopRow = destFrameRect.top / spriteWorldP->tileHeight;
- startCol = destFrameRect.left / spriteWorldP->tileWidth;
- stopCol = (destFrameRect.right-1) / spriteWorldP->tileWidth;
- if (fixPosition)
- startRow--; // Check tile just above startRow
- if (stopRow > startRow)
- return false;
- }
- else if (searchType == kSWBottomSide)
- {
- startRow = ((oldFrameRect.bottom-1) / spriteWorldP->tileHeight);
- stopRow = (destFrameRect.bottom-1) / spriteWorldP->tileHeight;
- startCol = destFrameRect.left / spriteWorldP->tileWidth;
- stopCol = (destFrameRect.right-1) / spriteWorldP->tileWidth;
- if (fixPosition) // Check tile just below startRow
- startRow++;
- if (stopRow < startRow)
- return false;
- }
- else if (searchType == kSWRightSide)
- {
- startCol = ((oldFrameRect.right-1) / spriteWorldP->tileWidth);
- stopCol = (destFrameRect.right-1) / spriteWorldP->tileWidth;
- startRow = destFrameRect.top / spriteWorldP->tileHeight;
- stopRow = (destFrameRect.bottom-1) / spriteWorldP->tileHeight;
- if (fixPosition) // Check tile just to the right of startCol
- startCol++;
- if (stopCol < startCol)
- return false;
- }
- else if (searchType == kSWLeftSide)
- {
- startCol = oldFrameRect.left / spriteWorldP->tileWidth;
- stopCol = destFrameRect.left / spriteWorldP->tileWidth;
- startRow = destFrameRect.top / spriteWorldP->tileHeight;
- stopRow = (destFrameRect.bottom-1) / spriteWorldP->tileHeight;
- if (fixPosition) // Check tile just to the left of startCol
- startCol--;
- if (stopCol > startCol)
- return false;
- }
- else // searchType == kSWEntireSprite
- {
- startRow = destFrameRect.top / spriteWorldP->tileHeight;
- stopRow = (destFrameRect.bottom-1) / spriteWorldP->tileHeight;
- startCol = destFrameRect.left / spriteWorldP->tileWidth;
- stopCol = (destFrameRect.right-1) / spriteWorldP->tileWidth;
- }
-
- if (startRow <= stopRow)
- rowIncrement = 1;
- else
- rowIncrement = -1;
-
- if (startCol <= stopCol)
- colIncrement = 1;
- else
- colIncrement = -1;
-
-
- // Find the first tileLayer that's not NULL
- for (tileLayer = startTileLayer; tileLayer <= endTileLayer; tileLayer++)
- {
- if (spriteWorldP->tileLayerArray[tileLayer] != NULL)
- break;
- }
-
-
- // Make sure things are within bounds (in case Sprite is hanging off edge of TileMap)
- if (rowIncrement > 0)
- {
- if (stopRow < 0)
- return false;
- else if (stopRow >= spriteWorldP->tileLayerArray[tileLayer]->numRows)
- stopRow = spriteWorldP->tileLayerArray[tileLayer]->numRows-1;
-
- if (startRow < 0)
- startRow = 0;
- else if (startRow >= spriteWorldP->tileLayerArray[tileLayer]->numRows)
- return false;
- }
- else // rowIncrement < 0
- {
- if (startRow < 0)
- return false;
- else if (startRow >= spriteWorldP->tileLayerArray[tileLayer]->numRows)
- startRow = spriteWorldP->tileLayerArray[tileLayer]->numRows-1;
-
- if (stopRow < 0)
- stopRow = 0;
- else if (stopRow >= spriteWorldP->tileLayerArray[tileLayer]->numRows)
- return false;
- }
-
- if (colIncrement > 0)
- {
- if (stopCol < 0)
- return false;
- else if (stopCol >= spriteWorldP->tileLayerArray[tileLayer]->numCols)
- stopCol = spriteWorldP->tileLayerArray[tileLayer]->numCols-1;
-
- if (startCol < 0)
- startCol = 0;
- else if (startCol >= spriteWorldP->tileLayerArray[tileLayer]->numCols)
- return false;
- }
- else // colIncrement < 0
- {
- if (startCol < 0)
- return false;
- else if (startCol >= spriteWorldP->tileLayerArray[tileLayer]->numCols)
- startCol = spriteWorldP->tileLayerArray[tileLayer]->numCols-1;
-
- if (stopCol < 0)
- stopCol = 0;
- else if (stopCol >= spriteWorldP->tileLayerArray[tileLayer]->numCols)
- return false;
- }
-
-
-
- // Look for the tiles in each layer. We have two separate loops: one that scans
- // through each row, then each col, and one that scans through each col, then each
- // row. You must use the correct type depending on which direction the sprite is moving.
- // (horizontally or vertically) for things to work correctly.
-
- if (searchType == kSWTopSide || searchType == kSWBottomSide || searchType == kSWEntireSprite)
- {
- for (tileLayer = startTileLayer; tileLayer <= endTileLayer; tileLayer++)
- {
- if (spriteWorldP->tileLayerArray[tileLayer] == NULL)
- continue;
-
- tileMap = spriteWorldP->tileLayerArray[tileLayer]->tileMap;
-
- // Scan through all cols in a row before moving to next row
- rowLoopTest = true;
- for (row = startRow; rowLoopTest; row += rowIncrement)
- {
- rowLoopTest = row != stopRow;
-
- colLoopTest = true;
- for (col = startCol; colLoopTest; col += colIncrement)
- {
- colLoopTest = col != stopCol;
- tileID = tileMap[row][col];
- if (tileID >= firstTileID && tileID <= lastTileID)
- {
- foundTile = true;
- goto exit;
- }
- }
- }
- }
- }
- else
- {
- for (tileLayer = startTileLayer; tileLayer <= endTileLayer; tileLayer++)
- {
- if (spriteWorldP->tileLayerArray[tileLayer] == NULL)
- continue;
-
- tileMap = spriteWorldP->tileLayerArray[tileLayer]->tileMap;
-
- // Scan through all rows in a col before moving to next col
- colLoopTest = true;
- for (col = startCol; colLoopTest; col += colIncrement)
- {
- colLoopTest = col != stopCol;
-
- rowLoopTest = true;
- for (row = startRow; rowLoopTest; row += rowIncrement)
- {
- rowLoopTest = row != stopRow;
- tileID = tileMap[row][col];
- if (tileID >= firstTileID && tileID <= lastTileID)
- {
- foundTile = true;
- goto exit;
- }
- }
- }
- }
- }
-
- exit:
-
-
- if (foundTile && fixPosition)
- {
- if (searchType == kSWTopSide)
- {
- // (top of tile just below the tile the sprite is in) - (curSpriteTop)
- temp = (row+1) * spriteWorldP->tileHeight - destFrameRect.top;
- srcSpriteP->destFrameRect.top += temp;
- srcSpriteP->destFrameRect.bottom += temp;
- srcSpriteP->needsToBeDrawn = true;
- }
- else if (searchType == kSWBottomSide)
- {
- temp = destFrameRect.bottom - row * spriteWorldP->tileHeight;
- srcSpriteP->destFrameRect.top -= temp;
- srcSpriteP->destFrameRect.bottom -= temp;
- srcSpriteP->needsToBeDrawn = true;
- }
- else if (searchType == kSWRightSide)
- {
- temp = destFrameRect.right - col * spriteWorldP->tileWidth;
- srcSpriteP->destFrameRect.left -= temp;
- srcSpriteP->destFrameRect.right -= temp;
- srcSpriteP->needsToBeDrawn = true;
- }
- else if (searchType == kSWLeftSide)
- {
- temp = (col+1) * spriteWorldP->tileWidth - destFrameRect.left;
- srcSpriteP->destFrameRect.left += temp;
- srcSpriteP->destFrameRect.right += temp;
- srcSpriteP->needsToBeDrawn = true;
- }
- }
-
- return foundTile;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWWrapRectToWorkArea - I think this is identical to SWEraseWrappedSprite, and is here
- // simply so Scrolling.c isn't required during compiles.
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWWrapRectToWorkArea(
- SpriteWorldPtr spriteWorldP,
- Rect* destRectP)
- {
- Rect destRect = *destRectP;
- Rect tempDestRect;
- FramePtr srcFrameP = spriteWorldP->backFrameP;
- FramePtr dstFrameP = spriteWorldP->workFrameP;
-
- SW_ASSERT(spriteWorldP != NULL);
- SW_ASSERT(spriteWorldP->backFrameP->isFrameLocked);
- SW_ASSERT(spriteWorldP->workFrameP->isFrameLocked);
-
- SetGWorld(spriteWorldP->workFrameP->framePort, nil);
-
- // Make destRect local to the offscreen area
- destRect.top -= spriteWorldP->vertScrollRectOffset;
- destRect.bottom -= spriteWorldP->vertScrollRectOffset;
- destRect.left -= spriteWorldP->horizScrollRectOffset;
- destRect.right -= spriteWorldP->horizScrollRectOffset;
-
-
- // Draw main image
- (*spriteWorldP->offscreenDrawProc)(srcFrameP, dstFrameP, &destRect, &destRect);
-
-
- // Wrap to top //
- if (destRect.bottom > dstFrameP->frameRect.bottom)
- {
- tempDestRect.top = destRect.top - dstFrameP->frameRect.bottom;
- tempDestRect.bottom = destRect.bottom - dstFrameP->frameRect.bottom;
- tempDestRect.left = destRect.left;
- tempDestRect.right = destRect.right;
-
- (*spriteWorldP->offscreenDrawProc)(srcFrameP, dstFrameP,
- &tempDestRect, &tempDestRect);
-
- // Wrap to upper left or right corner //
- if (destRect.right > dstFrameP->frameRect.right)
- {
- tempDestRect.left -= dstFrameP->frameRect.right;
- tempDestRect.right -= dstFrameP->frameRect.right;
-
- (*spriteWorldP->offscreenDrawProc)(srcFrameP, dstFrameP,
- &tempDestRect, &tempDestRect);
- }
- else if (destRect.left < dstFrameP->frameRect.left)
- {
- tempDestRect.left += dstFrameP->frameRect.right;
- tempDestRect.right += dstFrameP->frameRect.right;
-
- (*spriteWorldP->offscreenDrawProc)(srcFrameP, dstFrameP,
- &tempDestRect, &tempDestRect);
- }
- }
-
- // Wrap to left or right side //
- if (destRect.right > dstFrameP->frameRect.right)
- {
- tempDestRect.top = destRect.top;
- tempDestRect.bottom = destRect.bottom;
- tempDestRect.left = destRect.left - dstFrameP->frameRect.right;
- tempDestRect.right = destRect.right - dstFrameP->frameRect.right;
-
- (*spriteWorldP->offscreenDrawProc)(srcFrameP, dstFrameP,
- &tempDestRect, &tempDestRect);
- }
- else if (destRect.left < dstFrameP->frameRect.left)
- {
- tempDestRect.top = destRect.top;
- tempDestRect.bottom = destRect.bottom;
- tempDestRect.left = destRect.left + dstFrameP->frameRect.right;
- tempDestRect.right = destRect.right + dstFrameP->frameRect.right;
-
- (*spriteWorldP->offscreenDrawProc)(srcFrameP, dstFrameP,
- &tempDestRect, &tempDestRect);
- }
-
-
- // Wrap to bottom //
- if (destRect.top < dstFrameP->frameRect.top)
- {
- tempDestRect.top = destRect.top + dstFrameP->frameRect.bottom;
- tempDestRect.bottom = destRect.bottom + dstFrameP->frameRect.bottom;
- tempDestRect.left = destRect.left;
- tempDestRect.right = destRect.right;
-
- (*spriteWorldP->offscreenDrawProc)(srcFrameP, dstFrameP,
- &tempDestRect, &tempDestRect);
-
- // Wrap to lower left or right corner //
- if (destRect.right > dstFrameP->frameRect.right)
- {
- tempDestRect.left -= dstFrameP->frameRect.right;
- tempDestRect.right -= dstFrameP->frameRect.right;
-
- (*spriteWorldP->offscreenDrawProc)(srcFrameP, dstFrameP,
- &tempDestRect, &tempDestRect);
- }
- else if (destRect.left < dstFrameP->frameRect.left)
- {
- tempDestRect.left += dstFrameP->frameRect.right;
- tempDestRect.right += dstFrameP->frameRect.right;
-
- (*spriteWorldP->offscreenDrawProc)(srcFrameP, dstFrameP,
- &tempDestRect, &tempDestRect);
- }
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWWrapRectFromExtraBackFrame - similar to SWWrapRectToScreen, just modified so the
- // srcFramePtr is the extraBackFramePtr, the dstFrameP is the backFrameP, and the src
- // and dst rects are what they should be. Note: the dstRect you pass to this function is
- // the tile's rect *before* it's made local to the offscreen area and wrapped. It is also
- // important that the actual dstRectP is modified, not a copy, since the callers expect this.
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWWrapRectFromExtraBackFrame(
- SpriteWorldPtr spriteWorldP,
- Rect *dstRectP)
- {
- FramePtr srcFrameP = spriteWorldP->extraBackFrameP;
- FramePtr dstFrameP = spriteWorldP->backFrameP;
- Rect srcRect, tempSrcRect, tempDstRect;
- short topClip=0, rightClip=0, bottomClip=0, leftClip=0;
- short vertBackRectOffset, horizBackRectOffset;
-
- SW_ASSERT(spriteWorldP != NULL);
- SW_ASSERT(srcFrameP->isFrameLocked);
- SW_ASSERT(dstFrameP->isFrameLocked);
-
- // The code below is ripped from SWCalculateOffscreenScrollRect
- // It is modified to do a similar function for the extraBackFrameP.
- vertBackRectOffset = spriteWorldP->extraBackFrameP->frameRect.bottom *
- (dstRectP->top / spriteWorldP->extraBackFrameP->frameRect.bottom);
-
- horizBackRectOffset = spriteWorldP->extraBackFrameP->frameRect.right *
- (dstRectP->left / spriteWorldP->extraBackFrameP->frameRect.right);
-
- srcRect.top = dstRectP->top - vertBackRectOffset;
- srcRect.bottom = dstRectP->bottom - vertBackRectOffset;
- srcRect.left = dstRectP->left - horizBackRectOffset;
- srcRect.right = dstRectP->right - horizBackRectOffset;
-
- // We must do the dstRect calculation below *after* the code above!
-
- // Make the tile's dest rect local to the offscreen area
- dstRectP->top -= spriteWorldP->vertScrollRectOffset;
- dstRectP->bottom -= spriteWorldP->vertScrollRectOffset;
- dstRectP->left -= spriteWorldP->horizScrollRectOffset;
- dstRectP->right -= spriteWorldP->horizScrollRectOffset;
-
- // Wrap dstRect to top or bottom of offscreen area
- if (dstRectP->bottom > dstFrameP->frameRect.bottom)
- {
- dstRectP->top -= dstFrameP->frameRect.bottom;
- dstRectP->bottom -= dstFrameP->frameRect.bottom;
- }
- else if (dstRectP->top < dstFrameP->frameRect.top)
- {
- dstRectP->top += dstFrameP->frameRect.bottom;
- dstRectP->bottom += dstFrameP->frameRect.bottom;
- }
-
- // Wrap dstRect to left or right side of offscreen area
- if (dstRectP->right > dstFrameP->frameRect.right)
- {
- dstRectP->left -= dstFrameP->frameRect.right;
- dstRectP->right -= dstFrameP->frameRect.right;
- }
- else if (dstRectP->left < dstFrameP->frameRect.left)
- {
- dstRectP->left += dstFrameP->frameRect.right;
- dstRectP->right += dstFrameP->frameRect.right;
- }
-
-
- // 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
- 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 = dstRectP->top;
- tempDstRect.bottom = dstRectP->top + topClip;
- tempDstRect.left = dstRectP->left + leftClip;
- tempDstRect.right = dstRectP->right - rightClip;
-
- (*spriteWorldP->screenDrawProc)(srcFrameP, dstFrameP, &tempSrcRect, &tempDstRect);
-
-
- if (leftClip) // Calculate 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 = dstRectP->left;
- tempDstRect.top = dstRectP->top;
- tempDstRect.right = dstRectP->left + leftClip;
- tempDstRect.bottom = dstRectP->top + topClip;
-
- (*spriteWorldP->screenDrawProc)(srcFrameP, dstFrameP, &tempSrcRect, &tempDstRect);
- }
- else if (rightClip) // Calculate 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 = dstRectP->top;
- tempDstRect.right = dstRectP->right;
- tempDstRect.bottom = dstRectP->top + topClip;
- tempDstRect.left = dstRectP->right - rightClip;
-
- (*spriteWorldP->screenDrawProc)(srcFrameP, dstFrameP, &tempSrcRect, &tempDstRect);
- }
- }
-
-
- // Draw middle section //
-
- // Calculate main middle piece (not wrapped)
- tempDstRect.left = dstRectP->left + leftClip;
- tempDstRect.top = dstRectP->top + topClip;
- tempDstRect.right = dstRectP->right - rightClip;
- tempDstRect.bottom = dstRectP->bottom - bottomClip;
-
- (*spriteWorldP->screenDrawProc)(srcFrameP, dstFrameP, &srcRect, &tempDstRect);
-
-
- 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 = dstRectP->left;
- tempDstRect.right = dstRectP->left + leftClip;
- tempDstRect.top = dstRectP->top + topClip;
- tempDstRect.bottom = dstRectP->bottom - bottomClip;
-
- (*spriteWorldP->screenDrawProc)(srcFrameP, dstFrameP, &tempSrcRect, &tempDstRect);
- }
- else 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 = dstRectP->right;
- tempDstRect.left = dstRectP->right - rightClip;
- tempDstRect.top = dstRectP->top + topClip;
- tempDstRect.bottom = dstRectP->bottom - bottomClip;
-
- (*spriteWorldP->screenDrawProc)(srcFrameP, dstFrameP, &tempSrcRect, &tempDstRect);
- }
-
-
- // Draw bottom section //
-
- if (bottomClip)
- {
- // Calculate 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 = dstRectP->bottom;
- tempDstRect.top = dstRectP->bottom - bottomClip;
- tempDstRect.left = dstRectP->left + leftClip;
- tempDstRect.right = dstRectP->right - rightClip;
-
- (*spriteWorldP->screenDrawProc)(srcFrameP, dstFrameP, &tempSrcRect, &tempDstRect);
-
- 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 = dstRectP->bottom;
- tempDstRect.left = dstRectP->left;
- tempDstRect.top = dstRectP->bottom - bottomClip;
- tempDstRect.right = dstRectP->left + leftClip;
-
- (*spriteWorldP->screenDrawProc)(srcFrameP, dstFrameP, &tempSrcRect, &tempDstRect);
- }
- else 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 = dstRectP->bottom;
- tempDstRect.right = dstRectP->right;
- tempDstRect.top = dstRectP->bottom - bottomClip;
- tempDstRect.left = dstRectP->right - rightClip;
-
- (*spriteWorldP->screenDrawProc)(srcFrameP, dstFrameP, &tempSrcRect, &tempDstRect);
- }
- }
- }
-
-