home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MacFormat 1999 Spring
/
macformat-077.iso
/
Shareware Plus
/
Development
/
SpriteWorld 2.2
/
SpriteWorld files
/
Sources
/
SpriteFrame.c
< prev
next >
Encoding:
Amiga
Atari
Commodore
DOS
FM Towns/JPY
Macintosh
Macintosh JP
NeXTSTEP
RISC OS/Acorn
UTF-8
Wrap
Text File
|
1999-02-08
|
27.3 KB
|
1,096 lines
|
[
TEXT/CWIE
]
///--------------------------------------------------------------------------------------
// SpriteFrame.c
//
// Portions are copyright: © 1991-94 Tony Myles, All rights reserved worldwide.
//
// Description: implementation of the frame stuff
///--------------------------------------------------------------------------------------
#ifndef __SWCOMMON__
#include "SWCommonHeaders.h"
#endif
#ifndef __TOOLUTILS__
#include <ToolUtils.h>
#endif
#ifndef __MEMORY__
#include <Memory.h>
#endif
#ifndef __RESOURCES__
#include <Resources.h>
#endif
#ifndef __ERRORS__
#include <Errors.h>
#endif
#ifndef __SPRITEWORLDUTILS__
#include "SpriteWorldUtils.h"
#endif
#ifndef __SPRITECOMPILER__
#include "SpriteCompiler.h"
#endif
#ifndef __SPRITEFRAME__
#include "SpriteFrame.h"
#endif
///--------------------------------------------------------------------------------------
// SWCreateFrame
///--------------------------------------------------------------------------------------
SW_FUNC OSErr SWCreateFrame(
GDHandle theGDH,
FramePtr* newFrameP,
Rect* frameRect,
short depth)
{
OSErr err = noErr;
GWorldPtr frameGWorld;
FramePtr tempFrameP;
long numScanLines;
SW_ASSERT(theGDH != NULL);
SW_ASSERT(frameRect->top >= 0 && frameRect->left >= 0 &&
frameRect->right > frameRect->left && frameRect->bottom > frameRect->top);
*newFrameP = NULL;
frameGWorld = NULL;
numScanLines = frameRect->bottom - frameRect->top;
tempFrameP = (FramePtr)NewPtrClear((Size)sizeof(FrameRec) +
(sizeof(unsigned long) * (numScanLines+1)));
if (tempFrameP != NULL)
{
if ( (**((**theGDH).gdPMap)).pixelSize == depth )
err = NewGWorld( &frameGWorld, depth, frameRect, nil, theGDH, noNewDevice );
else
err = NewGWorld( &frameGWorld, depth, frameRect, nil, nil, (GWorldFlags)nil );
if (err == noErr)
{
tempFrameP->framePort = frameGWorld;
tempFrameP->frameRect = *frameRect;
tempFrameP->hotSpotH = 0;
tempFrameP->hotSpotV = 0;
tempFrameP->tileMaskIsSolid = false;
tempFrameP->numScanLines = numScanLines;
tempFrameP->sharesGWorld = false;
tempFrameP->isFrameLocked = false;
tempFrameP->isWindowFrame = false;
SWInitializeFrame( tempFrameP, depth );
*newFrameP = tempFrameP;
}
}
else
{
err = MemError();
}
if (err != noErr)
{
if (tempFrameP != NULL)
{
if (tempFrameP->framePort != NULL)
DisposeGWorld(tempFrameP->framePort);
DisposePtr((Ptr)tempFrameP);
}
}
SWSetStickyIfError( err );
return err;
}
///--------------------------------------------------------------------------------------
// SWCreateWindowFrame
///--------------------------------------------------------------------------------------
SW_FUNC OSErr SWCreateWindowFrame(
FramePtr* newFrameP,
Rect* frameRect,
short maxHeight)
{
OSErr err = noErr;
GDHandle currentGDH;
GWorldPtr windowGWorld;
FramePtr tempFrameP = NULL;
short depth;
long numScanLines;
Point globalOffset;
SW_ASSERT(frameRect->top >= 0 && frameRect->left >= 0 &&
frameRect->right > frameRect->left && frameRect->bottom > frameRect->top);
*newFrameP = NULL;
GetGWorld( &windowGWorld, ¤tGDH );
// more scanlines than we need, but this saves us from
// needing to calculate an offset in BlitPixie, and allows
// blitting to outside the worldRect.
numScanLines = (windowGWorld->portRect.bottom - windowGWorld->portRect.top);
numScanLines = SW_MAX(numScanLines, maxHeight);
// Clip frameRect with the window's boundaries
frameRect->top = SW_MAX(frameRect->top, windowGWorld->portRect.top);
frameRect->left = SW_MAX(frameRect->left, windowGWorld->portRect.left);
frameRect->bottom = SW_MIN(frameRect->bottom, windowGWorld->portRect.bottom);
frameRect->right = SW_MIN(frameRect->right, windowGWorld->portRect.right);
globalOffset = topLeft( *frameRect );
LocalToGlobal( &globalOffset );
tempFrameP = (FramePtr)NewPtrClear((Size)sizeof(FrameRec) +
(sizeof(unsigned long) * numScanLines));
if (tempFrameP != NULL)
{
depth = (**(**currentGDH).gdPMap).pixelSize;
tempFrameP->framePort = windowGWorld;
tempFrameP->frameRect = *frameRect;
// cache frameRowBytes for use by our blitter routine
tempFrameP->frameRowBytes = (**tempFrameP->framePort->portPixMap).rowBytes & 0x7FFF;
// this calculation generates a mask value that we use to
// long word align the rectangle when we draw the frame.
// note that the expression "sizeof(long) * kBitsPerByte" gives us
// the number of bits in a long.
// align on long word boundary
tempFrameP->rightAlignFactor = ((sizeof(long) * kBitsPerByte) / depth) - 1;
tempFrameP->leftAlignFactor = ~(tempFrameP->rightAlignFactor);
// useCount not used for window/work/back frames
tempFrameP->useCount = 0;
// here we set up an array of offsets to the scan lines of
// this frame. this allows us to address a particular scan line
// without doing a costly multiply.
tempFrameP->numScanLines = numScanLines;
tempFrameP->scanLinePtrArray = (unsigned long*)(tempFrameP + 1);
{
tempFrameP->worldRectOffset = 0;
if (depth < 8)
{
short roundOff;
roundOff = 8/depth;
tempFrameP->worldRectOffset =
(globalOffset.h - frameRect->left) -
(((globalOffset.h - frameRect->left)/roundOff)*roundOff);
}
for (numScanLines = 0; numScanLines < tempFrameP->numScanLines; numScanLines++)
{
tempFrameP->scanLinePtrArray[numScanLines] =
((numScanLines+(globalOffset.v - frameRect->top) ) *
tempFrameP->frameRowBytes) +
(globalOffset.h - frameRect->left)*4/(32/depth);
}
}
tempFrameP->sharesGWorld = false;
tempFrameP->isWindowFrame = true;
*newFrameP = tempFrameP;
}
else
{
err = MemError();
}
if (err != noErr)
{
if (tempFrameP != NULL)
{
DisposePtr((Ptr)tempFrameP);
}
}
SWSetStickyIfError( err );
return err;
}
///--------------------------------------------------------------------------------------
// SWCreateFrameFromCicnResource
///--------------------------------------------------------------------------------------
SW_FUNC OSErr SWCreateFrameFromCicnResource(
SpriteWorldPtr destSpriteWorld,
FramePtr* newFrameP,
short iconResID,
MaskType maskType)
{
OSErr err;
GWorldPtr saveGWorld;
GDHandle saveGDH;
GDHandle theGDH;
FramePtr tempFrameP;
CIconHandle cIconH;
RgnHandle maskRgn;
Rect frameRect;
*newFrameP = NULL;
tempFrameP = NULL;
SW_ASSERT(destSpriteWorld != NULL);
GetGWorld(&saveGWorld, &saveGDH);
cIconH = GetCIcon( iconResID );
if (cIconH != NULL)
{
HNoPurge((Handle)cIconH);
frameRect = (**cIconH).iconPMap.bounds;
theGDH = destSpriteWorld->mainSWGDH;
err = SWCreateFrame(theGDH, &tempFrameP, &frameRect, destSpriteWorld->pixelDepth);
}
else
{
err = MemError();
if ( err == noErr )
err = resNotFound;
}
if (err == noErr)
{
(void)LockPixels( GetGWorldPixMap(tempFrameP->framePort) );
SetGWorld(tempFrameP->framePort, nil);
EraseRect( &frameRect );
PlotCIcon(&frameRect, cIconH);
UnlockPixels( GetGWorldPixMap(tempFrameP->framePort) );
// make a region mask
if ((maskType & kRegionMask) != 0)
{
err = SWCreateRegionFromCIconMask(&maskRgn, cIconH);
if (err == noErr)
{
SWSetFrameMaskRgn(tempFrameP, maskRgn);
}
}
}
if (err == noErr)
{
// make a pixel mask
if ((maskType & kPixelMask) != 0)
{
err = SWCreateGWorldFromCIconMask(destSpriteWorld, &tempFrameP->maskPort, cIconH);
if (err == noErr && destSpriteWorld->pixelDepth <= 8)
{
(void)LockPixels( GetGWorldPixMap(tempFrameP->maskPort) );
SetGWorld(tempFrameP->maskPort, nil);
InvertRect(&tempFrameP->maskPort->portRect);
UnlockPixels( GetGWorldPixMap(tempFrameP->maskPort) );
}
}
}
if (cIconH != NULL)
{
DisposeCIcon(cIconH);
}
if (err == noErr)
{
*newFrameP = tempFrameP;
}
if (err != noErr)
{
// an error occurred so dispose of anything we managed to create
if (tempFrameP != NULL)
{
SWDisposeFrame(&tempFrameP);
}
}
SetGWorld(saveGWorld, nil);
SWSetStickyIfError( err );
return err;
}
///--------------------------------------------------------------------------------------
// SWCreateFrameFromPictResource
///--------------------------------------------------------------------------------------
SW_FUNC OSErr SWCreateFrameFromPictResource(
SpriteWorldPtr destSpriteWorld,
FramePtr* newFrameP,
short pictResID,
short maskResID,
MaskType maskType)
{
OSErr err;
GWorldPtr saveGWorld;
GDHandle saveGDH;
GDHandle theGDH;
PicHandle spritePictH,
maskPictH;
FramePtr tempFrameP;
RgnHandle maskRgn;
Rect frameRect;
SW_ASSERT(destSpriteWorld != NULL);
tempFrameP = NULL;
*newFrameP = NULL;
GetGWorld(&saveGWorld, &saveGDH);
spritePictH = GetPicture(pictResID);
if (spritePictH != NULL)
{
frameRect = (**spritePictH).picFrame;
OffsetRect( &frameRect, -frameRect.left, -frameRect.top );
theGDH = destSpriteWorld->mainSWGDH;
err = SWCreateFrame(theGDH, &tempFrameP, &frameRect, destSpriteWorld->pixelDepth);
if (err == noErr)
{
(void)LockPixels( GetGWorldPixMap(tempFrameP->framePort) );
SetGWorld(tempFrameP->framePort, nil);
EraseRect(&frameRect); // Necessary for some wierd picture formats, like XOr
DrawPicture(spritePictH, &frameRect);
UnlockPixels( GetGWorldPixMap(tempFrameP->framePort) );
ReleaseResource((Handle)spritePictH);
}
// make a region mask
if (((maskType & kRegionMask) != 0) && (err == noErr))
{
maskPictH = GetPicture(maskResID);
if (maskPictH != NULL)
{
err = SWCreateRegionFromPict(&maskRgn, maskPictH );
ReleaseResource((Handle)maskPictH);
}
else
{
err = MemError();
if ( err == noErr )
err = resNotFound;
}
if (err == noErr)
{
SWSetFrameMaskRgn(tempFrameP, maskRgn);
}
}
// make a pixel mask
if (((maskType & kPixelMask) != 0) && (err == noErr))
{
err = SWCreateGWorldFromPictResource(destSpriteWorld, &tempFrameP->maskPort, maskResID);
if (err == noErr)
{
if ( pictResID == maskResID )
{
err = SWBlackenGWorld( tempFrameP->maskPort );
if (err == noErr)
err = SWWhitenGWorld( tempFrameP->framePort );
}
if (err == noErr && destSpriteWorld->pixelDepth <= 8)
{
(void)LockPixels( GetGWorldPixMap(tempFrameP->maskPort) );
SetGWorld(tempFrameP->maskPort, nil);
InvertRect(&tempFrameP->maskPort->portRect);
UnlockPixels( GetGWorldPixMap(tempFrameP->maskPort) );
}
}
}
if (err == noErr)
{
*newFrameP = tempFrameP;
}
else
{
// an error occurred so dispose of anything we managed to create
if (tempFrameP != NULL)
{
SWDisposeFrame(&tempFrameP);
}
}
}
else
{
err = MemError();
if ( err == noErr )
err = resNotFound;
}
SetGWorld(saveGWorld, nil);
SWSetStickyIfError( err );
return err;
}
///--------------------------------------------------------------------------------------
// SWCreateFrameFromGWorldAndRect
///--------------------------------------------------------------------------------------
SW_FUNC OSErr SWCreateFrameFromGWorldAndRect(
FramePtr* newFrameP,
GWorldPtr pictGWorld,
GWorldPtr maskGWorld,
Rect* frameRect,
MaskType maskType)
{
OSErr err;
GWorldPtr tempMaskGWorld;
err = SWCreateFrameFromGWorldAndRectStart( &tempMaskGWorld,
frameRect->right - frameRect->left, frameRect->bottom - frameRect->top, maskType );
if ( err == noErr ) {
err = SWCreateFrameFromGWorldAndRectPartial( newFrameP, pictGWorld, maskGWorld,
tempMaskGWorld, frameRect, maskType );
SWCreateFrameFromGWorldAndRectFinish( tempMaskGWorld );
}
SWSetStickyIfError( err );
return err;
}
///--------------------------------------------------------------------------------------
// SWCreateFrameFromGWorldAndRectStart
///--------------------------------------------------------------------------------------
SW_FUNC OSErr SWCreateFrameFromGWorldAndRectStart(
GWorldPtr *tempMaskGWorld,
short maxWidth,
short maxHeight,
MaskType maskType)
{
OSErr err = noErr;
*tempMaskGWorld = NULL;
if ((maskType & kRegionMask) != 0)
{
err = SWCreateRegionFromGWorldAndRectStart( tempMaskGWorld, maxWidth, maxHeight );
}
return err;
}
///--------------------------------------------------------------------------------------
// SWCreateFrameFromGWorldAndRectFinish
///--------------------------------------------------------------------------------------
SW_FUNC void SWCreateFrameFromGWorldAndRectFinish(
GWorldPtr tempMaskGWorld)
{
SWCreateRegionFromGWorldAndRectFinish( tempMaskGWorld );
}
///--------------------------------------------------------------------------------------
// SWCreateFrameFromGWorldAndRectPartial
///--------------------------------------------------------------------------------------
SW_FUNC OSErr SWCreateFrameFromGWorldAndRectPartial(
FramePtr* newFrameP,
GWorldPtr pictGWorld,
GWorldPtr maskGWorld,
GWorldPtr tempMaskGWorld,
Rect* frameRect,
MaskType maskType)
{
OSErr err = noErr;
short depth;
long numScanLines;
FramePtr tempFrameP;
RgnHandle maskRgn;
SW_ASSERT(pictGWorld != NULL);
SW_ASSERT(frameRect->top >= 0 && frameRect->left >= 0 &&
frameRect->right > frameRect->left && frameRect->bottom > frameRect->top);
tempFrameP = NULL;
*newFrameP = NULL;
numScanLines = frameRect->bottom - frameRect->top;
depth = (**(GetGWorldPixMap( pictGWorld ))).pixelSize;
tempFrameP = (FramePtr)NewPtrClear((Size)sizeof(FrameRec) +
(sizeof(unsigned long) * (numScanLines+1)));
if (tempFrameP != NULL)
{
tempFrameP->framePort = pictGWorld;
// make a pixel mask
if ((maskType & kPixelMask) != 0)
{
SW_ASSERT(maskGWorld != NULL);
tempFrameP->maskPort = maskGWorld;
}
tempFrameP->frameRect = *frameRect;
tempFrameP->sharesGWorld = true;
tempFrameP->numScanLines = numScanLines;
SWInitializeFrame( tempFrameP, depth );
}
else
{
err = MemError();
}
if (err == noErr)
{
// make a region mask
if (((maskType & kRegionMask) != 0) && (err == noErr))
{
SW_ASSERT(maskGWorld != NULL);
err = SWCreateRegionFromGWorldAndRectPartial(&maskRgn, maskGWorld,
tempMaskGWorld, frameRect);
if (err == noErr)
{
SWSetFrameMaskRgn(tempFrameP, maskRgn);
}
}
if (err == noErr)
{
*newFrameP = tempFrameP;
}
else
{
// an error occurred so dispose of anything we managed to create
if (tempFrameP != NULL)
{
SWDisposeFrame(&tempFrameP);
}
}
}
SWSetStickyIfError( err );
return err;
}
///--------------------------------------------------------------------------------------
// SWDisposeFrame
///--------------------------------------------------------------------------------------
SW_FUNC Boolean SWDisposeFrame(
FramePtr *oldFramePP)
{
Boolean frameDisposed;
FramePtr oldFrameP = *oldFramePP;
frameDisposed = false;
if (oldFrameP != NULL)
{
// is this frame still in use by another sprite?
if (oldFrameP->useCount > 1)
{
// one less sprite is using it now!
oldFrameP->useCount--;
}
else // no more sprites are using this frame
{
frameDisposed = true;
if (oldFrameP->framePort != NULL)
{
if ( !oldFrameP->sharesGWorld )
DisposeGWorld(oldFrameP->framePort);
oldFrameP->framePort = NULL;
}
if (oldFrameP->maskRgn != NULL)
{
DisposeRgn(oldFrameP->maskRgn);
oldFrameP->maskRgn = NULL;
}
if (oldFrameP->maskPort != NULL)
{
if ( !oldFrameP->sharesGWorld )
DisposeGWorld(oldFrameP->maskPort);
oldFrameP->maskPort = NULL;
}
if (oldFrameP->pixCodeH != NULL)
{
DisposeHandle((Handle)oldFrameP->pixCodeH);
oldFrameP->pixCodeH = NULL;
oldFrameP->frameBlitterP = NULL;
}
DisposePtr((Ptr)oldFrameP);
*oldFramePP = NULL; // Change the original pointer to NULL
}
}
return frameDisposed;
}
///--------------------------------------------------------------------------------------
// SWDisposeWindowFrame
///--------------------------------------------------------------------------------------
SW_FUNC void SWDisposeWindowFrame(
FramePtr *oldFramePP)
{
FramePtr oldFrameP = *oldFramePP;
if (oldFrameP != NULL)
{
DisposePtr((Ptr)oldFrameP);
*oldFramePP = NULL; // Change the original pointer to NULL
}
}
///--------------------------------------------------------------------------------------
// SWInitializeFrame
///--------------------------------------------------------------------------------------
SW_FUNC void SWInitializeFrame(
FramePtr tempFrameP,
short depth )
{
long curScanLine;
SW_ASSERT(tempFrameP != NULL);
// cache frameRowBytes for use by our blitter routine
tempFrameP->frameRowBytes = (**tempFrameP->framePort->portPixMap).rowBytes & 0x7FFF;
// this calculation generates a mask value that we use to
// long word align the rectangle when we draw the frame.
// note that the expression "sizeof(long) * kBitsPerByte" gives us
// the number of bits in a long.
// align on long word boundary
tempFrameP->rightAlignFactor = ((sizeof(long) * kBitsPerByte) / depth) - 1;
tempFrameP->leftAlignFactor = ~(tempFrameP->rightAlignFactor);
// the useCount keeps track of the number of sprites that
// are using this frame. we need to know this so we don't
// dispose this frame twice when we are disposing the
// sprites that use it.
tempFrameP->useCount = 0;
tempFrameP->worldRectOffset = 0;
// here we set up an array of offsets to the scan lines of
// this frame. this allows us to address a particular scan line
// without doing a costly multiply.
tempFrameP->scanLinePtrArray = (unsigned long*)(tempFrameP + 1);
for (curScanLine = 0; curScanLine < tempFrameP->numScanLines; curScanLine++)
{
tempFrameP->scanLinePtrArray[curScanLine] =
((tempFrameP->frameRect.top + curScanLine) * tempFrameP->frameRowBytes);
}
}
///--------------------------------------------------------------------------------------
// SWSetFrameMaskRgn
///--------------------------------------------------------------------------------------
SW_FUNC void SWSetFrameMaskRgn(
FramePtr srcFrameP,
RgnHandle maskRgn)
{
SW_ASSERT(srcFrameP != NULL);
SW_ASSERT(maskRgn != NULL);
if (maskRgn != NULL)
{
srcFrameP->maskRgn = maskRgn;
srcFrameP->offsetPoint.h = (**maskRgn).rgnBBox.left;
srcFrameP->offsetPoint.v = (**maskRgn).rgnBBox.top;
}
}
///--------------------------------------------------------------------------------------
// SWSetFrameHotSpot
///--------------------------------------------------------------------------------------
SW_FUNC void SWSetFrameHotSpot(
FramePtr srcFrameP,
short hotSpotH,
short hotSpotV)
{
SW_ASSERT(srcFrameP != NULL);
srcFrameP->hotSpotH = hotSpotH;
srcFrameP->hotSpotV = hotSpotV;
}
///--------------------------------------------------------------------------------------
// SWCopyFrame
///--------------------------------------------------------------------------------------
SW_FUNC OSErr SWCopyFrame(
SpriteWorldPtr destSpriteWorldP,
FramePtr oldFrameP,
FramePtr *newFrameP,
Boolean copyMasks)
{
OSErr err;
GWorldPtr saveGWorld;
GDHandle saveGDH;
GDHandle theGDH;
GWorldFlags pixelState;
short depth;
FramePtr tempFrameP;
Rect frameRect;
SW_ASSERT(newFrameP != NULL);
SW_ASSERT(oldFrameP != NULL);
SW_ASSERT(destSpriteWorldP != NULL);
*newFrameP = NULL;
tempFrameP = NULL;
depth = destSpriteWorldP->pixelDepth;
theGDH = destSpriteWorldP->mainSWGDH;
GetGWorld(&saveGWorld, &saveGDH);
// Get size of new frame
frameRect = oldFrameP->frameRect;
OffsetRect(&frameRect, -frameRect.left, -frameRect.top);
// Create the new frame
err = SWCreateFrame(theGDH, &tempFrameP, &frameRect, depth);
// Copy the image from the old frame into the new frame
if ( err == noErr )
{
pixelState = GetPixelsState( oldFrameP->framePort->portPixMap );
(void)LockPixels( GetGWorldPixMap(oldFrameP->framePort) );
(void)LockPixels( GetGWorldPixMap(tempFrameP->framePort) );
SetGWorld( oldFrameP->framePort, nil ); ForeColor( blackColor ); BackColor( whiteColor );
SetGWorld( tempFrameP->framePort, nil );
CopyBits ( (BitMap*)*GetGWorldPixMap( oldFrameP->framePort ),
(BitMap*)*GetGWorldPixMap( tempFrameP->framePort ),
&oldFrameP->frameRect,
&frameRect,
srcCopy,
nil);
SetPixelsState( oldFrameP->framePort->portPixMap, pixelState );
UnlockPixels( GetGWorldPixMap(tempFrameP->framePort) );
}
// copy region mask
if ((oldFrameP->maskRgn != NULL) && (err == noErr))
{
tempFrameP->maskRgn = NewRgn();
if (tempFrameP->maskRgn == NULL)
err = MemError();
else if (copyMasks)
CopyRgn(oldFrameP->maskRgn, tempFrameP->maskRgn);
}
// copy pixel mask
if ((oldFrameP->maskPort != NULL) && (err == noErr))
{
if ( (**((**theGDH).gdPMap)).pixelSize == depth )
err = NewGWorld( &tempFrameP->maskPort, depth, &frameRect, nil, theGDH, noNewDevice );
else
err = NewGWorld( &tempFrameP->maskPort, depth, &frameRect, nil, nil, 0 );
// Copy pixel mask from old frame into new frame
if ((err == noErr) && (copyMasks))
{
pixelState = GetPixelsState( oldFrameP->maskPort->portPixMap );
(void)LockPixels( GetGWorldPixMap(oldFrameP->maskPort) );
(void)LockPixels( GetGWorldPixMap(tempFrameP->maskPort) );
SetGWorld( oldFrameP->maskPort, nil ); ForeColor( blackColor ); BackColor( whiteColor );
SetGWorld( tempFrameP->maskPort, nil );
CopyBits( (BitMap*)*GetGWorldPixMap( oldFrameP->maskPort ),
(BitMap*)*GetGWorldPixMap( tempFrameP->maskPort ),
&oldFrameP->frameRect,
&frameRect,
srcCopy,
nil);
SetPixelsState( oldFrameP->maskPort->portPixMap, pixelState );
UnlockPixels( GetGWorldPixMap(tempFrameP->maskPort) );
}
}
if (err == noErr)
{
*newFrameP = tempFrameP;
}
else
{
// an error occurred so dispose of anything we managed to create
if (tempFrameP != NULL)
{
SWDisposeFrame(&tempFrameP);
}
}
SetGWorld(saveGWorld, nil);
SWSetStickyIfError( err );
return err;
}
///--------------------------------------------------------------------------------------
// SWUpdateFrameMasks - updates the pixel and region masks of a frame
///--------------------------------------------------------------------------------------
SW_FUNC OSErr SWUpdateFrameMasks(
SpriteWorldPtr destSpriteWorldP,
FramePtr srcFrameP)
{
GWorldPtr saveGWorld, newGWld;
GDHandle saveGDH;
Rect gwldRect;
ColorSearchUPP blackenColSearchUPP;
Boolean frameWasUnlocked = false;
OSErr err = noErr;
SW_ASSERT(destSpriteWorldP != NULL);
SW_ASSERT(srcFrameP != NULL);
GetGWorld( &saveGWorld, &saveGDH );
if (!srcFrameP->isFrameLocked)
{
SWLockFrame(srcFrameP);
frameWasUnlocked = true;
}
gwldRect = srcFrameP->framePort->portRect;
// Create 1-bit GWorld
err = NewGWorld(&newGWld, 1, &gwldRect, nil, nil, 0 );
if ( err == noErr )
{
blackenColSearchUPP = NewColorSearchProc( blackenColorSearch );
(void)LockPixels( GetGWorldPixMap(newGWld) );
SetGWorld( srcFrameP->framePort, nil ); ForeColor( blackColor ); BackColor( whiteColor );
SetGWorld( newGWld, nil );
AddSearch( blackenColSearchUPP );
// Copy 8-bit image into 1-bit GWorld while turning it into a mask
CopyBits( (BitMap*)*GetGWorldPixMap( srcFrameP->framePort ),
(BitMap*)*GetGWorldPixMap( newGWld ),
&srcFrameP->framePort->portRect,
&gwldRect,
srcCopy,
nil);
DelSearch( blackenColSearchUPP );
DisposeRoutineDescriptor( blackenColSearchUPP );
// update the region mask if there is one
if (srcFrameP->maskRgn != NULL)
{
err = BitMapToRegion(srcFrameP->maskRgn, (BitMap*)*GetGWorldPixMap( newGWld ) );
SWSetFrameMaskRgn(srcFrameP, srcFrameP->maskRgn);
}
// update the pixel mask if there is one
if (srcFrameP->maskPort != NULL)
{
SetGWorld( srcFrameP->maskPort, nil ); ForeColor( blackColor ); BackColor( whiteColor );
CopyBits( (BitMap*)*GetGWorldPixMap( newGWld ),
(BitMap*)*GetGWorldPixMap( srcFrameP->maskPort ),
&gwldRect,
&srcFrameP->maskPort->portRect,
srcCopy,
nil);
if (destSpriteWorldP->pixelDepth <= 8)
{
SetGWorld(srcFrameP->maskPort, nil);
InvertRect(&srcFrameP->maskPort->portRect);
}
}
UnlockPixels( GetGWorldPixMap(newGWld) );
DisposeGWorld( newGWld );
}
if (frameWasUnlocked)
SWUnlockFrame(srcFrameP);
SetGWorld( saveGWorld, saveGDH );
SWSetStickyIfError( err );
return err;
}
///--------------------------------------------------------------------------------------
// SWLockFrame
///--------------------------------------------------------------------------------------
SW_FUNC void SWLockFrame(
FramePtr srcFrameP)
{
PixMapHandle pixMapH;
SW_ASSERT(srcFrameP != NULL);
if (!srcFrameP->isFrameLocked)
{
srcFrameP->isFrameLocked = true;
pixMapH = GetGWorldPixMap( srcFrameP->framePort );
(void)LockPixels( pixMapH );
HLockHi( (Handle)pixMapH );
srcFrameP->framePixHndl = pixMapH;
srcFrameP->framePix = (PixMapPtr)StripAddress( *(Handle)pixMapH );
srcFrameP->frameBaseAddr = GetPixBaseAddr( pixMapH );
srcFrameP->frameRowBytes = (**pixMapH).rowBytes & 0x7FFF;
if (srcFrameP->pixCodeH != NULL)
{
HLockHi((Handle)srcFrameP->pixCodeH);
srcFrameP->frameBlitterP = (BlitFuncPtr)StripAddress( *srcFrameP->pixCodeH );
}
if (srcFrameP->maskPort != NULL)
{
pixMapH = GetGWorldPixMap( srcFrameP->maskPort );
(void)LockPixels( pixMapH );
HLockHi( (Handle)pixMapH );
srcFrameP->maskPixHndl = pixMapH;
srcFrameP->maskPix = (PixMapPtr)StripAddress( *(Handle)pixMapH );
srcFrameP->maskBaseAddr = GetPixBaseAddr( pixMapH );
}
}
}
///--------------------------------------------------------------------------------------
// SWUnlockFrame
///--------------------------------------------------------------------------------------
SW_FUNC void SWUnlockFrame(
FramePtr srcFrameP)
{
SW_ASSERT(srcFrameP != NULL);
if (srcFrameP->isFrameLocked)
{
srcFrameP->isFrameLocked = false;
if (srcFrameP->framePort != NULL && srcFrameP->framePixHndl != NULL)
{
HUnlock( (Handle)srcFrameP->framePixHndl );
UnlockPixels(srcFrameP->framePixHndl);
}
if (srcFrameP->maskPort != NULL && srcFrameP->maskPixHndl != NULL)
{
HUnlock( (Handle)srcFrameP->maskPixHndl );
UnlockPixels(srcFrameP->maskPixHndl);
}
srcFrameP->framePix = NULL;
srcFrameP->frameBaseAddr = NULL;
srcFrameP->maskPix = NULL;
srcFrameP->maskBaseAddr = NULL;
if (srcFrameP->pixCodeH != NULL)
{
HUnlock((Handle)srcFrameP->pixCodeH);
srcFrameP->frameBlitterP = NULL;
}
}
}
///--------------------------------------------------------------------------------------
// SWLockWindowFrame
///--------------------------------------------------------------------------------------
SW_FUNC void SWLockWindowFrame(
FramePtr windowFrameP)
{
PixMapHandle pixMapH;
SW_ASSERT(windowFrameP != NULL);
if (!windowFrameP->isFrameLocked)
{
windowFrameP->isFrameLocked = true;
pixMapH = windowFrameP->framePort->portPixMap;
HLockHi( (Handle)pixMapH );
windowFrameP->framePixHndl = pixMapH;
windowFrameP->framePix = (PixMapPtr)StripAddress( *(Handle)pixMapH );
windowFrameP->frameBaseAddr = GetPixBaseAddr( pixMapH );
windowFrameP->frameRowBytes = (**pixMapH).rowBytes & 0x7FFF;
}
}
///--------------------------------------------------------------------------------------
// SWUnlockWindowFrame
///--------------------------------------------------------------------------------------
SW_FUNC void SWUnlockWindowFrame(
FramePtr windowFrameP)
{
SW_ASSERT(windowFrameP != NULL);
if (windowFrameP->isFrameLocked)
{
windowFrameP->isFrameLocked = false;
HUnlock( (Handle)windowFrameP->framePixHndl );
windowFrameP->framePix = NULL;
windowFrameP->frameBaseAddr = NULL;
}
}