Per's removal of the memory heap system. Now MALLOC is just malloc, and not some wrapper around a wrapper that will allocate it from a specific pool.
The MSVC poject will need to be updated I guess, as some files were deleted. git-svn-id: svn+ssh://svn.gna.org/svn/warzone/trunk@1343 4a71c877-e1ca-e34f-864e-861f7616d084master
parent
fe90b5374a
commit
42ed587327
|
@ -10,10 +10,10 @@ BUILT_SOURCES = resource_parser.tab.h strres_parser.tab.h
|
|||
CLEANFILES = resource_parser.tab.h strres_parser.tab.h
|
||||
|
||||
noinst_LIBRARIES = libframework.a
|
||||
noinst_HEADERS = block.h configfile.h cursors.h cursors16.h debug.h font.h fractions.h frame.h \
|
||||
frameint.h frameresource.h heap.h input.h listmacs.h mem.h memint.h resly.h \
|
||||
noinst_HEADERS = configfile.h cursors.h cursors16.h debug.h font.h fractions.h frame.h \
|
||||
frameint.h frameresource.h heap.h input.h listmacs.h mem.h resly.h \
|
||||
strres.h strresly.h treap.h treapint.h trig.h types.h
|
||||
|
||||
libframework_a_SOURCES = SDL_framerate.c block.c configfile.c debug.c exceptionhandler.c frame.c \
|
||||
frameresource.c heap.c input.c mem.c resource_lexer.lex.c resource_parser.tab.c \
|
||||
libframework_a_SOURCES = SDL_framerate.c configfile.c debug.c exceptionhandler.c frame.c \
|
||||
frameresource.c heap.c input.c resource_lexer.lex.c resource_parser.tab.c \
|
||||
strres.c strres_lexer.lex.c strres_parser.tab.c treap.c trig.c
|
||||
|
|
|
@ -1,15 +1,13 @@
|
|||
MAKERULES=../../makerules
|
||||
include $(MAKERULES)/configure.mk
|
||||
|
||||
SRC=block.c \
|
||||
configfile.c \
|
||||
SRC=configfile.c \
|
||||
debug.c \
|
||||
exceptionhandler.c \
|
||||
frame.c \
|
||||
frameresource.c \
|
||||
heap.c \
|
||||
input.c \
|
||||
mem.c \
|
||||
resource_parser.tab.c \
|
||||
resource_lexer.lex.c \
|
||||
strres.c \
|
||||
|
|
|
@ -1,649 +0,0 @@
|
|||
/*
|
||||
This file is part of Warzone 2100.
|
||||
Copyright (C) 1999-2004 Eidos Interactive
|
||||
Copyright (C) 2005-2007 Warzone Resurrection Project
|
||||
|
||||
Warzone 2100 is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Warzone 2100 is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Warzone 2100; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
/*
|
||||
* Block.c
|
||||
*
|
||||
* Routines to allocate memory from one large block.
|
||||
* Any memory allocated is only available to reallocated after
|
||||
* the whole block has been reset.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/* Allow frame header files to be singly included */
|
||||
#define FRAME_LIB_INCLUDE
|
||||
|
||||
// memory usage printf's
|
||||
#define DEBUG_GROUP0
|
||||
|
||||
#include "types.h"
|
||||
#include "debug.h"
|
||||
#include "mem.h"
|
||||
#include "heap.h"
|
||||
#include "treap.h"
|
||||
#include "treapint.h"
|
||||
#include "memint.h"
|
||||
#include "listmacs.h"
|
||||
|
||||
#include "block.h"
|
||||
|
||||
/* What functions to use for the real malloc and free */
|
||||
|
||||
#define RMALLOC malloc
|
||||
#define RFREE free
|
||||
|
||||
|
||||
/* Whether allocated memory is initialised to a value and whether the memory
|
||||
* is trashed before it is freed.
|
||||
* This is done automatically by Visual C's memory routines.
|
||||
*/
|
||||
#define MEMORY_SET TRUE
|
||||
|
||||
// the filename and line number of the last call to the block functions
|
||||
static const char *pCallFileName;
|
||||
static SDWORD callLine;
|
||||
|
||||
// the list of allocated blocks
|
||||
static BLOCK_HEAP *psBlockList=NULL;
|
||||
|
||||
// initialise the block system
|
||||
BOOL blkInitialise(void)
|
||||
{
|
||||
ASSERT( psBlockList==NULL, "blkInitialise: Blocks already initialised" ); // blkShutDown() needs to be called
|
||||
|
||||
LIST_INIT(psBlockList);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// shutdown the block system
|
||||
void blkShutDown(void)
|
||||
{
|
||||
BLOCK_HEAP *psNext;
|
||||
|
||||
if (psBlockList)
|
||||
{
|
||||
debug( LOG_NEVER, "blkShutDown: blocks still allocated:\n" );
|
||||
while (psBlockList)
|
||||
{
|
||||
psNext = psBlockList->psNext;
|
||||
blkDestroy(psBlockList);
|
||||
psBlockList = psNext;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Note the call position for a blkAlloc or blkFree
|
||||
void blkCallPos(const char *pFileName, SDWORD line)
|
||||
{
|
||||
pCallFileName = pFileName;
|
||||
callLine = line;
|
||||
}
|
||||
|
||||
// Create a new block heap
|
||||
BOOL blkCreate(BLOCK_HEAP **ppsHeap, SDWORD init, SDWORD ext)
|
||||
{
|
||||
|
||||
debug( LOG_NEVER, "BLKCREATE CALLED !!!!!!!!!!!!!!!!!!!!!!\n" );
|
||||
*ppsHeap = (BLOCK_HEAP*)RMALLOC(sizeof(BLOCK_HEAP));
|
||||
if (!*ppsHeap)
|
||||
{
|
||||
debug( LOG_ERROR, "blkCreate: Out of memory" );
|
||||
abort();
|
||||
return FALSE;
|
||||
}
|
||||
(*ppsHeap)->psBlocks = (BLOCK_HEAP_MEM*)RMALLOC(sizeof(BLOCK_HEAP_MEM));
|
||||
if (!(*ppsHeap)->psBlocks)
|
||||
{
|
||||
debug( LOG_ERROR, "blkCreate: Out of memory" );
|
||||
abort();
|
||||
return FALSE;
|
||||
}
|
||||
(*ppsHeap)->psBlocks->pMem = (UBYTE*)RMALLOC(init);
|
||||
if (!(*ppsHeap)->psBlocks->pMem)
|
||||
{
|
||||
|
||||
debug( LOG_ERROR, "blkCreate: Out of memory" );
|
||||
abort();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
(*ppsHeap)->init = init;
|
||||
(*ppsHeap)->ext = ext;
|
||||
(*ppsHeap)->psBlocks->size = init;
|
||||
(*ppsHeap)->psBlocks->pFree = (*ppsHeap)->psBlocks->pMem;
|
||||
(*ppsHeap)->psBlocks->psNext = NULL;
|
||||
|
||||
#ifdef DEBUG_MALLOC
|
||||
(*ppsHeap)->pFileName = pCallFileName;
|
||||
(*ppsHeap)->line = callLine;
|
||||
(*ppsHeap)->psMemTreap = NULL;
|
||||
(*ppsHeap)->free = FALSE;
|
||||
(*ppsHeap)->TotalAllocated=0;
|
||||
#endif
|
||||
|
||||
LIST_ADD(psBlockList, *ppsHeap);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Release a block heap
|
||||
void blkDestroy(BLOCK_HEAP *psHeap)
|
||||
{
|
||||
BLOCK_HEAP_MEM *psCurr, *psNext;
|
||||
|
||||
#ifdef DEBUG_MALLOC
|
||||
if (psHeap->psMemTreap != NULL)
|
||||
{
|
||||
debug( LOG_NEVER, "blkDestroy: %s at %d: memory allocated :\n", psHeap->pFileName, psHeap->line );
|
||||
#ifdef REALLY_DEBUG_MALLOC
|
||||
memRecReport(psHeap->psMemTreap);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
LIST_REMOVE(psBlockList, psHeap, BLOCK_HEAP);
|
||||
|
||||
for(psCurr=psHeap->psBlocks; psCurr; psCurr=psNext)
|
||||
{
|
||||
RFREE(psCurr->pMem);
|
||||
psNext = psCurr->psNext;
|
||||
RFREE(psCurr);
|
||||
}
|
||||
RFREE(psHeap);
|
||||
}
|
||||
|
||||
|
||||
#ifdef DEBUG_MALLOC
|
||||
void memMemoryDump(MEM_NODE *Node);
|
||||
#endif
|
||||
|
||||
void blkPrintDetails(BLOCK_HEAP *psHeap)
|
||||
{
|
||||
if (psHeap!=NULL)
|
||||
{
|
||||
#ifdef DEBUG_MALLOC
|
||||
UDWORD Left = (UDWORD)((psHeap->psBlocks->pMem)+(psHeap->psBlocks->size)-(psHeap->psBlocks->pFree));
|
||||
debug( LOG_NEVER, "ptr=%p init=%d ext=%d used=%d (Start=$%p Free=$%p Left=%d)\n", psHeap,psHeap->init, psHeap->ext,psHeap->TotalAllocated, psHeap->psBlocks->pMem, psHeap->psBlocks->pFree, Left );
|
||||
memMemoryDump(psHeap->psMemTreap);
|
||||
#else
|
||||
debug( LOG_NEVER, "ptr=%p init=%d ext=%d\n", psHeap, psHeap->init, psHeap->ext );
|
||||
#endif
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
debug( LOG_NEVER, "NULL POINTER IN BLOCK LIST\n" );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// report on the blocks
|
||||
void blkReport(void)
|
||||
{
|
||||
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
UDWORD BlockNumber=0;
|
||||
BLOCK_HEAP *psCurHeap;
|
||||
|
||||
debug( LOG_NEVER, "\n\nBlock Report. Current Block=%p:\n", memGetBlockHeap() );
|
||||
|
||||
psCurHeap=psBlockList;
|
||||
|
||||
while (psCurHeap)
|
||||
{
|
||||
debug( LOG_NEVER, "Block %d)",BlockNumber++ );
|
||||
blkPrintDetails(psCurHeap);
|
||||
|
||||
psCurHeap = psCurHeap->psNext;
|
||||
}
|
||||
debug( LOG_NEVER, "\n\n" );
|
||||
#endif
|
||||
}
|
||||
|
||||
#if(0) // no longer used - uploaded in small chunks
|
||||
// This is a special free that checks to see if we can free up the memory
|
||||
// We can only do this if it is the last allocated memory in the block
|
||||
//
|
||||
// This can be used for scratch memory ... Critical on the Playstation where memory is so tight
|
||||
//
|
||||
// - e.g. The sound data must be stored as one 400k file. This must be loaded into scratch memory
|
||||
// we clearly do not have 400k of spare memory around.
|
||||
//
|
||||
//
|
||||
// Returns true or false
|
||||
//
|
||||
BOOL blkSpecialFree(BLOCK_HEAP *psHeap, void *Ptr)
|
||||
{
|
||||
BLOCK_HEAP_MEM *psCurr;
|
||||
|
||||
UDWORD RequestedFreeMem=(UDWORD)Ptr;
|
||||
|
||||
for(psCurr = psHeap->psBlocks; psCurr; psCurr = psCurr->psNext)
|
||||
{
|
||||
|
||||
if ((UDWORD)psCurr->pLastAllocated == RequestedFreeMem)
|
||||
{
|
||||
#ifdef DEBUG_MALLOC
|
||||
|
||||
UDWORD BlockSize=((UDWORD)psCurr->pFree)-RequestedFreeMem;
|
||||
debug( LOG_NEVER, "FREED %d block bytes\n", BlockSize ); // del me now !
|
||||
psHeap->TotalAllocated-=BlockSize;
|
||||
#endif
|
||||
|
||||
psCurr->pFree = psCurr->pLastAllocated;
|
||||
psCurr->pLastAllocated=0; // remove pointer so that it cant be allocated again
|
||||
|
||||
|
||||
return(TRUE); // able to return mem
|
||||
}
|
||||
}
|
||||
return(FALSE); // unable to free mem
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
// Allocate some memory from a block heap
|
||||
void *blkAlloc(BLOCK_HEAP *psHeap, SDWORD size)
|
||||
{
|
||||
void *pAlloc;
|
||||
BLOCK_HEAP_MEM *psCurr, *psNew;
|
||||
|
||||
#ifdef DEBUG_MALLOC
|
||||
SDWORD allocSize;
|
||||
MEM_NODE *psNode;
|
||||
#endif
|
||||
|
||||
// Round up to nearest 4 bytes ( 32 bit align ).. Neaded for Playstation.. PD.
|
||||
size = (size + 3) & 0xfffffffc;
|
||||
|
||||
// can't allocate 0 bytes
|
||||
if (size <= 0)
|
||||
{
|
||||
ASSERT( FALSE, "blkAlloc: cannot allocate 0 bytes" );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_MALLOC
|
||||
// see if free has been called for this block
|
||||
if (psHeap->free)
|
||||
{
|
||||
debug( LOG_NEVER, "Block Heap: %s at %d: Alloc after free:\n free %s at %d\n alloc %s at %d\n", psHeap->pFileName, psHeap->line, psHeap->pFreeFile, psHeap->freeLine, pCallFileName, callLine );
|
||||
psHeap->free = FALSE;
|
||||
}
|
||||
|
||||
// increase the size of the block to allow for the treap entry and overwrite blocks
|
||||
allocSize = size;
|
||||
size += sizeof(MEM_NODE) + 2 * SAFETY_ZONE_SIZE;
|
||||
psHeap->TotalAllocated+=allocSize;
|
||||
#endif
|
||||
|
||||
// find a block with a large enough segment free
|
||||
pAlloc = NULL;
|
||||
for(psCurr = psHeap->psBlocks; psCurr; psCurr = psCurr->psNext)
|
||||
{
|
||||
if (psCurr->pFree + size <= psCurr->pMem + psCurr->size)
|
||||
{
|
||||
pAlloc = psCurr->pFree;
|
||||
|
||||
psCurr->pFree += size;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// if there wasn't a block try to allocate a new one
|
||||
if ((psCurr == NULL) && (psHeap->ext != 0))
|
||||
{
|
||||
psNew = (BLOCK_HEAP_MEM*)RMALLOC(sizeof(BLOCK_HEAP_MEM));
|
||||
if (!psNew)
|
||||
{
|
||||
ASSERT( FALSE, "blkAlloc: warning out of memory" );
|
||||
|
||||
// Out of memory
|
||||
return NULL;
|
||||
|
||||
}
|
||||
if (size < psHeap->ext)
|
||||
{
|
||||
psNew->pMem = (UBYTE*)RMALLOC(psHeap->ext);
|
||||
psNew->size = psHeap->ext;
|
||||
}
|
||||
else
|
||||
{
|
||||
psNew->pMem = (UBYTE*)RMALLOC(size);
|
||||
psNew->size = size;
|
||||
}
|
||||
if (!psNew->pMem)
|
||||
{
|
||||
// Out of memory
|
||||
RFREE(psNew);
|
||||
ASSERT( FALSE, "blkAlloc: warning out of memory" );
|
||||
return NULL;
|
||||
}
|
||||
psNew->psNext = NULL;
|
||||
|
||||
psNew->pFree = psNew->pMem + size;
|
||||
pAlloc = psNew->pMem;
|
||||
|
||||
// Add the block to the end of the list
|
||||
for(psCurr=psHeap->psBlocks; psCurr->psNext != NULL; psCurr = psCurr->psNext)
|
||||
;
|
||||
psCurr->psNext = psNew;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_MALLOC
|
||||
if (!pAlloc)
|
||||
{
|
||||
// failed to allocate the memory
|
||||
|
||||
ASSERT( FALSE, "Warning: malloc returning NULL - [%s - %d] %d bytes",pCallFileName,callLine, size );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// add the allocated memory into the treap
|
||||
psNode = (MEM_NODE *)pAlloc;
|
||||
psNode->pFile = pCallFileName;
|
||||
psNode->line = callLine;
|
||||
psNode->size = allocSize;
|
||||
|
||||
/* Store the new entry in the memory treap */
|
||||
psNode->priority = (UDWORD)rand();
|
||||
psNode->key = (void*)psNode;
|
||||
psNode->pObj = psNode;
|
||||
psNode->psLeft = NULL;
|
||||
psNode->psRight = NULL;
|
||||
treapAddNode((TREAP_NODE **)&psHeap->psMemTreap, (TREAP_NODE *)psNode, memBlockCmp);
|
||||
|
||||
/* Now initialise the memory - try to catch unitialised variables */
|
||||
memset((UBYTE *)(psNode) + sizeof(MEM_NODE),
|
||||
SAFETY_ZONE_BYTE, SAFETY_ZONE_SIZE);
|
||||
memset((UBYTE *)(psNode) + sizeof(MEM_NODE) + SAFETY_ZONE_SIZE + allocSize,
|
||||
SAFETY_ZONE_BYTE, SAFETY_ZONE_SIZE);
|
||||
#if MEMORY_SET
|
||||
/* The PC initialises malloc'ed memory already, no need to do it again */
|
||||
memset((UBYTE *)(psNode) + sizeof(MEM_NODE) + SAFETY_ZONE_SIZE,
|
||||
INITIALISE_BYTE, allocSize);
|
||||
#endif
|
||||
|
||||
// offset the return value by the header size
|
||||
pAlloc = ((UBYTE *)(pAlloc) + sizeof(MEM_NODE) + SAFETY_ZONE_SIZE);
|
||||
#endif
|
||||
|
||||
psCurr->pLastAllocated=(UBYTE*)pAlloc;
|
||||
///* - error trapping an out-of-mem allocation !!!
|
||||
|
||||
//NoMemChk:
|
||||
return pAlloc;
|
||||
}
|
||||
//*/
|
||||
|
||||
// return a chunk of memory to the block
|
||||
// this only does anything whith DEBUG_BLOCK defined
|
||||
void blkFree(BLOCK_HEAP *psHeap, void *pMemToFree)
|
||||
{
|
||||
#ifdef DEBUG_MALLOC
|
||||
MEM_NODE sNode, *psDeleted;
|
||||
SDWORD i, InvalidBottom, InvalidTop;
|
||||
UBYTE *pMemBase;
|
||||
#if MEMORY_SET
|
||||
SDWORD Size;
|
||||
#endif
|
||||
|
||||
|
||||
// note the call to free
|
||||
psHeap->free = TRUE;
|
||||
psHeap->pFreeFile = pCallFileName;
|
||||
psHeap->freeLine = callLine;
|
||||
|
||||
// Create a dummy node for the search
|
||||
// This is only looked at by memBlockCmp so only need to set the object and size
|
||||
sNode.pObj = ((UBYTE *)pMemToFree) - sizeof(MEM_NODE) - SAFETY_ZONE_SIZE;
|
||||
sNode.size = 1;
|
||||
|
||||
/* Get the node for the memory block */
|
||||
psDeleted = (MEM_NODE *)treapDelRec((TREAP_NODE **)&psHeap->psMemTreap,
|
||||
(void*)&sNode, memBlockCmp);
|
||||
ASSERT( psDeleted != NULL,
|
||||
"Invalid pointer passed to mem_Free by:\n"
|
||||
"File: %s\nLine: %d\n\n"
|
||||
"Attempt to free already freed pointer?",
|
||||
pCallFileName, callLine );
|
||||
if (psDeleted)
|
||||
{
|
||||
/* The pointer is valid, check the buffer zones */
|
||||
pMemBase = (UBYTE *)(pMemToFree) - SAFETY_ZONE_SIZE;
|
||||
InvalidBottom = InvalidTop = 0;
|
||||
for(i=0; i<SAFETY_ZONE_SIZE; i++)
|
||||
{
|
||||
if (pMemBase[i] != SAFETY_ZONE_BYTE)
|
||||
{
|
||||
InvalidBottom++;
|
||||
}
|
||||
if (pMemBase[i + psDeleted->size + SAFETY_ZONE_SIZE] != SAFETY_ZONE_BYTE)
|
||||
{
|
||||
InvalidTop++;
|
||||
}
|
||||
}
|
||||
// this breaks debug... ***** look into why...
|
||||
// ASSERT( !InvalidBottom && !InvalidTop,
|
||||
// "Safety zone on memory overwritten.\n"
|
||||
// "%d Invalid bytes (of %d) found below memory buffer.\n"
|
||||
// "%d Invalid bytes (of %d) found above memory buffer.\n\n"
|
||||
// "Memory allocated by:\nFile: %s\nLine: %d\n"
|
||||
// "Memory freed by:\nFile: %s\nLine: %d\n",
|
||||
// InvalidBottom, SAFETY_ZONE_SIZE, InvalidTop, SAFETY_ZONE_SIZE,
|
||||
// psDeleted->pFile, psDeleted->line,
|
||||
// pCallFileName, callLine );
|
||||
|
||||
/* Trash the memory before it is freed */
|
||||
#if MEMORY_SET
|
||||
Size = psDeleted->size;
|
||||
memset(pMemToFree, FREE_BYTE, Size);
|
||||
#endif
|
||||
}
|
||||
|
||||
#else
|
||||
// non debug free !
|
||||
// psHeap = psHeap;
|
||||
// pMemToFree = pMemToFree;
|
||||
#endif
|
||||
|
||||
{
|
||||
// BOOL bRes;
|
||||
|
||||
#if(1)
|
||||
|
||||
//DBPRINTF(("UNABLE TO FREE MEMORY\n"));
|
||||
|
||||
|
||||
#else
|
||||
bRes=blkSpecialFree(psHeap, pMemToFree); // Free it up if we can ! - we can only free the last entry
|
||||
#ifdef DEBUG
|
||||
if (bRes==TRUE)
|
||||
{
|
||||
debug( LOG_NEVER, "blkFree called - memory successfully released\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
// debug( LOG_NEVER, "blkFree called - memory NOT released\n" );
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// Reset a block heap
|
||||
void blkReset(BLOCK_HEAP *psHeap)
|
||||
{
|
||||
BLOCK_HEAP_MEM *psCurr;
|
||||
#ifdef DEBUG_GROUP0
|
||||
SDWORD block=0, alloc=0;
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_MALLOC
|
||||
if (psHeap->psMemTreap != NULL)
|
||||
{
|
||||
debug( LOG_NEVER, "blkReset: %s at %d: memory allocated :\n", psHeap->pFileName, psHeap->line );
|
||||
#ifdef REALLY_DEBUG_MALLOC
|
||||
memRecReport(psHeap->psMemTreap);
|
||||
#endif
|
||||
}
|
||||
psHeap->psMemTreap = NULL;
|
||||
psHeap->free = FALSE;
|
||||
|
||||
psHeap->TotalAllocated=0;
|
||||
|
||||
debug( LOG_NEVER, "blkReset: %s at %d: memory usage:\n", psHeap->pFileName, psHeap->line );
|
||||
#else
|
||||
debug( LOG_NEVER, "blkReset: memory usage:\n" );
|
||||
#endif
|
||||
|
||||
psCurr = psHeap->psBlocks;
|
||||
while(psCurr)
|
||||
{
|
||||
#ifdef DEBUG_GROUP0
|
||||
alloc += psCurr->pFree - psCurr->pMem;
|
||||
block += psCurr->size;
|
||||
#endif
|
||||
#if defined(DEBUG_MALLOC) && MEMORY_SET
|
||||
memset(psCurr->pMem, FREE_BYTE, psCurr->size);
|
||||
#endif
|
||||
psCurr->pFree = psCurr->pMem;
|
||||
psCurr = psCurr->psNext;
|
||||
}
|
||||
|
||||
debug( LOG_NEVER, " Blocks allocated %dk, Memory allocated %dk\n", block/1024, alloc/1024 );
|
||||
}
|
||||
|
||||
|
||||
// Find which block a pointer is from if any
|
||||
BLOCK_HEAP *blkFind(void *pPtr)
|
||||
{
|
||||
BLOCK_HEAP *psHeap;
|
||||
BLOCK_HEAP_MEM *psMem;
|
||||
|
||||
for(psHeap=psBlockList; psHeap; psHeap=psHeap->psNext)
|
||||
{
|
||||
for(psMem=psHeap->psBlocks; psMem; psMem=psMem->psNext)
|
||||
{
|
||||
if ((UBYTE *)pPtr >= psMem->pMem &&
|
||||
(UBYTE *)pPtr < psMem->pMem + psMem->size)
|
||||
{
|
||||
return psHeap;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
// check if a pointer is valid in a block
|
||||
BOOL blkPointerValid(BLOCK_HEAP *psHeap, void *pData, SDWORD size)
|
||||
{
|
||||
#ifdef DEBUG_MALLOC
|
||||
MEM_NODE sNode;
|
||||
void *Tmp;
|
||||
|
||||
ASSERT( size, "blkPointerValid: cannot check a pointer with zero size" );
|
||||
|
||||
if (pData == NULL)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Create a dummy node for the search
|
||||
// This is only looked at by memBlockCmp so only need to set the object and size
|
||||
sNode.pObj = ((UBYTE *)pData) - sizeof(MEM_NODE) - SAFETY_ZONE_SIZE;
|
||||
sNode.size = size;
|
||||
|
||||
// See if the block is in the treap
|
||||
Tmp = treapFindRec((TREAP_NODE *)psHeap->psMemTreap, (void*)&sNode, memBlockCmp);
|
||||
if (Tmp != NULL)
|
||||
// if (treapFindRec((TREAP_NODE *)psHeap->psMemTreap, (void*)&sNode, memBlockCmp))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
#else
|
||||
psHeap = psHeap;
|
||||
pData = pData;
|
||||
size = size;
|
||||
|
||||
return TRUE;
|
||||
#endif
|
||||
}
|
||||
|
||||
// check if a pointer is valid in any currently allocated block
|
||||
BOOL blkPointerValidAll(void *pData, SDWORD size)
|
||||
{
|
||||
#ifdef DEBUG_MALLOC
|
||||
BLOCK_HEAP *psCurr;
|
||||
|
||||
for(psCurr=psBlockList; psCurr; psCurr=psCurr->psNext)
|
||||
{
|
||||
if (blkPointerValid(psCurr, pData, size))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
#else
|
||||
pData = pData;
|
||||
size = size;
|
||||
|
||||
return TRUE;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
BLOCK_HEAP *psSuspendedHeap=NULL;
|
||||
|
||||
// suspend the current block ... all allocations pass though to system memory allocation
|
||||
// if a block is already suspended then an assertion will occur.
|
||||
void blockSuspendUsage(void)
|
||||
{
|
||||
ASSERT( psSuspendedHeap==NULL, "a memory block is already suspended" );
|
||||
|
||||
psSuspendedHeap = memGetBlockHeap();
|
||||
memSetBlockHeap(NULL);
|
||||
|
||||
}
|
||||
|
||||
// restore the current block - if there is one
|
||||
void blockUnsuspendUsage(void)
|
||||
{
|
||||
memSetBlockHeap(psSuspendedHeap);
|
||||
psSuspendedHeap=NULL;
|
||||
|
||||
}
|
|
@ -1,160 +0,0 @@
|
|||
/*
|
||||
This file is part of Warzone 2100.
|
||||
Copyright (C) 1999-2004 Eidos Interactive
|
||||
Copyright (C) 2005-2007 Warzone Resurrection Project
|
||||
|
||||
Warzone 2100 is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Warzone 2100 is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Warzone 2100; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
/*! \file block.h
|
||||
* \brief Routines to allocate memory from one large block.
|
||||
*
|
||||
* Any memory allocated is only available to be reallocated after
|
||||
* the whole block has been reset.
|
||||
*/
|
||||
#ifndef _block_h
|
||||
#define _block_h
|
||||
|
||||
#include "mem.h"
|
||||
#include "memint.h"
|
||||
|
||||
/**********************************************************************************/
|
||||
/* type definitions */
|
||||
|
||||
typedef struct _block_heap_mem
|
||||
{
|
||||
SDWORD size; // size of block
|
||||
UBYTE *pFree; // pointer to the start of the free memory section
|
||||
UBYTE *pMem; // pointer to the base of the memory block
|
||||
UBYTE *pLastAllocated; // The start of the last allocated block (so that it can be freed by blkSpecialFree
|
||||
|
||||
struct _block_heap_mem *psNext;
|
||||
} BLOCK_HEAP_MEM;
|
||||
|
||||
typedef struct _block_heap
|
||||
{
|
||||
SDWORD init, ext; // initial and extension block sizes
|
||||
BLOCK_HEAP_MEM *psBlocks;
|
||||
#ifdef DEBUG_MALLOC
|
||||
const char *pFileName;
|
||||
SDWORD line;
|
||||
MEM_NODE *psMemTreap; // treap of the memory blocks
|
||||
BOOL free; // whether free has been called for this block
|
||||
const char *pFreeFile; // where the last free was called from
|
||||
SDWORD freeLine;
|
||||
UDWORD TotalAllocated; // Total amount of bytes used in the block (sum of all alloc's)
|
||||
#endif
|
||||
|
||||
struct _block_heap *psNext;
|
||||
} BLOCK_HEAP;
|
||||
|
||||
|
||||
/**********************************************************************************/
|
||||
/* function prototypes */
|
||||
|
||||
// initialise the block system
|
||||
extern BOOL blkInitialise(void);
|
||||
|
||||
// shutdown the block system
|
||||
extern void blkShutDown(void);
|
||||
|
||||
// Create a new block heap
|
||||
extern BOOL blkCreate(BLOCK_HEAP **ppsHeap, SDWORD init, SDWORD ext);
|
||||
|
||||
// Release a block heap
|
||||
extern void blkDestroy(BLOCK_HEAP *psHeap);
|
||||
|
||||
// Allocate some memory from a block heap
|
||||
extern void *blkAlloc(BLOCK_HEAP *psHeap, SDWORD size);
|
||||
|
||||
// return a chunk of memory to the block
|
||||
// this only does anything whith DEBUG_BLOCK defined
|
||||
extern void blkFree(BLOCK_HEAP *psHeap, void *pMemToFree);
|
||||
|
||||
// Reset a block heap
|
||||
extern void blkReset(BLOCK_HEAP *psHeap);
|
||||
|
||||
// Find which block a pointer is from if any
|
||||
extern BLOCK_HEAP *blkFind(void *pPtr);
|
||||
|
||||
// check if a pointer is valid in a block
|
||||
extern BOOL blkPointerValid(BLOCK_HEAP *psHeap, void *pData, SDWORD size);
|
||||
|
||||
// check if a pointer is valid in any currently allocated block
|
||||
extern BOOL blkPointerValidAll(void *pData, SDWORD size);
|
||||
|
||||
// Note the call position for a blkAlloc or blkFree
|
||||
extern void blkCallPos(const char *pFileName, SDWORD line);
|
||||
|
||||
void blkPrintDetails(BLOCK_HEAP *psHeap);
|
||||
void blkReport(void);
|
||||
BOOL blkSpecialFree(BLOCK_HEAP *psHeap, void *Ptr);
|
||||
void blockSuspendUsage(void);
|
||||
void blockUnsuspendUsage(void);
|
||||
|
||||
|
||||
/**********************************************************************************/
|
||||
/* macro definitions */
|
||||
|
||||
|
||||
#ifdef DEBUG_MALLOC
|
||||
|
||||
#define BLOCK_CREATE(ppsHeap, init, ext) \
|
||||
(blkCallPos(__FILE__, __LINE__), \
|
||||
blkCreate((ppsHeap), (init), (ext)))
|
||||
|
||||
#define BLOCK_DESTROY(psHeap) \
|
||||
blkCallPos(__FILE__, __LINE__); \
|
||||
blkDestroy(psHeap)
|
||||
|
||||
#define BLOCK_ALLOC(psHeap, size) \
|
||||
(blkCallPos(__FILE__, __LINE__), \
|
||||
blkAlloc(psHeap, size))
|
||||
|
||||
#define BLOCK_FREE(psHeap, pMemToFree) \
|
||||
blkCallPos(__FILE__, __LINE__); \
|
||||
blkFree(psHeap, pMemToFree)
|
||||
|
||||
#define BLOCK_RESET(psHeap) \
|
||||
blkCallPos(__FILE__, __LINE__); \
|
||||
blkReset(psHeap)
|
||||
|
||||
#define BLOCK_PTRVALID(psHeap, pData, size) \
|
||||
blkPointerValid(psHeap, pData, size)
|
||||
|
||||
#else
|
||||
|
||||
#define BLOCK_CREATE(ppsHeap, init, ext) \
|
||||
blkCreate((ppsHeap), (init), (ext))
|
||||
|
||||
#define BLOCK_DESTROY(psHeap) \
|
||||
blkDestroy(psHeap)
|
||||
|
||||
#define BLOCK_ALLOC(psHeap, size) \
|
||||
blkAlloc(psHeap, size)
|
||||
|
||||
#define BLOCK_FREE(psHeap, pMemToFree) \
|
||||
blkFree(psHeap, pMemToFree)
|
||||
|
||||
#define BLOCK_RESET(psHeap) \
|
||||
blkReset(psHeap)
|
||||
|
||||
#define BLOCK_PTRVALID(psHeap, pData, size) \
|
||||
(TRUE)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -405,12 +405,6 @@ void frameShutDown(void)
|
|||
|
||||
// Shutdown the resource stuff
|
||||
resShutDown();
|
||||
|
||||
// shutdown the block memory heap
|
||||
blkShutDown();
|
||||
|
||||
/* Shutdown the memory system */
|
||||
memShutDown();
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
|
|
|
@ -34,7 +34,6 @@
|
|||
|
||||
#include "heap.h"
|
||||
#include "treap.h"
|
||||
#include "block.h"
|
||||
|
||||
#include "fractions.h"
|
||||
#include "trig.h"
|
||||
|
|
|
@ -117,12 +117,10 @@ void resSetBaseDir(char *pResDir)
|
|||
|
||||
/* Parse the res file */
|
||||
BOOL resLoad(const char *pResFile, SDWORD blockID,
|
||||
char *pLoadBuffer, SDWORD bufferSize,
|
||||
BLOCK_HEAP *psMemHeap)
|
||||
char *pLoadBuffer, SDWORD bufferSize)
|
||||
{
|
||||
char *pBuffer;
|
||||
UDWORD size;
|
||||
BLOCK_HEAP *psOldHeap;
|
||||
|
||||
strcpy(aCurrResDir, aResDir);
|
||||
|
||||
|
@ -135,19 +133,12 @@ BOOL resLoad(const char *pResFile, SDWORD blockID,
|
|||
|
||||
debug(LOG_WZ, "resLoad: loading %s", pResFile);
|
||||
|
||||
// make sure the WRF doesn't get loaded into a block heap
|
||||
psOldHeap = memGetBlockHeap();
|
||||
memSetBlockHeap(NULL);
|
||||
|
||||
// Load the RES file; allocate memory for a wrf, and load it
|
||||
if (!loadFile(pResFile, &pBuffer, &size)) {
|
||||
debug(LOG_ERROR, "resLoad: failed to load %s", pResFile);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// now set the memory system to use the block heap
|
||||
memSetBlockHeap(psMemHeap);
|
||||
|
||||
// and parse it
|
||||
resSetInputBuffer(pBuffer, size);
|
||||
if (res_parse() != 0) {
|
||||
|
@ -155,9 +146,6 @@ BOOL resLoad(const char *pResFile, SDWORD blockID,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
// reset the memory system
|
||||
memSetBlockHeap(psOldHeap);
|
||||
|
||||
FREE(pBuffer);
|
||||
|
||||
return TRUE;
|
||||
|
@ -357,16 +345,12 @@ static BOOL RetreiveResourceFile(char *ResourceName, RESOURCEFILE **NewResource)
|
|||
return(TRUE);
|
||||
}
|
||||
|
||||
blockSuspendUsage();
|
||||
|
||||
// This is needed for files that do not fit in the WDG cache ... (VAB file for example)
|
||||
if (!loadFile(ResourceName, &pBuffer, &size))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
blockUnsuspendUsage();
|
||||
|
||||
ResData->type=RESFILETYPE_LOADED;
|
||||
ResData->size=size;
|
||||
ResData->pBuffer=pBuffer;
|
||||
|
|
|
@ -97,8 +97,7 @@ extern void resSetBaseDir(char *pResDir);
|
|||
/* Parse the res file */
|
||||
struct _block_heap;
|
||||
BOOL resLoad(const char *pResFile, SDWORD blockID,
|
||||
char *pLoadBuffer, SDWORD bufferSize,
|
||||
struct _block_heap *psMemHeap);
|
||||
char *pLoadBuffer, SDWORD bufferSize);
|
||||
|
||||
/* Release all the resources currently loaded and the resource load functions */
|
||||
extern void resReleaseAll(void);
|
||||
|
|
|
@ -37,7 +37,6 @@
|
|||
#include "heap.h"
|
||||
#include "treap.h"
|
||||
#include "treapint.h"
|
||||
#include "block.h"
|
||||
|
||||
// Control whether a heap usage report is printed out when a heap is destroyed
|
||||
#define HEAP_USAGE_REPORT FALSE
|
||||
|
@ -185,7 +184,6 @@ BOOL heapCreate(OBJ_HEAP **ppsHeap, UDWORD size, UDWORD init, UDWORD ext)
|
|||
(*ppsHeap)->initAlloc = init;
|
||||
(*ppsHeap)->extAlloc = ext;
|
||||
(*ppsHeap)->psExt = NULL;
|
||||
(*ppsHeap)->psBlkHeap = memGetBlockHeap();
|
||||
#if DEBUG_HEAP
|
||||
(*ppsHeap)->maxUsage = 0;
|
||||
(*ppsHeap)->currUsage = 0;
|
||||
|
@ -251,7 +249,6 @@ BOOL heapAlloc(OBJ_HEAP *psHeap, void **ppObject)
|
|||
UDWORD i;
|
||||
FREE_OBJECT *psCurr = NULL;
|
||||
UBYTE *pBase;
|
||||
BLOCK_HEAP *psCurrBlk;
|
||||
#if DEBUG_HEAP
|
||||
HEAP_OBJHDR *psHdr;
|
||||
FREE_OBJECT *psFree;
|
||||
|
@ -273,10 +270,6 @@ BOOL heapAlloc(OBJ_HEAP *psHeap, void **ppObject)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
/* No objects left - need to add a heap extension */
|
||||
psCurrBlk = memGetBlockHeap();
|
||||
memSetBlockHeap(psHeap->psBlkHeap);
|
||||
|
||||
#ifdef REALLY_DEBUG_HEAP
|
||||
debug(LOG_MEMORY, "heapAlloc: Heap %s, line %d extended. Max use: %d\n", psHeap->pFile, psHeap->line, psHeap->maxUsage);
|
||||
#endif
|
||||
|
@ -296,7 +289,6 @@ BOOL heapAlloc(OBJ_HEAP *psHeap, void **ppObject)
|
|||
FREE(psNew);
|
||||
return FALSE;
|
||||
}
|
||||
memSetBlockHeap(psCurrBlk);
|
||||
|
||||
#if DEBUG_HEAP
|
||||
/* Initialise the memory to check for overwrites */
|
||||
|
|
|
@ -63,8 +63,6 @@ typedef struct _obj_heap
|
|||
UDWORD initAlloc; // The initial number of objects allocated
|
||||
UDWORD extAlloc; // The number of objects to allocate after the initial
|
||||
// allocation is used up
|
||||
struct _block_heap *psBlkHeap; // which block heap (if any) this object heap was allocated from
|
||||
|
||||
FREE_OBJECT *psFree; // The currently free objects
|
||||
|
||||
UBYTE *pMemory; // The main memory heap
|
||||
|
|
|
@ -1,529 +0,0 @@
|
|||
/*
|
||||
This file is part of Warzone 2100.
|
||||
Copyright (C) 1999-2004 Eidos Interactive
|
||||
Copyright (C) 2005-2007 Warzone Resurrection Project
|
||||
|
||||
Warzone 2100 is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Warzone 2100 is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Warzone 2100; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
/*
|
||||
* mem.c
|
||||
*
|
||||
* Replacements for malloc and free to track memory usage.
|
||||
*
|
||||
* Also allows pointer validity checking.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
/* Allow frame header files to be singly included */
|
||||
#define FRAME_LIB_INCLUDE
|
||||
|
||||
#include "types.h"
|
||||
#include "debug.h"
|
||||
#include "mem.h"
|
||||
#include "heap.h"
|
||||
#include "treap.h"
|
||||
#include "treapint.h"
|
||||
#include "memint.h"
|
||||
#include "block.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
/* Whether allocated memory is initialised to a value and whether the memory
|
||||
* is trashed before it is freed.
|
||||
* This is done automatically by Visual C's memory routines.
|
||||
*/
|
||||
// No piece of code should ever depend upon memory being initialized (RAII: Resource Acquisition Is Initialization)
|
||||
// Therefore I humbly comment this line out, which might very well result in
|
||||
// buggy code becoming even buggier (just search this file for the next
|
||||
// instance of MEMORY_SET). -- Giel
|
||||
//#define MEMORY_SET TRUE
|
||||
|
||||
/* Number of bytes after which memory amounts are displayed in Kb */
|
||||
#define SHOW_KB_LIMIT (0x400)
|
||||
|
||||
/* What functions to use for the real malloc and free */
|
||||
|
||||
#define RMALLOC malloc
|
||||
#define RFREE free
|
||||
|
||||
|
||||
/* The root of the memory treap */
|
||||
static MEM_NODE *psMemRoot = NULL;
|
||||
|
||||
/* The current block heap to use instead of MALLOC */
|
||||
static BLOCK_HEAP *psCurrBlockHeap;
|
||||
|
||||
/* Initialise the memory system */
|
||||
BOOL memInitialise(void)
|
||||
{
|
||||
if (psMemRoot != NULL)
|
||||
{
|
||||
debug(LOG_MEMORY, "memInitialise: *** WARNING *** : memory still allocated??");
|
||||
}
|
||||
psMemRoot = NULL;
|
||||
|
||||
psCurrBlockHeap = NULL;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/* Release the memory treap */
|
||||
static void memTreapDestroy(TREAP_NODE *psRoot)
|
||||
{
|
||||
if (psRoot)
|
||||
{
|
||||
// Destroy the sub trees
|
||||
memTreapDestroy(psRoot->psLeft);
|
||||
memTreapDestroy(psRoot->psRight);
|
||||
|
||||
// Free the root
|
||||
RFREE(psRoot);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Shutdown the memory system */
|
||||
void memShutDown(void)
|
||||
{
|
||||
// Report any memory still allocated
|
||||
#ifdef REALLY_DEBUG_MALLOC
|
||||
memMemoryReport();
|
||||
#endif
|
||||
|
||||
// Free up the allocated memory
|
||||
memTreapDestroy((TREAP_NODE *)psMemRoot);
|
||||
}
|
||||
|
||||
|
||||
/* Set a block heap to use for all memory allocation rather than standard malloc/free */
|
||||
void memSetBlockHeap(BLOCK_HEAP *psHeap)
|
||||
{
|
||||
|
||||
psCurrBlockHeap = psHeap;
|
||||
}
|
||||
|
||||
|
||||
/* Get the current block heap */
|
||||
BLOCK_HEAP *memGetBlockHeap(void)
|
||||
{
|
||||
return psCurrBlockHeap;
|
||||
}
|
||||
|
||||
|
||||
/* compare two memory blocks
|
||||
* NOTE: key1 is always the block passed into the treap code
|
||||
* and therefore not necessarily to be trusted
|
||||
*/
|
||||
SDWORD memBlockCmp(void *key1, void *key2)
|
||||
{
|
||||
UBYTE *start1, *start2, *end1, *end2;
|
||||
|
||||
// Calculate the edges of the memory blocks
|
||||
start1 = (UBYTE *)((char *)(((MEM_NODE *)key1)->pObj) + sizeof(MEM_NODE) + SAFETY_ZONE_SIZE);
|
||||
start2 = (UBYTE *)((char *)(((MEM_NODE *)key2)->pObj) + sizeof(MEM_NODE) + SAFETY_ZONE_SIZE);
|
||||
end1 = start1 + ((MEM_NODE *)key1)->size;
|
||||
end2 = start2 + ((MEM_NODE *)key2)->size;
|
||||
|
||||
// see if one block is inside another
|
||||
if ((start1 >= start2 && end1 <= end2))// || // block 1 inside block 2
|
||||
// (start2 >= start1 && end2 <= end1)) // block 2 inside block 1
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else if (start1 < start2)
|
||||
{
|
||||
// less than
|
||||
return -1;
|
||||
}
|
||||
|
||||
// greater than
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_MALLOC
|
||||
|
||||
/* Replacement for malloc that records where the memory was requested.
|
||||
* All allocated memory is initialised to INITIALISE_BYTE
|
||||
* A buffer is also allocated at the top and bottom of the memory to check for
|
||||
* overwrites.
|
||||
*/
|
||||
void *memMalloc(const char *pFileName, SDWORD LineNumber, size_t Size)
|
||||
{
|
||||
void *pMemBase;
|
||||
MEM_NODE *psNode;
|
||||
|
||||
ASSERT( (pFileName != NULL), "No filename passed to mem_Malloc" );
|
||||
ASSERT( Size != 0, "Cannot allocate 0 bytes of memory." );
|
||||
|
||||
if (psCurrBlockHeap != NULL)
|
||||
{
|
||||
// use a block heap rather than normal malloc
|
||||
blkCallPos(pFileName, LineNumber);
|
||||
return blkAlloc(psCurrBlockHeap, Size);
|
||||
}
|
||||
|
||||
pMemBase = RMALLOC( Size + sizeof(MEM_NODE) + 2 * SAFETY_ZONE_SIZE );
|
||||
if (!pMemBase)
|
||||
{
|
||||
|
||||
|
||||
ASSERT( FALSE, "Warning: malloc returning NULL - [%s - %d]",pFileName,LineNumber );
|
||||
debug( LOG_NEVER, "[%s - %d] %zu bytes\n", pFileName, LineNumber, Size );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Got the main bit of memory - set up the node entry */
|
||||
// This part of code adds information about which file requested
|
||||
// on what line what amount of memory.
|
||||
psNode = (MEM_NODE *)pMemBase;
|
||||
psNode->pFile = (char *)RMALLOC( strlen(pFileName)+1 );
|
||||
if (!psNode->pFile)
|
||||
{
|
||||
RFREE(pMemBase);
|
||||
debug( LOG_NEVER, "Warning: malloc returning NULL" );
|
||||
return NULL;
|
||||
}
|
||||
strcpy((char *)psNode->pFile, pFileName);
|
||||
psNode->line = LineNumber;
|
||||
psNode->size = Size;
|
||||
|
||||
/* Store the new entry in the memory treap */
|
||||
psNode->priority = (UDWORD)rand();
|
||||
psNode->key = (void*)psNode;
|
||||
psNode->pObj = psNode;
|
||||
psNode->psLeft = NULL;
|
||||
psNode->psRight = NULL;
|
||||
treapAddNode((TREAP_NODE **)&psMemRoot, (TREAP_NODE *)psNode, memBlockCmp);
|
||||
|
||||
/* Now initialise the memory - try to catch unitialised variables */
|
||||
// Fill up the safety zone left of (or before) and right of (or after)
|
||||
// the requested memory page, with SAFETY_ZONE_BYTE to be able to
|
||||
// catch writing out of bounds.
|
||||
memset((UBYTE *)(pMemBase) + sizeof(MEM_NODE), // Left or before the requested memchunk
|
||||
SAFETY_ZONE_BYTE, SAFETY_ZONE_SIZE);
|
||||
memset((UBYTE *)(pMemBase) + sizeof(MEM_NODE) + SAFETY_ZONE_SIZE + Size, // Right or after chunck
|
||||
SAFETY_ZONE_BYTE, SAFETY_ZONE_SIZE);
|
||||
#ifdef MEMORY_SET
|
||||
// Initialize memory before returning its address (WRONG!!! The code that requests mem should ensure initialization)
|
||||
memset((UBYTE *)(pMemBase) + sizeof(MEM_NODE) + SAFETY_ZONE_SIZE,
|
||||
INITIALISE_BYTE, Size);
|
||||
#endif
|
||||
|
||||
return ((UBYTE *)(pMemBase) + sizeof(MEM_NODE) + SAFETY_ZONE_SIZE);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef DEBUG_MALLOC
|
||||
|
||||
/* Replacement for malloc for release builds. */
|
||||
void *memMallocRelease(size_t Size)
|
||||
{
|
||||
if (psCurrBlockHeap != NULL)
|
||||
{
|
||||
// use a block heap rather than normal malloc
|
||||
return blkAlloc(psCurrBlockHeap, Size);
|
||||
}
|
||||
|
||||
return RMALLOC(Size);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_MALLOC
|
||||
|
||||
/* Replacement for free
|
||||
*
|
||||
* Checks whether the pointer is valid before freeing it.
|
||||
* If the pointer is invalid, it asserts.
|
||||
* The buffer zones around the allocated memory are also checked for
|
||||
* overwrites.
|
||||
* All memory is reset to FREE_BYTE before freeing to avoid using
|
||||
* freed memory.
|
||||
*/
|
||||
void memFree(const char *pFileName, SDWORD LineNumber, void *pMemToFree)
|
||||
{
|
||||
MEM_NODE sNode, *psDeleted;
|
||||
UWORD i, InvalidBottom, InvalidTop;
|
||||
UBYTE *pMemBase;
|
||||
BLOCK_HEAP *psBlock;
|
||||
|
||||
|
||||
ASSERT( (pFileName != NULL), "No filename passed to memFree" );
|
||||
ASSERT( (pMemToFree != NULL), "Attempt to free NULL pointer, called by:\n"
|
||||
"File: %s\nLine: %d\n", pFileName, LineNumber );
|
||||
|
||||
if (pMemToFree == NULL) return;
|
||||
|
||||
// see if the pointer was allocated in a block
|
||||
psBlock = blkFind(pMemToFree);
|
||||
if (psBlock != NULL)
|
||||
{
|
||||
// use a block heap rather than normal free
|
||||
blkCallPos(pFileName, LineNumber);
|
||||
blkFree(psBlock, pMemToFree);
|
||||
return;
|
||||
}
|
||||
|
||||
// Create a dummy node for the search
|
||||
// This is only looked at by memBlockCmp so only need to set the object and size
|
||||
sNode.pObj = ((UBYTE *)pMemToFree) - sizeof(MEM_NODE) - SAFETY_ZONE_SIZE;
|
||||
sNode.size = 1;
|
||||
|
||||
/* Get the node for the memory block */
|
||||
psDeleted = (MEM_NODE *)treapDelRec((TREAP_NODE **)&psMemRoot,
|
||||
(void*)&sNode, memBlockCmp);
|
||||
|
||||
|
||||
ASSERT( psDeleted != NULL,
|
||||
"Invalid pointer passed to memFree by:\n"
|
||||
"File: %s\nLine: %d\n\n"
|
||||
"Attempt to free already freed pointer?",
|
||||
pFileName, LineNumber );
|
||||
if (psDeleted)
|
||||
{
|
||||
/* The pointer is valid, check the buffer zones */
|
||||
pMemBase = (UBYTE *)(pMemToFree) - SAFETY_ZONE_SIZE;
|
||||
InvalidBottom = InvalidTop = 0;
|
||||
|
||||
// Check wether out of bound writes have occured since memMalloc()
|
||||
for(i=0; i<SAFETY_ZONE_SIZE; i++)
|
||||
{
|
||||
if (pMemBase[i] != SAFETY_ZONE_BYTE)
|
||||
{
|
||||
InvalidBottom++;
|
||||
}
|
||||
if (pMemBase[i + psDeleted->size + SAFETY_ZONE_SIZE] != SAFETY_ZONE_BYTE)
|
||||
{
|
||||
InvalidTop++;
|
||||
}
|
||||
}
|
||||
|
||||
ASSERT( !InvalidBottom && !InvalidTop,
|
||||
"Safety zone on memory overwritten.\n"
|
||||
"%d Invalid bytes (of %d) found below memory buffer.\n"
|
||||
"%d Invalid bytes (of %d) found above memory buffer.\n\n"
|
||||
"Memory allocated by:\nFile: %s\nLine: %d\n"
|
||||
"Memory freed by:\nFile: %s\nLine: %d\n",
|
||||
InvalidBottom, SAFETY_ZONE_SIZE, InvalidTop, SAFETY_ZONE_SIZE,
|
||||
psDeleted->pFile, psDeleted->line,
|
||||
pFileName, LineNumber );
|
||||
|
||||
/* Now free the memory */
|
||||
|
||||
RFREE((char *)psDeleted->pFile);
|
||||
RFREE(psDeleted);
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef DEBUG_MALLOC
|
||||
|
||||
/* Replacement for Free for release builds */
|
||||
void memFreeRelease(void *pMemToFree)
|
||||
{
|
||||
// see if the pointer was allocated in a block
|
||||
BLOCK_HEAP* psBlock = blkFind(pMemToFree);
|
||||
if (psBlock != NULL)
|
||||
{
|
||||
// use a block heap rather than normal free
|
||||
blkFree(psBlock, pMemToFree);
|
||||
return;
|
||||
}
|
||||
|
||||
RFREE(pMemToFree);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* Checks whether the memory buffer pointed to by pPtr of size Size
|
||||
* is contained in any of the memory blocks allocated.
|
||||
*/
|
||||
BOOL memPointerValid(void *pPtr, size_t size)
|
||||
{
|
||||
MEM_NODE sNode;
|
||||
|
||||
ASSERT( size, "memPointerValid: cannot check a pointer with zero size" );
|
||||
|
||||
if (pPtr == NULL)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Create a dummy node for the search
|
||||
// This is only looked at by memBlockCmp so only need to set the object and size
|
||||
sNode.pObj = ((UBYTE *)pPtr) - sizeof(MEM_NODE) - SAFETY_ZONE_SIZE;
|
||||
sNode.size = size;
|
||||
|
||||
// See if the block is in the treap
|
||||
if (treapFindRec((TREAP_NODE *)psMemRoot, (void*)&sNode, memBlockCmp))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// check the block heaps as well (if the code is there)
|
||||
#ifdef DEBUG_MALLOC
|
||||
return blkPointerValidAll(pPtr, size);
|
||||
#else
|
||||
return FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#ifdef REALLY_DEBUG_MALLOC
|
||||
/* Recursive function to print out the list of memory blocks */
|
||||
SDWORD memRecReport(MEM_NODE *psRoot)
|
||||
{
|
||||
if (psRoot)
|
||||
{
|
||||
if (psRoot->size < SHOW_KB_LIMIT)
|
||||
{
|
||||
debug(LOG_MEMORY, "memRecReport for %s line %d: \t%d bytes",
|
||||
psRoot->pFile, psRoot->line, psRoot->size);
|
||||
}
|
||||
else
|
||||
{
|
||||
debug(LOG_MEMORY, "memRecReport for %s line %d: \t%d kilobytes",
|
||||
psRoot->pFile, psRoot->line, (int) psRoot->size / 1024);
|
||||
}
|
||||
|
||||
return memRecReport((MEM_NODE *)psRoot->psLeft) +
|
||||
memRecReport((MEM_NODE *)psRoot->psRight) +
|
||||
psRoot->size;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_MALLOC
|
||||
#define MAXMODULES (32)
|
||||
typedef struct
|
||||
{
|
||||
char pFile[128];
|
||||
int Count;
|
||||
int Total;
|
||||
} MEMMOD;
|
||||
static MEMMOD MemModuleInfo[MAXMODULES];
|
||||
|
||||
static UDWORD MemTotalEntries;
|
||||
static UDWORD MemTotalModules;
|
||||
static UDWORD MemTotalAllocated;
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_MALLOC
|
||||
/* Recursive function to total up the amount of mem allocated */
|
||||
static void memSummary(MEM_NODE *psRoot)
|
||||
{
|
||||
|
||||
// bsort
|
||||
if (psRoot)
|
||||
{
|
||||
int i;
|
||||
BOOL FoundModule;
|
||||
|
||||
MemTotalEntries++;
|
||||
MemTotalAllocated+=psRoot->size;
|
||||
|
||||
FoundModule=FALSE;
|
||||
for (i=0;i<(SDWORD)MemTotalModules;i++)
|
||||
{
|
||||
if (strcmp(psRoot->pFile,MemModuleInfo[i].pFile)==0)
|
||||
{
|
||||
MemModuleInfo[i].Count++;
|
||||
MemModuleInfo[i].Total+=psRoot->size;
|
||||
FoundModule=TRUE;
|
||||
}
|
||||
}
|
||||
if (FoundModule==FALSE)
|
||||
{
|
||||
if (MemTotalModules <MAXMODULES)
|
||||
{
|
||||
strcpy(MemModuleInfo[MemTotalModules].pFile,psRoot->pFile);
|
||||
MemModuleInfo[MemTotalModules].Count=1;
|
||||
MemModuleInfo[MemTotalModules].Total=psRoot->size;
|
||||
MemTotalModules++;
|
||||
}
|
||||
}
|
||||
|
||||
memSummary((MEM_NODE *)psRoot->psLeft);
|
||||
memSummary((MEM_NODE *)psRoot->psRight);
|
||||
}
|
||||
return ;
|
||||
}
|
||||
#endif
|
||||
|
||||
void memMemoryDump(MEM_NODE *Node)
|
||||
{
|
||||
#ifdef DEBUG_MALLOC
|
||||
int i;
|
||||
|
||||
MemTotalEntries=0;
|
||||
MemTotalModules=0;
|
||||
MemTotalAllocated=0;
|
||||
memSummary(Node);
|
||||
|
||||
debug(LOG_MEMORY, "Memory Summary: %d bytes allocated in %d handy size chunks", MemTotalAllocated, MemTotalEntries);
|
||||
for (i=0;i<(SDWORD)MemTotalModules;i++)
|
||||
{
|
||||
debug(LOG_MEMORY, "memMemoryDump: %d) [%s] %d allocations totalling %d bytes",
|
||||
i, MemModuleInfo[i].pFile, MemModuleInfo[i].Count, MemModuleInfo[i].Total);
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#ifdef REALLY_DEBUG_MALLOC
|
||||
/* Report on currently allocated memory.
|
||||
*/
|
||||
void memMemoryReport(void)
|
||||
{
|
||||
SDWORD TotMem;
|
||||
|
||||
if (!psMemRoot)
|
||||
{
|
||||
debug(LOG_MEMORY, "memMemoryReport: No memory allocated");
|
||||
}
|
||||
else
|
||||
{
|
||||
TotMem = memRecReport(psMemRoot);
|
||||
|
||||
if (TotMem < SHOW_KB_LIMIT)
|
||||
{
|
||||
debug(LOG_MEMORY, "memMemoryReport: Total memory allocated is %d bytes", TotMem);
|
||||
}
|
||||
else
|
||||
{
|
||||
debug(LOG_MEMORY, "memMemoryReport: Total memory allocated is %d kilobytes", (int) TotMem / 1024);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Display the memory treap */
|
||||
void memDisplayTreap(void)
|
||||
{
|
||||
#ifdef DEBUG_MALLOC
|
||||
debug(LOG_MEMORY, "Memory Allocation Treap:");
|
||||
treapDisplayRec((TREAP_NODE *)psMemRoot, 0);
|
||||
#endif
|
||||
}
|
|
@ -25,82 +25,9 @@
|
|||
#define _mem_h
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "types.h"
|
||||
#include "debug.h"
|
||||
|
||||
/* DEBUG_MALLOC == TRUE uses debugging malloc and free
|
||||
DEBUG_MALLOC == FALSE uses normal malloc and free */
|
||||
#ifdef DEBUG
|
||||
|
||||
#define DEBUG_MALLOC TRUE
|
||||
#define DEBUG_HEAP TRUE
|
||||
/* Uncomment below for even more debug spam */
|
||||
#undef REALLY_DEBUG_HEAP
|
||||
#undef REALLY_DEBUG_MALLOC
|
||||
|
||||
#else
|
||||
|
||||
#undef DEBUG_MALLOC
|
||||
#undef DEBUG_HEAP
|
||||
#define MALLOC(size) malloc(size)
|
||||
#define FREE(ptr) do { free(ptr); ptr = NULL; } while(0)
|
||||
#define PTRVALID(ptr, size) (ptr != NULL)
|
||||
|
||||
#endif
|
||||
|
||||
/* Function Prototypes */
|
||||
|
||||
/* Initialise the memory system */
|
||||
BOOL memInitialise(void);
|
||||
/* Shutdown the memory system */
|
||||
void memShutDown(void);
|
||||
|
||||
/* Set a block heap to use for all memory allocation rather than standard malloc/free */
|
||||
struct _block_heap;
|
||||
void memSetBlockHeap(struct _block_heap *psHeap);
|
||||
/* Get the current block heap */
|
||||
struct _block_heap *memGetBlockHeap(void);
|
||||
|
||||
/* malloc and free replacements */
|
||||
#ifdef DEBUG_MALLOC
|
||||
void *memMalloc(const char *pFileName, SDWORD LineNumber, size_t Size);
|
||||
void memFree(const char *pFileName, SDWORD LineNumber, void *pMemToFree);
|
||||
|
||||
#define MALLOC(size) memMalloc(__FILE__, __LINE__, size)
|
||||
#define FREE(ptr) do { memFree(__FILE__, __LINE__, ptr); ptr = NULL; } while(0)
|
||||
|
||||
#else // !DEBUG_MALLOC
|
||||
void *memMallocRelease(size_t Size);
|
||||
void memFreeRelease(void *pMemToFree);
|
||||
|
||||
#define MALLOC(size) memMallocRelease(size)
|
||||
#define FREE(ptr) do { memFreeRelease(ptr); ptr = NULL; } while(0)
|
||||
|
||||
#endif // DEBUG_MALLOC
|
||||
|
||||
/* Check a pointer refers to a valid block of memory */
|
||||
BOOL memPointerValid(void *pPtr, size_t Size);
|
||||
|
||||
#ifdef REALLY_DEBUG_MALLOC
|
||||
/* Report on currently allocated memory */
|
||||
void memMemoryReport(void);
|
||||
|
||||
/* Recursive function to print out the list of memory blocks */
|
||||
extern SDWORD memRecReport(MEM_NODE *psRoot);
|
||||
#endif
|
||||
/* Display the memory treap */
|
||||
void memDisplayTreap(void);
|
||||
|
||||
#ifdef DEBUG_MALLOC
|
||||
|
||||
|
||||
#ifndef NO_PTRVALID
|
||||
#define PTRVALID(ptr, size) memPointerValid(ptr, size)
|
||||
#else
|
||||
#define PTRVALID(ptr, size) (((ptr)==NULL)?FALSE:TRUE)
|
||||
#endif
|
||||
|
||||
#else // !DEBUG_MALLOC
|
||||
|
||||
#define PTRVALID(ptr, size) (TRUE)
|
||||
|
||||
#endif // DEBUG_MALLOC
|
||||
|
||||
#endif // _mem_h_
|
||||
|
|
|
@ -1,49 +0,0 @@
|
|||
/*
|
||||
This file is part of Warzone 2100.
|
||||
Copyright (C) 1999-2004 Eidos Interactive
|
||||
Copyright (C) 2005-2007 Warzone Resurrection Project
|
||||
|
||||
Warzone 2100 is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Warzone 2100 is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Warzone 2100; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
/*! \file memint.h
|
||||
* \brief Internal framework definitions for the memory system.
|
||||
*/
|
||||
#ifndef _memint_h
|
||||
#define _memint_h
|
||||
|
||||
/* The size of saftey buffer to leave before and after any malloc'ed memory.
|
||||
Can use this to check writing over end of buffers */
|
||||
|
||||
#define SAFETY_ZONE_SIZE (32)
|
||||
|
||||
|
||||
/* The character used to initialise malloc'ed memory, or to trash memory before
|
||||
freeing it */
|
||||
#define SAFETY_ZONE_BYTE (0xac)
|
||||
#define INITIALISE_BYTE (0xcd)
|
||||
#define FREE_BYTE (0xdd)
|
||||
|
||||
// memory block header for the treap code
|
||||
typedef struct _mem_node
|
||||
{
|
||||
TREAP_NODE_BASE; // The treap data to store the node
|
||||
TREAP_NODE_DEBUG; // The debug info for the node (file, line).
|
||||
UDWORD size; // The memory block size
|
||||
} MEM_NODE;
|
||||
|
||||
/* compare two memory blocks */
|
||||
extern SDWORD memBlockCmp(void *key1, void *key2);
|
||||
#endif
|
||||
|
|
@ -130,10 +130,10 @@ animObj_HashFreeElementFunc( void * psElement )
|
|||
{
|
||||
#ifdef DEBUG
|
||||
ANIM_OBJECT *psObj = (ANIM_OBJECT *) psElement;
|
||||
#endif
|
||||
|
||||
ASSERT( PTRVALID(psObj, sizeof(ANIM_OBJECT)),
|
||||
"animObj_HashFreeElementFunc: object pointer invalid\n" );
|
||||
#endif
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
|
|
@ -60,9 +60,6 @@ static STACK_CHUNK *psCurrChunk=NULL;
|
|||
/* The current free entry on the current stack chunk */
|
||||
static UDWORD currEntry=0;
|
||||
|
||||
/* The block heap the stack was created in */
|
||||
static BLOCK_HEAP *psStackBlock;
|
||||
|
||||
/* Get rid of the top value without returning it */
|
||||
static inline BOOL stackRemoveTop(void);
|
||||
|
||||
|
@ -77,8 +74,6 @@ BOOL stackEmpty(void)
|
|||
/* Allocate a new chunk for the stack */
|
||||
static BOOL stackNewChunk(UDWORD size)
|
||||
{
|
||||
BLOCK_HEAP *psHeap;
|
||||
|
||||
/* see if a chunk has already been allocated */
|
||||
if (psCurrChunk->psNext != NULL)
|
||||
{
|
||||
|
@ -87,9 +82,6 @@ static BOOL stackNewChunk(UDWORD size)
|
|||
}
|
||||
else
|
||||
{
|
||||
psHeap = memGetBlockHeap();
|
||||
memSetBlockHeap(psStackBlock);
|
||||
|
||||
/* Allocate a new chunk */
|
||||
psCurrChunk->psNext = (STACK_CHUNK *)MALLOC(sizeof(STACK_CHUNK));
|
||||
if (!psCurrChunk->psNext)
|
||||
|
@ -112,8 +104,6 @@ static BOOL stackNewChunk(UDWORD size)
|
|||
/* initialize pointers
|
||||
note: 0 means type == VAL_BOOL */
|
||||
memset(psCurrChunk->psNext->aVals, 0, sizeof(INTERP_VAL) * size);
|
||||
|
||||
memSetBlockHeap(psHeap);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
@ -983,8 +973,6 @@ BOOL castTop(INTERP_TYPE neededType)
|
|||
/* Initialise the stack */
|
||||
BOOL stackInitialise(void)
|
||||
{
|
||||
psStackBlock = memGetBlockHeap();
|
||||
|
||||
psStackBase = (STACK_CHUNK *)MALLOC(sizeof(STACK_CHUNK));
|
||||
if (psStackBase == NULL)
|
||||
{
|
||||
|
|
|
@ -1084,16 +1084,11 @@ static void dataStrResRelease(void *pData)
|
|||
static BOOL dataScriptLoad(char *pBuffer, UDWORD size, void **ppData)
|
||||
{
|
||||
SCRIPT_CODE *psProg=NULL;
|
||||
BLOCK_HEAP *psHeap;
|
||||
BOOL printHack = FALSE;
|
||||
|
||||
calcCheatHash(pBuffer,size,CHEAT_SCRIPT);
|
||||
|
||||
debug(LOG_WZ, "COMPILING SCRIPT ...%s",GetLastResourceFilename());
|
||||
// make sure the memory system uses normal malloc for a compile
|
||||
psHeap = memGetBlockHeap();
|
||||
memSetBlockHeap(NULL);
|
||||
|
||||
scr_lineno = 1;
|
||||
|
||||
if (!scriptCompile(pBuffer, size, &psProg, SCRIPTTYPE)) // see script.h
|
||||
|
@ -1101,7 +1096,6 @@ static BOOL dataScriptLoad(char *pBuffer, UDWORD size, void **ppData)
|
|||
debug(LOG_ERROR, "Script %s did not compile", GetLastResourceFilename());
|
||||
return FALSE;
|
||||
}
|
||||
memSetBlockHeap(psHeap);
|
||||
|
||||
if (printHack)
|
||||
{
|
||||
|
|
|
@ -618,22 +618,22 @@ BOOL runMultiPlayerMenu(void)
|
|||
{
|
||||
initLoadingScreen( TRUE );
|
||||
/* if (!resLoad("wrf/forcedit.wrf", 500,
|
||||
DisplayBuffer, displayBufferSize,
|
||||
psGameHeap)) //need the object heaps to have been set up before loading
|
||||
DisplayBuffer, displayBufferSize))
|
||||
//need the object heaps to have been set up before loading
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
*/
|
||||
if (!resLoad("wrf/piestats.wrf", 501,
|
||||
DisplayBuffer, displayBufferSize,
|
||||
psGameHeap)) //need the object heaps to have been set up before loading
|
||||
DisplayBuffer, displayBufferSize))
|
||||
//need the object heaps to have been set up before loading
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!resLoad("wrf/forcedit2.wrf", 502,
|
||||
DisplayBuffer, displayBufferSize,
|
||||
psGameHeap)) //need the object heaps to have been set up before loading
|
||||
DisplayBuffer, displayBufferSize))
|
||||
//need the object heaps to have been set up before loading
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
|
17
src/game.c
17
src/game.c
|
@ -1783,12 +1783,9 @@ BOOL loadGame(char *pGameToLoad, BOOL keepObjects, BOOL freeMem, BOOL UserSaveGa
|
|||
}
|
||||
if(bMultiPlayer)
|
||||
{
|
||||
blockSuspendUsage();
|
||||
loadMultiStats(saveGameData.sPName,&playerStats); // stats stuff
|
||||
setMultiStats(NetPlay.dpidPlayer,playerStats,FALSE);
|
||||
setMultiStats(NetPlay.dpidPlayer,playerStats,TRUE);
|
||||
blockUnsuspendUsage();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1929,7 +1926,6 @@ BOOL loadGame(char *pGameToLoad, BOOL keepObjects, BOOL freeMem, BOOL UserSaveGa
|
|||
if (saveGameOnMission && UserSaveGame)
|
||||
{
|
||||
LOADBARCALLBACK(); // loadingScreenCallback();
|
||||
memSetBlockHeap(psMapHeap);//should be set
|
||||
|
||||
//the scroll limits for the mission map have already been written
|
||||
if (saveGameVersion >= VERSION_29)
|
||||
|
@ -1975,9 +1971,6 @@ BOOL loadGame(char *pGameToLoad, BOOL keepObjects, BOOL freeMem, BOOL UserSaveGa
|
|||
}
|
||||
}
|
||||
|
||||
//set mission heap
|
||||
memSetBlockHeap(psMissionHeap);
|
||||
|
||||
// reload the objects that were in the mission list
|
||||
//except droids these are always loaded directly to the mission.apsDroidList
|
||||
/*
|
||||
|
@ -2868,14 +2861,10 @@ error:
|
|||
BOOL saveGame(char *aFileName, SDWORD saveType)
|
||||
{
|
||||
UDWORD fileExtension;
|
||||
BLOCK_HEAP *psHeap;
|
||||
DROID *psDroid, *psNext;
|
||||
|
||||
debug(LOG_WZ, "saveGame: %s", aFileName);
|
||||
|
||||
psHeap = memGetBlockHeap();
|
||||
memSetBlockHeap(NULL);
|
||||
|
||||
fileExtension = strlen(aFileName) - 3;
|
||||
gameTimeStop();
|
||||
|
||||
|
@ -3195,15 +3184,11 @@ BOOL saveGame(char *aFileName, SDWORD saveType)
|
|||
swapMissionPointers();
|
||||
}
|
||||
|
||||
|
||||
memSetBlockHeap(psHeap);
|
||||
|
||||
/* Start the game clock */
|
||||
gameTimeStart();
|
||||
return TRUE;
|
||||
|
||||
error:
|
||||
memSetBlockHeap(psHeap);
|
||||
/* Start the game clock */
|
||||
gameTimeStart();
|
||||
|
||||
|
@ -4058,11 +4043,9 @@ BOOL gameLoadV(char *pFileData, UDWORD filesize, UDWORD version)
|
|||
}
|
||||
if(bMultiPlayer)
|
||||
{
|
||||
blockSuspendUsage();
|
||||
loadMultiStats(psSaveGame->sPName,&playerStats); // stats stuff
|
||||
setMultiStats(NetPlay.dpidPlayer,playerStats,FALSE);
|
||||
setMultiStats(NetPlay.dpidPlayer,playerStats,TRUE);
|
||||
blockUnsuspendUsage();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
74
src/init.c
74
src/init.c
|
@ -108,31 +108,6 @@ extern char * global_mods[];
|
|||
extern char * campaign_mods[];
|
||||
extern char * multiplay_mods[];
|
||||
|
||||
|
||||
// the sizes for the game block heap
|
||||
#define GAMEBLOCK_INIT (2*1024*1024)
|
||||
#define GAMEBLOCK_EXT (1024*1024)
|
||||
// the sizes for the campaign map block heap
|
||||
#define MAPBLOCK_INIT (1024*1024)
|
||||
#define MAPBLOCK_EXT (32*1024)
|
||||
// the sizes for the mission block heap
|
||||
#define MISSIONBLOCK_INIT (2*1024*1024)
|
||||
#define MISSIONBLOCK_EXT (512*1024)
|
||||
|
||||
|
||||
// the block heap for the game data
|
||||
BLOCK_HEAP *psGameHeap;
|
||||
|
||||
// the block heap for the campaign map
|
||||
BLOCK_HEAP *psMapHeap;
|
||||
|
||||
// the block heap for the pre WRF data
|
||||
BLOCK_HEAP *psMissionHeap;
|
||||
|
||||
// the block id for the game data
|
||||
#define GAME_BLOCKID 100
|
||||
|
||||
|
||||
// Ascii to font image id lookup table for frontend font.
|
||||
//
|
||||
|
||||
|
@ -1031,24 +1006,6 @@ BOOL systemInitialise(void)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
// create a block heap for the game data
|
||||
if (!BLOCK_CREATE(&psGameHeap, GAMEBLOCK_INIT, GAMEBLOCK_EXT))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// create a block heap for the campaign map
|
||||
if (!BLOCK_CREATE(&psMapHeap, MAPBLOCK_INIT, MAPBLOCK_EXT))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// create a block heap for the pre WRF data
|
||||
if (!BLOCK_CREATE(&psMissionHeap, MISSIONBLOCK_INIT, MISSIONBLOCK_EXT))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#ifdef ARROWS
|
||||
arrowInit();
|
||||
#endif
|
||||
|
@ -1084,12 +1041,6 @@ BOOL systemShutdown(void)
|
|||
free( data_dirs );
|
||||
*/
|
||||
|
||||
// release the block heaps
|
||||
BLOCK_DESTROY(psGameHeap);
|
||||
BLOCK_DESTROY(psMapHeap);
|
||||
BLOCK_DESTROY(psMissionHeap);
|
||||
|
||||
|
||||
if (!bDisableLobby && !multiShutdown()) // ajl. init net stuff
|
||||
{
|
||||
return FALSE;
|
||||
|
@ -1161,9 +1112,6 @@ BOOL frontendInitialise(const char *ResourceFile)
|
|||
{
|
||||
debug(LOG_MAIN, "Initialising frontend : %s", ResourceFile);
|
||||
|
||||
// allocate memory from the pre data heap
|
||||
memSetBlockHeap(psGameHeap);
|
||||
|
||||
if(!InitialiseGlobals()) // Initialise all globals and statics everywhere.
|
||||
{
|
||||
return FALSE;
|
||||
|
@ -1202,10 +1150,9 @@ BOOL frontendInitialise(const char *ResourceFile)
|
|||
}
|
||||
|
||||
debug(LOG_MAIN, "frontEndInitialise: loading resource file .....");
|
||||
if (!resLoad(ResourceFile, 0,
|
||||
DisplayBuffer, displayBufferSize,
|
||||
psGameHeap)) //need the object heaps to have been set up before loading in the save game
|
||||
if (!resLoad(ResourceFile, 0, DisplayBuffer, displayBufferSize))
|
||||
{
|
||||
//need the object heaps to have been set up before loading in the save game
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -1244,8 +1191,6 @@ BOOL frontendInitialise(const char *ResourceFile)
|
|||
|
||||
SetFormAudioIDs(-1,ID_SOUND_WINDOWCLOSE); // disable the open noise since distorted in 3dfx builds.
|
||||
|
||||
memSetBlockHeap(NULL);
|
||||
|
||||
initMiscVars();
|
||||
|
||||
gameTimeInit();
|
||||
|
@ -1304,19 +1249,12 @@ BOOL frontendShutdown(void)
|
|||
*/
|
||||
pie_TexShutDown();
|
||||
|
||||
|
||||
|
||||
// reset the block heap
|
||||
BLOCK_RESET(psGameHeap);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/* Initialisation before data is loaded */
|
||||
|
||||
|
@ -1324,9 +1262,6 @@ BOOL frontendShutdown(void)
|
|||
|
||||
BOOL stageOneInitialise(void)
|
||||
{
|
||||
BLOCK_HEAP *psHeap;
|
||||
|
||||
|
||||
debug(LOG_MAIN, "stageOneInitalise");
|
||||
|
||||
// Initialise all globals and statics everwhere.
|
||||
|
@ -1367,17 +1302,12 @@ BOOL stageOneInitialise(void)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
// debug mode only so use normal MALLOC
|
||||
psHeap = memGetBlockHeap();
|
||||
memSetBlockHeap(NULL);
|
||||
#ifdef DISP2D
|
||||
if (!disp2DInitialise())
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
memSetBlockHeap(psHeap);
|
||||
|
||||
|
||||
if ( !anim_Init( anim_GetShapeFunc ) )
|
||||
{
|
||||
|
|
|
@ -66,15 +66,6 @@ BOOL rebuildSearchPath( searchPathMode mode, BOOL force );
|
|||
|
||||
BOOL buildMapList(void);
|
||||
|
||||
// the block heap for the game data
|
||||
extern BLOCK_HEAP *psGameHeap;
|
||||
|
||||
// the block heap for the campaign map
|
||||
extern BLOCK_HEAP *psMapHeap;
|
||||
|
||||
// the block heap for the pre WRF data
|
||||
extern BLOCK_HEAP *psMissionHeap;
|
||||
|
||||
extern IMAGEFILE *FrontImages;
|
||||
|
||||
#endif // _init_h
|
||||
|
|
|
@ -500,10 +500,7 @@ KEY_MAPPING *keyAddMapping(KEY_STATUS status,KEY_CODE metaCode, KEY_CODE subCode
|
|||
void (*pKeyMapFunc)(void), const char *name)
|
||||
{
|
||||
KEY_MAPPING *newMapping;
|
||||
BLOCK_HEAP *psHeap;
|
||||
|
||||
psHeap = memGetBlockHeap();
|
||||
memSetBlockHeap(NULL);
|
||||
/* Get some memory for our binding */
|
||||
newMapping = (KEY_MAPPING*)MALLOC(sizeof(KEY_MAPPING));
|
||||
|
||||
|
@ -513,8 +510,6 @@ BLOCK_HEAP *psHeap;
|
|||
newMapping->pName = (char*)MALLOC(strlen(name)+1);
|
||||
ASSERT( newMapping->pName != NULL, "Couldn't allocate the memory for the string in a mapping" );
|
||||
|
||||
memSetBlockHeap(psHeap);
|
||||
|
||||
/* Copy over the name */
|
||||
strcpy(newMapping->pName,name);
|
||||
|
||||
|
|
100
src/levels.c
100
src/levels.c
|
@ -466,18 +466,11 @@ BOOL levReleaseMissionData(void)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
if ((psCurrLevel->type == LDS_COMPLETE ||
|
||||
psCurrLevel->type >= MULTI_TYPE_START) && psCurrLevel->game == -1)
|
||||
{
|
||||
BLOCK_RESET(psMissionHeap);
|
||||
}
|
||||
|
||||
// free up the old data
|
||||
for(i=LEVEL_MAXFILES-1; i >= 0; i--)
|
||||
{
|
||||
if (i == psCurrLevel->game)
|
||||
{
|
||||
BLOCK_RESET(psMissionHeap);
|
||||
if (psCurrLevel->psBaseData == NULL)
|
||||
{
|
||||
if (!stageTwoShutDown())
|
||||
|
@ -492,10 +485,6 @@ BOOL levReleaseMissionData(void)
|
|||
resReleaseBlockData(i + CURRENT_DATAID);
|
||||
}
|
||||
}
|
||||
if (psCurrLevel->type == LDS_BETWEEN)
|
||||
{
|
||||
BLOCK_RESET(psMissionHeap);
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -539,8 +528,6 @@ BOOL levReleaseAll(void)
|
|||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BLOCK_RESET(psGameHeap);
|
||||
}
|
||||
|
||||
psCurrLevel=NULL;
|
||||
|
@ -563,20 +550,14 @@ static BOOL levLoadSingleWRF(char *pName)
|
|||
{
|
||||
return FALSE;
|
||||
}
|
||||
BLOCK_RESET(psGameHeap);
|
||||
memSetBlockHeap(psGameHeap);
|
||||
|
||||
// load the data
|
||||
debug(LOG_WZ, "levLoadSingleWRF: Loading %s ...", pName);
|
||||
if (!resLoad(pName, 0,
|
||||
DisplayBuffer, displayBufferSize,
|
||||
psGameHeap))
|
||||
if (!resLoad(pName, 0, DisplayBuffer, displayBufferSize))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BLOCK_RESET(psMissionHeap);
|
||||
memSetBlockHeap(psMissionHeap);
|
||||
|
||||
if (!stageThreeInitialise())
|
||||
{
|
||||
return FALSE;
|
||||
|
@ -620,11 +601,7 @@ BOOL levLoadBaseData(char *pName)
|
|||
// clear all the old data
|
||||
levReleaseAll();
|
||||
|
||||
// basic game data is loaded in the game heap
|
||||
memSetBlockHeap(psGameHeap);
|
||||
|
||||
// initialise
|
||||
BLOCK_RESET(psGameHeap);
|
||||
if (!stageOneInitialise())
|
||||
{
|
||||
return FALSE;
|
||||
|
@ -639,8 +616,7 @@ BOOL levLoadBaseData(char *pName)
|
|||
// load the data
|
||||
debug(LOG_WZ, "levLoadBaseData: Loading %s", psBaseData->apDataFiles[i]);
|
||||
if (!resLoad(psBaseData->apDataFiles[i], i,
|
||||
DisplayBuffer, displayBufferSize,
|
||||
psGameHeap))
|
||||
DisplayBuffer, displayBufferSize))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -663,7 +639,6 @@ BOOL levLoadData(char *pName, char *pSaveName, SDWORD saveType)
|
|||
{
|
||||
LEVEL_DATASET *psNewLevel, *psBaseData, *psChangeLevel;
|
||||
SDWORD i;
|
||||
BLOCK_HEAP *psCurrHeap;
|
||||
BOOL bCamChangeSaveGame;
|
||||
|
||||
debug(LOG_WZ, "Loading level %s", pName);
|
||||
|
@ -767,16 +742,10 @@ BOOL levLoadData(char *pName, char *pSaveName, SDWORD saveType)
|
|||
}
|
||||
|
||||
|
||||
// basic game data is loaded in the game heap
|
||||
debug( LOG_NEVER, "levLoadData: Setting game heap\n" );
|
||||
memSetBlockHeap(psGameHeap);
|
||||
|
||||
// initialise if necessary
|
||||
if (psNewLevel->type == LDS_COMPLETE || //psNewLevel->type >= MULTI_TYPE_START ||
|
||||
psBaseData != NULL)
|
||||
{
|
||||
debug( LOG_NEVER, "levLoadData: reset game heap\n" );
|
||||
BLOCK_RESET(psGameHeap);
|
||||
if (!stageOneInitialise())
|
||||
{
|
||||
return FALSE;
|
||||
|
@ -794,8 +763,7 @@ BOOL levLoadData(char *pName, char *pSaveName, SDWORD saveType)
|
|||
// load the data
|
||||
debug(LOG_WZ, "levLoadData: Loading %s ...", psBaseData->apDataFiles[i]);
|
||||
if (!resLoad(psBaseData->apDataFiles[i], i,
|
||||
DisplayBuffer, displayBufferSize,
|
||||
psGameHeap))
|
||||
DisplayBuffer, displayBufferSize))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -824,10 +792,6 @@ BOOL levLoadData(char *pName, char *pSaveName, SDWORD saveType)
|
|||
}
|
||||
}
|
||||
|
||||
debug( LOG_NEVER, "levLoadData: setting map heap\n" );
|
||||
BLOCK_RESET(psMapHeap);
|
||||
memSetBlockHeap(psMapHeap);
|
||||
|
||||
//set the mission type before the saveGame data is loaded
|
||||
if (saveType == GTYPE_SAVE_MIDMISSION)
|
||||
{
|
||||
|
@ -862,10 +826,6 @@ BOOL levLoadData(char *pName, char *pSaveName, SDWORD saveType)
|
|||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
debug( LOG_NEVER, "levLoadData: setting mission heap\n" );
|
||||
BLOCK_RESET(psMissionHeap);
|
||||
memSetBlockHeap(psMissionHeap);
|
||||
}
|
||||
|
||||
//we need to load up the save game data here for a camchange
|
||||
|
@ -882,10 +842,6 @@ BOOL levLoadData(char *pName, char *pSaveName, SDWORD saveType)
|
|||
}
|
||||
}
|
||||
|
||||
debug( LOG_NEVER, "levLoadData: setting map heap\n" );
|
||||
BLOCK_RESET(psMapHeap);
|
||||
memSetBlockHeap(psMapHeap);
|
||||
|
||||
debug( LOG_NEVER, "levLoadData: loading savegame: %s\n", pSaveName );
|
||||
if (!loadGame(pSaveName, FALSE, TRUE,TRUE))
|
||||
{
|
||||
|
@ -902,14 +858,12 @@ BOOL levLoadData(char *pName, char *pSaveName, SDWORD saveType)
|
|||
//psChangeLevel = NULL;
|
||||
|
||||
//stageTwoShutDown??
|
||||
//block_reset??
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// load the new data
|
||||
debug( LOG_NEVER, "levLoadData: loading mission dataset: %s\n", psNewLevel->pName );
|
||||
psCurrHeap = memGetBlockHeap();
|
||||
for(i=0; i<LEVEL_MAXFILES; i++)
|
||||
{
|
||||
if (psNewLevel->game == i)
|
||||
|
@ -923,35 +877,11 @@ BOOL levLoadData(char *pName, char *pSaveName, SDWORD saveType)
|
|||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
debug( LOG_NEVER, "levLoadData: setting map heap\n" );
|
||||
BLOCK_RESET(psMapHeap);
|
||||
memSetBlockHeap(psMapHeap);
|
||||
psCurrHeap = psMapHeap;
|
||||
}
|
||||
|
||||
// missions with a seperate map have to use the mission heap now
|
||||
if ((psNewLevel->type == LDS_MKEEP
|
||||
||psNewLevel->type == LDS_MCLEAR
|
||||
||psNewLevel->type == LDS_MKEEP_LIMBO
|
||||
) &&
|
||||
pSaveName == NULL)
|
||||
{
|
||||
debug( LOG_NEVER, "levLoadData: setting mission heap\n" );
|
||||
BLOCK_RESET(psMissionHeap);
|
||||
memSetBlockHeap(psMissionHeap);
|
||||
psCurrHeap = psMissionHeap;
|
||||
}
|
||||
|
||||
// load a savegame if there is one - but not if already done so
|
||||
if (pSaveName != NULL && !bCamChangeSaveGame)
|
||||
{
|
||||
// make sure the map gets loaded into the right heap
|
||||
debug( LOG_NEVER, "levLoadData: setting map heap\n" );
|
||||
BLOCK_RESET(psMapHeap);
|
||||
memSetBlockHeap(psMapHeap);
|
||||
psCurrHeap = psMapHeap;
|
||||
|
||||
//set the mission type before the saveGame data is loaded
|
||||
if (saveType == GTYPE_SAVE_MIDMISSION)
|
||||
{
|
||||
|
@ -1078,23 +1008,13 @@ BOOL levLoadData(char *pName, char *pSaveName, SDWORD saveType)
|
|||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// set the mission heap now if it isn't already being used
|
||||
if (memGetBlockHeap() != psMissionHeap)
|
||||
{
|
||||
debug( LOG_NEVER, "levLoadData: setting mission heap\n" );
|
||||
BLOCK_RESET(psMissionHeap);
|
||||
memSetBlockHeap(psMissionHeap);
|
||||
}
|
||||
psCurrHeap = psMissionHeap;
|
||||
}
|
||||
else if (psNewLevel->apDataFiles[i])
|
||||
{
|
||||
// load the data
|
||||
debug(LOG_WZ, "levLoadData: Loading %s", psNewLevel->apDataFiles[i]);
|
||||
if (!resLoad(psNewLevel->apDataFiles[i], i + CURRENT_DATAID,
|
||||
DisplayBuffer, displayBufferSize,
|
||||
psCurrHeap))
|
||||
DisplayBuffer, displayBufferSize))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -1103,16 +1023,6 @@ BOOL levLoadData(char *pName, char *pSaveName, SDWORD saveType)
|
|||
|
||||
dataClearSaveFlag();
|
||||
|
||||
// set the mission heap now if it isn't already being used
|
||||
if (memGetBlockHeap() != psMissionHeap)
|
||||
{
|
||||
debug( LOG_NEVER, "levLoadData: setting mission heap\n" );
|
||||
BLOCK_RESET(psMissionHeap);
|
||||
memSetBlockHeap(psMissionHeap);
|
||||
psCurrHeap = psMissionHeap;
|
||||
}
|
||||
|
||||
|
||||
//if (pSaveName != NULL && saveType == GTYPE_SAVE_MIDMISSION)
|
||||
if (pSaveName != NULL)
|
||||
{
|
||||
|
|
|
@ -452,11 +452,6 @@ init://jump here from the end if re_initialising
|
|||
|
||||
debug(LOG_MAIN, "reinitializing");
|
||||
|
||||
if (!blkInitialise())
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bDisableLobby = FALSE;
|
||||
|
||||
loadConfig();
|
||||
|
|
|
@ -124,16 +124,12 @@ BOOL startLimitScreen(void)
|
|||
{
|
||||
initLoadingScreen( TRUE );//changed by jeremy mar8
|
||||
|
||||
if (!resLoad("wrf/piestats.wrf", 501,
|
||||
DisplayBuffer, displayBufferSize,
|
||||
psGameHeap))//need the object heaps to have been set up before loading
|
||||
if (!resLoad("wrf/piestats.wrf", 501, DisplayBuffer, displayBufferSize))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!resLoad("wrf/forcedit2.wrf", 502,
|
||||
DisplayBuffer, displayBufferSize,
|
||||
psGameHeap))//need the object heaps to have been set up before loading
|
||||
if (!resLoad("wrf/forcedit2.wrf", 502, DisplayBuffer, displayBufferSize))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue