home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-11-25 | 48.6 KB | 1,779 lines | [TEXT/KAHL] |
- ///--------------------------------------------------------------------------------------
- // 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, row, col, numOffscreenCols, numOffscreenRows;
-
- SWAssert( spriteWorldP != NULL && !spriteWorldP->tilingIsInitialized && tileHeight > 0 && tileWidth > 0 && maxNumTiles > 0 );
-
- if (spriteWorldP->tilingIsInitialized)
- {
- err = kTilingAlreadyInitialized;
- }
-
-
- if (err == noErr)
- {
- spriteWorldP->tilingIsOn = true;
- spriteWorldP->tilingIsInitialized = true;
- spriteWorldP->maxNumTiles = maxNumTiles;
- spriteWorldP->tileHeight = tileHeight;
- spriteWorldP->tileWidth = tileWidth;
- spriteWorldP->tileMap = NULL;
-
- numOffscreenRows = spriteWorldP->backRect.bottom / tileHeight;
- numOffscreenCols = spriteWorldP->backRect.right / tileWidth;
- spriteWorldP->numOffscreenTileMapRows = numOffscreenRows;
- spriteWorldP->numOffscreenTileMapCols = numOffscreenCols;
- }
-
-
- if (err == noErr)
- {
- // Allocate memory for offscreenTileMap
- arraySize = (Size)numOffscreenRows * numOffscreenCols * sizeof(short);
- spriteWorldP->offscreenTileMap = (short *)NewPtr(arraySize);
- err = MemError();
-
- if (err == noErr)
- {
- // Set all elements to -1 (indicating that each tile needs to be drawn)
- for (row = 0; row < numOffscreenRows; row++)
- for (col = 0; col < numOffscreenCols; col++)
- spriteWorldP->offscreenTileMap[(long)row * numOffscreenCols + col] = -1;
- }
- }
-
-
- if (err == noErr)
- {
- // Allocate memory for changedTiles array of rects
- arraySize = (Size)(numOffscreenRows+1) * (numOffscreenCols+1) * sizeof(Rect);
- // Warning, arraySize calculation used in assert in SWAddChangeRect - probably should be SpriteWorld field
- spriteWorldP->changedTiles = (Rect *)NewPtr(arraySize);
- err = MemError();
- }
-
-
- 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;
- }
- }
-
-
- SWSetStickyIfError(err);
- return err;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWExitTiling
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWExitTiling(
- SpriteWorldPtr spriteWorldP)
- {
- short tileIndex;
-
- SWAssert( spriteWorldP != NULL );
-
- // Was tiling ever initialized?
- if (spriteWorldP->tilingIsInitialized)
- {
- tileIndex = spriteWorldP->maxNumTiles;
- while ( tileIndex-- )
- {
- SWDisposeTile( spriteWorldP, tileIndex );
- }
-
- SWDisposeTileMap(spriteWorldP);
-
- DisposePtr((Ptr)spriteWorldP->offscreenTileMap);
- DisposePtr((Ptr)spriteWorldP->tileFrameArray);
- DisposePtr((Ptr)spriteWorldP->changedTiles);
- DisposePtr((Ptr)spriteWorldP->curTileImage);
-
- spriteWorldP->tilingIsInitialized = false;
- spriteWorldP->tilingIsOn = false;
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWCreateTileMap
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC OSErr SWCreateTileMap(
- SpriteWorldPtr spriteWorldP,
- TileMapPtr *tileMapP,
- short numTileMapRows,
- short numTileMapCols)
- {
- TileMapPtr tempTileMap;
- Size arraySize;
- short row;
- OSErr err = noErr;
-
- SWAssert( spriteWorldP != NULL && tileMapP != NULL && numTileMapRows > 0 && numTileMapCols > 0 );
-
- // Dispose the old TileMap if there is one
- SWDisposeTileMap(spriteWorldP);
-
- // Allocate the first "dimension" of the array - tileMap[row]
- arraySize = (Size)numTileMapRows * sizeof(short*); // array of pointers
- tempTileMap = (short**)NewPtr(arraySize); // to the second array
- err = MemError();
-
- if (err == noErr)
- {
- // Allocate the second "dimension" of the array - tileMap[row][col]
- arraySize = (Size)numTileMapCols * sizeof(short);
- for (row = 0; row < numTileMapRows; row++)
- {
- tempTileMap[row] = (short*)NewPtrClear(arraySize);
- err = MemError();
-
- if (err) // Out of memory! Dispose whatever we managed to create.
- {
- while (--row >= 0)
- {
- DisposePtr((Ptr)tempTileMap[row]);
- }
-
- DisposePtr((Ptr)tempTileMap);
- tempTileMap = NULL;
-
- break;
- }
- }
- }
-
- // Assign the new tileMap to the SpriteWorld
- *tileMapP = spriteWorldP->tileMap = tempTileMap;
- spriteWorldP->numTileMapRows = numTileMapRows;
- spriteWorldP->numTileMapCols = numTileMapCols;
-
- SWSetStickyIfError(err);
- return err;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWDisposeTileMap
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWDisposeTileMap(
- SpriteWorldPtr spriteWorldP)
- {
- short row;
-
- SWAssert( spriteWorldP != NULL );
-
- if (spriteWorldP->tileMap != NULL)
- {
- // Dispose the second half of the tileMap
- for (row = 0; row < spriteWorldP->numTileMapRows; row++)
- DisposePtr((Ptr)spriteWorldP->tileMap[row]);
-
- // Dispose the first half (must be done in this order)
- DisposePtr((Ptr)spriteWorldP->tileMap);
- spriteWorldP->tileMap = NULL;
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWResizeTileMap
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC OSErr SWResizeTileMap(
- SpriteWorldPtr spriteWorldP,
- TileMapPtr *tileMapP,
- short numNewTileMapRows,
- short numNewTileMapCols)
- {
- short *tileMapData;
- short **tileMapDataH;
- Size arraySize;
- short row, numTileMapRows, numTileMapCols;
- short numRowsToCopy, numColsToCopy;
- OSErr err = noErr;
-
- SWAssert( spriteWorldP != NULL && tileMapP != NULL && *tileMapP != NULL && numNewTileMapRows > 0 && numNewTileMapCols > 0 );
-
- numTileMapRows = spriteWorldP->numTileMapRows;
- numTileMapCols = spriteWorldP->numTileMapCols;
-
- if (spriteWorldP->tileMap == NULL)
- {
- err = kNullTileMapErr;
- }
-
- // Don't do anything if the TileMap is already the requested size.
- if (numTileMapRows == numNewTileMapRows && numTileMapCols == numNewTileMapCols)
- {
- return noErr;
- }
-
-
- if (err == noErr) // Allocate memory for the tileMapData
- {
- arraySize = (Size)numTileMapRows * numTileMapCols * sizeof(short);
- tileMapDataH = (short **)NewHandle(arraySize);
- if (tileMapDataH == NULL)
- err = memFullErr;
- }
-
-
- if (err == noErr)
- {
- HLock((Handle)tileMapDataH);
- tileMapData = *tileMapDataH;
-
- // Copy the old TileMap into the tileMapData
- arraySize = (Size)numTileMapCols * sizeof(short);
- for (row = 0; row < numTileMapRows; row++)
- {
- BlockMove(&spriteWorldP->tileMap[row][0],
- &tileMapData[(long)row * numTileMapCols], arraySize);
- }
-
- HUnlock((Handle)tileMapDataH);
-
- // Dispose the old TileMap now that we've saved its data
- SWDisposeTileMap(spriteWorldP);
-
- // Create the new TileMap
- err = SWCreateTileMap(spriteWorldP, tileMapP, numNewTileMapRows,
- numNewTileMapCols);
- }
-
-
- if (err == noErr)
- {
- numRowsToCopy = SW_MIN(numTileMapRows, numNewTileMapRows);
- numColsToCopy = SW_MIN(numTileMapCols, numNewTileMapCols);
-
- HLock((Handle)tileMapDataH);
- tileMapData = *tileMapDataH;
-
- // Copy the old tileMapData into the new TileMap
- arraySize = (Size)numColsToCopy * sizeof(short);
- for (row = 0; row < numRowsToCopy; row++)
- {
- BlockMove(&tileMapData[(long)row * numTileMapCols],
- &spriteWorldP->tileMap[row][0], arraySize);
- }
-
- spriteWorldP->numTileMapRows = numNewTileMapRows;
- spriteWorldP->numTileMapCols = numNewTileMapCols;
- DisposeHandle((Handle)tileMapDataH);
- }
- else
- { // Not enough memory to create the resized TileMap!
- // Put things back the way they were (recreate the old TileMap)
- err = SWCreateTileMap(spriteWorldP, tileMapP, numTileMapRows,
- numTileMapCols);
-
- if (err == noErr) // Copy the data back into the TileMap
- {
- HLock((Handle)tileMapDataH);
- tileMapData = *tileMapDataH;
-
- // Copy the tileMapData into the TileMap
- arraySize = (Size)numTileMapCols * sizeof(short);
- for (row = 0; row < numTileMapRows; row++)
- {
- BlockMove(&tileMapData[(long)row * numTileMapCols],
- &spriteWorldP->tileMap[row][0], arraySize);
- }
- }
-
- DisposeHandle((Handle)tileMapDataH);
- err = memFullErr; // Couldn't create the resized TileMap
- }
-
-
- SWSetStickyIfError(err);
- return err;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWLoadTileMap
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC OSErr SWLoadTileMap(
- SpriteWorldPtr spriteWorldP,
- TileMapPtr *tileMapP,
- short resourceID)
- {
- short *tileMapData;
- short **tileMapDataH;
- short row, numTileMapRows, numTileMapCols;
- Size arraySize;
- OSErr err = noErr;
-
- SWAssert( spriteWorldP != NULL && tileMapP != NULL );
-
- tileMapDataH = (short **)Get1Resource('TMAP', resourceID);
- if (tileMapDataH == NULL)
- {
- err = ResError();
- if (err == noErr)
- err = resNotFound;
- }
-
- if (err == noErr) // Copy the resource data into the tileMap //
- {
- HLock((Handle)tileMapDataH);
- tileMapData = *tileMapDataH;
-
- // Get the variables saved in the first two elements of the tileMapData
- numTileMapRows = tileMapData[0];
- numTileMapCols = tileMapData[1];
-
- // Don't create a new tileMap if there is already one that's the same size
- if (spriteWorldP->tileMap == NULL ||
- numTileMapRows != spriteWorldP->numTileMapRows ||
- numTileMapCols != spriteWorldP->numTileMapCols)
- {
- // Dispose the old tileMap if there is one
- SWDisposeTileMap(spriteWorldP);
-
- // Let the new TileMap go as low in the heap as possible
- HUnlock((Handle)tileMapDataH);
-
- err = SWCreateTileMap(spriteWorldP, tileMapP, numTileMapRows,
- numTileMapCols);
-
- HLock((Handle)tileMapDataH);
- tileMapData = *tileMapDataH;
- }
- else
- {
- *tileMapP = spriteWorldP->tileMap;
- }
- }
-
-
- if (err == noErr)
- {
- // Copy the data into the tileMap array
- arraySize = (Size)numTileMapCols * sizeof(short);
- for (row = 0; row < numTileMapRows; row++)
- {
- BlockMove(&tileMapData[(long)row * numTileMapCols + 2],
- &spriteWorldP->tileMap[row][0], arraySize);
- }
- }
-
-
- if (tileMapDataH != NULL)
- {
- ReleaseResource((Handle)tileMapDataH);
- }
-
-
- SWSetStickyIfError(err);
- return err;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWSaveTileMap
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC OSErr SWSaveTileMap(
- SpriteWorldPtr spriteWorldP,
- short resourceID)
- {
- short *tileMapData;
- short **tileMapDataH;
- short row, numTileMapRows, numTileMapCols;
- Boolean createdNewResource;
- Size arraySize;
- OSErr err = noErr;
-
- SWAssert( spriteWorldP != NULL );
-
- numTileMapRows = spriteWorldP->numTileMapRows,
- numTileMapCols = spriteWorldP->numTileMapCols;
-
- // Make sure there is a tileMap to save
- if (spriteWorldP->tileMap == NULL)
- {
- err = kNullTileMapErr;
- }
-
-
- if (err == noErr) // Load or create the resource //
- {
- tileMapDataH = (short **)Get1Resource('TMAP', resourceID);
-
- // Is there already a resource with this ID?
- if (tileMapDataH != NULL)
- {
- arraySize = ((Size)numTileMapRows * numTileMapCols + 2) * sizeof(short);
- SetHandleSize((Handle)tileMapDataH, arraySize);
- err = MemError();
-
- if (err != noErr)
- ReleaseResource((Handle)tileMapDataH);
-
- createdNewResource = false;
- }
- else if (ResError() == resNotFound || ResError() == noErr)
- {
- arraySize = ((Size)numTileMapRows * numTileMapCols + 2) * sizeof(short);
- tileMapDataH = (short **)NewHandle(arraySize);
- err = MemError();
-
- createdNewResource = true;
- }
- else
- {
- err = ResError();
- }
- }
-
-
- if (err == noErr) // Copy the data into the resource handle //
- {
- HLock((Handle)tileMapDataH);
- tileMapData = *tileMapDataH;
-
- // Save these variables in the first two elements of the tileMapData
- tileMapData[0] = numTileMapRows;
- tileMapData[1] = numTileMapCols;
-
- // Move the two-dimensional array into a one-dimensional array,
- // so we can save it into a single resource.
- arraySize = (Size)numTileMapCols * sizeof(short);
- for (row = 0; row < numTileMapRows; row++)
- {
- BlockMove(&spriteWorldP->tileMap[row][0],
- &tileMapData[(long)row * numTileMapCols + 2], arraySize);
- }
- }
-
-
- if (err == noErr) // Add the resource or mark it as changed //
- {
- if (createdNewResource)
- {
- AddResource((Handle)tileMapDataH, 'TMAP', resourceID, "\p");
- err = ResError();
-
- if (err != noErr)
- DisposHandle((Handle)tileMapDataH);
-
- }
- else
- {
- ChangedResource((Handle)tileMapDataH);
- err = ResError();
-
- if (err != noErr)
- ReleaseResource((Handle)tileMapDataH);
- }
- }
-
-
- if (err == noErr) // Update the resource file and clean up //
- {
- UpdateResFile( CurResFile() );
- ReleaseResource((Handle)tileMapDataH);
- }
-
-
- SWSetStickyIfError(err);
- return err;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWLockTiles
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWLockTiles(
- SpriteWorldPtr spriteWorldP)
- {
- short tileIndex;
-
- SWAssert( spriteWorldP != NULL );
-
- 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;
-
- SWAssert( spriteWorldP != NULL );
-
- if (spriteWorldP->tilingIsInitialized)
- {
- for (tileIndex = 0; tileIndex < spriteWorldP->maxNumTiles; tileIndex++)
- {
- if (spriteWorldP->tileFrameArray[tileIndex] != NULL)
- SWUnlockFrame(spriteWorldP->tileFrameArray[tileIndex]);
- }
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWSetTilingOn
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWSetTilingOn(
- SpriteWorldPtr spriteWorldP,
- Boolean tilingIsOn)
- {
- SWAssert( spriteWorldP != NULL );
-
- spriteWorldP->tilingIsOn = tilingIsOn;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWSetSpriteUnderTiles
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWSetSpriteUnderTiles(
- SpritePtr srcSpriteP,
- Boolean isUnder)
- {
- SWAssert( srcSpriteP != NULL );
-
- srcSpriteP->isUnderTiles = isUnder;
-
- // Redraw sprite over/under tiles
- srcSpriteP->needsToBeDrawn = true;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWSetTileMaskDrawProc
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC OSErr SWSetTileMaskDrawProc(
- SpriteWorldPtr spriteWorldP,
- DrawProcPtr drawProc)
- {
- OSErr err = noErr;
-
- SWAssert( spriteWorldP != NULL && drawProc != NULL );
-
- if (spriteWorldP->pixelDepth != 8)
- {
- if (drawProc == BlitPixie8BitMaskDrawProc ||
- drawProc == BP8BitInterlacedMaskDrawProc ||
- drawProc == BlitPixie8BitPartialMaskDrawProc ||
- drawProc == BP8BitInterlacedPartialMaskDrawProc)
- {
- err = kWrongDepthErr;
- }
- }
-
- if ( err == noErr )
- spriteWorldP->tileMaskDrawProc = drawProc;
-
- 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;
-
- SWAssert( spriteWorldP != NULL && spriteWorldP->tilingIsInitialized );
- SWAssert( spriteWorldP->tileWidth <= 32 && spriteWorldP->tileHeight <= 32 );
-
- 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;
- newFrameP->frameRect.right = newFrameP->frameRect.left + spriteWorldP->tileWidth;
- newFrameP->frameRect.bottom = newFrameP->frameRect.top + 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;
- }
- }
-
- 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;
-
- SWAssert( spriteWorldP != NULL && spriteWorldP->tilingIsInitialized );
- SWAssert( 0 <= startTileID && startTileID <= endTileID && endTileID < spriteWorldP->maxNumTiles );
- SWAssert( horizBorderWidth >= 0 && vertBorderHeight >= 0 );
-
- err = noErr;
- newFrameP = NULL;
- tempPictGWorldP = NULL;
- tempMaskGWorldP = 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 );
- }
- 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;
-
- 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)
- {
- GetGWorld( ¤tGWorld, ¤tGDH );
- (void)LockPixels( GetGWorldPixMap(tempMaskGWorldP) );
- SetGWorld(tempMaskGWorldP, nil);
- InvertRect(&tempMaskGWorldP->portRect);
- SetGWorld( currentGWorld, currentGDH );
- UnlockPixels( GetGWorldPixMap(tempMaskGWorldP) );
- }
- // If no pixel Mask wanted, dispose
- // of the GWorld we used to make region
- else
- {
- DisposeGWorld( tempMaskGWorldP );
- }
- }
- }
- SWCreateFrameFromGWorldAndRectFinish( tempTempMaskGWorldP );
- }
-
- SWSetStickyIfError(err);
- return err;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWDisposeTile
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWDisposeTile(
- SpriteWorldPtr spriteWorldP,
- short tileID)
- {
- short tileIndex;
- Boolean gWorldStillInUse;
-
- SWAssert( spriteWorldP != NULL && 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] );
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWDrawTilesInBackground
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC OSErr SWDrawTilesInBackground(
- SpriteWorldPtr spriteWorldP)
- {
- GWorldPtr holdGWorld;
- GDHandle holdGDH;
- OSErr err = noErr;
-
- SWAssert( spriteWorldP != NULL && spriteWorldP->tilingIsInitialized );
-
- GetGWorld( &holdGWorld, &holdGDH );
-
- if (spriteWorldP->tileMap == NULL)
- {
- err = kNullTileMapErr;
- }
- else if ( !spriteWorldP->tilingIsInitialized )
- {
- err = kTilingNotInitialized;
- }
- else
- {
- SWDrawTilesInRect(spriteWorldP, &spriteWorldP->visScrollRect, true);
- }
-
- SetGWorld( holdGWorld, holdGDH );
- SWSetStickyIfError(err);
- return err;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWResetTilingCache
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWResetTilingCache(SpriteWorldPtr spriteWorldP)
- {
- short row, col;
-
- SWAssert( spriteWorldP != NULL && spriteWorldP->tilingIsInitialized );
-
- // Set all elements to -1 (indicating that each tile needs to be drawn)
- for (row = 0; row < spriteWorldP->numOffscreenTileMapRows; row++)
- {
- for (col = 0; col < spriteWorldP->numOffscreenTileMapCols; col++)
- {
- spriteWorldP->offscreenTileMap[(long)row *
- spriteWorldP->numOffscreenTileMapCols + col] = -1;
- }
- }
- }
-
- #define SW_DEBUG_DDCHANGERECT 0
-
- #if SW_DEBUG_DDCHANGERECT
- static RgnHandle DebugGetChangedRgn( SpriteWorldPtr spriteWorldP, Rect *addRectP )
- {
- RgnHandle resultRgn;
- RgnHandle tempRgn;
- short index;
-
- resultRgn = NewRgn();
- tempRgn = NewRgn();
- for ( index = 0; index < spriteWorldP->numTilesChanged; index++ ) {
- RectRgn( tempRgn, &spriteWorldP->changedTiles[index] );
- UnionRgn( resultRgn, tempRgn, resultRgn );
- }
- if ( addRectP ) {
- RectRgn( tempRgn, addRectP );
- UnionRgn( resultRgn, tempRgn, resultRgn );
- }
- DisposeRgn( tempRgn );
- return resultRgn;
- }
-
- static DebugValidateChangeRgn( SpriteWorldPtr spriteWorldP, RgnHandle expected )
- {
- RgnHandle after;
-
- after = DebugGetChangedRgn( spriteWorldP, NULL );
- SWAssert( EqualRgn( expected, after ) );
- DisposeRgn( expected );
- DisposeRgn( after );
- }
- #else
-
- #define DebugGetChangedRgn( x ) NULL
- #define DebugValidateChangeRgn( x, y )
-
- #endif
-
- static void SWAddChangeRect(SpriteWorldPtr spriteWorldP, Rect *changedRectP )
- {
- short index;
- Rect *changedTileP;
- #if SW_DEBUG_DDCHANGERECT
- RgnHandle before;
- #endif
-
-
- SWAssert( spriteWorldP != NULL && spriteWorldP->changedTiles != NULL && changedRectP != NULL );
-
- #if SW_DEBUG_DDCHANGERECT
- before = DebugGetChangedRgn( spriteWorldP, changedRectP );
- #endif
-
- if ( changedRectP->left >= changedRectP->right || changedRectP->top >= changedRectP->bottom ) {
- DebugValidateChangeRgn( spriteWorldP, before );
- return; // empty changedRectP
- }
-
- changedTileP = spriteWorldP->changedTiles;
- for ( index = 0; index < spriteWorldP->numTilesChanged; index++, changedTileP++) {
- // check for changedRectP entirely contained inside changedTileP
- if ( changedTileP->left <= changedRectP->left && changedTileP->top <= changedRectP->top &&
- changedTileP->right >= changedRectP->right && changedTileP->bottom >= changedRectP->bottom ) {
- DebugValidateChangeRgn( spriteWorldP, before );
- return;
- }
-
- // check for changedRectP entirely contained by changedTileP
- if ( changedTileP->left >= changedRectP->left && changedTileP->top >= changedRectP->top &&
- changedTileP->right <= changedRectP->right && changedTileP->bottom <= changedRectP->bottom ) {
- *changedTileP = *changedRectP;
- DebugValidateChangeRgn( spriteWorldP, before );
- return;
- }
- }
-
- changedTileP = spriteWorldP->changedTiles;
- for ( index = 0; index < spriteWorldP->numTilesChanged; index++, changedTileP++) {
- // check for changedRectP vertically adjacent to changedTileP
- if ( changedTileP->left == changedRectP->left && changedTileP->right == changedRectP->right ) {
- if ( changedTileP->top <= changedRectP->bottom && changedRectP->bottom <= changedTileP->bottom ||
- changedRectP->top <= changedTileP->bottom && changedTileP->bottom <= changedRectP->bottom ) {
- changedTileP->top = SW_MIN( changedTileP->top, changedRectP->top );
- changedTileP->bottom = SW_MAX( changedTileP->bottom, changedRectP->bottom );
- DebugValidateChangeRgn( spriteWorldP, before );
- return;
- }
- }
-
- // check for changedRectP horizontally adjacent to changedTileP
- if ( changedTileP->top == changedRectP->top && changedTileP->bottom == changedRectP->bottom ) {
- if ( changedTileP->left <= changedRectP->right && changedRectP->right <= changedTileP->right ||
- changedRectP->left <= changedTileP->right && changedTileP->right <= changedRectP->right ) {
- changedTileP->left = SW_MIN( changedTileP->left, changedRectP->left );
- changedTileP->right = SW_MAX( changedTileP->right, changedRectP->right );
- DebugValidateChangeRgn( spriteWorldP, before );
- return;
- }
- }
- }
-
- SWAssert( spriteWorldP->numTilesChanged + 1 < (spriteWorldP->numOffscreenTileMapRows+1) * (spriteWorldP->numOffscreenTileMapCols+1) );
- spriteWorldP->changedTiles[spriteWorldP->numTilesChanged++] = *changedRectP;
- DebugValidateChangeRgn( spriteWorldP, before );
- }
-
- /*
- static void SWDrawTileFrame(
- SpriteWorldPtr spriteWorldP,
- FramePtr tileFrameP,
- FramePtr dstFrameP,
- Rect *srcRectP,
- Rect *dstRectP )
- {
- if (tileFrameP->tileMaskIsSolid)
- {
- // Draw the tile without using a mask
- (*spriteWorldP->offscreenDrawProc)(tileFrameP, dstFrameP, srcRectP, dstRectP );
- }
- else
- {
- // Draw the masked part of the tile
- (*spriteWorldP->tileMaskDrawProc)(tileFrameP, dstFrameP, srcRectP, dstRectP );
- }
- }
- */
-
- ///--------------------------------------------------------------------------------------
- // SWDrawTile - sets value in tileMap and draws tile if visible in visScrollRect.
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWDrawTile(
- SpriteWorldPtr spriteWorldP,
- short tileRow,
- short tileCol,
- short tileID)
- {
- short row, col, offscreenTileRow, offscreenTileCol;
- Rect* visScrollRectP = &spriteWorldP->visScrollRect;
- Rect* backRectP = &spriteWorldP->backRect;
- Rect srcRect, dstRect;
- FramePtr tileFrameP;
- Boolean tileClipped;
-
- SWAssert( spriteWorldP != NULL && spriteWorldP->tilingIsInitialized );
- SWAssert( 0 <= tileRow && tileRow < spriteWorldP->numTileMapRows );
- SWAssert( 0 <= tileCol && tileCol < spriteWorldP->numTileMapCols );
- SWAssert( 0 <= tileID && tileID < spriteWorldP->maxNumTiles );
-
- // Set value in tileMap and get tileFrameP
- spriteWorldP->tileMap[tileRow][tileCol] = tileID;
- tileFrameP = spriteWorldP->tileFrameArray[spriteWorldP->curTileImage[tileID]];
-
- row = tileRow * spriteWorldP->tileHeight;
- col = tileCol * spriteWorldP->tileWidth;
-
- srcRect = tileFrameP->frameRect;
- dstRect.bottom = row + spriteWorldP->tileHeight;
- dstRect.right = col + spriteWorldP->tileWidth;
-
-
- // Clip tile with visScrollRect
- tileClipped = false;
- if (row < visScrollRectP->top)
- {
- dstRect.top = visScrollRectP->top;
- srcRect.top += visScrollRectP->top - row;
- tileClipped = true;
- }
- else
- dstRect.top = row;
-
- if (col < visScrollRectP->left)
- {
- dstRect.left = visScrollRectP->left;
- srcRect.left += visScrollRectP->left - col;
- tileClipped = true;
- }
- else
- dstRect.left = col;
-
-
- if (dstRect.bottom > visScrollRectP->bottom)
- {
- srcRect.bottom -= dstRect.bottom - visScrollRectP->bottom;
- dstRect.bottom = visScrollRectP->bottom;
- tileClipped = true;
- }
-
- if (dstRect.right > visScrollRectP->right)
- {
- srcRect.right -= 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
- SWAddChangeRect( spriteWorldP, &dstRect );
-
- // 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;
- }
-
-
- // Draw tile in the background frame
- SetGWorld(spriteWorldP->backFrameP->framePort, nil);
-
- // SWDrawTileFrame( spriteWorldP, tileFrameP, spriteWorldP->backFrameP, &srcRect, &dstRect);
- (*spriteWorldP->offscreenDrawProc)(tileFrameP,
- spriteWorldP->backFrameP, &srcRect, &dstRect);
-
-
- // Copy tile to the work area
- SetGWorld(spriteWorldP->workFrameP->framePort, nil);
- (*spriteWorldP->offscreenDrawProc)(spriteWorldP->backFrameP,
- spriteWorldP->workFrameP, &dstRect, &dstRect);
-
-
- offscreenTileRow = dstRect.top / spriteWorldP->tileHeight;
- offscreenTileCol = dstRect.left / spriteWorldP->tileWidth;
-
- // Set new tile value in offscreenTileMap
- if (tileClipped)
- {
- spriteWorldP->offscreenTileMap[(long)offscreenTileRow *
- spriteWorldP->numOffscreenTileMapCols + offscreenTileCol] = -1;
- }
- else
- {
- spriteWorldP->offscreenTileMap[(long)offscreenTileRow *
- spriteWorldP->numOffscreenTileMapCols + offscreenTileCol] =
- spriteWorldP->curTileImage[tileID];
- }
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWSetTileChangeProc
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWSetTileChangeProc(
- SpriteWorldPtr spriteWorldP,
- TileChangeProcPtr tileChangeProc)
- {
- SWAssert( spriteWorldP != NULL && spriteWorldP->tilingIsInitialized && tileChangeProc != NULL );
-
- spriteWorldP->tileChangeProc = tileChangeProc;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWChangeTileImage
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWChangeTileImage(
- SpriteWorldPtr spriteWorldP,
- short tileID,
- short newImage)
- {
- SWAssert( spriteWorldP != NULL && spriteWorldP->tilingIsInitialized );
- SWAssert( 0 <= tileID && tileID < spriteWorldP->maxNumTiles );
- SWAssert( 0 <= newImage && 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;
- short startRow, startCol, stopRow, stopCol;
- short tileWidth = spriteWorldP->tileWidth;
- short tileHeight = spriteWorldP->tileHeight;
-
- SWAssert( spriteWorldP != NULL && spriteWorldP->tilingIsInitialized );
- SWAssert( 0 <= tileID && tileID < spriteWorldP->maxNumTiles );
-
- // Convert pixel row and col into tile row and col
- startRow = spriteWorldP->visScrollRect.top / tileHeight;
- startCol = spriteWorldP->visScrollRect.left / tileWidth;
- stopRow = (spriteWorldP->visScrollRect.bottom-1) / tileHeight;
- stopCol = (spriteWorldP->visScrollRect.right-1) / tileWidth;
-
-
- for (tileRow = startRow; tileRow <= stopRow; tileRow++)
- {
- for (tileCol = startCol; tileCol <= stopCol; tileCol++)
- {
- if (tileID == spriteWorldP->tileMap[tileRow][tileCol])
- {
- SWDrawTile(spriteWorldP, tileRow, tileCol, tileID);
- }
- }
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWResetCurrentTileImages
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWResetCurrentTileImages(
- SpriteWorldPtr spriteWorldP)
- {
- short tileIndex;
-
- SWAssert( spriteWorldP != NULL && spriteWorldP->tilingIsInitialized );
-
- if (spriteWorldP->tilingIsInitialized)
- {
- for (tileIndex = 0; tileIndex < spriteWorldP->maxNumTiles; tileIndex++)
- spriteWorldP->curTileImage[tileIndex] = tileIndex;
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWDrawTilesInRect - draw tiles in updateRect of backFrame
- ///--------------------------------------------------------------------------------------
-
- 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;
- Rect* visScrollRectP = &spriteWorldP->visScrollRect;
- Rect* backRectP = &spriteWorldP->backRect;
- Rect updateRect = *updateRectP;
- short tileWidth = spriteWorldP->tileWidth;
- short tileHeight = spriteWorldP->tileHeight;
-
- SWAssert( spriteWorldP != NULL && spriteWorldP->tilingIsInitialized && spriteWorldP->tileMap != NULL && updateRectP != NULL );
-
- 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;
-
- SWAssert( 0 <= startRow && startRow <= spriteWorldP->numTileMapRows );
- SWAssert( 0 <= startCol && startCol <= spriteWorldP->numTileMapCols );
- SWAssert( 0 <= stopRow && stopRow <= spriteWorldP->numTileMapRows );
- SWAssert( 0 <= stopCol && stopCol <= spriteWorldP->numTileMapCols );
-
- for (tileRow = startRow; tileRow <= stopRow; tileRow++)
- {
- row = tileRow * tileHeight;
-
- for (tileCol = startCol; tileCol <= stopCol; tileCol++)
- {
- col = tileCol * tileWidth;
-
- tileID = spriteWorldP->tileMap[tileRow][tileCol];
- tileFrameP = spriteWorldP->tileFrameArray[spriteWorldP->curTileImage[tileID]];
-
- srcRect = tileFrameP->frameRect;
- 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;
- 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;
- }
-
- offscreenTileRow = dstRect.top / tileHeight;
- offscreenTileCol = dstRect.left / tileWidth;
-
-
- // Save time by not drawing tile if already the same
- if (spriteWorldP->offscreenTileMap[(long)offscreenTileRow *
- spriteWorldP->numOffscreenTileMapCols + offscreenTileCol] !=
- spriteWorldP->curTileImage[tileID] || !optimizingOn)
- {
- // Draw the tile
- // SWDrawTileFrame( spriteWorldP, tileFrameP, spriteWorldP->backFrameP, &srcRect, &dstRect);
- (*spriteWorldP->offscreenDrawProc)(tileFrameP,
- spriteWorldP->backFrameP, &srcRect, &dstRect);
-
- // Set new tile value in offscreenTileMap
- if (tileClipped)
- {
- spriteWorldP->offscreenTileMap[(long)offscreenTileRow *
- spriteWorldP->numOffscreenTileMapCols + offscreenTileCol] = -1;
- }
- else
- {
- spriteWorldP->offscreenTileMap[(long)offscreenTileRow *
- spriteWorldP->numOffscreenTileMapCols + offscreenTileCol] =
- spriteWorldP->curTileImage[tileID];
- }
- }
- }
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // 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)
- {
- Rect* backRectP = &spriteWorldP->backRect;
- Rect updateRect = *updateRectP;
- short tileWidth = spriteWorldP->tileWidth;
- short tileHeight = spriteWorldP->tileHeight;
- short row, col, tileRow, tileCol, tileID;
- short startRow, startCol, stopRow, stopCol;
- Rect srcRect, dstRect;
- FramePtr tileFrameP;
-
- SWAssert( spriteWorldP != NULL && spriteWorldP->tilingIsInitialized && updateRectP != NULL );
-
- // 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;
-
-
- for (tileRow = startRow; tileRow <= stopRow; tileRow++)
- {
- row = tileRow * tileHeight;
-
- for (tileCol = startCol; tileCol <= stopCol; tileCol++)
- {
- col = tileCol * tileWidth;
-
- tileID = spriteWorldP->tileMap[tileRow][tileCol];
- tileFrameP = spriteWorldP->tileFrameArray[spriteWorldP->curTileImage[tileID]];
-
- // Skip tiles that have no mask, and therefore aren't above the sprites
- if (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;
- }
-
- // SWDrawTileFrame( spriteWorldP, tileFrameP, spriteWorldP->workFrameP, &srcRect, &dstRect);
-
- 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->tileMaskDrawProc)(tileFrameP,
- spriteWorldP->workFrameP, &srcRect, &dstRect);
- }
- }
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWWrapRectToWorkArea
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWWrapRectToWorkArea(
- SpriteWorldPtr spriteWorldP,
- Rect* destRectP)
- {
- Rect destRect = *destRectP;
- Rect tempDestRect;
- FramePtr srcFrameP = spriteWorldP->backFrameP;
- FramePtr dstFrameP = spriteWorldP->workFrameP;
-
- SWAssert( spriteWorldP != NULL && spriteWorldP->tilingIsInitialized && destRectP != NULL );
-
- 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);
- }
- }
- }
-