diff options
author | Paul Gilbert | 2017-11-21 21:05:40 -0500 |
---|---|---|
committer | Paul Gilbert | 2017-11-21 21:05:40 -0500 |
commit | 13f74027e8e561662bad29bac9f9950782a2ebea (patch) | |
tree | 7cb957cc71225d658d1903743d665689e0dfef26 /engines | |
parent | 89d20bafa98168dbe58ba0b71058deaf6026e9ba (diff) | |
download | scummvm-rg350-13f74027e8e561662bad29bac9f9950782a2ebea.tar.gz scummvm-rg350-13f74027e8e561662bad29bac9f9950782a2ebea.tar.bz2 scummvm-rg350-13f74027e8e561662bad29bac9f9950782a2ebea.zip |
TSAGE: Fix loading savegames with unreferenced dynamic objects
Diffstat (limited to 'engines')
-rw-r--r-- | engines/tsage/saveload.cpp | 14 | ||||
-rw-r--r-- | engines/tsage/saveload.h | 3 |
2 files changed, 14 insertions, 3 deletions
diff --git a/engines/tsage/saveload.cpp b/engines/tsage/saveload.cpp index 3cb8e52692..03f615db21 100644 --- a/engines/tsage/saveload.cpp +++ b/engines/tsage/saveload.cpp @@ -211,12 +211,14 @@ Common::Error Saver::restore(int slot) { // Note: I don't store pointers to instantiated objects here, because it's not necessary - the mere act // of instantiating a saved object registers it with the saver, and will then be resolved to whatever // object originally had a pointer to it as part of the post-processing step + DynObjects dynObjects; Common::String className; serializer.syncString(className); while (className != "END") { SavedObject *savedObject; if (!_factoryPtr || ((savedObject = _factoryPtr(className)) == NULL)) error("Unknown class name '%s' encountered trying to restore savegame", className.c_str()); + dynObjects.push_back(savedObject); // Populate the contents of the object savedObject->synchronize(serializer); @@ -226,7 +228,12 @@ Common::Error Saver::restore(int slot) { } // Post-process any unresolved pointers to get the correct pointer - resolveLoadPointers(); + resolveLoadPointers(dynObjects); + + // Post-process safety check: if any dynamically created objects didn't get any + // references, then delete them, since they'd never be freed otherwise + for (DynObjects::iterator i = dynObjects.begin(); i != dynObjects.end(); ++i) + delete *i; delete saveFile; @@ -392,7 +399,7 @@ void Saver::listObjects() { /** * Returns the pointer associated with the specified object index */ -void Saver::resolveLoadPointers() { +void Saver::resolveLoadPointers(DynObjects &dynObjects) { if (_unresolvedPtrs.size() == 0) // Nothing to resolve return; @@ -410,6 +417,9 @@ void Saver::resolveLoadPointers() { SavedObject **objPP = r._savedObject; *objPP = pObj; iPtr = _unresolvedPtrs.erase(iPtr); + + // If it's a dynamic object, remove it from the dynamic objects list + dynObjects.remove(pObj); } else { ++iPtr; } diff --git a/engines/tsage/saveload.h b/engines/tsage/saveload.h index be5ff51ffb..04a1e02b28 100644 --- a/engines/tsage/saveload.h +++ b/engines/tsage/saveload.h @@ -201,6 +201,7 @@ public: typedef SavedObject *(*SavedObjectFactory)(const Common::String &className); class Saver { + typedef Common::List<SavedObject *> DynObjects; private: Common::List<SavedObject *> _objList; FunctionList<bool> _saveNotifiers; @@ -213,7 +214,7 @@ private: bool _macroSaveFlag; bool _macroRestoreFlag; - void resolveLoadPointers(); + void resolveLoadPointers(DynObjects &dynObjects); public: Saver(); ~Saver(); |