snes9x/macosx/ReClassicfication/FakeHandles.c
2019-11-27 16:08:12 -08:00

270 lines
7.0 KiB
C
Executable File

/* ===========================================================================
PROJECT: FakeHandles
FILE: FakeHandles.c
PURPOSE: Simulate Handles on machines which only have ANSI-C to easily
port some of the more simple Macintosh code fragments to other
platforms.
(C) Copyright 1998 by Uli Kusterer, all rights reserved.
======================================================================== */
#pragma mark [Headers]
// -----------------------------------------------------------------------------
// Headers:
// -----------------------------------------------------------------------------
#include "FakeHandles.h"
// -----------------------------------------------------------------------------
// Globals:
// -----------------------------------------------------------------------------
/* The last entry in the master pointer array is mis-used to hold a pointer
to another master pointer array. Thus, we have a linked list of master
pointer arrays in RAM, and we don't run out of master pointers as easily. */
MasterPointer gMasterPointers[MASTERPOINTER_CHUNK_SIZE];
long gFakeHandleError = noErr;
/* -----------------------------------------------------------------------------
FakeInitHandles:
Call this to initialize the fake memory Manager at the start of your
program. Only call this once or you'll lose all your Handles and will have
stale memory lying around. Pass the global gMasterPointers in
masterPtrArray.
REVISIONS:
98-08-30 UK Created.
----------------------------------------------------------------------------- */
void FakeInitHandles( MasterPointer* masterPtrArray )
{
long x;
for( x = 0; x < MASTERPOINTER_CHUNK_SIZE; x++ )
{
masterPtrArray[x].actualPointer = NULL;
masterPtrArray[x].used = false;
masterPtrArray[x].memoryFlags = 0;
masterPtrArray[x].size = 0;
}
gFakeHandleError = noErr;
}
/* -----------------------------------------------------------------------------
FakeMoreMasters:
Call this if you need more master pointers Called internally by
FakeNewHandle() when it runs out of master pointers.
REVISIONS:
98-08-30 UK Created.
----------------------------------------------------------------------------- */
void FakeMoreMasters()
{
long x;
MasterPointer* vMPtrBlock;
MasterPointer* vCurrBlock;
// Make a new master pointer block:
vMPtrBlock = malloc( MASTERPOINTER_CHUNK_SIZE *sizeof(MasterPointer) );
if( vMPtrBlock == NULL )
{
gFakeHandleError = memFulErr;
return;
}
// Clear it:
for( x = 0; x < MASTERPOINTER_CHUNK_SIZE; x++ )
{
vMPtrBlock[x].actualPointer = NULL;
vMPtrBlock[x].used = false;
vMPtrBlock[x].memoryFlags = 0;
vMPtrBlock[x].size = 0;
}
// Find last master pointer in last master pointer block:
vCurrBlock = gMasterPointers;
while( vCurrBlock[MASTERPOINTER_CHUNK_SIZE -1].used == true )
vCurrBlock = (MasterPointer*) vCurrBlock[MASTERPOINTER_CHUNK_SIZE-1].actualPointer;
// Make this last master pointer point to our new block:
vCurrBlock[MASTERPOINTER_CHUNK_SIZE-1].actualPointer = (char*) vMPtrBlock;
vCurrBlock[MASTERPOINTER_CHUNK_SIZE-1].used = true;
vMPtrBlock[MASTERPOINTER_CHUNK_SIZE-1].size = MASTERPOINTER_CHUNK_SIZE *sizeof(MasterPointer);
gFakeHandleError = noErr;
}
Handle FakeNewEmptyHandle()
{
Handle theHandle = NULL;
long x;
MasterPointer* vCurrBlock = gMasterPointers;
bool notFound = true;
gFakeHandleError = noErr;
while( notFound )
{
for( x = 0; x < (MASTERPOINTER_CHUNK_SIZE-1); x++ )
{
if( !(vCurrBlock[x].used) )
{
vCurrBlock[x].used = true;
vCurrBlock[x].memoryFlags = 0;
vCurrBlock[x].size = 0;
theHandle = (Handle) &(vCurrBlock[x]);
notFound = false;
break;
}
}
if( !vCurrBlock[MASTERPOINTER_CHUNK_SIZE-1].used ) // Last is unused? We need a new master pointer block!
{
FakeMoreMasters();
if( !vCurrBlock[MASTERPOINTER_CHUNK_SIZE-1].used ) // No new block added?!
notFound = false; // Terminate, it's very likely an error occurred.
}
vCurrBlock = (MasterPointer*) vCurrBlock[MASTERPOINTER_CHUNK_SIZE-1].actualPointer; // Go next master pointer block.
}
return theHandle;
}
/* -----------------------------------------------------------------------------
NewHandle:
Create a new Handle. This creates a new entry in the Master Ptr array and
allocates memory of the specified size for it. Then it returns a Ptr to
this entry.
Returns NULL if not successful. If MemError() is noErr upon a NULL return
value, we are out of master pointers.
REVISIONS:
2001-02-16 UK Added support for error codes.
1998-08-30 UK Created.
----------------------------------------------------------------------------- */
Handle FakeNewHandle( long theSize )
{
MasterPointer * theHandle = (MasterPointer*) FakeNewEmptyHandle();
theHandle->actualPointer = malloc( theSize );
if( theHandle->actualPointer == NULL )
{
FakeDisposeHandle( (Handle) theHandle );
gFakeHandleError = memFulErr;
}
else
theHandle->size = theSize;
return (Handle)theHandle;
}
/* -----------------------------------------------------------------------------
DisposeHandle:
Dispose an existing Handle. Only call this once or you might kill valid
memory or worse.
This frees the memory we use and marks the entry for the specified Handle
as unused.
REVISIONS:
1998-08-30 UK Created.
----------------------------------------------------------------------------- */
void FakeDisposeHandle( Handle theHand )
{
MasterPointer* theEntry = (MasterPointer*) theHand;
if( theEntry->actualPointer )
free( theEntry->actualPointer );
theEntry->used = false;
theEntry->actualPointer = NULL;
theEntry->memoryFlags = 0;
theEntry->size = 0;
}
void FakeEmptyHandle( Handle theHand )
{
MasterPointer* theEntry = (MasterPointer*) theHand;
if( theEntry->actualPointer )
free( theEntry->actualPointer );
theEntry->actualPointer = NULL;
}
/* -----------------------------------------------------------------------------
GetHandleSize:
Return the size of an existing Handle. This simply examines the "size"
field of the Handle's entry.
REVISIONS:
1998-08-30 UK Created.
----------------------------------------------------------------------------- */
long FakeGetHandleSize( Handle theHand )
{
MasterPointer* theEntry = (MasterPointer*) theHand;
gFakeHandleError = noErr;
return( theEntry->size );
}
/* -----------------------------------------------------------------------------
SetHandleSize:
Change the size of an existing Handle. This reallocates the Handle (keeping
its data) and updates the size field of the Handle's entry accordingly.
REVISIONS:
1998-08-30 UK Created.
----------------------------------------------------------------------------- */
void FakeSetHandleSize( Handle theHand, long theSize )
{
MasterPointer* theEntry = (MasterPointer*) theHand;
char* thePtr;
thePtr = theEntry->actualPointer;
thePtr = realloc( thePtr, theSize );
if( thePtr )
{
theEntry->actualPointer = thePtr;
theEntry->size = theSize;
gFakeHandleError = noErr;
}
else
gFakeHandleError = memFulErr;
}