[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