PDA

View Full Version : Repetitious handle assigning




Mu0n
Jan 23, 2005, 08:49 PM
Platform I'm programming on: System 7.5.5, THINK C 6.
Target platforms: System 1 to MacOS 9.2 (I don't care about anything from 7.0 and up, they just happen to work, without multitasking awareness though, but I couldn't care less. The main target is System 6. Possibly between 6.0.3 and 6.0.8 to take advantage of the extended Time Manager).

I'm trying to use and re-use a handle (a "sprite graphic" handle in my
example) to a struct which contains an offscreen bitmap (handle), among
other things. My functions already allocates memory for the handle
itself and for its internal BitMapHandle.

In my dummy debug program, I'm declaring a global SpriteHandle (called
theBkg, because it'll handle a background graphic to be displayed),
which will be loaded up during runtime, Disposed of, possibly reloaded
again, and so on. I thought the DisposBitMap used on the element of the
struct and DisposHandle used on the handle itself would effectively cut
ties to their corresponding memory blocks, and reset these Handle's
content (the address to these memory areas) to NULL, but checking their
values in debug mode clearly shows that these addresses do not change.

I've tried to do 2 cycles of "Allocate handles, load graphics, delete
handles" and it crashes during the 2nd load graphics step.

Here is a short sample code in C which responds to keyDown events by
allocating/assigning/loading the graphics. The second and subsequent
keyDown events it detects, it first Disposes the Handle, then tries to
reassign/reload it. KeyDown events have to be separated by a keyUp
event in order for my program to react (so that you don't get a bunch
of keyDown events all at once - not sure if it was needed, but here it
is). Following the main function is a couple of functions I'm using
that I provide for reference.

The graphic used is whatever is contained into PICT resource ID=128.

The purpose of being able to do this is that I'll need to add/destroy
sprite elements to an evolving linked list during runtime of a game.

#include "Sprites.h"

SpriteHandle theBkg = NULL;

void main(void)
{
EventRecord wutup;
Boolean released = true;
int count=0;
Str63 theString;

InitMacStuff(); //toolbox init calls, the standard ones
MacPlusArea(black, white); //just sets a window the size of a whole
screen

SetEventMask(everyEvent);
do
{
GetNextEvent(everyEvent, &wutup);
if(wutup.what == keyDown && released == true)
{
released = false;
if(theBkg == NULL)
{
theBkg = CreateSprite(1,false,false);
LoadPictIntoSpriteFrame(theBkg,1,128);
DrawSprite(theBkg,1,srcCopy); //Crash doesn't occur here, so I won't provide the function
}
else
{
DeleteSprite(theBkg);
theBkg = CreateSprite(1,false,false);
LoadPictIntoSpriteFrame(theBkg,1,128);
DrawSprite(theBkg,1,srcCopy);
}
count++;
NumToString(count,theString);
MoveTo(250,250);
DrawString(theString);
}
else if(wutup.what == keyUp) released = true;
}
while(wutup.what != mouseDown);
}


****KEY FUNCTIONS/DEFINITIONS USED****

typedef struct Sprite{
Rect theRect, bufferRect;
int numberFrames, speed;
BitMapHandle buffer;
BitMapHandle frames;
BitMapHandle masks;
} Sprite;

typedef Sprite *SpritePtr, **SpriteHandle;

void DeleteSprite(SpriteHandle theSprite)
{
short loop;
BitMapHandle bh,mh,buffh;
Boolean isMasked,isBuffered;

bh = (**theSprite).frames;
isMasked = IsSpriteMasked(theSprite);
if(isMasked)
{
mh = (**theSprite).masks;
}

for(loop = 0; loop < (**theSprite).numberFrames; loop++)
{
MyDisposePtr( (*bh)[loop].baseAddr);
if(isMasked)
{
MyDisposePtr((*mh)[loop].baseAddr);
}
}
MyDisposeHandle((Handle) (**theSprite).frames);
if(isMasked)
{
MyDisposeHandle((Handle) (**theSprite).masks);
}
isBuffered=IsSpriteCleaning(theSprite);
if(isBuffered)
{
buffh= (**theSprite).buffer;
MyDisposePtr( (**buffh).baseAddr);
MyDisposeHandle((Handle)buffh);
}
MyDisposeHandle((Handle) theSprite);
}


SpriteHandle CreateSprite(int frameAmount, Boolean wantMasks, Boolean
wantBuffer)
{
SpriteHandle theSprite = NULL;
BitMapHandle bh = NULL, mh = NULL, buffh = NULL;
Rect emptyRect = {0,0,0,0};

if(NULL != (theSprite = (SpriteHandle)
NewHandleClear(sizeof(Sprite))) && NULL != (bh = (BitMapHandle)NewHandleClear(sizeof(BitMap)*frameAmount)) && NULL != (mh = (BitMapHandle)NewHandleClear(sizeof(BitMap)*frameAmount)) && NULL != (buffh = (BitMapHandle)NewHandleClear(sizeof(BitMap))) )
{
// all the allocations succeeded
(**theSprite).frames = bh;
(**theSprite).numberFrames = frameAmount;
(**theSprite).theRect = emptyRect;
(**theSprite).bufferRect = emptyRect;
if(wantMasks==false) MyDisposeHandle((Handle)mh);
else (**theSprite).masks = mh;
if(wantBuffer==false) MyDisposeHandle((Handle)buffh);
else (**theSprite).buffer = buffh;
return theSprite;
}

// something failed. clean up
MyDisposeHandle((Handle) bh);
MyDisposeHandle((Handle) mh);
MyDisposeHandle((Handle) buffh);
MyDisposeHandle((Handle) theSprite);

return NULL;
}


void MyDisposeHandle(Handle h)
{
if(NULL != h)
{
DisposeHandle(h);
}
}

void MyDisposePtr(Ptr p)
{
if(NULL != p)
{
DisposePtr(p);
}
}

void MyDisposeBitMap(BitMap *bmp)
{
if(NULL != bmp)
{
MyDisposePtr(bmp->baseAddr);
}
}

void LoadPictIntoSpriteFrame(SpriteHandle theSprite,short theFrame, int
resID)
{
BitMap loadBM, maskBM;
BitMapHandle bh = NULL, mh = NULL;
Boolean isRectEmpty;

loadBM.baseAddr = NULL;
maskBM.baseAddr = NULL;

HLock((Handle)theSprite);
isRectEmpty = EmptyRect(&((**theSprite).theRect));
HUnlock((Handle)theSprite);

if(LoadPicResIntoBitMap(&loadBM, resID))
{
if(isRectEmpty) (**theSprite).theRect = loadBM.bounds;

/* only sets it once--the first time a frame is loaded.
I'll have to assume all other frames will have the exact same
bounds.*/

bh = (**theSprite).frames;
(*bh)[theFrame] = loadBM;
if(IsSpriteMasked(theSprite))
{
mh = (**theSprite).masks;
maskBM.bounds = loadBM.bounds;
if(maskBM.baseAddr == NULL) InitBitMap(&maskBM);
MyCalcMask(&(*bh)[theFrame],&maskBM);
(*mh)[theFrame] = maskBM;
}
}
}



widgetman
Jan 23, 2005, 10:38 PM
um...excuse the un-helpful response, but when you say system 7; do you mean Mac System 7 right? um...why?

Mu0n
Jan 23, 2005, 11:17 PM
um...excuse the un-helpful response, but when you say system 7; do you mean Mac System 7 right? um...why?

Indeed. And why? Why not. I just want to make a small game that can run on a Mac Plus.

widgetman
Jan 24, 2005, 11:52 AM
i completely respect that. i was just curious.