#include #include "cm_local.h" #include "hstring.h" // mapPoolBlockCount is defined differently in the executable (sv_main.cpp) and the game dll (g_main.cpp) cuz //we likely don't need as many blocks in the executable as we do in the game extern int mapPoolBlockCount; // Used to fool optimizer during compilation of mem touch routines. int HaHaOptimizer2=0; CMapPoolLow &GetMapPool() { // this may need to be ifdefed to be different for different modules static CMapPoolLow thePool; return thePool; } #define MAPBLOCK_SIZE_NODES (1024) #define MAPNODE_FREE (0xa1) #define MAPNODE_INUSE (0x94) struct SMapNode { unsigned char mData[MAP_NODE_SIZE-2]; unsigned char mMapBlockNum; unsigned char mTag; }; class CMapBlock { int mId; char mRaw[(MAPBLOCK_SIZE_NODES+1)*MAP_NODE_SIZE]; SMapNode *mNodes; int mLastNode; public: CMapBlock(int id,vector &freeList) : mLastNode(0) { // Alloc node storage for MAPBLOCK_SIZE_NODES worth of nodes. mNodes=(SMapNode *)((((unsigned long)mRaw)+MAP_NODE_SIZE)&~(unsigned long)0x1f); // Set all nodes to initially be free. int i; for(i=0;i=&mNodes[0])&&(((SMapNode *)node)<&mNodes[MAPBLOCK_SIZE_NODES])); } }; CMapPoolLow::CMapPoolLow() { mLastBlockNum=-1; } CMapPoolLow::~CMapPoolLow() { #if _DEBUG char mess[1000]; #if _GAME if(mFreeList.size()mTag==MAPNODE_FREE); assert((((SMapNode *)node)->mMapBlockNum)>=0); assert((((SMapNode *)node)->mMapBlockNum)<256); assert((((SMapNode *)node)->mMapBlockNum)<=mLastBlockNum); assert(mMapBlocks[((SMapNode *)node)->mMapBlockNum]->bOwnsNode(node)); // Ok, mark the node as in use. ((SMapNode *)node)->mTag=MAPNODE_INUSE; return(node); } void CMapPoolLow::Free(void *p) { // Validate that someone isn't trying to double free this node and also // that the end marker is intact. assert(((SMapNode *)p)->mTag==MAPNODE_INUSE); assert((((SMapNode *)p)->mMapBlockNum)>=0); assert((((SMapNode *)p)->mMapBlockNum)<256); assert((((SMapNode *)p)->mMapBlockNum)<=mLastBlockNum); assert(mMapBlocks[((SMapNode *)p)->mMapBlockNum]->bOwnsNode(p)); // Ok, mark the the node as free. ((SMapNode *)p)->mTag=MAPNODE_FREE; // Add a new freelist entry to point at this node. mFreeList.push_back(p); } void CMapPoolLow::TouchMem() { int i,j; unsigned char *memory; int totSize=0; for(i=0;i=0&&hash=0&&mFindPtr(BLOCK_SIZE-mBytesUsed)) { return(0); } // Return the pointer to the start of allocated space. char *ret=&mRaw[mBytesUsed]; mBytesUsed+=sizeBytes; return ret; } bool operator== (const CHSBlock &block) const { if(!memcmp(mRaw,block.mRaw,BLOCK_SIZE)) { return(true); } return(false); } }; class CPool { vector mBlockVec; public: int mNextStringId; int mLastBlockNum; CPool(void) : mNextStringId(1), mLastBlockNum(-1) { memset(gCharPtrs,0,MAX_HSTRINGS*4); } ~CPool(void) { int i; for (i=0;i=0) { // Get the pointer to the start of allocated space in the current block. raw=mBlockVec[mLastBlockNum]->Alloc(sizeBytes); } if(!raw) { // Ok, make a new empty block and append it. CHSBlock *block=new(CHSBlock); mBlockVec.push_back(block); mLastBlockNum++; raw=mBlockVec[mLastBlockNum]->Alloc(sizeBytes); } // Should never really happen!! assert(raw); id=mNextStringId; gCharPtrs[mNextStringId]=raw; mNextStringId++; return(raw); } bool operator== (const CPool &pool) const { int i; for(i=0;i0&&id0&&mId0&&mId