diff options
Diffstat (limited to 'engines')
-rw-r--r-- | engines/supernova/detection.cpp | 72 | ||||
-rw-r--r-- | engines/supernova/supernova.cpp | 17 | ||||
-rw-r--r-- | engines/supernova/supernova.h | 4 |
3 files changed, 89 insertions, 4 deletions
diff --git a/engines/supernova/detection.cpp b/engines/supernova/detection.cpp index 5770871406..b587dbb623 100644 --- a/engines/supernova/detection.cpp +++ b/engines/supernova/detection.cpp @@ -24,6 +24,7 @@ #include "common/file.h" #include "common/savefile.h" #include "common/system.h" +#include "graphics/thumbnail.h" #include "engines/advancedDetector.h" #include "supernova/supernova.h" @@ -83,6 +84,7 @@ public: virtual int getMaximumSaveSlot() const { return 99; } + virtual SaveStateDescriptor querySaveMetaInfos(const char *target, int slot) const; }; bool SupernovaMetaEngine::hasFeature(MetaEngineFeature f) const { @@ -92,6 +94,13 @@ bool SupernovaMetaEngine::hasFeature(MetaEngineFeature f) const { case kSupportsListSaves: // fallthrough case kSupportsDeleteSave: + // fallthrough + case kSavesSupportMetaInfo: + // fallthrough + case kSavesSupportThumbnail: + // fallthrough + case kSavesSupportCreationDate: + // fallthrough return true; default: return false; @@ -120,10 +129,17 @@ SaveStateList SupernovaMetaEngine::listSaves(const char *target) const { if (saveSlot >= 0 && saveSlot <= getMaximumSaveSlot()) { Common::InSaveFile *savefile = g_system->getSavefileManager()->openForLoading(*file); if (savefile) { - savefile->skip(2); - savefile->read(saveFileDesc, sizeof(saveFileDesc)); - saveFileList.push_back(SaveStateDescriptor(saveSlot, saveFileDesc)); - + uint saveHeader = savefile->readUint32LE(); + if (saveHeader == SAVEGAME_HEADER) { + byte saveVersion = savefile->readByte(); + if (saveVersion <= SAVEGAME_VERSION) { + int saveFileDescSize = savefile->readSint16LE(); + char* saveFileDesc = new char[saveFileDescSize]; + savefile->read(saveFileDesc, saveFileDescSize); + saveFileList.push_back(SaveStateDescriptor(saveSlot, saveFileDesc)); + delete [] saveFileDesc; + } + } delete savefile; } } @@ -138,6 +154,54 @@ void SupernovaMetaEngine::removeSaveState(const char *target, int slot) const { g_system->getSavefileManager()->removeSavefile(filename); } +SaveStateDescriptor SupernovaMetaEngine::querySaveMetaInfos(const char *target, int slot) const { + Common::String fileName = Common::String::format("msn_save.%03d", slot); + Common::InSaveFile *savefile = g_system->getSavefileManager()->openForLoading(fileName); + + if (savefile) { + uint saveHeader = savefile->readUint32LE(); + if (saveHeader != SAVEGAME_HEADER) { + delete savefile; + return SaveStateDescriptor(); + } + byte saveVersion = savefile->readByte(); + if (saveVersion > SAVEGAME_VERSION){ + delete savefile; + return SaveStateDescriptor(); + } + + int descriptionSize = savefile->readSint16LE(); + char* description = new char[descriptionSize]; + savefile->read(description, descriptionSize); + SaveStateDescriptor desc(slot, description); + delete [] description; + + uint32 saveDate = savefile->readUint32LE(); + int day = (saveDate >> 24) & 0xFF; + int month = (saveDate >> 16) & 0xFF; + int year = saveDate & 0xFFFF; + desc.setSaveDate(year, month, day); + + uint16 saveTime = savefile->readUint16LE(); + int hour = (saveTime >> 8) & 0xFF; + int minutes = saveTime & 0xFF; + desc.setSaveTime(hour, minutes); + + + if (Graphics::checkThumbnailHeader(*savefile)) { + Graphics::Surface *const thumbnail = Graphics::loadThumbnail(*savefile); + desc.setThumbnail(thumbnail); + } + + delete savefile; + + return desc; + } + + return SaveStateDescriptor(); +} + + #if PLUGIN_ENABLED_DYNAMIC(SUPERNOVA) REGISTER_PLUGIN_DYNAMIC(SUPERNOVA, PLUGIN_TYPE_ENGINE, SupernovaMetaEngine); #else diff --git a/engines/supernova/supernova.cpp b/engines/supernova/supernova.cpp index 5128a1c531..17033dadd4 100644 --- a/engines/supernova/supernova.cpp +++ b/engines/supernova/supernova.cpp @@ -814,6 +814,20 @@ bool SupernovaEngine::loadGame(int slot) { if (!savefile) return false; + uint saveHeader = savefile->readUint32LE(); + if (saveHeader != SAVEGAME_HEADER) { + warning("No header found in '%s'", filename.c_str()); + delete savefile; + return Common::kUnknownError; + } + + byte saveVersion = savefile->readByte(); + if (saveVersion > SAVEGAME_VERSION) { + warning("Save game version %i not supported", saveVersion); + delete savefile; + return Common::kUnknownError; + } + int descriptionSize = savefile->readSint16LE(); savefile->skip(descriptionSize); savefile->skip(6); @@ -833,6 +847,9 @@ bool SupernovaEngine::saveGame(int slot, const Common::String &description) { Common::OutSaveFile *savefile = _saveFileMan->openForSaving(filename); if (!savefile) return false; + + savefile->writeUint32LE(SAVEGAME_HEADER); + savefile->writeByte(SAVEGAME_VERSION); TimeDate currentDate; _system->getTimeAndDate(currentDate); diff --git a/engines/supernova/supernova.h b/engines/supernova/supernova.h index 2073c0f300..df9108ec6e 100644 --- a/engines/supernova/supernova.h +++ b/engines/supernova/supernova.h @@ -42,6 +42,10 @@ namespace Supernova { +#define SAVEGAME_HEADER MKTAG('M','S','N','1') +#define SAVEGAME_VERSION 1 + + struct ScreenBuffer { ScreenBuffer() : _x(0) |