M4: Handle original save files outer file structure

This commit is contained in:
Paul Gilbert 2023-10-03 20:42:28 -07:00 committed by Eugene Sandulenko
parent e2b6d6f083
commit 2a96a63e8e
4 changed files with 95 additions and 1 deletions

View File

@ -139,7 +139,49 @@ Common::Error M4Engine::loadGameState(int slot) {
}
Common::Error M4Engine::loadGameStateDoIt(int slot) {
return Engine::loadGameState(slot);
Common::InSaveFile *save = getOriginalSave(slot);
if (save) {
// Skip original description
int descSize = save->readUint32LE();
save->seek(descSize + 45, SEEK_CUR);
int thumbSize = save->readUint32LE();
save->seek(thumbSize, SEEK_CUR);
// We're now at data section, handle it
Common::Serializer s(save, nullptr);
Common::Error result = syncGame(s);
delete save;
return result;
} else {
return Engine::loadGameState(slot);
}
}
Common::InSaveFile *M4Engine::getOriginalSave(int slot) const {
Common::InSaveFile *save = g_system->getSavefileManager()->openForLoading(
getSaveStateName(slot));
char name[16];
if (save) {
if (save->seek(-44, SEEK_END) && save->read(name, 7) == 7 &&
!strncmp(name, "MIRROR", 7)) {
save->seek(0);
return save;
} else if (save->seek(-44, SEEK_END) && save->read(name, 7) == 7 &&
!strncmp(name, "FAUCET ", 7)) {
save->seek(0);
return save;
}
delete save;
}
return nullptr;
}
Common::Error M4Engine::syncGame(Common::Serializer &s) {

View File

@ -52,6 +52,12 @@ private:
*/
void m4_inflight();
/**
* Opens up a savefile in a given slot, and if it's an
* original savegame, returns a reference to it
*/
Common::InSaveFile *getOriginalSave(int slot) const;
protected:
// Engine APIs
Common::Error run() override;

View File

@ -20,6 +20,8 @@
*/
#include "common/translation.h"
#include "common/savefile.h"
#include "common/system.h"
#include "m4/metaengine.h"
#include "m4/detection.h"
@ -75,6 +77,45 @@ bool M4MetaEngine::hasFeature(MetaEngineFeature f) const {
(f == kSupportsLoadingDuringStartup);
}
SaveStateDescriptor M4MetaEngine::querySaveMetaInfos(const char *target, int slot) const {
Common::String saveName = Common::String::format("%s.%03u", target, slot);
Common::InSaveFile *save = getOriginalSave(saveName);
if (save) {
save->skip(4);
char saveDesc[32];
save->read(saveDesc, 32);
saveDesc[31] = '\0';
delete save;
SaveStateDescriptor desc(this, slot, saveDesc);
return desc;
} else {
return AdvancedMetaEngine::querySaveMetaInfos(target, slot);
}
}
Common::InSaveFile *M4MetaEngine::getOriginalSave(const Common::String &saveName) const {
Common::InSaveFile *save = g_system->getSavefileManager()->openForLoading(saveName);
char name[16];
if (save) {
if (save->seek(-44, SEEK_END) && save->read(name, 7) == 7 &&
!strncmp(name, "MIRROR", 7)) {
save->seek(0);
return save;
} else if (save->seek(-44, SEEK_END) && save->read(name, 7) == 7 &&
!strncmp(name, "FAUCET ", 7)) {
save->seek(0);
return save;
}
delete save;
}
return nullptr;
}
#if PLUGIN_ENABLED_DYNAMIC(M4)
REGISTER_PLUGIN_DYNAMIC(M4, PLUGIN_TYPE_ENGINE, M4MetaEngine);
#else

View File

@ -25,6 +25,9 @@
#include "engines/advancedDetector.h"
class M4MetaEngine : public AdvancedMetaEngine {
private:
Common::InSaveFile *getOriginalSave(const Common::String &saveName) const;
public:
const char *getName() const override;
@ -38,6 +41,8 @@ public:
bool hasFeature(MetaEngineFeature f) const override;
const ADExtraGuiOptionsMap *getAdvancedExtraGuiOptions() const override;
SaveStateDescriptor querySaveMetaInfos(const char *target, int slot) const override;
};
#endif // M4_METAENGINE_H