aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorPaul Gilbert2017-11-21 21:05:40 -0500
committerPaul Gilbert2017-11-21 21:05:40 -0500
commit13f74027e8e561662bad29bac9f9950782a2ebea (patch)
tree7cb957cc71225d658d1903743d665689e0dfef26 /engines
parent89d20bafa98168dbe58ba0b71058deaf6026e9ba (diff)
downloadscummvm-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.cpp14
-rw-r--r--engines/tsage/saveload.h3
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();