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.
GameSource/pixiZAM - direct blitter/pixiZAM.c
#include "PixiZAM.h" |
OSErr LoadPixiFromCIcon(pixiZAM *pz, short resID) |
/* |
Load the icons into a GWorld, then copy from the GWorld |
to the pixiZAM. |
Need to: Either read the icon data directly from the iconHandle (GetResource) |
or fix the crappy GWOrld extra rowLong problem for real. |
*/ |
{ |
CIconHandle cicn; // the icon we are loading |
GWorldPtr image; // the image of the icon |
GWorldPtr mask; // the mask that defines it |
long imageSize; // number of bytes for the image |
char *pixBaseAddr; // base address of pixmap in GWORld |
OSErr err = noErr; // |
char *maskFixer; // used to make sure the mask is correct |
Rect alignedBounds; // rect stretched to be long aligned |
short realRowBytes; // this will one day be the real rowBytes, no padding |
short needDump = 0; // bit flags set here to manage memory |
enum { kDumpCicn = 1, // if any of these flags are set |
kDumpImageGWorld = 2, // the object they represent will |
kDumpMaskGWorld = 4, // be disposed of at the end of the function |
kDumpImageZAM = 8 // in the case of an error, if any of the |
}; // pixiZAM has been allocated, it will be dumped |
/* |
first load in the color icon |
*/ |
cicn = GetCIcon(resID); |
if(!cicn) { |
err = ResError(); |
ErrMsgCode("\pErrror GetCIcon",err); |
} |
/* now create a GWorld from it, and set the bit to dump it. */ |
if(err == noErr) { |
needDump |= kDumpCicn; |
err = CreateGWorldFromCIcon(&image, cicn); |
if(err != noErr) { |
ErrMsgCode("\pError creating GWorld for image",err); |
} |
} |
/* if that was cool, we do the same thing for the mask */ |
if(err == noErr) { |
needDump |= kDumpImageGWorld; |
err = CreateGWorldFromCIconMask(&mask, cicn); |
if(err != noErr) { |
ErrMsgCode("\pError creating GWorld",err); |
} |
} |
/* we now do not need the icon anymore */ |
if( (needDump & kDumpCicn) != 0) |
DisposCIcon(cicn); |
/* Calculate the needed memory for the pixiZAM image, and get it */ |
if(err == noErr) { |
needDump |= kDumpMaskGWorld; |
//realRowBytes = (image->portRect.right - image->portRect.left); |
realRowBytes = 0x7FFF & (**image->portPixMap).rowBytes; |
alignedBounds = image->portRect; |
LongAlignRect(&alignedBounds); |
imageSize = (alignedBounds.bottom |
- alignedBounds.top) |
* realRowBytes; |
if (imageSize & 3) { |
imageSize &= ~3; |
imageSize += 4; |
} |
pz->image = (long*)NewPtrClear(imageSize); |
if(!pz->image) { |
err = MemError(); |
ErrMsgCode("\pError allocating pz->image",err); |
} |
} |
/* get the same amount of memory for the mask */ |
if(err == noErr) { |
pz->mask = (long*)NewPtrClear(imageSize); |
if(!pz->mask) { |
err = MemError(); |
ErrMsgCode("\pError allocating pz->mask",err); |
needDump |= kDumpImageZAM; |
} |
} |
/* now load the GWorlds into the pixiZAM buffers */ |
if(err == noErr) { |
LockPixels(image); |
pixBaseAddr = GetPixBaseAddr(GetGWorldPixMap(image)); |
BlockMove(pixBaseAddr, pz->image, imageSize); |
UnlockPixels(image); |
LockPixels(mask); |
pixBaseAddr = GetPixBaseAddr(GetGWorldPixMap(mask)); |
BlockMove(pixBaseAddr, pz->mask, imageSize); |
UnlockPixels(mask); |
/* this makes any byte of the mask that has on pixels */ |
/* all the way turned on, just to make sure the mask color */ |
/* indexes are correct */ |
maskFixer = (char*)pz->mask; |
while(imageSize--) { |
if(*maskFixer) |
*maskFixer = 0xFF; |
*maskFixer++; |
} |
/* initialize the rest of the pixiZAM structure */ |
pz->bounds = image->portRect; |
pz->height = image->portRect.bottom - image->portRect.top; |
pz->rowLongs = (realRowBytes/ 4); |
} |
/* check the bits in needDump, and clean up what we allocated */ |
if(needDump & kDumpImageGWorld) |
DisposeGWorld(image); |
if(needDump & kDumpMaskGWorld) |
DisposeGWorld(mask); |
if( needDump & kDumpImageZAM) |
DisposePtr(image); // only if allocated and an error occured |
return err; |
} |
void PixelMover(pixiZAM *srcPixi, PixMapHandle destMap, Rect *destRect) |
/* |
This is a non-masked straight copy. |
The entire source is copied to the topLeft of the destination rectangle |
Assumes: The destination's color table matches the pixiZAMs |
The pixiZAM is 8 bits deep, and so is the destination |
*/ |
{ |
register long *dst; |
register long *src; |
register long *mask; |
register long numRowsToCopy; |
register long rowLongsOffset; |
register long stripRowBytes; |
char mmuMode; |
stripRowBytes = (0x7FFF & (**destMap).rowBytes); |
src = srcPixi->image; |
mask = srcPixi->mask; |
LongAlignRect(destRect); |
dst = (long *)(GetPixBaseAddr(destMap) + (stripRowBytes * destRect->top) + destRect->left); |
mmuMode = true32b; |
SwapMMUMode(&mmuMode); |
numRowsToCopy = srcPixi->height; |
rowLongsOffset = (stripRowBytes/4) - srcPixi->rowLongs; |
while(numRowsToCopy--) { |
switch(srcPixi->rowLongs) { |
#include "pmSplat.gen" |
} |
dst += rowLongsOffset; |
} |
SwapMMUMode(&mmuMode); |
} |
void MaskedPixelMover(pixiZAM *srcPixi, PixMapHandle destMap, Rect *destRect) |
/* |
This is a masked copy. |
The entire source is copied to the topLeft of the destination rectangle |
Assumes: The destination's color table matches the pixiZAMs |
The pixiZAM is 8 bits deep, and so is the destination |
Also assumes that clipping won't be needed, so don't tell this |
to do anything stupid, cause it will. |
NeedTo: Correct problems in the pixiZam loaded because the images contain |
an extra longword at the end of each row, inherited from the GWorld. |
Also NeedTo: Write one that take a source and destination rectangle |
*/ |
{ |
register long *dst; |
register long *src; |
register long *mask; |
register long numRowsToCopy; |
register long rowLongsOffset; |
register long stripRowBytes; |
char mmuMode; |
stripRowBytes = (0x7FFF & (**destMap).rowBytes); |
src = srcPixi->image; |
mask = srcPixi->mask; |
LongAlignRect(destRect); |
dst = (long *)(GetPixBaseAddr(destMap) + (stripRowBytes * destRect->top) + destRect->left); |
mmuMode = true32b; |
SwapMMUMode(&mmuMode); |
numRowsToCopy = srcPixi->height; |
rowLongsOffset = (stripRowBytes/4) - srcPixi->rowLongs; |
while(numRowsToCopy--) { |
switch(srcPixi->rowLongs) { |
#include "pmSplatMask.gen" |
} |
dst += rowLongsOffset; |
} |
SwapMMUMode(&mmuMode); |
} |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-01-14