/
Crimson2/alias/
Crimson2/area.tmp/
Crimson2/area.tmp/AnomalySpaceDock/
Crimson2/area.tmp/AnomalyStation/
Crimson2/area.tmp/AntHill/
Crimson2/area.tmp/ArcticTerrarium/
Crimson2/area.tmp/BuilderCity/
Crimson2/area.tmp/Dungeon/
Crimson2/area.tmp/MiningDock/
Crimson2/area.tmp/PipeSystem/
Crimson2/area.tmp/RattArea/
Crimson2/area.tmp/RobotFactory/
Crimson2/area.tmp/SilverDale/
Crimson2/area.tmp/StarshipFearless/
Crimson2/area.tmp/StationConduits/
Crimson2/area.tmp/TerrariumAlpha/
Crimson2/area.tmp/TerrariumBeta/
Crimson2/area.tmp/TestArea/
Crimson2/area.tmp/Void/
Crimson2/area/
Crimson2/area/AnomalySpaceDock/
Crimson2/area/AnomalyStation/
Crimson2/area/MiningDock/
Crimson2/area/PipeSystem/
Crimson2/area/SilverDale/
Crimson2/area/StationConduits/
Crimson2/area/Void/
Crimson2/board/
Crimson2/clone/
Crimson2/lib/
Crimson2/mole/
Crimson2/mole/mole_src/HELP/
Crimson2/player/
Crimson2/util/
Crimson2/wldedit/
Crimson2/wldedit/res/
/* since mallocs are a blow to performance and wastefull of memory besides
   malloc multiple blocks of a given size at once to minimize memory waste
   and never really free anything just keep it in a linked list of free blocks
   of that size (since we will be re-using blocks of the same size very
   frequently)  
   
   if you dont know why I allways double and use powers of two, dont play with 
   my mem management functions, you dont know enough yet....
   
   by the way dont mix up MemFree&MemAlloc with malloc/free cuz bad things will happen
*/

typedef struct memType { /* kinda a small structure heh? */
  struct memType  *mNext;
} MEM; /* is just overlaid on top of allready (and much larger) allocated blocks */

extern BYTE *memSpace;
extern LWORD memSpaceUsed; /* nothing in here is *EVER* free'd */
extern LWORD memSpaceByte;
extern LWORD memUsed;

extern void  MemInit(void);
extern void  MemInitDone(void);

#define      MEM_MALLOC -1 /* use this for size/blocksize to directly MALLOC things */
extern BYTE *MemFree(MEM *memFree, LWORD size);
extern BYTE *MemAlloc(LWORD size, LWORD blockSize);
extern void *MemReallocDouble(BYTE *errorStr, void *memPtr, LWORD memSize, LWORD memNum, LWORD *memByte); 

extern void *MemMoveHigher(void *dst, void *src, LWORD size);

/* use the macros, they're more convenient */
#define      MEMFREE(mem, type)               mem=(type*)MemFree((MEM*)mem,sizeof(type))
#define      MEMALLOC(mem, type, blocksize)   mem=(type*)MemAlloc(sizeof(type),blocksize)
#define      REALLOC(errorstr, memptr, memtype, memnum, membyte) memptr = MemReallocDouble(errorstr, memptr, sizeof(memtype), memnum, &membyte)

/* exit on an error cuz we're going down anyways */
#define MALLOC(mem, type, num) \
do { \
  if (! (mem = (type *)malloc(num*sizeof(type))) ) { \
    Log(LOG_ERROR, "malloc failure: dying a horrible death...\n"); \
    exit(ERROR_NOMEM);\
  }\
  memUsed += (num*sizeof(type)); \
} while(0)  \

#define FREE(mem, size) \
do { \
  /* memset(mem, 0, size) */ \
  free(mem); \
  memUsed -= size; \
} while(0)  \


#ifdef BLAH
/* double mem requests every time */
/* note can only access < curMaxSize */
/* str should be something like "WARNING! resizing XXYYZZ\n" */
/* mem should be a pointer pre-inited to NULL if empty */
/* curMaxByte determines the size of the initial malloc too, curMaxSize is recalc'd for any change */
#define REALLOC(errorstr, memptr, memtype, memnum, membyte) \
do { \
  if ( (memptr == NULL) || (memnum >= (membyte/sizeof(memtype)) ) ){ \
    if (memptr) \
      membyte *=2; \
    if (!memptr) { \
      if ( !(memptr = (memtype *)malloc(membyte)) ) { \
        Log(LOG_ERROR, "realloc/malloc failure: dying a horrible death...\n"); \
        exit(ERROR_NOMEM); \
      } \
      break; \
    } else { \
      if ( !(memptr = (memtype *)realloc(memptr, membyte)) ) { \
        Log(LOG_ERROR, "realloc failure: dying a horrible death...\n"); \
        exit(ERROR_NOMEM); \
      } \
    } \
    Log(LOG_ERROR, errorstr); \
  } \
} while(0) 

#endif