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.
Test.c
/* |
File: Test.c |
Contains: This snippet drag races CopyBits (using a mask region) and CopyMask |
(using a mask BitMap). Which do you think is faster? The results may |
surprise you. |
Written by: Tony Myles |
Copyright: Copyright © 1992-1999 by Apple Computer, Inc., All Rights Reserved. |
You may incorporate this Apple sample source code into your program(s) without |
restriction. This Apple sample source code has been provided "AS IS" and the |
responsibility for its operation is yours. You are not permitted to redistribute |
this Apple sample source code as "Apple sample source 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 source |
code, but that you've made changes. |
Change History (most recent first): |
7/9/1999 Karl Groethe Updated for Metrowerks Codewarror Pro 2.1 |
*/ |
#include <QuickDraw.h> |
//#include <DebugUtils.h> |
#include <Dialogs.h> |
//#include <GWorldUtils.h> |
#include <TextUtils.h> |
#include <Resources.h> |
#include "Sample.h" |
#include "Test.h" |
#include <Sound.h> |
///-------------------------------------------------------------------------------------- |
// LetTheGameBegin |
///-------------------------------------------------------------------------------------- |
void LetTheGameBegin(DialogPtr srcDialogP) |
{ |
OSErr err; |
CGrafPtr saveCPort; |
GDHandle saveGDevice; |
PixMapHandle srcPixMap; |
GWorldPtr pictGWorld = NULL, maskGWorld = NULL; |
GrafPtr offScrnPort = NULL; |
RgnHandle maskRgn = NULL; |
Rect srcRect, dstRect, itemRect; |
short frame; |
long ticks; |
Str255 itemStr; |
PixPatHandle pixPatH; |
SetCursor(*GetCursor(watchCursor)); |
GetGWorld(&saveCPort, &saveGDevice); |
SetGWorld((CGrafPtr)srcDialogP, NULL); |
itemStr[0] = 0; |
SetDItemText(srcDialogP, kCopyBitsFramesItem, itemStr); |
SetDItemText(srcDialogP, kCopyBitsTicksItem, itemStr); |
SetDItemText(srcDialogP, kCopyBitsFPSItem, itemStr); |
SetDItemText(srcDialogP, kCopyMaskFramesItem, itemStr); |
SetDItemText(srcDialogP, kCopyMaskTicksItem, itemStr); |
SetDItemText(srcDialogP, kCopyMaskFPSItem, itemStr); |
GetDItemRect(srcDialogP, kCopyBitsPictItem, &itemRect); |
OffsetRect(&itemRect, -itemRect.left, -itemRect.top); |
itemRect.right += kFrameCount; |
err = CreateOptimumGWorld(&pictGWorld, &itemRect); |
if (err == noErr) |
{ |
SetGWorld(pictGWorld, NULL); |
srcPixMap = GetGWorldPixMap(pictGWorld); |
(void)LockPixels(srcPixMap); |
pixPatH = GetPixPat(kPixPatResID); |
if (pixPatH != NULL) |
{ |
FillCRect(&itemRect, pixPatH); |
DisposePixPat(pixPatH); |
} |
err = CreateGWorldFromPictResource(&maskGWorld, kApplePictResID); |
} |
if (err == noErr) |
{ |
offScrnPort = NULL; |
err = CreateGrafPortFromPictResource(kApplePictResID, &offScrnPort); |
} |
if (err == noErr) |
{ |
maskRgn = NewRgn(); |
err = BitMapToRegion(maskRgn, &offScrnPort->portBits); |
} |
if (err == noErr) |
{ |
GetDItemRect(srcDialogP, kCopyBitsPictItem, &itemRect); |
OffsetRgn(maskRgn, itemRect.left, itemRect.top); |
srcRect = itemRect; |
OffsetRect(&srcRect, -srcRect.left, -srcRect.top); |
dstRect = itemRect; |
SetGWorld((CGrafPtr)srcDialogP, NULL); |
ticks = TickCount(); |
for (frame = 0; frame < kFrameCount; frame++) |
{ |
CopyBits((BitMapPtr)*srcPixMap, &srcDialogP->portBits, |
&srcRect, &dstRect, srcCopy, maskRgn); |
srcRect.left++; |
srcRect.right++; |
} |
ticks = TickCount() - ticks; |
NumToString(kFrameCount, itemStr); |
SetDItemText(srcDialogP, kCopyBitsFramesItem, itemStr); |
NumToString(ticks, itemStr); |
SetDItemText(srcDialogP, kCopyBitsTicksItem, itemStr); |
NumToString((ticks < 60) ? kFrameCount : kFrameCount / (ticks / 60), itemStr); |
SetDItemText(srcDialogP, kCopyBitsFPSItem, itemStr); |
GetDItemRect(srcDialogP, kCopyMaskPictItem, &itemRect); |
srcRect = itemRect; |
OffsetRect(&srcRect, -srcRect.left, -srcRect.top); |
dstRect = itemRect; |
ticks = TickCount(); |
for (frame = 0; frame < kFrameCount; frame++) |
{ |
CopyMask((BitMapPtr)*srcPixMap, &offScrnPort->portBits, &srcDialogP->portBits, |
&srcRect, &offScrnPort->portRect, &dstRect); |
srcRect.left++; |
srcRect.right++; |
} |
ticks = TickCount() - ticks; |
NumToString(kFrameCount, itemStr); |
SetDItemText(srcDialogP, kCopyMaskFramesItem, itemStr); |
NumToString(ticks, itemStr); |
SetDItemText(srcDialogP, kCopyMaskTicksItem, itemStr); |
NumToString((ticks < 60) ? kFrameCount : kFrameCount / (ticks / 60), itemStr); |
SetDItemText(srcDialogP, kCopyMaskFPSItem, itemStr); |
UnlockPixels(srcPixMap); |
} |
if (maskRgn != NULL) |
DisposeRgn(maskRgn); |
if (offScrnPort != NULL) |
DisposeGrafPort(offScrnPort); |
if (maskGWorld != NULL) |
DisposeGWorld(maskGWorld); |
if (pictGWorld != NULL) |
DisposeGWorld(pictGWorld); |
SetCursor(&qd.arrow); |
SysBeep(0); |
} |
///-------------------------------------------------------------------------------------- |
// CreateOptimumGWorld |
// |
// create a new GWorld optimized for speed in copying |
// to the graphics device that intersects the given rect. |
///-------------------------------------------------------------------------------------- |
OSErr CreateOptimumGWorld(GWorldPtr *optGWorld, Rect *devRect) |
{ |
OSErr err; |
CGrafPtr saveCPort; |
GDHandle saveGDevice; |
GWorldPtr tempGWorld; |
//PixMapHandle pixMapH; |
Rect tempRect = *devRect; |
*optGWorld = NULL; |
GetGWorld(&saveCPort, &saveGDevice); |
LocalToGlobal((Point *)&tempRect.top); |
LocalToGlobal((Point *)&tempRect.bottom); |
err = NewGWorld(&tempGWorld, 0, &tempRect, NULL, NULL, 0); |
if (err == noErr) |
{ |
SetGWorld(tempGWorld, NULL); |
EraseRect(&tempGWorld->portRect); |
*optGWorld = tempGWorld; |
} |
SetGWorld(saveCPort, saveGDevice); |
return err; |
} |
///-------------------------------------------------------------------------------------- |
// CreateGWorldFromPict |
// |
// creates a offScreen GWorld and draws the specified pict into it |
///-------------------------------------------------------------------------------------- |
OSErr CreateGWorldFromPict(GWorldPtr *pictGWorld, PicHandle pictH) |
{ |
OSErr err; |
CGrafPtr saveCPort; |
GDHandle saveGDevice; |
GWorldPtr tempGWorld; |
PixMapHandle tempPixMapH; |
Rect pictRect; |
*pictGWorld = NULL; |
GetGWorld(&saveCPort, &saveGDevice); |
pictRect.left = pictRect.top = 0; |
pictRect.right = (**pictH).picFrame.right - (**pictH).picFrame.left; |
pictRect.bottom = (**pictH).picFrame.bottom - (**pictH).picFrame.top; |
err = CreateOptimumGWorld(&tempGWorld, &pictRect); |
if (err == noErr) |
{ |
*pictGWorld = tempGWorld; |
SetGWorld(tempGWorld, NULL); |
tempPixMapH = GetGWorldPixMap(tempGWorld); |
(void)LockPixels(tempPixMapH); |
DrawPicture(pictH, &pictRect); |
UnlockPixels(tempPixMapH); |
} |
SetGWorld(saveCPort, saveGDevice); |
return err; |
} |
///-------------------------------------------------------------------------------------- |
// CreateGWorldFromPictResource |
///-------------------------------------------------------------------------------------- |
OSErr CreateGWorldFromPictResource(GWorldPtr *pictGWorldP, short pictResID) |
{ |
OSErr err; |
PicHandle newPictH; |
newPictH = GetPicture(pictResID); |
if (newPictH != NULL) |
{ |
err = CreateGWorldFromPict(pictGWorldP, newPictH); |
ReleaseResource((Handle)newPictH); |
} |
return err; |
} |
////-------------------------------------------------------------------------------------- |
// CreateGrafPort |
// |
// originally written by Forrest Tanaka |
////-------------------------------------------------------------------------------------- |
OSErr CreateGrafPort(Rect *newPortRect, GrafPtr *newPort) |
{ |
OSErr err = noErr; |
GrafPtr savePort; // save port for later restore |
GrafPtr localPort; // local copy of GrafPort |
Rect localPortRect; // local copy of bounds |
*newPort = NULL; |
// save off the current port |
GetPort(&savePort); |
// set the top-left corner of bounds to (0,0) |
localPortRect = *newPortRect; |
OffsetRect(&localPortRect, -newPortRect->left, -newPortRect->top); |
// allocate a new GrafPort |
localPort = (GrafPtr)NewPtrClear(sizeof(GrafPort)); |
if (localPort != NULL) |
{ |
// initialize the new port and make the current port |
OpenPort(localPort); |
SetPort(localPort); |
ForeColor(blackColor); |
BackColor(whiteColor); |
// initialize and allocate the bitmap |
localPort->portBits.bounds = localPortRect; |
localPort->portBits.rowBytes = ((localPortRect.right + 15) >> 4) << 1; |
localPort->portBits.baseAddr = NewPtrClear(localPort->portBits.rowBytes * |
(long)localPortRect.bottom); |
if (localPort->portBits.baseAddr != NULL) |
{ |
// clean up the new port |
localPort->portRect = localPortRect; |
ClipRect(&localPortRect); |
RectRgn(localPort->visRgn, &localPortRect); |
EraseRect(&localPortRect); |
*newPort = localPort; |
} |
else // allocation failed |
{ |
// capture the error |
err = MemError(); |
// deallocate the port |
ClosePort(localPort); |
DisposePtr((Ptr)localPort); |
} |
} |
else |
{ |
err = MemError(); |
} |
SetPort(savePort); |
return err; |
} |
////-------------------------------------------------------------------------------------- |
// CreateGrafPortFromPictResource |
// |
// this routine will set up an offscreen port, and draw a pict into it |
// the offscreen port is the exact size of the pict |
///-------------------------------------------------------------------------------------- |
OSErr CreateGrafPortFromPictResource(short pictID, GrafPtr *offScrnPort) |
{ |
OSErr err; |
GrafPtr savePort; |
PicHandle pictH; |
Rect tmpRect; |
GetPort(&savePort); |
pictH = GetPicture(pictID); |
if (pictH != NULL) |
{ |
tmpRect.left = tmpRect.top = 0; |
tmpRect.right = (**pictH).picFrame.right - (**pictH).picFrame.left; |
tmpRect.bottom = (**pictH).picFrame.bottom - (**pictH).picFrame.top; |
// create a port |
err = CreateGrafPort(&tmpRect, offScrnPort); |
if (err == noErr) |
{ |
SetPort(*offScrnPort); |
// draw the picture |
DrawPicture(pictH, &tmpRect); |
} |
ReleaseResource((Handle)pictH); |
} |
else |
{ |
err = ResError(); |
if (err == noErr) |
{ |
err = resNotFound; |
} |
} |
SetPort(savePort); |
return err; |
} |
////-------------------------------------------------------------------------------------- |
// DisposeGrafPort |
// |
// originally written by Forrest Tanaka |
///-------------------------------------------------------------------------------------- |
void DisposeGrafPort(GrafPtr doomedPort) |
{ |
ClosePort(doomedPort); |
DisposePtr(doomedPort->portBits.baseAddr); |
DisposePtr((Ptr)doomedPort); |
} |
///-------------------------------------------------------------------------------------- |
// GetDItemText |
// |
// get the text of a dialog item |
///-------------------------------------------------------------------------------------- |
void GetDItemText(DialogPtr dlgP, short itemNum, Str255 iStr) |
{ |
short itemType; |
Rect itemRect; |
Handle itemH; |
GetDialogItem(dlgP, itemNum, &itemType, &itemH, &itemRect); |
GetDialogItemText(itemH, iStr); |
} |
///-------------------------------------------------------------------------------------- |
// SetDItemText |
// |
// set the text of a dialog item |
///-------------------------------------------------------------------------------------- |
void SetDItemText(DialogPtr dlgP, short itemNum, Str255 iStr) |
{ |
short itemType; |
Rect itemRect; |
Handle itemH; |
GetDialogItem(dlgP, itemNum, &itemType, &itemH, &itemRect); |
SetDialogItemText(itemH, iStr); |
} |
///-------------------------------------------------------------------------------------- |
// GetDItemRect |
// |
// return the rect of a dialog item |
///-------------------------------------------------------------------------------------- |
void GetDItemRect(DialogPtr dlgP, short itemNum, Rect *itemRect) |
{ |
short itemType; |
Handle itemH; |
GetDialogItem(dlgP, itemNum, &itemType, &itemH, itemRect); |
} |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-07-22