? sword2_memory_03_28_04.diff Index: mem_view.cpp =================================================================== RCS file: /cvsroot/scummvm/scummvm/sword2/mem_view.cpp,v retrieving revision 1.26 diff -u -r1.26 mem_view.cpp --- mem_view.cpp 5 Feb 2004 14:19:04 -0000 1.26 +++ mem_view.cpp 28 Mar 2004 23:10:17 -0000 @@ -26,6 +26,8 @@ namespace Sword2 { +#ifndef _WIN32_WCE + void MemoryManager::displayMemory(void) { int pass, found_end, k, j, free = 0; StandardHeader *file_header; @@ -161,4 +163,6 @@ percent, (_vm->_resman->fetchUsage() / 1024)); } +#endif + } // End of namespace Sword2 Index: memory.cpp =================================================================== RCS file: /cvsroot/scummvm/scummvm/sword2/memory.cpp,v retrieving revision 1.23 diff -u -r1.23 memory.cpp --- memory.cpp 5 Feb 2004 14:19:04 -0000 1.23 +++ memory.cpp 28 Mar 2004 23:10:17 -0000 @@ -37,6 +37,9 @@ #include "common/stdafx.h" #include "sword2/sword2.h" #include "sword2/resman.h" +#ifdef _WIN32_WCE +#include "common/config-manager.h" +#endif namespace Sword2 { @@ -44,6 +47,100 @@ // #define MEMDEBUG 1 +#ifdef _WIN32_WCE + +#define DEFAULT_CLEANUP_THRESHOLD (1024 * 8000) +int CLEANUP_THRESHOLD; + +MemoryManager::MemoryManager(Sword2Engine *vm) : _vm(vm) { + uint32 i; + for (i = 0; i < MAX_mem_blocks; i++) + _memList[i].state = MEM_null; + _lastBlock = 0; + _memoryAllocated = 0; + _cleanupCounter = 0; + CLEANUP_THRESHOLD = ConfMan.getInt("memory_cleanup_threshold"); + if (!CLEANUP_THRESHOLD) { + CLEANUP_THRESHOLD = DEFAULT_CLEANUP_THRESHOLD; + ConfMan.set("memory_cleanup_threshold", CLEANUP_THRESHOLD); + ConfMan.flushToDisk(); + } +} + +MemoryManager::~MemoryManager() { +} + +int32 MemoryManager::ptrToInt(const uint8 *p) { + return (int32)p; +} + +uint8 *MemoryManager::intToPtr(int32 n) { + return (uint8*)n; +} + +Memory *MemoryManager::allocMemory(uint32 size, uint32 type, uint32 unique_id) { + uint32 i; + // Find a free slot + for (i=0; i< MAX_mem_blocks; i++) + if (_memList[i].state == MEM_null) + break; + if (i == MAX_mem_blocks) + error("Out of mem blocks"); + if (i > _lastBlock) + _lastBlock = i; + + _memList[i].size = size; + _memList[i].uid = unique_id; + _memList[i].state = type; + _memList[i].ad = (uint8*)malloc(size); + if (!_memList[i].ad) { + error("Memory allocation failed"); + } + _memoryAllocated += size; + + warning("Memory Allocated %d", _memoryAllocated); + + if (_memoryAllocated > CLEANUP_THRESHOLD) { + _cleanupCounter++; + if (_cleanupCounter == 50) { + _cleanupCounter = 0; + while (_vm->_resman->helpTheAgedOut()); + warning("Memory Allocated after cleanup %d", _memoryAllocated); + } + } + + return &_memList[i]; +} + +void MemoryManager::freeMemory(Memory *block) { + _memoryAllocated -= block->size; + free(block->ad); + block->state = MEM_null; + // Recompute last block if the last block was freed + if (block == &_memList[_lastBlock]) { + uint32 i; + _lastBlock = 0; + for (i=0; i _lastBlock) + _lastBlock = i; + } +} + +void MemoryManager::floatMemory(Memory *block) { +} + +void MemoryManager::lockMemory(Memory *block) { +} + +// Debugging function +void MemoryManager::displayMemory() { +} + +void MemoryManager::memoryString(char *string) { +} + +#else + MemoryManager::MemoryManager(Sword2Engine *vm) : _vm(vm) { uint32 j; uint8 *memory_base; @@ -279,7 +376,7 @@ // can't move now - this block is now crying out to be floated or // free'd again - block->state = MEM_locked; + //block->state = MEM_locked; #ifdef MEMDEBUG debugMemory(); @@ -573,4 +670,7 @@ return 1; } +#endif + } // End of namespace Sword2 + Index: memory.h =================================================================== RCS file: /cvsroot/scummvm/scummvm/sword2/memory.h,v retrieving revision 1.14 diff -u -r1.14 memory.h --- memory.h 6 Jan 2004 13:44:17 -0000 1.14 +++ memory.h 28 Mar 2004 23:10:17 -0000 @@ -78,6 +78,8 @@ // VirtualDefrag. int32 _suggestedStart; +#ifndef _WIN32_WCE + Memory *lowLevelAlloc(uint32 size, uint32 type, uint32 unique_id); int32 defragMemory(uint32 req_size); @@ -89,11 +91,19 @@ void debugMemory(void); const char *fetchOwner(uint32 uid); +#endif + public: // List of defined memory handles - each representing a block of memory Memory _memList[MAX_mem_blocks]; uint32 _baseMemBlock; +#ifdef _WIN32_WCE + uint32 _lastBlock; + uint32 _memoryAllocated; + uint32 _cleanupCounter; +#endif + MemoryManager(Sword2Engine *vm); ~MemoryManager(void); Index: resman.cpp =================================================================== RCS file: /cvsroot/scummvm/scummvm/sword2/resman.cpp,v retrieving revision 1.87.2.1 diff -u -r1.87.2.1 resman.cpp --- resman.cpp 4 Mar 2004 08:02:49 -0000 1.87.2.1 +++ resman.cpp 28 Mar 2004 23:10:17 -0000 @@ -834,6 +834,8 @@ debug(5, "remove(%d) not even in memory!", res); } +#ifndef _WIN32_WCE + void ResourceManager::removeAll(void) { // remove all res files from memory - ready for a total restart // including player object & global variables resource @@ -854,6 +856,30 @@ } while (j != -1); } +#else + +void ResourceManager::removeAll(void) { + // remove all res files from memory - ready for a total restart + // including player object & global variables resource + + int j; + uint32 res; + uint32 lastBlock = _vm->_memory->_lastBlock; + + + for (j=0; j_memory->_memList[j].uid < 65536) { // a resource + res = _vm->_memory->_memList[j].uid; + _age[res] = 0; // effectively gone from _resList + _vm->_memory->freeMemory(_resList[res]); // release the memory too + } + } +} + +#endif + +#ifndef _WIN32_WCE + void ResourceManager::killAll(bool wantInfo) { // remove all res files from memory // its quicker to search the mem blocs for res files than search @@ -896,6 +922,52 @@ } } +#else + +void ResourceManager::killAll(bool wantInfo) { + // remove all res files from memory + // its quicker to search the mem blocs for res files than search + // resource lists for those in memory + + int j; + uint32 res; + uint32 nuked = 0; + StandardHeader *header; + uint32 lastBlock = _vm->_memory->_lastBlock; + + + for (j=0; j_memory->_memList[j].state != MEM_null && + _vm->_memory->_memList[j].uid < 65536) { // a resource + res = _vm->_memory->_memList[j].uid; + + // not the global vars which are assumed to be open in + // memory & not the player object! + if (res != 1 && res != CUR_PLAYER_ID) { + header = (StandardHeader *) openResource(res); + closeResource(res); + + _age[res] = 0; // effectively gone from _resList + _vm->_memory->freeMemory(_resList[res]); // release the memory too + nuked++; + + // if this was called from the console, + if (wantInfo) { + Debug_Printf("Nuked %5d: %s\n", res, header->name); + debug(5, " nuked %d: %s", res, header->name); + } + } + } + } + + // if this was called from the console + if (wantInfo) { + Debug_Printf("Expelled %d resource(s)\n", nuked); + } +} + +#endif + //---------------------------------------------------------------------------- // Like killAll but only kills objects (except George & the variable table of // course) - ie. forcing them to reload & restart their scripts, which @@ -904,6 +976,8 @@ // disappear forever, or some plaster-filled holes in sand to crash the game & // get James in trouble again. +#ifndef _WIN32_WCE + void ResourceManager::killAllObjects(bool wantInfo) { // remove all object res files from memory, excluding George // its quicker to search the mem blocs for res files than search @@ -946,6 +1020,52 @@ Debug_Printf("Expelled %d object resource(s)\n", nuked); } +#else + +void ResourceManager::killAllObjects(bool wantInfo) { + // remove all object res files from memory, excluding George + // its quicker to search the mem blocs for res files than search + // resource lists for those in memory + + int j; + uint32 res; + uint32 nuked = 0; + StandardHeader *header; + uint32 lastBlock = _vm->_memory->_lastBlock; + + for (j=0; j_memory->_memList[j].state != MEM_null && + _vm->_memory->_memList[j].uid < 65536) { // a resource + res = _vm->_memory->_memList[j].uid; + //not the global vars which are assumed to be open in + // memory & not the player object! + if (res != 1 && res != CUR_PLAYER_ID) { + header = (StandardHeader *) openResource(res); + closeResource(res); + + if (header->fileType == GAME_OBJECT) { + _age[res] = 0; // effectively gone from _resList + _vm->_memory->freeMemory(_resList[res]); // release the memory too + nuked++; + + // if this was called from the console + if (wantInfo) { + Debug_Printf("Nuked %5d: %s\n", res, header->name); + debug(5, " nuked %d: %s", res, header->name); + } + } + } + } + } + + // if this was called from the console + if (wantInfo) + Debug_Printf("Expelled %d object resource(s)\n", nuked); +} + + +#endif + void ResourceManager::getCd(int cd) { uint8 *textRes; Index: driver/animation.cpp =================================================================== RCS file: /cvsroot/scummvm/scummvm/sword2/driver/animation.cpp,v retrieving revision 1.21.2.7 diff -u -r1.21.2.7 animation.cpp --- driver/animation.cpp 14 Mar 2004 13:50:38 -0000 1.21.2.7 +++ driver/animation.cpp 28 Mar 2004 23:10:18 -0000 @@ -116,6 +116,8 @@ #else buildLookup(); overlay = (NewGuiColor*)calloc(640 * 480, sizeof(NewGuiColor)); + if (!overlay) + return false; _vm->_system->show_overlay(); #endif @@ -251,6 +253,9 @@ return; lookup = (NewGuiColor *)calloc((BITDEPTH+1) * (BITDEPTH+1) * 256, sizeof(NewGuiColor)); + if (!lookup) { + error("buildLookup failed - memory management failure"); + } int y, cb, cr; int r, g, b;