diff --git a/engines/kingdom/detection.cpp b/engines/kingdom/detection.cpp index 881645b9250..42c23603786 100644 --- a/engines/kingdom/detection.cpp +++ b/engines/kingdom/detection.cpp @@ -40,6 +40,8 @@ static const PlainGameDescriptor kingdomGames[] = { namespace Kingdom { +#define MAX_SAVES 99 + static const ADGameDescription gameDescriptions[] = { // Kingdom PC DOS Demo version, provided by Strangerke { @@ -84,10 +86,20 @@ public: virtual bool hasFeature(MetaEngineFeature f) const; virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const; + virtual int getMaximumSaveSlot() const; + virtual SaveStateList listSaves(const char *target) const; + virtual void removeSaveState(const char *target, int slot) const; + SaveStateDescriptor querySaveMetaInfos(const char *target, int slot) const; }; bool KingdomMetaEngine::hasFeature(MetaEngineFeature f) const { - return false; + return + (f == kSupportsListSaves) || + (f == kSupportsLoadingDuringStartup) || + (f == kSupportsDeleteSave) || + (f == kSavesSupportMetaInfo) || + (f == kSavesSupportThumbnail) || + (f == kSavesSupportCreationDate); } bool KingdomMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const { @@ -97,6 +109,72 @@ bool KingdomMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADG return desc != nullptr; } +int KingdomMetaEngine::getMaximumSaveSlot() const { + return MAX_SAVES; +} + +SaveStateList KingdomMetaEngine::listSaves(const char *target) const { + Common::SaveFileManager *saveFileMan = g_system->getSavefileManager(); + Common::StringArray filenames; + Common::String saveDesc; + Common::String pattern = Common::String::format("%s.0##", target); + + filenames = saveFileMan->listSavefiles(pattern); + + Kingdom::KingdomSavegameHeader header; + + SaveStateList saveList; + for (Common::StringArray::const_iterator file = filenames.begin(); file != filenames.end(); ++file) { + const char *ext = strrchr(file->c_str(), '.'); + int slot = ext ? atoi(ext + 1) : -1; + + if (slot >= 0 && slot < MAX_SAVES) { + Common::InSaveFile *in = g_system->getSavefileManager()->openForLoading(*file); + + if (in) { + if (Kingdom::KingdomGame::readSavegameHeader(in, header)) { + saveList.push_back(SaveStateDescriptor(slot, header._saveName)); + + header._thumbnail->free(); + delete header._thumbnail; + } + + delete in; + } + } + } + + // Sort saves based on slot number. + Common::sort(saveList.begin(), saveList.end(), SaveStateDescriptorSlotComparator()); + return saveList; +} + +void KingdomMetaEngine::removeSaveState(const char *target, int slot) const { + Common::String filename = Common::String::format("%s.%03d", target, slot); + g_system->getSavefileManager()->removeSavefile(filename); +} + +SaveStateDescriptor KingdomMetaEngine::querySaveMetaInfos(const char *target, int slot) const { + Common::String filename = Common::String::format("%s.%03d", target, slot); + Common::InSaveFile *f = g_system->getSavefileManager()->openForLoading(filename); + + if (f) { + Kingdom::KingdomSavegameHeader header; + Kingdom::KingdomGame::readSavegameHeader(f, header); + delete f; + + // Create the return descriptor + SaveStateDescriptor desc(slot, header._saveName); + desc.setThumbnail(header._thumbnail); + desc.setSaveDate(header._year, header._month, header._day); + desc.setSaveTime(header._hour, header._minute); + + return desc; + } + + return SaveStateDescriptor(); +} + #if PLUGIN_ENABLED_DYNAMIC(KINGDOM) REGISTER_PLUGIN_DYNAMIC(KINGDOM, PLUGIN_TYPE_ENGINE, KingdomMetaEngine); #else diff --git a/engines/kingdom/kingdom.cpp b/engines/kingdom/kingdom.cpp index 3fed5bba72e..16dc4ca873e 100644 --- a/engines/kingdom/kingdom.cpp +++ b/engines/kingdom/kingdom.cpp @@ -696,7 +696,7 @@ void KingdomGame::DrawInventory() { DrawIcon(131, 39, 134 + _Inventory[3]); } -Common::String KingdomGame::generateSaveName(int slot) { +Common::String KingdomGame::getSavegameFilename(int slot) { return Common::String::format("%s.%03d", _targetName.c_str(), slot); } @@ -722,7 +722,7 @@ void KingdomGame::restoreGame() { } Common::Error KingdomGame::saveGameState(int slot, const Common::String &desc) { - Common::String savegameFile = generateSaveName(slot); + Common::String savegameFile = getSavegameFilename(slot); Common::SaveFileManager *saveMan = g_system->getSavefileManager(); Common::OutSaveFile *out = saveMan->openForSaving(savegameFile); @@ -743,7 +743,7 @@ Common::Error KingdomGame::saveGameState(int slot, const Common::String &desc) { } Common::Error KingdomGame::loadGameState(int slot) { - Common::String savegameFile = generateSaveName(slot); + Common::String savegameFile = getSavegameFilename(slot); Common::SaveFileManager *saveMan = g_system->getSavefileManager(); Common::InSaveFile *inFile = saveMan->openForLoading(savegameFile); if (!inFile) @@ -1479,8 +1479,8 @@ void KingdomGame::DrawIcon(int x, int y, int index) { int height = _kingartEntries[index].Height; ::Graphics::Surface *screen = g_system->lockScreen(); - for (uint curX = 0; curX < width; curX++) { - for (uint curY = 0; curY < height; curY++) { + for (int curX = 0; curX < width; curX++) { + for (int curY = 0; curY < height; curY++) { const byte *src = data + (curY * width) + curX; byte *dst = (byte *)screen->getBasePtr(curX + x, curY + y); if (*src != 0xFF) diff --git a/engines/kingdom/kingdom.h b/engines/kingdom/kingdom.h index 6da0a2b71f4..65ced52b214 100644 --- a/engines/kingdom/kingdom.h +++ b/engines/kingdom/kingdom.h @@ -102,6 +102,7 @@ namespace Kingdom { const ADGameDescription *_gameDescription; const char *getGameId() const; Common::Platform getPlatform() const; + static bool readSavegameHeader(Common::InSaveFile *in, KingdomSavegameHeader &header); private: Console *_console; @@ -275,8 +276,7 @@ namespace Kingdom { void restoreGame(); virtual Common::Error loadGameState(int slot); virtual Common::Error saveGameState(int slot, const Common::String &desc); - Common::String generateSaveName(int slot); - static bool readSavegameHeader(Common::InSaveFile *in, KingdomSavegameHeader &header); + Common::String getSavegameFilename(int slot); void writeSavegameHeader(Common::OutSaveFile *out, KingdomSavegameHeader &header); void synchronize(Common::Serializer &s); void refreshScreen();