Retired Document
Important: This sample code may not represent best practices for current development. The project may use deprecated symbols and illustrate technologies and techniques that are no longer recommended.
Source/Sprite.c
//¥ ------------------------------------------------------------------------------------------ ¥ |
//¥ |
//¥ Copyright © 1996 Apple Computer, Inc., All Rights Reserved |
//¥ |
//¥ |
//¥ You may incorporate this sample code into your applications without |
//¥ restriction, though the sample code has been provided "AS IS" and the |
//¥ responsibility for its operation is 100% yours. However, what you are |
//¥ not permitted to do is to redistribute the source as "DSC Sample Code" |
//¥ after having made changes. If you're going to re-distribute the source, |
//¥ we require that you make it clear in the source that the code was |
//¥ descended from Apple Sample Code, but that you've made changes. |
//¥ |
//¥ Authors: |
//¥ Chris De Salvo |
//¥ |
//¥ ------------------------------------------------------------------------------------------ ¥ |
//¥ ------------------------------ Includes |
#include <Resources.h> |
#include "Blitter.h" |
#include "ErrorHandler.h" |
#include "MemoryHandler.h" |
#include "Sprite.h" |
//¥ ------------------------------ Private Definitions |
#define kSpriteResType 'SPRT' |
//¥ ------------------------------ Private Types |
//¥ ------------------------------ Private Variables |
//¥ ------------------------------ Private Functions |
static void NewFramesFromPtr(SpritePtr theSprite, Ptr theData, UInt32 numFrames); |
//¥ ------------------------------ Public Variables |
//¥ -------------------- SpriteLoad |
SpritePtr |
SpriteLoad(SInt16 resNum) |
{ |
SpritePtr theSprite; |
Handle theHandle; |
UInt16 numFrames; |
Ptr index; |
theHandle = GetResource(kSpriteResType, resNum); |
if (! theHandle) |
return (nil); |
theSprite = (SpritePtr) NewPtrClear(sizeof (Sprite)); |
if (! theSprite) |
return (nil); |
HLockHi(theHandle); |
index = *theHandle; |
numFrames = *((UInt16 *) index); |
index += 2; |
theSprite->frames = (FramePtr *) NewTaggedPtrClear(numFrames * sizeof (FramePtr), 'FPTR', resNum); |
if (! theSprite->frames) |
{ |
HUnlock(theHandle); |
return (nil); |
} |
theSprite->numFrames = numFrames; |
NewFramesFromPtr(theSprite, index, numFrames); |
DisposeHandleZ(&theHandle); |
return (theSprite); |
} |
//¥ -------------------- NewFramesFromPtr |
static void |
NewFramesFromPtr(SpritePtr theSprite, Ptr theData, UInt32 numFrames) |
{ |
int i; |
UInt16 h, w; |
SInt16 hotX, hotY; |
for (i = 0; i < numFrames; i++) |
{ |
w = * ((UInt16 *) theData); |
theData += 2; |
h = * ((UInt16 *) theData); |
theData += 2; |
hotX = * ((SInt16 *) theData); |
theData += 2; |
hotY = * ((SInt16 *) theData); |
theData += 2; |
theSprite->frames[i] = (FramePtr) NewTaggedPtrClear(sizeof (Frame), 'FRAM', 1); |
if (! theSprite->frames[i]) |
FatalError("Could not allocate sprite frame."); |
theSprite->frames[i]->width = w; |
theSprite->frames[i]->height = h; |
theSprite->frames[i]->hotX = hotX; |
theSprite->frames[i]->hotY = hotY; |
theSprite->frames[i]->image = (UInt8 *) NewTaggedPtrClear(w * h, 'IMAG', i); |
if (! theSprite->frames[i]->image) |
FatalError("Could not allocate sprite frame bits."); |
BlockMoveData(theData, theSprite->frames[i]->image, w * h); |
theData += w * h; |
} |
} |
//¥ -------------------- SpriteDraw |
Rect |
SpriteDraw(SpritePtr theSprite, UInt32 frameNum, CGrafPtr dest, SInt32 x, SInt32 y) |
{ |
FramePtr theFrame; |
Rect blitRect; |
Rect emptyRect = { 0, 0, 0, 0 }; |
UInt32 h = 0, v = 0; |
theFrame = theSprite->frames[frameNum]; |
//¥ Set up a rectangle inside the image area that is clipped to the edges of the window |
blitRect.left = blitRect.top = 0; |
blitRect.right = theFrame->width; |
blitRect.bottom = theFrame->height; |
x -= theFrame->hotX; |
y -= theFrame->hotY; |
OffsetRect(&blitRect, x, y); |
if (blitRect.left < 0) |
h = -blitRect.left; |
if (blitRect.left > dest->portRect.right) |
return (emptyRect); |
if (blitRect.top < 0) |
v = -blitRect.top; |
if (blitRect.top > dest->portRect.bottom) |
return (emptyRect); |
if (blitRect.right > dest->portRect.right) |
blitRect.right = dest->portRect.right; |
if (blitRect.right < 0) |
return (emptyRect); |
if (blitRect.bottom > dest->portRect.bottom) |
blitRect.bottom = dest->portRect.bottom; |
if (blitRect.bottom < 0) |
return (emptyRect); |
OffsetRect(&blitRect, -blitRect.left, -blitRect.top); |
blitRect.left += h; |
blitRect.top += v; |
//¥ Blit the clipped area to the screen |
TransBitBlit(theFrame->image + (blitRect.top * theFrame->width) + blitRect.left, dest, |
blitRect.right - blitRect.left, blitRect.bottom - blitRect.top, theFrame->width, |
x + h, y + v); |
OffsetRect(&blitRect, x, y); |
return (blitRect); |
} |
//¥ -------------------- SpriteDispose |
void |
SpriteDispose(SpritePtr *theSprite) |
{ |
UInt32 i; |
if (! *theSprite) |
return; |
for (i = 0; i < (*theSprite)->numFrames; i++) |
{ |
DisposeTaggedPtrZ((Ptr *) &(*theSprite)->frames[i]->image); |
DisposeTaggedPtrZ((Ptr *) &(*theSprite)->frames[i]); |
} |
DisposeTaggedPtrZ((Ptr *) &(*theSprite)->frames); |
DisposeTaggedPtrZ((Ptr *) theSprite); |
} |
//¥ -------------------- SpriteHeight |
UInt16 |
SpriteHeight(SpritePtr whichSprite, UInt16 whichFrame) |
{ |
if (whichFrame > (whichSprite->numFrames - 1)) |
return (0); |
return (whichSprite->frames[whichFrame]->height); |
} |
//¥ -------------------- SpriteWidth |
UInt16 |
SpriteWidth(SpritePtr whichSprite, UInt16 whichFrame) |
{ |
if (whichFrame > (whichSprite->numFrames - 1)) |
return (0); |
return (whichSprite->frames[whichFrame]->width); |
} |
//¥ -------------------- IntersectRects |
Boolean |
IntersectRects(const RectPtr a, const RectPtr b) |
{ |
if (b->right < a->left) |
return (false); |
if (b->left > a->right) |
return (false); |
if (b->top > a->bottom) |
return (false); |
if (b->bottom < a->top) |
return (false); |
return (true); |
} |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-10-14