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.
MoofEncoder/GridEncode.cp
/* |
File: GridEncode.cp |
Contains: This is just a very simple encoder that shows how to build GRID and TILE resources. |
The TILE resource is a set of 32x32x1 byte tiles. This encoder takes a picture and |
dices it into 32x32 tiles, which it writes out to output file. It then builds a |
standard grid, repeating the original picture as a pattern across the grid. |
Eventually, it would be nice to make a program that lets someone graphically edit |
the available list of tiles and the actual GRID resource, much like any number |
of map editors out for various games. |
Written by: Timothy Carroll |
Copyright: Copyright © 1996-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/1/1999 Karl Groethe Updated for Metrowerks Codewarror Pro 2.1 |
2/24/97 Timothy Carroll Now explicitly include main.h |
8/15/96 Timothy Carroll Initial Release |
*/ |
#include <Resources.h> |
#include "Main.h" |
#include "GridEncode.h" |
#include "GridTilesFormat.h" |
#include "Error Macros.h" |
OSStatus GridTileEncode (short inputFileResNum, short outputFileResNum) |
{ |
OSStatus theErr; |
short saveResNum; |
// Used to compile the tile resource |
PicHandle tilePict = NULL; |
GWorldPtr tileWorld = NULL; |
PixMapHandle tilePix = NULL; |
CGrafPtr savePort; |
GDHandle saveDevice; |
Rect pictRect; |
long width, height, numTiles; |
long tileRowBytes; |
Ptr tileBaseAddress; |
long x, y, loop; |
Ptr destPtr, srcPtr; |
CellGridType *gridPtr; |
CellGridType currentValue; |
// Our output handles |
Handle tile = NULL; |
Handle grid = NULL; |
// Whether or not we've written it out as a resource |
Boolean tileIsResource = false, gridIsResource = false; |
saveResNum = CurResFile(); |
UseResFile (inputFileResNum); |
// First thing is to copy the color table resource to the output. |
theErr = CopyResource (inputFileResNum, outputFileResNum,'clut', kAppColorTableResID); |
FAIL_OSERR (theErr, "\pFailed to copy the color table to the destination file") |
// Load the color table and the graphic we want to dice into pieces |
gAppColorTable = GetCTable( kAppColorTableResID ); |
FAIL_NIL (gAppColorTable, "\pFailed to load the color table") |
tilePict = (PicHandle) Get1Resource ('PICT', kPICTInputResID); |
theErr = ResError(); |
FAIL_OSERR (theErr, "\pFailed to load the pict") |
FAIL_NIL (tilePict, "\pFailed to load the pict") |
// Create a GWorld and draw our PICT into it. |
pictRect = (**tilePict).picFrame; |
pictRect.right -= pictRect.left; |
pictRect.left = 0; |
pictRect.bottom -= pictRect.top; |
pictRect.top = 0; |
theErr = NewGWorld(&tileWorld, kPreferredDepth, &pictRect, gAppColorTable, NULL, keepLocal); |
FAIL_OSERR (theErr, "\pCouldn't allocate GWorld for encoding") |
FAIL_NIL (tileWorld, "\pCouldn't allocate GWorld for encoding") |
tilePix = GetGWorldPixMap(tileWorld); |
FAIL_NIL (tilePix, "\pCouldn't get the GWorld's PixMap") |
FAIL_FALSE ( LockPixels(tilePix), "\pCouldn't lock GWorld PixMap") |
GetGWorld (&savePort, &saveDevice); |
SetGWorld (tileWorld, NULL); |
EraseRect (&pictRect); |
DrawPicture (tilePict, &pictRect); |
SetGWorld (savePort, saveDevice); |
// We're done with the picture, release it |
ReleaseResource ((Handle) tilePict); |
tilePict = NULL; |
// Time to build the tile resource. We're going to dice it into as many |
// 32x32 tiles as we can. Any partial data to the bottom or the right will |
// be ignored -- we only build complete tiles. |
width = pictRect.right / 32; |
height = pictRect.bottom / 32; |
numTiles = width * height + 1; // Our first tile is always an all black tile, for the "borders" |
tile = NewHandleClear (sizeof (TileCollectionResHeader) + numTiles*kTileSize); |
theErr = MemError(); |
FAIL_OSERR (theErr, "\p Failed to create the tile resource file") |
FAIL_NIL (tile, "\p Failed to create the tile resource file") |
// Fill in the tile header. |
(**((TileCollectionResHeader **) tile)).version = 0; |
(**((TileCollectionResHeader **) tile)).depth = kPreferredDepth; |
(**((TileCollectionResHeader **) tile)).flags = 0; |
(**((TileCollectionResHeader **) tile)).numTiles = numTiles; |
tileBaseAddress = ( Ptr) GetPixBaseAddr( tilePix ); |
tileRowBytes = ( **tilePix ).rowBytes & 0x3fff; |
destPtr = (*tile) + sizeof (TileCollectionResHeader); |
// First tile, we just fill with black |
for (loop = 0; loop < 32; loop++) |
{ |
((UInt32 *) destPtr)[0] = 0xFFFFFFFF; |
((UInt32 *) destPtr)[1] = 0xFFFFFFFF; |
((UInt32 *) destPtr)[2] = 0xFFFFFFFF; |
((UInt32 *) destPtr)[3] = 0xFFFFFFFF; |
((UInt32 *) destPtr)[4] = 0xFFFFFFFF; |
((UInt32 *) destPtr)[5] = 0xFFFFFFFF; |
((UInt32 *) destPtr)[6] = 0xFFFFFFFF; |
((UInt32 *) destPtr)[7] = 0xFFFFFFFF; |
destPtr += 32; |
} |
// Iterate over each tile and copy 1K of data to the destination |
for (x = 0; x < width; x++) |
{ |
for (y = 0; y < height; y++) |
{ |
srcPtr = tileBaseAddress + 32*y*tileRowBytes + 32*x; |
for (loop = 0; loop < 32; loop++) |
{ |
register UInt32 temp1, temp2, temp3, temp4, temp5, temp6, temp7, temp8; |
temp1 = ((UInt32 *) srcPtr)[0]; |
temp2 = ((UInt32 *) srcPtr)[1]; |
temp3 = ((UInt32 *) srcPtr)[2]; |
temp4 = ((UInt32 *) srcPtr)[3]; |
temp5 = ((UInt32 *) srcPtr)[4]; |
temp6 = ((UInt32 *) srcPtr)[5]; |
temp7 = ((UInt32 *) srcPtr)[6]; |
temp8 = ((UInt32 *) srcPtr)[7]; |
((UInt32 *) destPtr)[0] = temp1; |
((UInt32 *) destPtr)[1] = temp2; |
((UInt32 *) destPtr)[2] = temp3; |
((UInt32 *) destPtr)[3] = temp4; |
((UInt32 *) destPtr)[4] = temp5; |
((UInt32 *) destPtr)[5] = temp6; |
((UInt32 *) destPtr)[6] = temp7; |
((UInt32 *) destPtr)[7] = temp8; |
srcPtr += tileRowBytes; |
destPtr += 32; |
} |
} |
} |
// Tile resource is done. Dispose of the GWorld |
DisposeGWorld ( tileWorld); |
tileWorld = NULL; |
// Time to create the GRID resource |
grid = NewHandle (sizeof (TileGridResHeader) + |
sizeof (CellGridType)*kGridWidth*kGridHeight); |
theErr = MemError(); |
FAIL_OSERR (theErr, "\p Failed to allocate memory for GRID resource") |
FAIL_NIL (grid, "\p Failed to allocate memory for GRID resource") |
// Fill in the header |
(**((TileGridResHeader **) grid)).version = 0; |
(**((TileGridResHeader **) grid)).flags = 0; |
(**((TileGridResHeader **) grid)).tileResID = kOutputResID; |
(**((TileGridResHeader **) grid)).width = kGridWidth; |
(**((TileGridResHeader **) grid)).height = kGridHeight; |
(**((TileGridResHeader **) grid)).defaultTile = 0; // our black tile |
// Point to the start of the grid data. |
gridPtr = (CellGridType * ) ((Ptr)(*grid) + sizeof (TileGridResHeader)); |
// Fill in each tile |
for (x = 0; x < kGridWidth; x++) |
{ |
for (y = 0; y < kGridWidth; y++) |
{ |
currentValue = (y % height)*height + (x % width) +1; |
*gridPtr = currentValue; |
gridPtr++; |
} |
} |
// Write the resources out to the output file. |
UseResFile (outputFileResNum); |
AddResource( tile, TileCollectionResType, kOutputResID, "\p" ); |
theErr = ResError(); |
FAIL_OSERR (theErr, "\pFailed to add the TILE resource to the file") |
tileIsResource = true; |
WriteResource( tile ); |
theErr = ResError(); |
FAIL_OSERR (theErr, "\pFailed to write the TILE resource to the file") |
ReleaseResource( tile ); |
tile = NULL; |
AddResource( grid, TileGridResType, kOutputResID, "\p" ); |
theErr = ResError(); |
FAIL_OSERR (theErr, "\pFailed to add the GRID resource to the file") |
gridIsResource = true; |
WriteResource( grid ); |
FAIL_OSERR (theErr, "\pFailed to write the GRID resource to the file") |
theErr = ResError(); |
ReleaseResource( grid ); |
grid = NULL; |
// Build the grid resource; |
goto cleanup; |
error: |
if (theErr == noErr) |
theErr = paramErr; |
cleanup: |
UseResFile (saveResNum); |
if (tilePict != NULL) |
ReleaseResource ((Handle) tilePict); |
if (tileWorld != NULL) |
DisposeGWorld (tileWorld); |
if (gAppColorTable != NULL) |
DisposeCTable (gAppColorTable); |
gAppColorTable = NULL; |
if (tile) |
if (tileIsResource) |
ReleaseResource (tile); |
else |
DisposeHandle (tile); |
if (grid) |
if (gridIsResource) |
ReleaseResource (grid); |
else |
DisposeHandle (grid); |
return theErr; |
} |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-10-14