From 857a35f7485b5594c280c0c597b3a876900e8aba Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 9 Oct 2009 10:32:33 +0000 Subject: Fixed all memory leaks as far as the initial title screen svn-id: r44814 --- engines/cruise/background.cpp | 1 + engines/cruise/cruise.cpp | 1 + engines/cruise/cruise_main.cpp | 67 ++++++++++++++++------ engines/cruise/dataLoader.cpp | 2 + engines/cruise/overlay.cpp | 127 ++++++++++++++++++++++++++++------------- engines/cruise/overlay.h | 2 + engines/cruise/saveload.cpp | 10 ++-- engines/cruise/script.cpp | 10 ++-- engines/cruise/script.h | 4 +- 9 files changed, 154 insertions(+), 70 deletions(-) diff --git a/engines/cruise/background.cpp b/engines/cruise/background.cpp index cd4e64384b..e8f0865270 100644 --- a/engines/cruise/background.cpp +++ b/engines/cruise/background.cpp @@ -208,6 +208,7 @@ int loadBackground(const char *name, int idx) { loadCVT(&ptr2); } + MemFree(ptrToFree); if (name != backgroundTable[idx].name) strcpy(backgroundTable[idx].name, name); diff --git a/engines/cruise/cruise.cpp b/engines/cruise/cruise.cpp index 98ccc61355..569f5bbf02 100644 --- a/engines/cruise/cruise.cpp +++ b/engines/cruise/cruise.cpp @@ -169,6 +169,7 @@ bool CruiseEngine::loadLanguageStrings() { } f.close(); + MemFree(data); } else { // Try and use one of the pre-defined language lists diff --git a/engines/cruise/cruise_main.cpp b/engines/cruise/cruise_main.cpp index f36651f7e5..e3e5b4c98d 100644 --- a/engines/cruise/cruise_main.cpp +++ b/engines/cruise/cruise_main.cpp @@ -45,20 +45,20 @@ gfxEntryStruct* linkedMsgList = NULL; Common::List memList; void MemoryList() { - printf("Current list of un-freed memory blocks:\n"); - Common::List::iterator i; - for (i = memList.begin(); i != memList.end(); ++i) { - byte *v = *i; - printf("%s - %d\n", (const char *)(v - 68), *((int32 *)(v - 72))); + if (!memList.empty()) { + printf("Current list of un-freed memory blocks:\n"); + Common::List::iterator i; + for (i = memList.begin(); i != memList.end(); ++i) { + byte *v = *i; + printf("%s - %d\n", (const char *)(v - 68), *((int32 *)(v - 72))); + } } } void *MemoryAlloc(uint32 size, bool clearFlag, int32 lineNum, const char *fname) { byte *result; - if (gDebugLevel > 0) - result = (byte *)malloc(size); - else { + if (gDebugLevel > 0) { // Find the point after the final slash const char *fnameP = fname + strlen(fname); while ((fnameP > fname) && (*(fnameP - 1) != '/') && (*(fnameP - 1) != '\\')) @@ -74,7 +74,8 @@ void *MemoryAlloc(uint32 size, bool clearFlag, int32 lineNum, const char *fname) // Add the block to the memory list result = v + 64 + 8; memList.push_back(result); - } + } else + result = (byte *)malloc(size); if (clearFlag) memset(result, 0, size); @@ -86,15 +87,14 @@ void MemoryFree(void *v) { if (!v) return; - if (gDebugLevel > 0) - free(v); - else { + if (gDebugLevel > 0) { byte *p = (byte *)v; assert(*((uint32 *) (p - 4)) == 0x41424344); memList.remove(p); free(p - 8 - 64); - } + } else + free(v); } void drawBlackSolidBoxSmall() { @@ -372,8 +372,7 @@ int loadFileSub1(uint8 **ptr, const char *name, uint8 *ptr2) { unpackedSize = loadFileVar1 = volumePtrToFileDescriptor[fileIdx].extSize + 2; - // TODO: here, can unpack in gfx module buffer - unpackedBuffer = (uint8 *) mallocAndZero(unpackedSize); + unpackedBuffer = (uint8 *)mallocAndZero(unpackedSize); if (!unpackedBuffer) { return (-2); @@ -410,6 +409,8 @@ void resetFileEntry(int32 entryNumber) { return; MemFree(filesDatabase[entryNumber].subData.ptr); + if (filesDatabase[entryNumber].subData.ptrMask) + MemFree(filesDatabase[entryNumber].subData.ptrMask); filesDatabase[entryNumber].subData.ptr = NULL; filesDatabase[entryNumber].subData.ptrMask = NULL; @@ -421,7 +422,6 @@ void resetFileEntry(int32 entryNumber) { filesDatabase[entryNumber].subData.resourceType = 0; filesDatabase[entryNumber].subData.compression = 0; filesDatabase[entryNumber].subData.name[0] = 0; - } uint8 *mainProc14(uint16 overlay, uint16 idx) { @@ -585,9 +585,8 @@ int removeFinishedScripts(scriptInstanceStruct *ptrHandle) { if (ptr->scriptNumber == -1) { oldPtr->nextScriptPtr = ptr->nextScriptPtr; - if (ptr->var6 && ptr->varA) { - // MemFree(ptr->var6); - } + if (ptr->data) + MemFree(ptr->data); MemFree(ptr); @@ -601,6 +600,26 @@ int removeFinishedScripts(scriptInstanceStruct *ptrHandle) { return (0); } +void removeAllScripts(scriptInstanceStruct *ptrHandle) { + scriptInstanceStruct *ptr = ptrHandle->nextScriptPtr; // can't destruct the head + scriptInstanceStruct *oldPtr = ptrHandle; + + if (!ptr) + return; + + do { + oldPtr->nextScriptPtr = ptr->nextScriptPtr; + + if (ptr->data) + MemFree(ptr->data); + + MemFree(ptr); + + ptr = oldPtr->nextScriptPtr; + } while (ptr); +} + + bool testMask(int x, int y, unsigned char* pData, int stride) { unsigned char* ptr = y * stride + x / 8 + pData; @@ -1960,6 +1979,16 @@ void CruiseEngine::mainLoop(void) { } } while (!playerDontAskQuit && quitValue2 && quitValue != 7); + + // Free data + removeAllScripts(&relHead); + removeAllScripts(&procHead); + freeOverlayTable(); + closeCnf(); + closeBase(); + resetFileEntryRange(0, NUM_FILE_ENTRIES); + freeObjectList(&cellHead); + freeBackgroundIncrustList(&backgroundIncrustHead); } } // End of namespace Cruise diff --git a/engines/cruise/dataLoader.cpp b/engines/cruise/dataLoader.cpp index ec3c42ee46..44946890db 100644 --- a/engines/cruise/dataLoader.cpp +++ b/engines/cruise/dataLoader.cpp @@ -349,6 +349,8 @@ int loadFullBundle(const char *name, int startIdx) { error("Unknown fileType in loadFullBundle"); } + MemFree(ptr); + return 0; } diff --git a/engines/cruise/overlay.cpp b/engines/cruise/overlay.cpp index 21332c58c5..4176337108 100644 --- a/engines/cruise/overlay.cpp +++ b/engines/cruise/overlay.cpp @@ -46,6 +46,82 @@ void initOverlayTable(void) { numOfLoadedOverlay = 1; } +void freeOverlayTable() { + for (int i = 0; i < 90; i++) { + if (overlayTable[i].alreadyLoaded) + freeOverlay(i); + } +} + +int freeOverlay(int overlayIdx) { + ovlDataStruct *ovlDataPtr; + int i; + + if (overlayTable[overlayIdx].alreadyLoaded == 0) + return -4; + + overlayTable[overlayIdx].alreadyLoaded = 0; + + ovlDataPtr = overlayTable[overlayIdx].ovlData; + + if (!ovlDataPtr) + return -4; + + + /* + if (overlayTable[overlayIdx].var1E) { + MemFree(overlayTable[overlayIdx].var1E); + overlayTable[overlayIdx].var1E = NULL; + } + + if (overlayTable[overlayIdx].var16) { + MemFree(overlayTable[overlayIdx].var16); + overlayTable[overlayIdx].var16 = NULL; + } */ + + removeScript(overlayIdx, -1, &procHead); + removeScript(overlayIdx, -1, &procHead); + + removeScript(overlayIdx, -1, &relHead); + removeScript(overlayIdx, -1, &relHead); + + if (ovlDataPtr->stringTable) { + for (i = 0; i < ovlDataPtr->numStrings; ++i) + MemFree(ovlDataPtr->stringTable[i].string); + MemFree(ovlDataPtr->stringTable); + } + if (ovlDataPtr->arrayProc) { + ovlData3Struct *tempPtr = tempPtr = ovlDataPtr->arrayProc; + for (i = 0; i < ovlDataPtr->numProc; ++i, ++tempPtr) + MemFree(tempPtr->dataPtr); + MemFree(ovlDataPtr->arrayProc); + } + if (ovlDataPtr->ptr1) { + ovlData3Struct *tempPtr = (ovlData3Struct *)ovlDataPtr->ptr1; + for (i = 0; i < ovlDataPtr->numRel; ++i, ++tempPtr) + MemFree(tempPtr->dataPtr); + MemFree(ovlDataPtr->ptr1); + } + + MemFree(ovlDataPtr->arraySymbGlob); + MemFree(ovlDataPtr->arrayNameSymbGlob); + MemFree(ovlDataPtr->data4Ptr); + MemFree(ovlDataPtr->arrayMsgRelHeader); + MemFree(ovlDataPtr->ptr8); + MemFree(ovlDataPtr->arrayObject); + MemFree(ovlDataPtr->arrayObjVar); + MemFree(ovlDataPtr->arrayStates); + MemFree(ovlDataPtr->nameVerbGlob); + MemFree(ovlDataPtr->arrayNameObj); + + MemFree(ovlDataPtr); + overlayTable[overlayIdx].ovlData = NULL; + + debug(1, "freeOverlay: finish !"); + + return 0; +} + int loadOverlay(const char *scriptName) { int newNumberOfScript; bool scriptNotLoadedBefore; @@ -107,8 +183,9 @@ int loadOverlay(const char *scriptName) { unpackedSize = volumePtrToFileDescriptor[fileIdx].extSize + 2; - // TODO: here, can unpack in gfx module buffer - unpackedBuffer = (byte *)mallocAndZero(unpackedSize); + // This memory block will be later passed to a MemoryReadStream, which will dispose of it + unpackedBuffer = (byte *)malloc(unpackedSize); + memset(unpackedBuffer, 0, unpackedSize); if (!unpackedBuffer) { return (-2); @@ -130,7 +207,8 @@ int loadOverlay(const char *scriptName) { debug(1, "OVL loading done..."); - Common::MemoryReadStream s(unpackedBuffer, unpackedSize); + Common::MemoryReadStream s(unpackedBuffer, unpackedSize, true); + unpackedBuffer = NULL; ovlData = overlayTable[scriptIdx].ovlData; @@ -486,8 +564,9 @@ int loadOverlay(const char *scriptName) { unpackedSize = volumePtrToFileDescriptor[fileIdx].extSize + 2; - // TODO: here, can unpack in gfx module buffer - unpackedBuffer = (byte *)mallocAndZero(unpackedSize); + // This memory block will be later passed to a MemoryReadStream, which will dispose of it + unpackedBuffer = (byte *)malloc(unpackedSize); + memset(unpackedBuffer, 0, unpackedSize); if (!unpackedBuffer) { return (-2); @@ -509,7 +588,8 @@ int loadOverlay(const char *scriptName) { loadPackedFileToMem(fileIdx, (uint8 *) unpackedBuffer); } - Common::MemoryReadStream s2(unpackedBuffer, unpackedSize); + Common::MemoryReadStream s2(unpackedBuffer, unpackedSize, true); + unpackedBuffer = NULL; ovlData->specialString1Length = s2.readUint16BE(); if (ovlData->specialString1Length) { @@ -612,43 +692,12 @@ int loadOverlay(const char *scriptName) { } int releaseOverlay(const char *name) { - int overlayIdx; - ovlDataStruct *ovlDataPtr; - - overlayIdx = findOverlayByName(name); + int overlayIdx = findOverlayByName(name); if (overlayIdx == -4) return -4; - if (overlayTable[overlayIdx].alreadyLoaded == 0) - return -4; - - overlayTable[overlayIdx].alreadyLoaded = 0; - - ovlDataPtr = overlayTable[overlayIdx].ovlData; - - if (!ovlDataPtr) - return -4; - /* - if (overlayTable[overlayIdx].var1E) { - MemFree(overlayTable[overlayIdx].var1E); - overlayTable[overlayIdx].var1E = NULL; - } - - if (overlayTable[overlayIdx].var16) { - MemFree(overlayTable[overlayIdx].var16); - overlayTable[overlayIdx].var16 = NULL; - } */ - - removeScript(overlayIdx, -1, &procHead); - removeScript(overlayIdx, -1, &procHead); - - removeScript(overlayIdx, -1, &relHead); - removeScript(overlayIdx, -1, &relHead); - - debug(1, "releaseOverlay: finish !"); - - return 0; + return freeOverlay(overlayIdx); } int32 findOverlayByName2(const char *name) { diff --git a/engines/cruise/overlay.h b/engines/cruise/overlay.h index a779e60964..338ec51caf 100644 --- a/engines/cruise/overlay.h +++ b/engines/cruise/overlay.h @@ -184,6 +184,8 @@ int loadOverlay(const char * scriptName); int32 findOverlayByName2(const char * name); int findOverlayByName(const char *overlayName); int releaseOverlay(const char *name); +int freeOverlay(int overlayIdx); +void freeOverlayTable(); } // End of namespace Cruise diff --git a/engines/cruise/saveload.cpp b/engines/cruise/saveload.cpp index 53d70044b4..b2a1514ae5 100644 --- a/engines/cruise/saveload.cpp +++ b/engines/cruise/saveload.cpp @@ -332,7 +332,7 @@ void syncScript(Common::Serializer &s, scriptInstanceStruct *entry) { s.syncAsSint16LE(ptr->ccr); s.syncAsSint16LE(ptr->scriptOffset); s.syncAsUint32LE(dummyLong); - s.syncAsSint16LE(ptr->varA); + s.syncAsSint16LE(ptr->dataSize); s.syncAsSint16LE(ptr->scriptNumber); s.syncAsSint16LE(ptr->overlayNumber); s.syncAsSint16LE(ptr->sysKey); @@ -342,12 +342,12 @@ void syncScript(Common::Serializer &s, scriptInstanceStruct *entry) { s.syncAsSint16LE(ptr->var18); s.syncAsSint16LE(ptr->var1A); - s.syncAsSint16LE(ptr->varA); + s.syncAsSint16LE(ptr->dataSize); - if (ptr->varA) { + if (ptr->dataSize) { if (s.isLoading()) - ptr->var6 = (byte *)mallocAndZero(ptr->varA); - s.syncBytes(ptr->var6, ptr->varA); + ptr->data = (byte *)mallocAndZero(ptr->dataSize); + s.syncBytes(ptr->data, ptr->dataSize); } if (s.isLoading()) { diff --git a/engines/cruise/script.cpp b/engines/cruise/script.cpp index 1e2921fe5e..9ef9c686b1 100644 --- a/engines/cruise/script.cpp +++ b/engines/cruise/script.cpp @@ -540,13 +540,13 @@ uint8 *attacheNewScriptToTail(scriptInstanceStruct *scriptHandlePtr, int16 overl if (!tempPtr) return (NULL); - tempPtr->var6 = NULL; + tempPtr->data = NULL; if (var_C) { - tempPtr->var6 = (uint8 *) mallocAndZero(var_C); + tempPtr->data = (uint8 *) mallocAndZero(var_C); } - tempPtr->varA = var_C; + tempPtr->dataSize = var_C; tempPtr->nextScriptPtr = NULL; tempPtr->scriptOffset = 0; @@ -568,7 +568,7 @@ uint8 *attacheNewScriptToTail(scriptInstanceStruct *scriptHandlePtr, int16 overl oldTail->nextScriptPtr = tempPtr; // attache the new node to the list - return (tempPtr->var6); + return (tempPtr->data); } int executeScripts(scriptInstanceStruct *ptr) { @@ -608,7 +608,7 @@ int executeScripts(scriptInstanceStruct *ptr) { currentData3DataPtr = ptr2->dataPtr; - scriptDataPtrTable[1] = (uint8 *) ptr->var6; + scriptDataPtrTable[1] = (uint8 *) ptr->data; scriptDataPtrTable[2] = getDataFromData3(ptr2, 1); scriptDataPtrTable[5] = ovlData->data4Ptr; // free strings scriptDataPtrTable[6] = ovlData->ptr8; diff --git a/engines/cruise/script.h b/engines/cruise/script.h index ea78de15da..bcaa2db9ff 100644 --- a/engines/cruise/script.h +++ b/engines/cruise/script.h @@ -39,8 +39,8 @@ struct scriptInstanceStruct { struct scriptInstanceStruct *nextScriptPtr; int16 ccr; int16 scriptOffset; - uint8 *var6; - int16 varA; + uint8 *data; + int16 dataSize; int16 scriptNumber; int16 overlayNumber; int16 sysKey; -- cgit v1.2.3