[Scummvm-git-logs] scummvm master -> cd54d61de7ebf26ae78aa4adce7d8975ff6a5c5d
elasota
noreply at scummvm.org
Sat Jul 9 05:56:23 UTC 2022
This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
cd54d61de7 MTROPOLIS: Add auto-save option and add versioning to save files.
Commit: cd54d61de7ebf26ae78aa4adce7d8975ff6a5c5d
https://github.com/scummvm/scummvm/commit/cd54d61de7ebf26ae78aa4adce7d8975ff6a5c5d
Author: elasota (ejlasota at gmail.com)
Date: 2022-07-09T01:55:56-04:00
Commit Message:
MTROPOLIS: Add auto-save option and add versioning to save files.
Changed paths:
engines/mtropolis/detection.cpp
engines/mtropolis/detection_tables.h
engines/mtropolis/modifiers.cpp
engines/mtropolis/modifiers.h
engines/mtropolis/mtropolis.cpp
engines/mtropolis/mtropolis.h
engines/mtropolis/plugin/standard.cpp
engines/mtropolis/plugin/standard.h
engines/mtropolis/runtime.cpp
engines/mtropolis/runtime.h
engines/mtropolis/saveload.cpp
engines/mtropolis/saveload.h
diff --git a/engines/mtropolis/detection.cpp b/engines/mtropolis/detection.cpp
index e9ea41b8fa7..8280f2867fa 100644
--- a/engines/mtropolis/detection.cpp
+++ b/engines/mtropolis/detection.cpp
@@ -59,6 +59,17 @@ static const ADExtraGuiOptionsMap optionsList[] = {
0
}
},
+ {
+ GAMEOPTION_AUTO_SAVE,
+ {
+ _s("Save Progress Automatically"),
+ _s("Automatically saves the game at certain progress points."),
+ "mtropolis_mod_auto_save",
+ true,
+ 0,
+ 0
+ }
+ },
{
GAMEOPTION_LAUNCH_DEBUG,
{
diff --git a/engines/mtropolis/detection_tables.h b/engines/mtropolis/detection_tables.h
index c84b5d8a308..40a63564187 100644
--- a/engines/mtropolis/detection_tables.h
+++ b/engines/mtropolis/detection_tables.h
@@ -30,6 +30,7 @@
#define GAMEOPTION_DYNAMIC_MIDI GUIO_GAMEOPTIONS2
#define GAMEOPTION_LAUNCH_DEBUG GUIO_GAMEOPTIONS3
#define GAMEOPTION_LAUNCH_BREAK GUIO_GAMEOPTIONS4
+#define GAMEOPTION_AUTO_SAVE GUIO_GAMEOPTIONS5
namespace MTropolis {
@@ -51,7 +52,7 @@ static const MTropolisGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformMacintosh,
ADGF_UNSTABLE,
- GUIO1(GAMEOPTION_WIDESCREEN_MOD)
+ GUIO2(GAMEOPTION_WIDESCREEN_MOD, GAMEOPTION_AUTO_SAVE)
},
GID_OBSIDIAN,
0,
@@ -78,7 +79,7 @@ static const MTropolisGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_UNSTABLE,
- GUIO1(GAMEOPTION_WIDESCREEN_MOD)
+ GUIO2(GAMEOPTION_WIDESCREEN_MOD, GAMEOPTION_AUTO_SAVE)
},
GID_OBSIDIAN,
0,
diff --git a/engines/mtropolis/modifiers.cpp b/engines/mtropolis/modifiers.cpp
index af7551546ee..cf7451fdd4d 100644
--- a/engines/mtropolis/modifiers.cpp
+++ b/engines/mtropolis/modifiers.cpp
@@ -34,7 +34,7 @@ class CompoundVarLoader : public ISaveReader {
public:
explicit CompoundVarLoader(RuntimeObject *object);
- bool readSave(Common::ReadStream *stream) override;
+ bool readSave(Common::ReadStream *stream, uint32 saveFileVersion) override;
private:
RuntimeObject *_object;
@@ -43,7 +43,7 @@ private:
CompoundVarLoader::CompoundVarLoader(RuntimeObject *object) : _object(object) {
}
-bool CompoundVarLoader::readSave(Common::ReadStream *stream) {
+bool CompoundVarLoader::readSave(Common::ReadStream *stream, uint32 saveFileVersion) {
if (_object == nullptr || !_object->isModifier())
return false;
@@ -52,7 +52,7 @@ bool CompoundVarLoader::readSave(Common::ReadStream *stream) {
if (!saveLoad)
return false;
- if (!saveLoad->load(modifier, stream))
+ if (!saveLoad->load(modifier, stream, saveFileVersion))
return false;
if (stream->err())
@@ -63,9 +63,6 @@ bool CompoundVarLoader::readSave(Common::ReadStream *stream) {
return true;
}
-
-
-
bool BehaviorModifier::load(ModifierLoaderContext &context, const Data::BehaviorModifier &data) {
if (data.numChildren > 0) {
ChildLoaderContext loaderContext;
@@ -1733,7 +1730,7 @@ void CompoundVariableModifier::SaveLoad::saveInternal(Common::WriteStream *strea
childSL.saveLoad->save(childSL.modifier, stream);
}
-bool CompoundVariableModifier::SaveLoad::loadInternal(Common::ReadStream *stream) {
+bool CompoundVariableModifier::SaveLoad::loadInternal(Common::ReadStream *stream, uint32 saveFileVersion) {
const uint32 numChildren = stream->readUint32BE();
if (stream->err())
return false;
@@ -1742,7 +1739,7 @@ bool CompoundVariableModifier::SaveLoad::loadInternal(Common::ReadStream *stream
return false;
for (const ChildSaveLoad &childSL : _childrenSaveLoad) {
- if (!childSL.saveLoad->load(childSL.modifier, stream))
+ if (!childSL.saveLoad->load(childSL.modifier, stream, saveFileVersion))
return false;
}
@@ -1825,7 +1822,7 @@ void BooleanVariableModifier::SaveLoad::saveInternal(Common::WriteStream *stream
stream->writeByte(_value ? 1 : 0);
}
-bool BooleanVariableModifier::SaveLoad::loadInternal(Common::ReadStream *stream) {
+bool BooleanVariableModifier::SaveLoad::loadInternal(Common::ReadStream *stream, uint32 saveFileVersion) {
byte b = stream->readByte();
if (stream->err())
return false;
@@ -1896,7 +1893,7 @@ void IntegerVariableModifier::SaveLoad::saveInternal(Common::WriteStream *stream
stream->writeSint32BE(_value);
}
-bool IntegerVariableModifier::SaveLoad::loadInternal(Common::ReadStream *stream) {
+bool IntegerVariableModifier::SaveLoad::loadInternal(Common::ReadStream *stream, uint32 saveFileVersion) {
_value = stream->readSint32BE();
if (stream->err())
@@ -1985,7 +1982,7 @@ void IntegerRangeVariableModifier::SaveLoad::saveInternal(Common::WriteStream *s
stream->writeSint32BE(_range.max);
}
-bool IntegerRangeVariableModifier::SaveLoad::loadInternal(Common::ReadStream *stream) {
+bool IntegerRangeVariableModifier::SaveLoad::loadInternal(Common::ReadStream *stream, uint32 saveFileVersion) {
_range.min = stream->readSint32BE();
_range.max = stream->readSint32BE();
@@ -2075,7 +2072,7 @@ void VectorVariableModifier::SaveLoad::saveInternal(Common::WriteStream *stream)
stream->writeDoubleBE(_vector.magnitude);
}
-bool VectorVariableModifier::SaveLoad::loadInternal(Common::ReadStream *stream) {
+bool VectorVariableModifier::SaveLoad::loadInternal(Common::ReadStream *stream, uint32 saveFileVersion) {
_vector.angleDegrees = stream->readDoubleBE();
_vector.magnitude = stream->readDoubleBE();
@@ -2167,7 +2164,7 @@ void PointVariableModifier::SaveLoad::saveInternal(Common::WriteStream *stream)
stream->writeSint16BE(_value.y);
}
-bool PointVariableModifier::SaveLoad::loadInternal(Common::ReadStream *stream) {
+bool PointVariableModifier::SaveLoad::loadInternal(Common::ReadStream *stream, uint32 saveFileVersion) {
_value.x = stream->readSint16BE();
_value.y = stream->readSint16BE();
@@ -2233,7 +2230,7 @@ void FloatingPointVariableModifier::SaveLoad::saveInternal(Common::WriteStream *
stream->writeDoubleBE(_value);
}
-bool FloatingPointVariableModifier::SaveLoad::loadInternal(Common::ReadStream *stream) {
+bool FloatingPointVariableModifier::SaveLoad::loadInternal(Common::ReadStream *stream, uint32 saveFileVersion) {
_value = stream->readDoubleBE();
if (stream->err())
@@ -2297,7 +2294,7 @@ void StringVariableModifier::SaveLoad::saveInternal(Common::WriteStream *stream)
stream->writeString(_value);
}
-bool StringVariableModifier::SaveLoad::loadInternal(Common::ReadStream *stream) {
+bool StringVariableModifier::SaveLoad::loadInternal(Common::ReadStream *stream, uint32 saveFileVersion) {
uint32 size = stream->readUint32BE();
if (stream->err())
diff --git a/engines/mtropolis/modifiers.h b/engines/mtropolis/modifiers.h
index e7c59224ae8..600f51e57da 100644
--- a/engines/mtropolis/modifiers.h
+++ b/engines/mtropolis/modifiers.h
@@ -690,7 +690,7 @@ private:
explicit SaveLoad(CompoundVariableModifier *modifier);
void saveInternal(Common::WriteStream *stream) const override;
- bool loadInternal(Common::ReadStream *stream) override;
+ bool loadInternal(Common::ReadStream *stream, uint32 saveFileVersion) override;
void commitLoad() const override;
private:
@@ -744,7 +744,7 @@ private:
private:
void commitLoad() const override;
void saveInternal(Common::WriteStream *stream) const override;
- bool loadInternal(Common::ReadStream *stream) override;
+ bool loadInternal(Common::ReadStream *stream, uint32 saveFileVersion) override;
BooleanVariableModifier *_modifier;
bool _value;
@@ -779,7 +779,7 @@ private:
private:
void commitLoad() const override;
void saveInternal(Common::WriteStream *stream) const override;
- bool loadInternal(Common::ReadStream *stream) override;
+ bool loadInternal(Common::ReadStream *stream, uint32 saveFileVersion) override;
IntegerVariableModifier *_modifier;
int32 _value;
@@ -817,7 +817,7 @@ private:
private:
void commitLoad() const override;
void saveInternal(Common::WriteStream *stream) const override;
- bool loadInternal(Common::ReadStream *stream) override;
+ bool loadInternal(Common::ReadStream *stream, uint32 saveFileVersion) override;
IntegerRangeVariableModifier *_modifier;
IntRange _range;
@@ -855,7 +855,7 @@ private:
private:
void commitLoad() const override;
void saveInternal(Common::WriteStream *stream) const override;
- bool loadInternal(Common::ReadStream *stream) override;
+ bool loadInternal(Common::ReadStream *stream, uint32 saveFileVersion) override;
VectorVariableModifier *_modifier;
AngleMagVector _vector;
@@ -893,7 +893,7 @@ private:
private:
void commitLoad() const override;
void saveInternal(Common::WriteStream *stream) const override;
- bool loadInternal(Common::ReadStream *stream) override;
+ bool loadInternal(Common::ReadStream *stream, uint32 saveFileVersion) override;
PointVariableModifier *_modifier;
Common::Point _value;
@@ -928,7 +928,7 @@ private:
private:
void commitLoad() const override;
void saveInternal(Common::WriteStream *stream) const override;
- bool loadInternal(Common::ReadStream *stream) override;
+ bool loadInternal(Common::ReadStream *stream, uint32 saveFileVersion) override;
FloatingPointVariableModifier *_modifier;
double _value;
@@ -963,7 +963,7 @@ private:
private:
void commitLoad() const override;
void saveInternal(Common::WriteStream *stream) const override;
- bool loadInternal(Common::ReadStream *stream) override;
+ bool loadInternal(Common::ReadStream *stream, uint32 saveFileVersion) override;
StringVariableModifier *_modifier;
Common::String _value;
diff --git a/engines/mtropolis/mtropolis.cpp b/engines/mtropolis/mtropolis.cpp
index a99247a3fd7..aca9a3b09e8 100644
--- a/engines/mtropolis/mtropolis.cpp
+++ b/engines/mtropolis/mtropolis.cpp
@@ -120,7 +120,9 @@ Common::Error MTropolisEngine::run() {
enhancedColorDepthMode = kColorDepthMode32Bit;
HackSuites::addObsidianBugFixes(*_gameDescription, _runtime->getHacks());
- HackSuites::addObsidianAutoSaves(*_gameDescription, _runtime->getHacks(), this);
+
+ if (ConfMan.getBool("mtropolis_mod_auto_save"))
+ HackSuites::addObsidianAutoSaves(*_gameDescription, _runtime->getHacks(), this);
if (ConfMan.getBool("mtropolis_mod_obsidian_widescreen")) {
_runtime->getHacks().reportDisplaySize = Common::Point(640, 480);
diff --git a/engines/mtropolis/mtropolis.h b/engines/mtropolis/mtropolis.h
index af743426c69..73dfac59ba3 100644
--- a/engines/mtropolis/mtropolis.h
+++ b/engines/mtropolis/mtropolis.h
@@ -70,6 +70,9 @@ protected:
void pauseEngineIntern(bool pause) override;
private:
+ static const uint kCurrentSaveFileVersion = 1;
+ static const uint kSavegameSignature = 0x6d545356; // mTSV
+
Common::ScopedPtr<Runtime> _runtime;
};
diff --git a/engines/mtropolis/plugin/standard.cpp b/engines/mtropolis/plugin/standard.cpp
index 767f1d8205a..3f82ec85235 100644
--- a/engines/mtropolis/plugin/standard.cpp
+++ b/engines/mtropolis/plugin/standard.cpp
@@ -2201,7 +2201,7 @@ void ObjectReferenceVariableModifier::SaveLoad::saveInternal(Common::WriteStream
stream->writeString(_objectPath);
}
-bool ObjectReferenceVariableModifier::SaveLoad::loadInternal(Common::ReadStream *stream) {
+bool ObjectReferenceVariableModifier::SaveLoad::loadInternal(Common::ReadStream *stream, uint32 saveFileVersion) {
uint32 stringLen = stream->readUint32BE();
if (stream->err())
return false;
@@ -2805,7 +2805,7 @@ void ListVariableModifier::SaveLoad::saveInternal(Common::WriteStream *stream) c
recursiveWriteList(_list.get(), stream);
}
-bool ListVariableModifier::SaveLoad::loadInternal(Common::ReadStream *stream) {
+bool ListVariableModifier::SaveLoad::loadInternal(Common::ReadStream *stream, uint32 saveFileVersion) {
Common::SharedPtr<DynamicList> list = recursiveReadList(stream);
if (list) {
_list = list;
diff --git a/engines/mtropolis/plugin/standard.h b/engines/mtropolis/plugin/standard.h
index ebb3242c652..f5033c6bc12 100644
--- a/engines/mtropolis/plugin/standard.h
+++ b/engines/mtropolis/plugin/standard.h
@@ -178,7 +178,7 @@ private:
private:
void commitLoad() const override;
void saveInternal(Common::WriteStream *stream) const override;
- bool loadInternal(Common::ReadStream *stream) override;
+ bool loadInternal(Common::ReadStream *stream, uint32 saveFileVersion) override;
ObjectReferenceVariableModifier *_modifier;
Common::String _objectPath;
@@ -326,7 +326,7 @@ private:
private:
void commitLoad() const override;
void saveInternal(Common::WriteStream *stream) const override;
- bool loadInternal(Common::ReadStream *stream) override;
+ bool loadInternal(Common::ReadStream *stream, uint32 saveFileVersion) override;
static void recursiveWriteList(DynamicList *list, Common::WriteStream *stream);
static Common::SharedPtr<DynamicList> recursiveReadList(Common::ReadStream *stream);
diff --git a/engines/mtropolis/runtime.cpp b/engines/mtropolis/runtime.cpp
index 58f0282930f..edbe6fe1645 100644
--- a/engines/mtropolis/runtime.cpp
+++ b/engines/mtropolis/runtime.cpp
@@ -7520,7 +7520,7 @@ void ModifierSaveLoad::save(Modifier *modifier, Common::WriteStream *stream) {
saveInternal(stream);
}
-bool ModifierSaveLoad::load(Modifier *modifier, Common::ReadStream *stream) {
+bool ModifierSaveLoad::load(Modifier *modifier, Common::ReadStream *stream, uint32 saveFileVersion) {
uint32 checkGUID = stream->readUint32BE();
uint16 nameLen = stream->readUint16BE();
@@ -7544,7 +7544,7 @@ bool ModifierSaveLoad::load(Modifier *modifier, Common::ReadStream *stream) {
if (modifier->getStaticGUID() != checkGUID)
return false;
- return loadInternal(stream);
+ return loadInternal(stream, saveFileVersion);
}
ModifierHooks::~ModifierHooks() {
diff --git a/engines/mtropolis/runtime.h b/engines/mtropolis/runtime.h
index 69ebbca804b..09a5afd473e 100644
--- a/engines/mtropolis/runtime.h
+++ b/engines/mtropolis/runtime.h
@@ -2547,7 +2547,7 @@ public:
virtual ~ModifierSaveLoad();
void save(Modifier *modifier, Common::WriteStream *stream);
- bool load(Modifier *modifier, Common::ReadStream *stream);
+ bool load(Modifier *modifier, Common::ReadStream *stream, uint32 saveFileVersion);
virtual void commitLoad() const = 0;
protected:
@@ -2556,7 +2556,7 @@ protected:
// Loads the modifier state from a stream into the save/load state and returns true
// if successful. This will not trigger any actual changes until "commit" is called.
- virtual bool loadInternal(Common::ReadStream *stream) = 0;
+ virtual bool loadInternal(Common::ReadStream *stream, uint32 saveFileVersion) = 0;
};
class ModifierHooks {
diff --git a/engines/mtropolis/saveload.cpp b/engines/mtropolis/saveload.cpp
index b4d3b28ee5c..0ae46092663 100644
--- a/engines/mtropolis/saveload.cpp
+++ b/engines/mtropolis/saveload.cpp
@@ -20,8 +20,10 @@
*/
#include "common/savefile.h"
+#include "common/system.h"
#include "common/translation.h"
+#include "gui/message.h"
#include "gui/saveload.h"
#include "mtropolis/mtropolis.h"
@@ -74,6 +76,10 @@ bool MTropolisEngine::promptSave(ISaveWriter *writer) {
Common::String saveFileName = getSaveStateName(slot);
Common::SharedPtr<Common::OutSaveFile> out(_saveFileMan->openForSaving(saveFileName, false));
+
+ out->writeUint32BE(kSavegameSignature);
+ out->writeUint32BE(kCurrentSaveFileVersion);
+
if (!writer->writeSave(out.get()) || out->err())
warning("An error occurred while writing file '%s'", saveFileName.c_str());
@@ -96,7 +102,37 @@ bool MTropolisEngine::promptLoad(ISaveReader *reader) {
Common::String saveFileName = getSaveStateName(slot);
Common::SharedPtr<Common::InSaveFile> in(_saveFileMan->openForLoading(saveFileName));
- if (!reader->readSave(in.get())) {
+
+ uint32 signature = in->readUint32BE();
+ uint32 saveFileVersion = in->readUint32BE();
+ if (in->err()) {
+ GUI::MessageDialog dialog(_("Failed to read version information from save file"));
+ dialog.runModal();
+
+ warning("An error occurred while reading the save file version from '%s'", saveFileName.c_str());
+ return false;
+ }
+
+ if (signature != kSavegameSignature) {
+ GUI::MessageDialog dialog(_("Failed to load save, the save file doesn't contain valid version information."));
+ dialog.runModal();
+
+ warning("Save file '%s' version is above the current save file version", saveFileName.c_str());
+ return false;
+ }
+
+ if (saveFileVersion > kCurrentSaveFileVersion) {
+ GUI::MessageDialog dialog(_("Failed to load save, the save file was created by a newer version of ScummVM."));
+ dialog.runModal();
+
+ warning("Save file '%s' version is above the current save file version", saveFileName.c_str());
+ return false;
+ }
+
+ if (!reader->readSave(in.get(), saveFileVersion)) {
+ GUI::MessageDialog dialog(_("Failed to load save, an error occurred when reading the save game data."));
+ dialog.runModal();
+
warning("An error occurred while reading file '%s'", saveFileName.c_str());
return false;
}
@@ -109,11 +145,17 @@ bool MTropolisEngine::autoSave(ISaveWriter *writer) {
Common::String saveFileName = getSaveStateName(slot);
Common::SharedPtr<Common::OutSaveFile> out(_saveFileMan->openForSaving(saveFileName, false));
+
+ out->writeUint32BE(kSavegameSignature);
+ out->writeUint32BE(kCurrentSaveFileVersion);
+
if (!writer->writeSave(out.get()) || out->err())
warning("An error occurred while writing file '%s'", saveFileName.c_str());
getMetaEngine()->appendExtendedSave(out.get(), getTotalPlayTime(), "Auto Save", true);
+ g_system->displayMessageOnOSD(_("Progress Saved"));
+
return true;
}
diff --git a/engines/mtropolis/saveload.h b/engines/mtropolis/saveload.h
index 3342f3d9f41..6ef2e173799 100644
--- a/engines/mtropolis/saveload.h
+++ b/engines/mtropolis/saveload.h
@@ -42,7 +42,7 @@ struct ISaveWriter : public IInterfaceBase {
};
struct ISaveReader : public IInterfaceBase {
- virtual bool readSave(Common::ReadStream *stream) = 0;
+ virtual bool readSave(Common::ReadStream *stream, uint32 saveFileVersion) = 0;
};
struct ISaveUIProvider : public IInterfaceBase {
More information about the Scummvm-git-logs
mailing list