[Scummvm-git-logs] scummvm master -> 9f07bbacd2c6dc183c13e5734138f9b9c4674820
mduggan
noreply at scummvm.org
Sun Apr 13 06:56:02 UTC 2025
This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://api.github.com/repos/scummvm/scummvm .
Summary:
9f07bbacd2 DGDS: Add support for loading original save format
Commit: 9f07bbacd2c6dc183c13e5734138f9b9c4674820
https://github.com/scummvm/scummvm/commit/9f07bbacd2c6dc183c13e5734138f9b9c4674820
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2025-04-13T16:53:54+10:00
Commit Message:
DGDS: Add support for loading original save format
Changed paths:
engines/dgds/dgds.cpp
engines/dgds/dgds.h
engines/dgds/metaengine.cpp
engines/dgds/scene.cpp
engines/dgds/scene.h
diff --git a/engines/dgds/dgds.cpp b/engines/dgds/dgds.cpp
index 42abb74c309..639764850c9 100644
--- a/engines/dgds/dgds.cpp
+++ b/engines/dgds/dgds.cpp
@@ -889,6 +889,32 @@ void DgdsEngine::disableKeymapper() {
_eventMan->getKeymapper()->setEnabledKeymapType(Common::Keymap::kKeymapTypeGui);
}
+Common::Error DgdsEngine::loadGameStream(Common::SeekableReadStream *stream) {
+ //
+ // First check if it's an original game save file
+ //
+ // This should be safe on ScummVM save files because they have
+ // a 32 bit version number first, so the string will be 0 length.
+ //
+ uint16 origSlotNum = stream->readUint16LE();
+ Common::String origName = stream->readString();
+ uint32 magic = stream->readUint32LE();
+
+ if (magic == _gdsScene->getMagic()) {
+ // Original type save.
+ debug("Loading original game save %03d '%s' magic %08x", origSlotNum, origName.c_str(), magic);
+ _menu->hideMenu();
+ _gdsScene->loadGameStateFromFile(stream, origName);
+ return Common::kNoError;
+ } else {
+ // Rewind stream to load ScummVM save
+ stream->seek(0, SEEK_SET);
+ Common::Serializer s(stream, nullptr);
+ return syncGame(s);
+ }
+}
+
+
Common::Error DgdsEngine::syncGame(Common::Serializer &s) {
//
// Version history:
@@ -898,7 +924,6 @@ Common::Error DgdsEngine::syncGame(Common::Serializer &s) {
// 3: Stopped saving ADS/TTM state
// 4: Stopped saving palette state
//
-
assert(_scene && _gdsScene);
_menu->hideMenu();
diff --git a/engines/dgds/dgds.h b/engines/dgds/dgds.h
index f431e423670..1eedfb4d349 100644
--- a/engines/dgds/dgds.h
+++ b/engines/dgds/dgds.h
@@ -247,10 +247,7 @@ public:
return syncGame(s);
}
- Common::Error loadGameStream(Common::SeekableReadStream *stream) override {
- Common::Serializer s(stream, nullptr);
- return syncGame(s);
- }
+ Common::Error loadGameStream(Common::SeekableReadStream *stream) override;
bool hasFeature(EngineFeature f) const override {
return
diff --git a/engines/dgds/metaengine.cpp b/engines/dgds/metaengine.cpp
index 3d9499c75c5..daa373cd8ca 100644
--- a/engines/dgds/metaengine.cpp
+++ b/engines/dgds/metaengine.cpp
@@ -24,6 +24,7 @@
#include "engines/advancedDetector.h"
#include "common/system.h"
#include "common/translation.h"
+#include "common/savefile.h"
#include "backends/keymapper/action.h"
#include "backends/keymapper/keymapper.h"
@@ -40,6 +41,7 @@ public:
Common::Error createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const override;
Common::KeymapArray initKeymaps(const char *target) const override;
+ SaveStateDescriptor querySaveMetaInfos(const char *target, int slot) const override;
};
bool DgdsMetaEngine::hasFeature(MetaEngineFeature f) const {
@@ -96,6 +98,44 @@ Common::KeymapArray DgdsMetaEngine::initKeymaps(const char *target) const {
return Common::Keymap::arrayOf(map);
}
+//
+// Used for detecting original game saves
+//
+// Ideally save file magic should be compared to the one in the GDS file,
+// but when loading from the launcher the game engine isn't created,
+// so use a static list.
+//
+static const uint32 GAME_MAGICS[] {
+ 0x53E83426, // Rise of the Dragon
+ 0xFF553726, // Heart of China
+ 0x7ADA2628, // Adventures of Willy Beamish
+};
+
+SaveStateDescriptor DgdsMetaEngine::querySaveMetaInfos(const char *target, int slot) const {
+ SaveStateDescriptor desc = AdvancedMetaEngine::querySaveMetaInfos(target, slot);
+ if (!desc.isValid() && slot > 0) {
+ const Common::String filename = getSavegameFile(slot, target);
+ Common::ScopedPtr<Common::InSaveFile> f(g_system->getSavefileManager()->openForLoading(filename));
+
+ if (f) {
+ uint16 origSlotNum = f->readUint16LE();
+ const Common::String origName = f->readString();
+ uint32 magic = f->readUint32BE();
+
+ for (uint32 game_magic : GAME_MAGICS) {
+ if (magic == game_magic && origSlotNum < 4096 && !origName.empty()) {
+ desc.setDescription(origName);
+ desc.setSaveSlot(slot);
+ break;
+ }
+ }
+ }
+ }
+
+ return desc;
+}
+
+
#if PLUGIN_ENABLED_DYNAMIC(DGDS)
REGISTER_PLUGIN_DYNAMIC(DGDS, PLUGIN_TYPE_ENGINE, DgdsMetaEngine);
#else
diff --git a/engines/dgds/scene.cpp b/engines/dgds/scene.cpp
index 7ee29f4e971..0b1ca895739 100644
--- a/engines/dgds/scene.cpp
+++ b/engines/dgds/scene.cpp
@@ -1811,11 +1811,6 @@ bool GDSScene::load(const Common::String &filename, ResourceManager *resourceMan
bool GDSScene::loadRestart(const Common::String &filename, ResourceManager *resourceManager, Decompressor *decompressor) {
- // TODO: RST file format is also the original save game format, so this
- // function could be used to load saves from the original games.
- // The only thing to change would be supporting loading of sound bank
- // and game time (which would need converting to our game time)
-
Common::SeekableReadStream *file = resourceManager->getResource(filename);
if (!file)
error("Game state data %s not found", filename.c_str());
@@ -1824,6 +1819,14 @@ bool GDSScene::loadRestart(const Common::String &filename, ResourceManager *reso
if (magic != _magic)
error("%s file magic doesn't match game (%04X vs %04X)", filename.c_str(), magic, _magic);
+ loadGameStateFromFile(file, filename);
+
+ delete file;
+
+ return true;
+}
+
+void GDSScene::loadGameStateFromFile(Common::SeekableReadStream *file, const Common::String &filename) {
uint16 num = file->readUint16LE();
// Find matching game item and load its values
while (num && !file->eos()) {
@@ -1979,10 +1982,9 @@ bool GDSScene::loadRestart(const Common::String &filename, ResourceManager *reso
num = triggers[t++];
}
}
-
- return true;
}
+
void GDSScene::initIconSizes() {
const Common::SharedPtr<Image> icons = DgdsEngine::getInstance()->getIcons();
uint16 nicons = icons ? icons->getFrames().size() : 0;
diff --git a/engines/dgds/scene.h b/engines/dgds/scene.h
index 07079094f4d..29ca00a6a2a 100644
--- a/engines/dgds/scene.h
+++ b/engines/dgds/scene.h
@@ -216,6 +216,7 @@ public:
bool load(const Common::String &filename, ResourceManager *resourceManager, Decompressor *decompressor);
bool loadRestart(const Common::String &filename, ResourceManager *resourceManager, Decompressor *decompressor);
+ void loadGameStateFromFile(Common::SeekableReadStream *file, const Common::String &filename);
bool parse(Common::SeekableReadStream *s) override;
bool parseInf(Common::SeekableReadStream *s);
const Common::String &getIconFile() const { return _iconFile; }
More information about the Scummvm-git-logs
mailing list