home *** CD-ROM | disk | FTP | other *** search
Text File | 1999-01-12 | 49.2 KB | 1,875 lines | [TEXT/CWIE] |
- ///--------------------------------------------------------------------------------------
- // Sprite.c
- //
- // Portions are copyright: © 1991-94 Tony Myles, All rights reserved worldwide.
- //
- // Description: implementation of the sprites
- ///--------------------------------------------------------------------------------------
-
-
- #ifndef __SWCOMMON__
- #include "SWCommonHeaders.h"
- #endif
-
- #ifndef __MEMORY__
- #include <Memory.h>
- #endif
-
- #ifndef __SPRITEWORLDUTILS__
- #include "SpriteWorldUtils.h"
- #endif
-
- #ifndef __SPRITEWORLD__
- #include "SpriteWorld.h"
- #endif
-
- #ifndef __SPRITE__
- #include "Sprite.h"
- #endif
-
- #ifndef __SPRITEFRAME__
- #include "SpriteFrame.h"
- #endif
-
- #ifndef __BLITPIXIE__
- #include "BlitPixie.h"
- #endif
-
- extern RgnHandle gCollisionSectRgn;
- extern RgnHandle gCollisionSpareRgn;
- extern SInt8 gSWmmuMode;
-
-
- ///--------------------------------------------------------------------------------------
- // SWCreateSprite
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC OSErr SWCreateSprite(
- SpritePtr* newSpriteP,
- void* spriteStorageP,
- short maxFrames)
- {
- OSErr err = noErr;
- SpritePtr tempSpriteP;
- Size frameArraySize;
-
- *newSpriteP = NULL;
-
- tempSpriteP = (spriteStorageP == NULL) ? (SpritePtr)NewPtr(sizeof(SpriteRec)) : (SpritePtr)spriteStorageP;
-
- if (tempSpriteP != NULL)
- {
- frameArraySize = (Size)maxFrames * sizeof(FramePtr);
-
- tempSpriteP->frameArray = (FramePtr *)NewPtrClear(frameArraySize);
-
- if (tempSpriteP->frameArray != NULL)
- {
- tempSpriteP->parentSpriteLayerP = NULL;
- tempSpriteP->nextSpriteP = NULL;
- tempSpriteP->prevSpriteP = NULL;
-
- // initialize drawing fields
- tempSpriteP->isVisible = true;
- tempSpriteP->needsToBeDrawn = true;
- tempSpriteP->needsToBeErased = false;
- tempSpriteP->destFrameRect.left = 0;
- tempSpriteP->destFrameRect.top = 0;
- tempSpriteP->destFrameRect.right = 0;
- tempSpriteP->destFrameRect.bottom = 0;
- tempSpriteP->oldFrameRect.left = 0;
- tempSpriteP->oldFrameRect.top = 0;
- tempSpriteP->oldFrameRect.right = 0;
- tempSpriteP->oldFrameRect.bottom = 0;
- tempSpriteP->deltaFrameRect.left = 0;
- tempSpriteP->deltaFrameRect.top = 0;
- tempSpriteP->deltaFrameRect.right = 0;
- tempSpriteP->deltaFrameRect.bottom = 0;
- tempSpriteP->frameDrawProc = SWStdSpriteDrawProc;
- tempSpriteP->tileDepth = 1;
-
- // initialize drawing fields for scrolling routines
- tempSpriteP->destOffscreenRect.left = 0;
- tempSpriteP->destOffscreenRect.top = 0;
- tempSpriteP->destOffscreenRect.right = 0;
- tempSpriteP->destOffscreenRect.bottom = 0;
- tempSpriteP->oldOffscreenRect.left = 0;
- tempSpriteP->oldOffscreenRect.top = 0;
- tempSpriteP->oldOffscreenRect.right = 0;
- tempSpriteP->oldOffscreenRect.bottom = 0;
- tempSpriteP->oldRectIsVisible = false;
-
- // initialize frame fields
- tempSpriteP->frameArrayIsShared = false;
- tempSpriteP->curFrameP = NULL;
- tempSpriteP->numFrames = 0;
- tempSpriteP->maxFrames = maxFrames;
- tempSpriteP->frameTimeInterval = -1;
- tempSpriteP->timeOfLastFrameChange = 0;
- tempSpriteP->frameAdvance = 1;
- tempSpriteP->curFrameIndex = 0;
- tempSpriteP->firstFrameIndex = 0;
- tempSpriteP->lastFrameIndex = 0;
- tempSpriteP->frameChangeProc = NULL;
-
- // initialize movement fields
- tempSpriteP->moveTimeInterval = 0;
- tempSpriteP->timeOfLastMove = 0;
- tempSpriteP->horizMoveDelta = 0;
- tempSpriteP->vertMoveDelta = 0;
- tempSpriteP->moveBoundsRect.left = 0;
- tempSpriteP->moveBoundsRect.top = 0;
- tempSpriteP->moveBoundsRect.right = 0;
- tempSpriteP->moveBoundsRect.bottom = 0;
- tempSpriteP->spriteMoveProc = NULL;
-
- tempSpriteP->spriteCollideProc = NULL;
-
- tempSpriteP->sharedPictGWorld = NULL;
- tempSpriteP->sharedMaskGWorld = NULL;
- tempSpriteP->spriteRemoval = kSWDontRemoveSprite;
- tempSpriteP->frameAdvanceMode = kSWWrapAroundMode;
-
- tempSpriteP->scaledWidth = -1;
- tempSpriteP->scaledHeight = -1;
-
- tempSpriteP->userData = 0;
-
- // the sprite has been successfully created
- *newSpriteP = tempSpriteP;
- }
- else
- {
- err = MemError();
-
- DisposePtr((Ptr)tempSpriteP);
- }
- }
- else
- {
- err = MemError();
- }
-
- SWSetStickyIfError( err );
- return err;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWCreateSpriteFromCicnResource
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC OSErr SWCreateSpriteFromCicnResource(
- SpriteWorldPtr destSpriteWorldP,
- SpritePtr* newSpriteP,
- void* spriteStorageP,
- short cIconID,
- short maxFrames,
- MaskType maskType)
- {
- OSErr err;
- SpritePtr tempSpriteP;
- FramePtr newFrameP;
- short frame;
-
- SW_ASSERT(destSpriteWorldP != NULL);
-
- *newSpriteP = NULL;
-
- err = SWCreateSprite(&tempSpriteP, spriteStorageP, maxFrames);
-
- if (err == noErr)
- {
- for (frame = 0; frame < maxFrames; frame++)
- {
- err = SWCreateFrameFromCicnResource(destSpriteWorldP, &newFrameP,
- cIconID + frame, maskType);
-
- if (err == noErr)
- {
- err = SWAddFrame(tempSpriteP, newFrameP);
- }
-
- if (err != noErr)
- {
- SWDisposeFrame(&newFrameP);
- SWDisposeSprite(&tempSpriteP);
- break;
- }
- }
-
- if (err == noErr)
- {
- SWSetSpriteFrameRange(tempSpriteP, 0, maxFrames - 1);
- SWSetCurrentFrameIndex(tempSpriteP, 0);
- *newSpriteP = tempSpriteP;
- }
- }
-
- SWSetStickyIfError( err );
- return err;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWCreateSpriteFromPictResource
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC OSErr SWCreateSpriteFromPictResource(
- SpriteWorldPtr destSpriteWorldP,
- SpritePtr* newSpriteP,
- void* spriteStorageP,
- short pictResID,
- short maskResID,
- short maxFrames,
- MaskType maskType)
- {
- OSErr err;
- SpritePtr tempSpriteP;
- FramePtr newFrameP;
- short frame;
-
- SW_ASSERT(destSpriteWorldP != NULL);
-
- *newSpriteP = NULL;
-
- err = SWCreateSprite(&tempSpriteP, spriteStorageP, maxFrames);
-
- if (err == noErr)
- {
- for (frame = 0; frame < maxFrames; frame++)
- {
- err = SWCreateFrameFromPictResource(destSpriteWorldP, &newFrameP,
- pictResID + frame, maskResID + frame, maskType);
-
- if (err == noErr)
- {
- err = SWAddFrame(tempSpriteP, newFrameP);
- }
-
- if (err != noErr)
- {
- SWDisposeFrame(&newFrameP);
- SWDisposeSprite(&tempSpriteP);
- break;
- }
- }
-
- if (err == noErr)
- {
- SWSetSpriteFrameRange(tempSpriteP, 0, maxFrames - 1);
- SWSetCurrentFrameIndex(tempSpriteP, 0);
- *newSpriteP = tempSpriteP;
- }
- }
-
- SWSetStickyIfError( err );
- return err;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // CalcMaxWidthHeight
- ///--------------------------------------------------------------------------------------
- static void CalcMaxWidthHeight(
- RectArrayPtr newRectArrayP,
- short *maxWidthP,
- short *maxHeightP )
- {
- short frame;
- Rect *rectP;
- short maxWidth, maxHeight;
-
-
- maxWidth = 0;
- maxHeight = 0;
-
- rectP = &newRectArrayP->frameRects[0];
- for( frame = 0; frame < newRectArrayP->numFrames; frame++ )
- {
- if ( rectP->right - rectP->left > maxWidth )
- {
- maxWidth = rectP->right - rectP->left;
- }
- if ( rectP->bottom - rectP->top > maxHeight )
- {
- maxHeight = rectP->bottom - rectP->top;
- }
- rectP++;
- }
- *maxWidthP = maxWidth;
- *maxHeightP =maxHeight;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWCreateSpriteFromSinglePict
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC OSErr SWCreateSpriteFromSinglePict(
- SpriteWorldPtr destSpriteWorldP,
- SpritePtr* newSpriteP,
- void* spriteStorageP,
- short pictResID,
- short maskResID,
- short frameDimension,
- short borderWidth,
- MaskType maskType)
- {
- OSErr err = noErr;
- Handle rectArrayHndl;
- RectArrayPtr newRectArrayP;
- PicHandle tempPic;
- GWorldPtr tempPictGWorldP;
- GWorldPtr tempMaskGWorldP;
- GWorldPtr tempTempMaskGWorldP;
- Rect frameRect;
- Boolean verticalStrip;
- SpritePtr tempSpriteP;
- FramePtr newFrameP;
- short maxFrames;
- short frame;
- short maxWidth, maxHeight;
-
- SW_ASSERT(destSpriteWorldP != NULL);
-
- tempPictGWorldP = NULL;
- tempMaskGWorldP = NULL;
- *newSpriteP = NULL;
- rectArrayHndl = NULL;
-
- if ( frameDimension == 0 )
- {
- rectArrayHndl = Get1Resource( 'nrct', pictResID );
-
- if ( rectArrayHndl == NULL )
- {
- err = MemError();
- if ( err == noErr )
- err = resNotFound;
- }
- else
- {
- HLock( rectArrayHndl );
- newRectArrayP = (RectArrayPtr)*rectArrayHndl;
- maxFrames = newRectArrayP->numFrames;
- CalcMaxWidthHeight( newRectArrayP, &maxWidth, &maxHeight );
- }
- }
- else
- {
- tempPic = GetPicture( pictResID );
- if ( tempPic == nil )
- {
- err = MemError();
- if ( err == noErr )
- err = resNotFound;
- }
- else
- {
- frameRect = (**(tempPic)).picFrame;
- OffsetRect( &frameRect, -frameRect.left, -frameRect.top );
- ReleaseResource( (Handle)tempPic );
- if ( frameRect.right-frameRect.left < frameRect.bottom-frameRect.top )
- {
- verticalStrip = true;
- maxFrames = frameRect.bottom/frameDimension;
- frameRect.bottom = -borderWidth;
- maxWidth = frameRect.right-frameRect.left;
- maxHeight = frameDimension;
- }
- else
- {
- verticalStrip = false;
- maxFrames = frameRect.right/frameDimension;
- frameRect.right = -borderWidth;
- maxWidth = frameDimension;
- maxHeight = frameRect.bottom-frameRect.top;
- }
- }
- }
-
- if ( err == noErr )
- {
- err = SWCreateSprite(&tempSpriteP, spriteStorageP, maxFrames);
-
- if (err == noErr)
- {
- err = SWCreateGWorldFromPictResource( destSpriteWorldP, &tempPictGWorldP, pictResID );
- if ( err == noErr && maskType != kNoMask )
- err = SWCreateGWorldFromPictResource(
- destSpriteWorldP, &tempMaskGWorldP, maskResID );
- if (err == noErr)
- {
- if ( pictResID == maskResID && tempMaskGWorldP != NULL )
- {
- err = SWBlackenGWorld( tempMaskGWorldP );
- }
- }
-
- if (err == noErr)
- {
- err = SWCreateFrameFromGWorldAndRectStart( &tempTempMaskGWorldP, maxWidth,
- maxHeight, maskType );
- }
-
- if (err == noErr)
- {
- for (frame = 0; frame < maxFrames; frame++)
- {
- if ( frameDimension == 0 )
- {
- frameRect = newRectArrayP->frameRects[frame];
- }
- else
- {
- if ( verticalStrip )
- {
- frameRect.top = frameRect.bottom + borderWidth;
- frameRect.bottom = frameRect.top + frameDimension;
- }
- else
- {
- frameRect.left = frameRect.right + borderWidth;
- frameRect.right = frameRect.left + frameDimension;
- }
- }
-
- err = SWCreateFrameFromGWorldAndRectPartial( &newFrameP, tempPictGWorldP,
- tempMaskGWorldP, tempTempMaskGWorldP, &frameRect, maskType);
-
- if (err == noErr)
- {
- err = SWAddFrame(tempSpriteP, newFrameP);
- }
-
- if (err != noErr)
- {
- SWDisposeFrame(&newFrameP);
- SWDisposeSprite(&tempSpriteP);
- break;
- }
- }
- SWCreateFrameFromGWorldAndRectFinish( tempTempMaskGWorldP );
- }
-
- if (err == noErr)
- {
- // make a pixel mask
- if ((maskType & kPixelMask) != 0)
- {
- if (destSpriteWorldP->pixelDepth <= 8)
- {
- (void)LockPixels( GetGWorldPixMap(tempMaskGWorldP) );
- SetGWorld(tempMaskGWorldP, nil);
- InvertRect(&tempMaskGWorldP->portRect);
- UnlockPixels( GetGWorldPixMap(tempMaskGWorldP) );
- }
- } // If no pixel Mask wanted, dispose
- else // of the GWorld we used to make region
- {
- DisposeGWorld( tempMaskGWorldP );
- tempMaskGWorldP = NULL;
- }
-
- SWSetSpriteFrameRange(tempSpriteP, 0, maxFrames - 1);
- SWSetCurrentFrameIndex(tempSpriteP, 0);
- tempSpriteP->sharedPictGWorld = tempPictGWorldP;
- tempSpriteP->sharedMaskGWorld = tempMaskGWorldP;
-
- *newSpriteP = tempSpriteP;
- }
- }
- }
-
- if ( rectArrayHndl != NULL )
- {
- HUnlock( rectArrayHndl );
- ReleaseResource( rectArrayHndl );
- }
-
- SWSetStickyIfError( err );
- return err;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWCreateSpriteFromSinglePictXY
- //
- // height/width code contributed by Mohsan Khan, 96-06-13. You can email Mohsan Khan at
- // xybernic@algonet.se, or visit his web page at www.algonet.se/~xybernic.
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC OSErr SWCreateSpriteFromSinglePictXY(
- SpriteWorldPtr destSpriteWorldP,
- SpritePtr* newSpriteP,
- void* spriteStorageP,
- short pictResID,
- short maskResID,
- short frameWidth,
- short frameHeight,
- short borderWidth,
- short borderHeight,
- short maxFrames,
- MaskType maskType)
- {
- OSErr err = noErr;
- PicHandle tempPic;
- GWorldPtr tempPictGWorldP,
- tempMaskGWorldP,
- tempTempMaskGWorldP;
- Rect frameRect;
- SpritePtr tempSpriteP;
- FramePtr newFrameP;
- short frame;
-
- SW_ASSERT(destSpriteWorldP != NULL);
-
- tempPictGWorldP = NULL;
- tempMaskGWorldP = NULL;
- *newSpriteP = NULL;
-
-
- tempPic = GetPicture( pictResID );
- if ( tempPic == nil )
- {
- err = MemError();
- if ( err == noErr )
- err = resNotFound;
- }
- else
- {
- ReleaseResource( (Handle)tempPic );
- }
-
- if ( err == noErr )
- {
- {
- err = SWCreateGWorldFromPictResource( destSpriteWorldP, &tempPictGWorldP, pictResID );
- if ( err == noErr && maskType != kNoMask )
- err = SWCreateGWorldFromPictResource(
- destSpriteWorldP, &tempMaskGWorldP, maskResID );
- if (err == noErr)
- {
- if ( pictResID == maskResID && tempMaskGWorldP != NULL )
- {
- err = SWBlackenGWorld( tempMaskGWorldP );
-
- if (err == noErr)
- err = SWWhitenGWorld( tempPictGWorldP );
- }
- }
- if ( maxFrames == 0 )
- {
- maxFrames = (tempPictGWorldP->portRect.right/frameWidth) *
- (tempPictGWorldP->portRect.bottom/frameHeight);
- }
- if (err == noErr)
- {
- err = SWCreateSprite(&tempSpriteP, spriteStorageP, maxFrames);
- }
- if (err == noErr)
- {
- err = SWCreateFrameFromGWorldAndRectStart( &tempTempMaskGWorldP, frameWidth,
- frameHeight, maskType );
- }
- if (err == noErr)
- {
- frameRect.left = 0;
- frameRect.top = 0;
- frameRect.right = frameWidth;
- frameRect.bottom = frameHeight;
-
- for (frame = 0; frame < maxFrames; frame++)
- {
- err = SWCreateFrameFromGWorldAndRectPartial( &newFrameP, tempPictGWorldP,
- tempMaskGWorldP, tempTempMaskGWorldP, &frameRect, maskType);
-
- if (err == noErr)
- {
- err = SWAddFrame(tempSpriteP, newFrameP);
- if ( frame < maxFrames-1 )
- {
- frameRect.left += frameWidth + borderWidth;
- frameRect.right = frameRect.left + frameWidth;
- if ( frameRect.right > tempPictGWorldP->portRect.right )
- {
- frameRect.left = 0;
- frameRect.right = frameWidth;
- frameRect.top += frameHeight + borderHeight;
- frameRect.bottom = frameRect.top + frameHeight;
-
- if ( frameRect.bottom > tempPictGWorldP->portRect.bottom )
- {
- err = kOutOfRangeErr;
- }
- }
- }
- }
- if ( err != noErr )
- {
- SWDisposeFrame(&newFrameP);
- SWDisposeSprite(&tempSpriteP);
- break;
- }
- } // end for
- SWCreateFrameFromGWorldAndRectFinish( tempTempMaskGWorldP );
- }
-
- if (err == noErr)
- {
- // make a pixel mask
- if ((maskType & kPixelMask) != 0)
- {
- if (destSpriteWorldP->pixelDepth <= 8)
- {
- (void)LockPixels( GetGWorldPixMap(tempMaskGWorldP) );
- SetGWorld(tempMaskGWorldP, nil);
- InvertRect(&tempMaskGWorldP->portRect);
- UnlockPixels( GetGWorldPixMap(tempMaskGWorldP) );
- }
- } // If no pixel Mask wanted, dispose
- else // of the GWorld we used to make region
- {
- DisposeGWorld( tempMaskGWorldP );
- tempMaskGWorldP = NULL;
- }
-
- SWSetSpriteFrameRange(tempSpriteP, 0, maxFrames - 1);
- SWSetCurrentFrameIndex(tempSpriteP, 0);
- tempSpriteP->sharedPictGWorld = tempPictGWorldP;
- tempSpriteP->sharedMaskGWorld = tempMaskGWorldP;
-
- *newSpriteP = tempSpriteP;
- }
- }
- }
- SWSetStickyIfError( err );
- return err;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWUpdateSpriteFromPictResource
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC OSErr SWUpdateSpriteFromPictResource(
- SpritePtr theSpriteP,
- short pictResID)
- {
- OSErr err = noErr;
- GDHandle currentGDH;
- GWorldPtr currentGWorld;
- GWorldPtr frameGWorld;
- PicHandle pictH;
- Rect frameRect;
- short frame;
-
- SW_ASSERT(theSpriteP != NULL);
-
- GetGWorld( ¤tGWorld, ¤tGDH );
-
- SWLockSprite( theSpriteP );
-
- if ( theSpriteP->sharedPictGWorld != NULL )
- {
- SetGWorld( theSpriteP->sharedPictGWorld, NULL );
- pictH = GetPicture( pictResID );
- if ( pictH != NULL )
- {
- frameRect = theSpriteP->sharedPictGWorld->portRect;
- EraseRect( &frameRect );
- DrawPicture( pictH, &frameRect );
- ReleaseResource( (Handle)pictH );
- }
- else
- {
- err = MemError();
- if ( err == noErr )
- err = resNotFound;
- }
- }
- else
- {
- for (frame = 0; frame < theSpriteP->maxFrames; frame++)
- {
- frameGWorld = theSpriteP->frameArray[frame]->framePort;
- if ( frameGWorld != NULL )
- {
- SetGWorld( frameGWorld, nil );
- pictH = GetPicture( pictResID + frame );
- if ( pictH != NULL )
- {
- frameRect = frameGWorld->portRect;
- EraseRect( &frameRect );
- DrawPicture( pictH, &frameRect );
- ReleaseResource( (Handle)pictH );
- }
- else
- {
- err = MemError();
- if ( err == noErr )
- err = resNotFound;
- break;
- }
- }
- }
- }
- SetGWorld( currentGWorld, currentGDH );
-
- SWSetStickyIfError( err );
- return err;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWCloneSprite
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC OSErr SWCloneSprite(
- SpritePtr cloneSpriteP,
- SpritePtr* newSpriteP,
- void* spriteStorageP)
- {
- SpritePtr tempSpriteP;
- short index;
- Size frameArraySize;
- OSErr err = noErr;
-
- SW_ASSERT(cloneSpriteP != NULL);
-
- // Allocate memory for the new Sprite
- tempSpriteP = (spriteStorageP == NULL) ? (SpritePtr)NewPtr(sizeof(SpriteRec)) : (SpritePtr)spriteStorageP;
- if (tempSpriteP == NULL)
- err = MemError();
-
- if (err == noErr)
- {
- // copy the clone sprite into the temp sprite
- *tempSpriteP = *cloneSpriteP;
-
- // clear the layer fields, in case the parent sprite is in a layer
- tempSpriteP->parentSpriteLayerP = NULL;
- tempSpriteP->nextSpriteP = NULL;
- tempSpriteP->prevSpriteP = NULL;
-
- tempSpriteP->frameArrayIsShared = false;
- }
-
- if (err == noErr)
- {
- // Create a new frameArray for this sprite
- frameArraySize = (Size)cloneSpriteP->maxFrames * sizeof(FramePtr);
- tempSpriteP->frameArray = (FramePtr *)NewPtrClear(frameArraySize);
-
- if (tempSpriteP->frameArray != NULL)
- {
- // copy the frame array, and increment useCount for each frame
- for (index = 0; index < cloneSpriteP->maxFrames; index++)
- {
- tempSpriteP->frameArray[index] = cloneSpriteP->frameArray[index];
- tempSpriteP->frameArray[index]->useCount++;
- }
- }
- else
- {
- err = MemError();
- DisposePtr((Ptr)tempSpriteP);
- }
- }
-
- if (err == noErr)
- *newSpriteP = tempSpriteP;
-
- SWSetStickyIfError( err );
- return err;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWFastCloneSprite
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC OSErr SWFastCloneSprite(
- SpritePtr cloneSpriteP,
- SpritePtr* newSpriteP,
- void* spriteStorageP)
- {
- SpritePtr tempSpriteP;
- OSErr err = noErr;
-
- SW_ASSERT(cloneSpriteP != NULL);
-
- // Allocate memory for the new Sprite
- tempSpriteP = (spriteStorageP == NULL) ? (SpritePtr)NewPtr(sizeof(SpriteRec)) : (SpritePtr)spriteStorageP;
- if (tempSpriteP == NULL)
- err = MemError();
-
- if (err == noErr)
- {
- // copy the clone sprite into the temp sprite
- *tempSpriteP = *cloneSpriteP;
-
- // clear the layer fields, in case the parent sprite is in a layer
- tempSpriteP->parentSpriteLayerP = NULL;
- tempSpriteP->nextSpriteP = NULL;
- tempSpriteP->prevSpriteP = NULL;
-
- tempSpriteP->frameArrayIsShared = true;
- *newSpriteP = tempSpriteP;
- }
-
- SWSetStickyIfError( err );
- return err;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWCloneSpriteFromTile
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC OSErr SWCloneSpriteFromTile(
- SpriteWorldPtr spriteWorldP,
- SpritePtr* newSpriteP,
- void* spriteStorageP,
- short firstTileID,
- short lastTileID)
- {
- OSErr err;
- SpritePtr tempSpriteP;
- FramePtr tileFrameP;
- short curTileID, curIndex, numFrames;
-
- SW_ASSERT(firstTileID <= lastTileID);
- SW_ASSERT(spriteWorldP->tileFrameArray != NULL);
-
- *newSpriteP = NULL;
- numFrames = (lastTileID - firstTileID) + 1;
- err = SWCreateSprite(&tempSpriteP, spriteStorageP, numFrames);
-
- if (err == noErr)
- {
- for (curTileID = firstTileID; curTileID <= lastTileID; curTileID++)
- {
- tileFrameP = spriteWorldP->tileFrameArray[curTileID];
- SW_ASSERT(tileFrameP != NULL);
- err = SWAddFrame(tempSpriteP, tileFrameP);
-
- if (err != noErr)
- {
- SWDisposeSprite(&tempSpriteP);
- break;
- }
- }
-
- if (err == noErr)
- {
- SWSetSpriteFrameRange(tempSpriteP, 0, numFrames - 1);
-
- // Set current index to be the same as the Tile's current image, if possible.
- curIndex = spriteWorldP->curTileImage[firstTileID];
- if (curIndex >= firstTileID && curIndex <= lastTileID)
- curIndex = spriteWorldP->curTileImage[firstTileID] - firstTileID;
- else
- curIndex = 0;
-
- SWSetCurrentFrameIndex(tempSpriteP, curIndex);
- *newSpriteP = tempSpriteP;
- }
- }
-
- SWSetStickyIfError( err );
- return err;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWRemoveSpriteFromAnimation
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWRemoveSpriteFromAnimation(
- SpriteWorldPtr spriteWorldP,
- SpritePtr spriteP,
- Boolean disposeOfSprite)
- {
- SW_ASSERT(spriteWorldP != NULL && spriteP != NULL);
-
- SWSetSpriteVisible( spriteP, false );
- SWRemoveSprite(spriteP);
- SWAddSprite(spriteWorldP->deadSpriteLayerP, spriteP);
-
- if ( disposeOfSprite )
- {
- spriteP->spriteRemoval = kSWRemoveAndDisposeSprite;
- }
- else
- {
- spriteP->spriteRemoval = kSWRemoveSprite;
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWDisposeSprite
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWDisposeSprite(
- SpritePtr *deadSpritePP)
- {
- SpritePtr deadSpriteP = *deadSpritePP;
-
- if (deadSpriteP != NULL)
- {
- SWCloseSprite(deadSpriteP);
- DisposePtr((Ptr)deadSpriteP);
-
- *deadSpritePP = NULL; // Set the original pointer to NULL
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWCloseSprite
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWCloseSprite(
- SpritePtr deadSpriteP)
- {
- short frame;
- Boolean framesDisposed;
-
- if (deadSpriteP != NULL)
- {
- // Dispose the frames if they aren't shared, or if this is the master sprite
- if (!deadSpriteP->frameArrayIsShared)
- {
- for (frame = 0; frame < deadSpriteP->numFrames; frame++)
- {
- framesDisposed = SWDisposeFrame(&deadSpriteP->frameArray[frame]);
- }
-
- if ( framesDisposed )
- {
- if ( deadSpriteP->sharedPictGWorld != NULL )
- {
- DisposeGWorld(deadSpriteP->sharedPictGWorld );
- deadSpriteP->sharedPictGWorld = NULL;
- }
-
- if ( deadSpriteP->sharedMaskGWorld != NULL )
- {
- DisposeGWorld(deadSpriteP->sharedMaskGWorld );
- deadSpriteP->sharedMaskGWorld = NULL;
- }
- }
-
- DisposePtr((Ptr)deadSpriteP->frameArray);
- }
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWLockSprite
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWLockSprite(
- SpritePtr srcSpriteP)
- {
- register long curFrame;
-
- SW_ASSERT(srcSpriteP != NULL);
-
- for (curFrame = 0; curFrame < srcSpriteP->numFrames; curFrame++)
- {
- SWLockFrame(srcSpriteP->frameArray[curFrame]);
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWUnlockSprite
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWUnlockSprite(
- SpritePtr srcSpriteP)
- {
- register long curFrame;
-
- SW_ASSERT(srcSpriteP != NULL);
-
- for (curFrame = 0; curFrame < srcSpriteP->numFrames; curFrame++)
- {
- SWUnlockFrame(srcSpriteP->frameArray[curFrame]);
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWStdSpriteDrawProc - for drawing sprites
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWStdSpriteDrawProc(
- FramePtr srcFrameP,
- FramePtr dstFrameP,
- Rect* srcRect,
- Rect* dstRect)
- {
- SW_ASSERT(srcFrameP->isFrameLocked && dstFrameP->isFrameLocked);
-
- if (srcFrameP->maskRgn != NULL)
- {
- Rect rgnRect = (**srcFrameP->maskRgn).rgnBBox;
-
- // move the mask region to the new sprite location
- OffsetRgn(srcFrameP->maskRgn,
- (dstRect->left - (srcRect->left - srcFrameP->frameRect.left) - rgnRect.left)
- + srcFrameP->offsetPoint.h,
- (dstRect->top - (srcRect->top - srcFrameP->frameRect.top) - rgnRect.top)
- + srcFrameP->offsetPoint.v);
- }
-
- // CopyBits with a mask region is generally faster than CopyMask
- CopyBits((BitMapPtr)srcFrameP->framePix, (BitMapPtr)dstFrameP->framePix,
- srcRect, dstRect, srcCopy, srcFrameP->maskRgn);
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWAddFrame
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC OSErr SWAddFrame(
- SpritePtr srcSpriteP,
- FramePtr newFrameP)
- {
- OSErr err = noErr;
-
- SW_ASSERT(srcSpriteP != NULL && newFrameP != NULL);
-
- // don’t exceed maximum number of frames
- if (srcSpriteP->numFrames < srcSpriteP->maxFrames)
- {
- srcSpriteP->frameArray[srcSpriteP->numFrames] = newFrameP;
-
- // increment the number of frames
- srcSpriteP->numFrames++;
- newFrameP->useCount++;
- }
- else
- {
- err = kMaxFramesErr;
- }
-
- SWSetStickyIfError( err );
- return err;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWInsertFrame
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC OSErr SWInsertFrame(
- SpritePtr srcSpriteP,
- FramePtr newFrameP,
- long frameIndex)
- {
- register long index;
- register FramePtr *frameArray;
- OSErr err = noErr;
-
- SW_ASSERT(srcSpriteP != NULL && newFrameP != NULL);
-
- frameArray = srcSpriteP->frameArray;
-
- // don’t exceed maximum number of frames
- if (frameIndex < srcSpriteP->maxFrames && frameIndex >= 0 &&
- srcSpriteP->numFrames < srcSpriteP->maxFrames)
- {
- // move frames above frameIndex up
- for (index = srcSpriteP->numFrames; index > frameIndex; index--)
- frameArray[index] = frameArray[index - 1];
-
- // fill the hole
- frameArray[frameIndex] = newFrameP;
-
- srcSpriteP->numFrames++;
- newFrameP->useCount++;
- }
- else
- {
- err = kMaxFramesErr;
- }
-
- SWSetStickyIfError( err );
- return err;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWRemoveFrame
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWRemoveFrame(
- SpritePtr srcSpriteP,
- FramePtr oldFrameP)
- {
- register long curFrame;
- register FramePtr *frameArray;
-
- SW_ASSERT(srcSpriteP != NULL && oldFrameP != NULL);
-
- curFrame = srcSpriteP->numFrames;
- frameArray = srcSpriteP->frameArray;
-
- // find the frame to be removed
- while (curFrame--)
- {
- if (frameArray[curFrame] == oldFrameP)
- {
- srcSpriteP->numFrames--;
- oldFrameP->useCount--;
-
- // move the rest of the frames down
- while (curFrame <= (srcSpriteP->numFrames - 1L))
- {
- frameArray[curFrame] = frameArray[curFrame + 1L];
- curFrame++;
- }
-
- break;
- }
- }
- }
-
- #pragma mark -
- ///--------------------------------------------------------------------------------------
- // SWSetCurrentFrame
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC OSErr SWSetCurrentFrame(
- SpritePtr srcSpriteP,
- FramePtr newFrameP)
- {
- short frameIndex = 0;
- Boolean foundFrame = false;
- OSErr err = noErr;
-
- SW_ASSERT(srcSpriteP != NULL && newFrameP != NULL);
-
- for (frameIndex = 0; frameIndex < srcSpriteP->numFrames; frameIndex++)
- {
- if (srcSpriteP->frameArray[frameIndex] == newFrameP)
- {
- SWSetCurrentFrameIndex(srcSpriteP, frameIndex);
- foundFrame = true;
- break;
- }
- }
-
- if (foundFrame == false)
- err = kBadParameterErr;
-
- SWSetStickyIfError( err );
- return err;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWSetCurrentFrameIndex
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWSetCurrentFrameIndex(
- SpritePtr srcSpriteP,
- short frameIndex)
- {
- register FramePtr newFrameP;
- short horizOffset, vertOffset;
-
- SW_ASSERT(srcSpriteP != NULL && frameIndex >= 0);
-
- if (frameIndex < srcSpriteP->numFrames)
- {
- newFrameP = srcSpriteP->frameArray[frameIndex];
-
- // If this is a brand new sprite, it won't have a current frame.
- // (This is used when calculating the hotSpot offset from old to new frame.)
- if (srcSpriteP->curFrameP == NULL)
- srcSpriteP->curFrameP = newFrameP;
-
- horizOffset = (srcSpriteP->destFrameRect.left - newFrameP->frameRect.left) +
- (srcSpriteP->curFrameP->hotSpotH - newFrameP->hotSpotH);
- vertOffset = (srcSpriteP->destFrameRect.top - newFrameP->frameRect.top) +
- (srcSpriteP->curFrameP->hotSpotV - newFrameP->hotSpotV);
-
- srcSpriteP->curFrameP = newFrameP;
- srcSpriteP->destFrameRect = newFrameP->frameRect;
-
- if (srcSpriteP->scaledWidth > 0)
- srcSpriteP->destFrameRect.right = srcSpriteP->destFrameRect.left +
- srcSpriteP->scaledWidth;
- if (srcSpriteP->scaledHeight > 0)
- srcSpriteP->destFrameRect.bottom = srcSpriteP->destFrameRect.top +
- srcSpriteP->scaledHeight;
-
-
- srcSpriteP->destFrameRect.left += horizOffset;
- srcSpriteP->destFrameRect.right += horizOffset;
- srcSpriteP->destFrameRect.top += vertOffset;
- srcSpriteP->destFrameRect.bottom += vertOffset;
-
- srcSpriteP->curFrameIndex = frameIndex;
-
- srcSpriteP->needsToBeDrawn = true;
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWSetSpriteCollideProc
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWSetSpriteCollideProc(
- SpritePtr srcSpriteP,
- CollideProcPtr collideProc)
- {
- SW_ASSERT(srcSpriteP != NULL);
- srcSpriteP->spriteCollideProc = collideProc;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWSetSpriteDrawProc
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC OSErr SWSetSpriteDrawProc(
- SpritePtr srcSpriteP,
- DrawProcPtr drawProc)
- {
- OSErr err = noErr;
- FramePtr headFrameP = NULL;
- short framePixelDepth = 0;
-
- SW_ASSERT(srcSpriteP != NULL && drawProc != NULL);
-
- #if SW_PPC
- if (drawProc == CompiledSprite8BitDrawProc)
- drawProc = BlitPixie8BitMaskDrawProc;
- #endif
-
- headFrameP = srcSpriteP->frameArray[0];
- if ( headFrameP != NULL )
- {
- if ( headFrameP->framePort != NULL )
- {
- framePixelDepth = (*headFrameP->framePort->portPixMap)->pixelSize;
- }
- }
-
- if (framePixelDepth != 8)
- {
- if ( (drawProc == BlitPixie8BitRectDrawProc) ||
- (drawProc == BlitPixie8BitMaskDrawProc) ||
- (drawProc == BP8BitInterlacedRectDrawProc) ||
- (drawProc == BP8BitInterlacedMaskDrawProc) ||
- (drawProc == BlitPixie8BitPartialMaskDrawProc) ||
- (drawProc == BP8BitInterlacedPartialMaskDrawProc) ||
- (drawProc == CompiledSprite8BitDrawProc) )
- {
- err = kWrongDepthErr;
- }
- }
-
- if (headFrameP->maskPort == NULL)
- {
- if ( (drawProc == BlitPixie8BitMaskDrawProc) ||
- (drawProc == BP8BitInterlacedMaskDrawProc) ||
- (drawProc == BlitPixie8BitPartialMaskDrawProc) ||
- (drawProc == BP8BitInterlacedPartialMaskDrawProc) ||
- (drawProc == CompiledSprite8BitDrawProc) )
- {
- err = kWrongMaskErr;
- }
- }
- else if (drawProc == CompiledSprite8BitDrawProc && headFrameP->pixCodeH == NULL)
- {
- err = kSpriteNotCompiledErr;
- }
-
- if ( err == noErr )
- srcSpriteP->frameDrawProc = drawProc;
-
- SWSetStickyIfError( err );
- return err;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWSetSpriteFrameAdvance
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWSetSpriteFrameAdvance(
- SpritePtr srcSpriteP,
- short frameAdvance)
- {
- SW_ASSERT(srcSpriteP != NULL);
- srcSpriteP->frameAdvance = frameAdvance;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWSetSpriteFrameAdvanceMode
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWSetSpriteFrameAdvanceMode(
- SpritePtr srcSpriteP,
- AdvanceType advanceMode)
- {
- SW_ASSERT(srcSpriteP != NULL);
- srcSpriteP->frameAdvanceMode = advanceMode;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWSetSpriteFrameRange
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWSetSpriteFrameRange(
- SpritePtr srcSpriteP,
- short firstFrameIndex,
- short lastFrameIndex)
- {
- SW_ASSERT(srcSpriteP != NULL);
-
- if ( firstFrameIndex < 0 )
- firstFrameIndex = 0;
-
- if ( lastFrameIndex > srcSpriteP->maxFrames - 1 )
- lastFrameIndex = srcSpriteP->maxFrames - 1;
-
- srcSpriteP->firstFrameIndex = firstFrameIndex;
- srcSpriteP->lastFrameIndex = lastFrameIndex;
-
- // Make sure the sprite's curFrameIndex is within the new frame range
- if (srcSpriteP->curFrameIndex < firstFrameIndex)
- SWSetCurrentFrameIndex(srcSpriteP, firstFrameIndex);
- else if (srcSpriteP->curFrameIndex > lastFrameIndex)
- SWSetCurrentFrameIndex(srcSpriteP, lastFrameIndex);
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWSetSpriteFrameTime
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWSetSpriteFrameTime(
- SpritePtr srcSpriteP,
- long timeInterval)
- {
- SW_ASSERT(srcSpriteP != NULL);
- srcSpriteP->frameTimeInterval = timeInterval;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWSetSpriteFrameProc
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWSetSpriteFrameProc(
- SpritePtr srcSpriteP,
- FrameProcPtr frameProc)
- {
- SW_ASSERT(srcSpriteP != NULL);
- srcSpriteP->frameChangeProc = frameProc;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWSetSpriteLocation
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWSetSpriteLocation(
- SpritePtr srcSpriteP,
- short horizLoc,
- short vertLoc)
- {
- SW_ASSERT(srcSpriteP != NULL);
-
- horizLoc -= srcSpriteP->curFrameP->hotSpotH;
- vertLoc -= srcSpriteP->curFrameP->hotSpotV;
-
- srcSpriteP->destFrameRect.bottom = vertLoc + (srcSpriteP->destFrameRect.bottom -
- srcSpriteP->destFrameRect.top);
- srcSpriteP->destFrameRect.right = horizLoc + (srcSpriteP->destFrameRect.right -
- srcSpriteP->destFrameRect.left);
- srcSpriteP->destFrameRect.top = vertLoc;
- srcSpriteP->destFrameRect.left = horizLoc;
-
- srcSpriteP->deltaFrameRect = srcSpriteP->destFrameRect;
- srcSpriteP->oldFrameRect = srcSpriteP->destFrameRect;
- srcSpriteP->needsToBeDrawn = true;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWSetSpriteMoveBounds
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWSetSpriteMoveBounds(
- SpritePtr srcSpriteP,
- Rect* moveBoundsRect)
- {
- SW_ASSERT(srcSpriteP != NULL);
- srcSpriteP->moveBoundsRect = *moveBoundsRect;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWSetSpriteMoveDelta
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWSetSpriteMoveDelta(
- SpritePtr srcSpriteP,
- short horizDelta,
- short vertDelta)
- {
- SW_ASSERT(srcSpriteP != NULL);
-
- // set sprite’s velocity
- srcSpriteP->horizMoveDelta = horizDelta;
- srcSpriteP->vertMoveDelta = vertDelta;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWSetSpriteMoveTime
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWSetSpriteMoveTime(
- SpritePtr srcSpriteP,
- long timeInterval)
- {
- SW_ASSERT(srcSpriteP != NULL);
- srcSpriteP->moveTimeInterval = timeInterval;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWSetSpriteMoveProc
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWSetSpriteMoveProc(
- SpritePtr srcSpriteP,
- MoveProcPtr moveProc)
- {
- SW_ASSERT(srcSpriteP != NULL);
- srcSpriteP->spriteMoveProc = moveProc;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWSetSpriteVisible
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWSetSpriteVisible(
- SpritePtr srcSpriteP,
- Boolean isVisible)
- {
- SW_ASSERT(srcSpriteP != NULL);
- srcSpriteP->isVisible = isVisible;
- srcSpriteP->needsToBeDrawn = true;
- srcSpriteP->needsToBeErased = !isVisible;
- }
-
-
- #pragma mark -
- ///--------------------------------------------------------------------------------------
- // SWMoveSprite
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWMoveSprite(
- SpritePtr srcSpriteP,
- short horizLoc,
- short vertLoc)
- {
- SW_ASSERT(srcSpriteP != NULL);
-
- horizLoc -= srcSpriteP->curFrameP->hotSpotH;
- vertLoc -= srcSpriteP->curFrameP->hotSpotV;
-
- if ((horizLoc != srcSpriteP->destFrameRect.left) ||
- (vertLoc != srcSpriteP->destFrameRect.top) )
- {
- srcSpriteP->destFrameRect.bottom = vertLoc + (srcSpriteP->destFrameRect.bottom -
- srcSpriteP->destFrameRect.top);
- srcSpriteP->destFrameRect.right = horizLoc + (srcSpriteP->destFrameRect.right -
- srcSpriteP->destFrameRect.left);
- srcSpriteP->destFrameRect.top = vertLoc;
- srcSpriteP->destFrameRect.left = horizLoc;
-
- srcSpriteP->needsToBeDrawn = true;
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWOffsetSprite
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWOffsetSprite(
- SpritePtr srcSpriteP,
- short horizOffset,
- short vertOffset)
- {
- SW_ASSERT(srcSpriteP != NULL);
-
- if ((horizOffset != 0) || (vertOffset != 0))
- {
- srcSpriteP->destFrameRect.right += horizOffset;
- srcSpriteP->destFrameRect.bottom += vertOffset;
- srcSpriteP->destFrameRect.left += horizOffset;
- srcSpriteP->destFrameRect.top += vertOffset;
-
- srcSpriteP->needsToBeDrawn = true;
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWBounceSprite
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC Boolean SWBounceSprite(
- SpritePtr srcSpriteP)
- {
- short horizOffset, vertOffset;
-
- SW_ASSERT(srcSpriteP != NULL);
-
- // Hit left side or right side
- if (srcSpriteP->destFrameRect.left < srcSpriteP->moveBoundsRect.left)
- {
- srcSpriteP->horizMoveDelta = -srcSpriteP->horizMoveDelta;
- horizOffset = (srcSpriteP->moveBoundsRect.left - srcSpriteP->destFrameRect.left) * 2;
- }
- else if (srcSpriteP->destFrameRect.right > srcSpriteP->moveBoundsRect.right)
- {
- srcSpriteP->horizMoveDelta = -srcSpriteP->horizMoveDelta;
- horizOffset = (srcSpriteP->moveBoundsRect.right - srcSpriteP->destFrameRect.right) * 2;
- }
- else
- horizOffset = 0;
-
-
- // Hit top or bottom
- if (srcSpriteP->destFrameRect.top < srcSpriteP->moveBoundsRect.top)
- {
- srcSpriteP->vertMoveDelta = -srcSpriteP->vertMoveDelta;
- vertOffset = (srcSpriteP->moveBoundsRect.top - srcSpriteP->destFrameRect.top) * 2;
- }
- else if (srcSpriteP->destFrameRect.bottom > srcSpriteP->moveBoundsRect.bottom)
- {
- srcSpriteP->vertMoveDelta = -srcSpriteP->vertMoveDelta;
- vertOffset = (srcSpriteP->moveBoundsRect.bottom - srcSpriteP->destFrameRect.bottom) * 2;
- }
- else
- vertOffset = 0;
-
-
- // Bounce the sprite if it had a collision with the wall
- if ((horizOffset != 0) || (vertOffset != 0))
- {
- SWOffsetSprite(srcSpriteP, horizOffset, vertOffset);
- return true;
- }
- else
- {
- return false;
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWWrapSprite
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC Boolean SWWrapSprite(
- SpritePtr srcSpriteP)
- {
- short horizOffset, vertOffset;
-
- SW_ASSERT(srcSpriteP != NULL);
-
- // Wrap to left or right
- if (srcSpriteP->oldFrameRect.left > srcSpriteP->moveBoundsRect.right)
- {
- horizOffset = - ((srcSpriteP->moveBoundsRect.right -
- srcSpriteP->moveBoundsRect.left) +
- (srcSpriteP->destFrameRect.right -
- srcSpriteP->destFrameRect.left) + srcSpriteP->horizMoveDelta);
- }
- else if (srcSpriteP->oldFrameRect.right < srcSpriteP->moveBoundsRect.left)
- {
- horizOffset = (srcSpriteP->moveBoundsRect.right -
- srcSpriteP->moveBoundsRect.left) +
- (srcSpriteP->destFrameRect.right -
- srcSpriteP->destFrameRect.left) - srcSpriteP->horizMoveDelta;
- }
- else
- horizOffset = 0;
-
-
- // Wrap to top or bottom
- if (srcSpriteP->oldFrameRect.top > srcSpriteP->moveBoundsRect.bottom)
- {
- vertOffset = -((srcSpriteP->moveBoundsRect.bottom -
- srcSpriteP->moveBoundsRect.top) +
- (srcSpriteP->destFrameRect.bottom -
- srcSpriteP->destFrameRect.top) + srcSpriteP->vertMoveDelta);
- }
- else if (srcSpriteP->oldFrameRect.bottom < srcSpriteP->moveBoundsRect.top)
- {
- vertOffset = (srcSpriteP->moveBoundsRect.bottom -
- srcSpriteP->moveBoundsRect.top) +
- (srcSpriteP->destFrameRect.bottom -
- srcSpriteP->destFrameRect.top) - srcSpriteP->vertMoveDelta;
- }
- else
- vertOffset = 0;
-
-
- // Wrap sprite, and set delta and old rects to current rect
- if ((horizOffset != 0) || (vertOffset != 0))
- {
- SWOffsetSprite(srcSpriteP, horizOffset, vertOffset);
-
- srcSpriteP->deltaFrameRect = srcSpriteP->destFrameRect;
- srcSpriteP->oldFrameRect = srcSpriteP->destFrameRect;
-
- return true;
- }
- else
- {
- return false;
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWRegionCollision
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC Boolean SWRegionCollision(
- SpritePtr srcSpriteP,
- SpritePtr dstSpriteP)
- {
- Rect rgnRect;
-
- SW_ASSERT(srcSpriteP != NULL && dstSpriteP != NULL);
- SW_ASSERT(srcSpriteP->curFrameP->maskRgn != NULL);
- SW_ASSERT(dstSpriteP->curFrameP->maskRgn != NULL);
-
- // copy one of the regions in case they're the same
- // (would happen if the sprites are clones using the same frame)
- CopyRgn( dstSpriteP->curFrameP->maskRgn, gCollisionSpareRgn );
-
- rgnRect = (**srcSpriteP->curFrameP->maskRgn).rgnBBox;
-
- // move the mask region to the new sprite location
- OffsetRgn(srcSpriteP->curFrameP->maskRgn,
- (srcSpriteP->destFrameRect.left - rgnRect.left) +
- srcSpriteP->curFrameP->offsetPoint.h,
- (srcSpriteP->destFrameRect.top - rgnRect.top) +
- srcSpriteP->curFrameP->offsetPoint.v);
-
- rgnRect = (**gCollisionSpareRgn).rgnBBox;
-
- // move the mask region to the new sprite location
- OffsetRgn(gCollisionSpareRgn,
- (dstSpriteP->destFrameRect.left - rgnRect.left) +
- dstSpriteP->curFrameP->offsetPoint.h,
- (dstSpriteP->destFrameRect.top - rgnRect.top) +
- dstSpriteP->curFrameP->offsetPoint.v);
-
- SectRgn(srcSpriteP->curFrameP->maskRgn, gCollisionSpareRgn, gCollisionSectRgn);
-
- return (!EmptyRgn(gCollisionSectRgn));
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWRadiusCollision
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC Boolean SWRadiusCollision(
- SpritePtr srcSpriteP,
- SpritePtr dstSpriteP)
- {
- Point centerOne, centerTwo;
- register short radiusOne, radiusTwo;
- register short horizDistance, vertDistance;
-
- SW_ASSERT(srcSpriteP != NULL && dstSpriteP != NULL);
-
- // get radii - - assumes circular sprites!
- radiusOne = (srcSpriteP->destFrameRect.right-srcSpriteP->destFrameRect.left)/2;
- radiusTwo = (dstSpriteP->destFrameRect.right-dstSpriteP->destFrameRect.left)/2;
-
- // find centers
- centerOne.h = srcSpriteP->destFrameRect.left + radiusOne;
- centerOne.v = srcSpriteP->destFrameRect.top + radiusOne;
- centerTwo.h = dstSpriteP->destFrameRect.left + radiusTwo;
- centerTwo.v = dstSpriteP->destFrameRect.top + radiusTwo;
-
- horizDistance = centerOne.h - centerTwo.h;
- vertDistance = centerOne.v - centerTwo.v;
-
- return ( (horizDistance*horizDistance) + (vertDistance*vertDistance) <
- ((radiusOne+radiusTwo)*(radiusOne+radiusTwo)) );
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWPixelCollision
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC Boolean SWPixelCollision(
- SpritePtr srcSpriteP,
- SpritePtr dstSpriteP)
- {
- Boolean collision;
- Rect sectRect;
- FramePtr srcFrameP,
- dstFrameP;
- short numBytesPerRow;
- short srcPieceTop,
- srcPieceLeft,
- dstPieceTop,
- dstPieceLeft;
- unsigned long srcBaseOffset,
- dstBaseOffset;
- unsigned char* srcPixelPtr;
- unsigned char* dstPixelPtr;
- short i, j;
-
- SW_ASSERT(srcSpriteP != NULL && dstSpriteP != NULL);
- SW_ASSERT(srcSpriteP->curFrameP->maskPort != NULL);
- SW_ASSERT(dstSpriteP->curFrameP->maskPort != NULL);
- SW_ASSERT(srcSpriteP->curFrameP->isFrameLocked);
- SW_ASSERT(dstSpriteP->curFrameP->isFrameLocked);
-
- collision = false;
-
- sectRect.left =
- SW_MAX(srcSpriteP->destFrameRect.left, dstSpriteP->destFrameRect.left);
- sectRect.top =
- SW_MAX(srcSpriteP->destFrameRect.top, dstSpriteP->destFrameRect.top);
- sectRect.right =
- SW_MIN(srcSpriteP->destFrameRect.right, dstSpriteP->destFrameRect.right);
- sectRect.bottom =
- SW_MIN(srcSpriteP->destFrameRect.bottom, dstSpriteP->destFrameRect.bottom);
-
- if ( sectRect.right > sectRect.left && sectRect.bottom > sectRect.top )
- {
- START_32_BIT_MODE
-
- srcFrameP = srcSpriteP->curFrameP;
- dstFrameP = dstSpriteP->curFrameP;
-
- // Make sure we're in 8-bit
- if (srcFrameP->framePix->pixelSize != 8)
- return false;
-
- // calculate the top left of the intersecting portions of the frameRects
- srcPieceTop = srcFrameP->frameRect.top + (sectRect.top-srcSpriteP->destFrameRect.top);
- srcPieceLeft = srcFrameP->frameRect.left + (sectRect.left-srcSpriteP->destFrameRect.left);
- dstPieceTop = dstFrameP->frameRect.top + (sectRect.top-dstSpriteP->destFrameRect.top);
- dstPieceLeft = dstFrameP->frameRect.left + (sectRect.left-dstSpriteP->destFrameRect.left);
-
- // calculate the offset to the first byte of the sectRect of srcSprite
- srcBaseOffset = srcFrameP->scanLinePtrArray[srcPieceTop - srcFrameP->frameRect.top] +
- srcPieceLeft;
-
- // ... and for the dstSprite
- dstBaseOffset = dstFrameP->scanLinePtrArray[dstPieceTop - dstFrameP->frameRect.top] +
- dstPieceLeft;
-
- // calculate pointers to the mask pixels within the overlapping sections
- srcPixelPtr = (unsigned char*)(srcFrameP->maskBaseAddr + srcBaseOffset);
- dstPixelPtr = (unsigned char*)(dstFrameP->maskBaseAddr + dstBaseOffset);
-
- // calculate the number of bytes in a row
- numBytesPerRow = (sectRect.right - sectRect.left);
-
- i = 0;
- while ( i < sectRect.bottom-sectRect.top && !collision )
- {
- j = 0;
- while ( j < numBytesPerRow && !collision )
- {
- j++;
- collision = ( (*srcPixelPtr | *dstPixelPtr) == 0 );
- srcPixelPtr++;
- dstPixelPtr++;
- }
- i++;
- srcPixelPtr += (unsigned long)(srcFrameP->frameRowBytes - numBytesPerRow);
- dstPixelPtr += (unsigned long)(dstFrameP->frameRowBytes - numBytesPerRow);
- }
-
- END_32_BIT_MODE
- }
- return collision;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWIsSpriteInRect
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC Boolean SWIsSpriteInRect(
- SpritePtr srcSpriteP,
- Rect* testRect)
- {
- SW_ASSERT(srcSpriteP != NULL);
-
- return ((srcSpriteP->destFrameRect.top < testRect->bottom) &&
- (srcSpriteP->destFrameRect.bottom > testRect->top) &&
- (srcSpriteP->destFrameRect.left < testRect->right) &&
- (srcSpriteP->destFrameRect.right > testRect->left));
- }
-
- ///--------------------------------------------------------------------------------------
- // SWIsSpriteFullyInRect
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC Boolean SWIsSpriteFullyInRect(
- SpritePtr srcSpriteP,
- Rect* testRect)
- {
- SW_ASSERT(srcSpriteP != NULL);
-
- return ((srcSpriteP->destFrameRect.top >= testRect->top) &&
- (srcSpriteP->destFrameRect.bottom <= testRect->bottom) &&
- (srcSpriteP->destFrameRect.left >= testRect->left) &&
- (srcSpriteP->destFrameRect.right <= testRect->right));
- }
-
- ///--------------------------------------------------------------------------------------
- // SWIsPointInSprite
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC Boolean SWIsPointInSprite(
- SpritePtr srcSpriteP,
- Point testPoint)
- {
- SW_ASSERT(srcSpriteP != NULL);
-
- return (testPoint.h >= srcSpriteP->destFrameRect.left) &&
- (testPoint.h < srcSpriteP->destFrameRect.right) &&
- (testPoint.v >= srcSpriteP->destFrameRect.top) &&
- (testPoint.v < srcSpriteP->destFrameRect.bottom);
- }
-
-