diff options
-rw-r--r-- | engines/adl/adl.cpp | 73 | ||||
-rw-r--r-- | engines/adl/adl.h | 2 | ||||
-rw-r--r-- | engines/adl/detection.cpp | 70 |
3 files changed, 110 insertions, 35 deletions
diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp index 8ffb929e7a..633705f2db 100644 --- a/engines/adl/adl.cpp +++ b/engines/adl/adl.cpp @@ -33,6 +33,7 @@ #include "engines/util.h" #include "graphics/palette.h" +#include "graphics/thumbnail.h" #include "adl/adl.h" #include "adl/display.h" @@ -86,7 +87,7 @@ Common::Error AdlEngine::run() { int saveSlot = ConfMan.getInt("save_slot"); if (saveSlot >= 0) { - if (!loadState(saveSlot)) + if (loadGameState(saveSlot).getCode() != Common::kNoError) error("Failed to load save game from slot %i", saveSlot); _display->setCursorPos(Common::Point(0, 23)); _isRestoring = true; @@ -297,11 +298,11 @@ void AdlEngine::doActions(const Command &command, byte noun, byte offset) { ++offset; break; case IDO_ACT_SAVE: - saveState(0); + saveGameState(0, ""); ++offset; break; case IDO_ACT_LOAD: - loadState(0); + loadGameState(0); ++offset; // Original engine continues processing here (?) break; @@ -528,13 +529,13 @@ void AdlEngine::showRoom() { printMessage(curRoom().description, false); } -bool AdlEngine::saveState(uint slot, const Common::String *description) { +Common::Error AdlEngine::saveGameState(int slot, const Common::String &desc) { Common::String fileName = Common::String::format("%s.s%02d", _targetName.c_str(), slot); Common::OutSaveFile *outFile = getSaveFileManager()->openForSaving(fileName); if (!outFile) { warning("Failed to open file '%s'", fileName.c_str()); - return false; + return Common::kUnknownError; } outFile->writeUint32BE(MKTAG('A', 'D', 'L', ':')); @@ -542,8 +543,8 @@ bool AdlEngine::saveState(uint slot, const Common::String *description) { char name[SAVEGAME_NAME_LEN] = { }; - if (description) - strncpy(name, description->c_str(), sizeof(name) - 1); + if (!desc.empty()) + strncpy(name, desc.c_str(), sizeof(name) - 1); else { Common::String defaultName("Save "); defaultName += 'A' + slot; @@ -552,6 +553,20 @@ bool AdlEngine::saveState(uint slot, const Common::String *description) { outFile->write(name, sizeof(name)); + TimeDate t; + g_system->getTimeAndDate(t); + + outFile->writeUint16BE(t.tm_year); + outFile->writeByte(t.tm_mon); + outFile->writeByte(t.tm_mday); + outFile->writeByte(t.tm_hour); + outFile->writeByte(t.tm_min); + + uint32 playTime = getTotalPlayTime(); + outFile->writeUint32BE(playTime); + + Graphics::saveThumbnail(*outFile); + outFile->writeByte(_state.room); outFile->writeByte(_state.moves); outFile->writeByte(_state.isDark); @@ -580,38 +595,45 @@ bool AdlEngine::saveState(uint slot, const Common::String *description) { if (outFile->err()) { delete outFile; warning("Failed to save game '%s'", fileName.c_str()); - return false; + return Common::kUnknownError; } delete outFile; - return true; + return Common::kNoError; } -bool AdlEngine::loadState(uint slot) { +Common::Error AdlEngine::loadGameState(int slot) { Common::String fileName = Common::String::format("%s.s%02d", _targetName.c_str(), slot); Common::InSaveFile *inFile = getSaveFileManager()->openForLoading(fileName); if (!inFile) { warning("Failed to open file '%s'", fileName.c_str()); - return false; + return Common::kUnknownError; } if (inFile->readUint32BE() != MKTAG('A', 'D', 'L', ':')) { warning("No header found in '%s'", fileName.c_str()); delete inFile; - return false; + return Common::kUnknownError; } byte saveVersion = inFile->readByte(); if (saveVersion != SAVEGAME_VERSION) { warning("Save game version %i not supported", saveVersion); delete inFile; - return false; + return Common::kUnknownError; } - initState(); - + // Skip description inFile->seek(SAVEGAME_NAME_LEN, SEEK_CUR); + // Skip save time + inFile->seek(6, SEEK_CUR); + + uint32 playTime = inFile->readUint32BE(); + + Graphics::skipThumbnail(*inFile); + + initState(); _state.room = inFile->readByte(); _state.moves = inFile->readByte(); @@ -649,7 +671,10 @@ bool AdlEngine::loadState(uint slot) { error("Failed to load game '%s'", fileName.c_str()); delete inFile; - return true; + + setTotalPlayTime(playTime); + + return Common::kNoError; } Room &AdlEngine::room(uint i) { @@ -930,22 +955,6 @@ void AdlEngine::delay(uint32 ms) { } } -Common::Error AdlEngine::loadGameState(int slot) { - if (loadState(slot)) { - _isRestoring = true; - return Common::kNoError; - } - - return Common::kUnknownError; -} - -Common::Error AdlEngine::saveGameState(int slot, const Common::String &desc) { - if (saveState(slot, &desc)) - return Common::kNoError; - - return Common::kUnknownError; -} - AdlEngine *AdlEngine::create(GameType type, OSystem *syst, const AdlGameDescription *gd) { switch(type) { case kGameTypeHires1: diff --git a/engines/adl/adl.h b/engines/adl/adl.h index 4d160f08b0..f8b2dca1b7 100644 --- a/engines/adl/adl.h +++ b/engines/adl/adl.h @@ -237,8 +237,6 @@ protected: private: void printEngineMessage(EngineMessage); - bool saveState(uint slot, const Common::String *description = nullptr); - bool loadState(uint slot); Common::String getTargetName() { return _targetName; } byte convertKey(uint16 ascii); diff --git a/engines/adl/detection.cpp b/engines/adl/detection.cpp index 5fe469d20f..27ce5939a3 100644 --- a/engines/adl/detection.cpp +++ b/engines/adl/detection.cpp @@ -23,6 +23,8 @@ #include "common/system.h" #include "common/savefile.h" +#include "graphics/thumbnail.h" + #include "engines/advancedDetector.h" #include "adl/adl.h" @@ -73,8 +75,10 @@ public: } bool hasFeature(MetaEngineFeature f) const; - int getMaximumSaveSlot() const { return 15; } + SaveStateDescriptor querySaveMetaInfos(const char *target, int slot) const; + int getMaximumSaveSlot() const { return 'O' - 'A'; } SaveStateList listSaves(const char *target) const; + void removeSaveState(const char *target, int slot) const; bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *gd) const; }; @@ -83,17 +87,76 @@ bool AdlMetaEngine::hasFeature(MetaEngineFeature f) const { switch(f) { case kSupportsListSaves: case kSupportsLoadingDuringStartup: + case kSupportsDeleteSave: + case kSavesSupportMetaInfo: + case kSavesSupportThumbnail: + case kSavesSupportCreationDate: + case kSavesSupportPlayTime: return true; default: return false; } } +SaveStateDescriptor AdlMetaEngine::querySaveMetaInfos(const char *target, int slot) const { + Common::String fileName = Common::String::format("%s.s%02d", target, slot); + Common::InSaveFile *inFile = g_system->getSavefileManager()->openForLoading(fileName); + + if (!inFile) + return SaveStateDescriptor(); + + if (inFile->readUint32BE() != MKTAG('A', 'D', 'L', ':')) { + delete inFile; + return SaveStateDescriptor(); + } + + byte saveVersion = inFile->readByte(); + if (saveVersion != SAVEGAME_VERSION) { + delete inFile; + return SaveStateDescriptor(); + } + + char name[SAVEGAME_NAME_LEN] = { }; + inFile->read(name, sizeof(name) - 1); + inFile->readByte(); + + if (inFile->eos() || inFile->err()) { + delete inFile; + return SaveStateDescriptor(); + } + + SaveStateDescriptor sd(slot, name); + + int year = inFile->readUint16BE(); + int month = inFile->readByte(); + int day = inFile->readByte(); + sd.setSaveDate(year + 1900, month + 1, day); + + int hour = inFile->readByte(); + int minutes = inFile->readByte(); + sd.setSaveTime(hour, minutes); + + uint32 playTime = inFile->readUint32BE(); + sd.setPlayTime(playTime); + + if (inFile->eos() || inFile->err()) { + delete inFile; + return SaveStateDescriptor(); + } + + Graphics::Surface *const thumbnail = Graphics::loadThumbnail(*inFile); + sd.setThumbnail(thumbnail); + + delete inFile; + return sd; +} + SaveStateList AdlMetaEngine::listSaves(const char *target) const { Common::SaveFileManager *saveFileMan = g_system->getSavefileManager(); Common::StringArray files = saveFileMan->listSavefiles(Common::String(target) + ".s##"); SaveStateList saveList; + for (uint i = 0; i < files.size(); ++i) { const Common::String &fileName = files[i]; Common::InSaveFile *inFile = saveFileMan->openForLoading(fileName); @@ -129,6 +192,11 @@ SaveStateList AdlMetaEngine::listSaves(const char *target) const { return saveList; } +void AdlMetaEngine::removeSaveState(const char *target, int slot) const { + Common::String fileName = Common::String::format("%s.s%02d", target, slot); + g_system->getSavefileManager()->removeSavefile(fileName); +} + bool AdlMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *gd) const { if (gd) *engine = AdlEngine::create(((const AdlGameDescription *)gd)->gameType, syst, (const AdlGameDescription *)gd); |