From ec3ccf5eb03ed347263abbd2fe6d87e3d0cc65b4 Mon Sep 17 00:00:00 2001 From: aryanrawlani28 Date: Fri, 7 Aug 2020 04:46:21 +0530 Subject: [PATCH] CINE: Split detection features & adapt to new plugins. --- configure | 2 +- engines/cine/cine.h | 13 +- engines/cine/detection.cpp | 317 +----------------------------- engines/cine/detection.h | 32 +++ engines/cine/detection_enums.h | 37 ++++ engines/cine/metaengine.cpp | 346 +++++++++++++++++++++++++++++++++ engines/cine/module.mk | 5 +- engines/cine/saveload.cpp | 4 +- 8 files changed, 426 insertions(+), 330 deletions(-) create mode 100644 engines/cine/detection.h create mode 100644 engines/cine/detection_enums.h create mode 100644 engines/cine/metaengine.cpp diff --git a/configure b/configure index 6fdf4d007bd..34dd47418d4 100755 --- a/configure +++ b/configure @@ -6169,7 +6169,7 @@ declare -a static_detect_engines=("PLUMBERS" "AGI" "SCUMM" "SKY" "DREAMWEB" "DRA "PETKA" "PINK" "PRINCE" "SHERLOCK" "SLUDGE" "STARTREK" "SUPERNOVA" "TEENAGENT" "TESTBED" "TINSEL" "TITANIC" "TOLTECS" "TONY" "TOON" "TOUCHE" "TSAGE" "TUCKER" "VOYEUR" "WAGE" "AVALANCHE" "BBVS" - "BLADERUNNER" "CHEWY") + "BLADERUNNER" "CHEWY" "CINE") detectId="_DETECTION" echo "Creating engines/plugins_table.h" diff --git a/engines/cine/cine.h b/engines/cine/cine.h index 6bc04b3c5de..aec244e4402 100644 --- a/engines/cine/cine.h +++ b/engines/cine/cine.h @@ -48,6 +48,7 @@ #include "cine/various.h" #include "cine/console.h" #include "cine/sound.h" +#include "cine/detection_enums.h" //#define DUMP_SCRIPTS @@ -81,18 +82,6 @@ */ namespace Cine { -enum CineGameType { - GType_FW = 1, - GType_OS -}; - -enum CineGameFeatures { - GF_CD = 1 << 0, - GF_DEMO = 1 << 1, - GF_ALT_FONT = 1 << 2, - GF_CRYPTED_BOOT_PRC = 1 << 3 -}; - struct CINEGameDescription; struct SeqListElement; diff --git a/engines/cine/detection.cpp b/engines/cine/detection.cpp index e51c079dcb7..311c922507c 100644 --- a/engines/cine/detection.cpp +++ b/engines/cine/detection.cpp @@ -24,34 +24,10 @@ #include "engines/advancedDetector.h" -#include "common/system.h" -#include "common/textconsole.h" #include "common/translation.h" -#include "common/util.h" -#include "cine/cine.h" -#include "cine/various.h" - -namespace Cine { - -#define MAX_SAVEGAMES (ARRAYSIZE(Cine::currentSaveName)) -#define SAVEGAME_NAME_LEN (sizeof(Cine::currentSaveName[0])) -#define SAVELIST_SIZE (MAX_SAVEGAMES * SAVEGAME_NAME_LEN) - -struct CINEGameDescription { - ADGameDescription desc; - - int gameType; - uint32 features; -}; - -bool CineEngine::mayHave256Colors() const { return getGameType() == Cine::GType_OS && getPlatform() == Common::kPlatformDOS; } -int CineEngine::getGameType() const { return _gameDescription->gameType; } -uint32 CineEngine::getFeatures() const { return _gameDescription->features; } -Common::Language CineEngine::getLanguage() const { return _gameDescription->desc.language; } -Common::Platform CineEngine::getPlatform() const { return _gameDescription->desc.platform; } - -} // End of namespace Cine +#include "cine/detection.h" +#include "cine/detection_enums.h" static const PlainGameDescriptor cineGames[] = { {"fw", "Future Wars"}, @@ -101,293 +77,6 @@ public: const char *getOriginalCopyright() const override { return "Cinematique evo 1 (C) Delphine Software"; } - - Common::Error createInstance(OSystem *syst, Engine **engine) const override { - return AdvancedMetaEngine::createInstance(syst, engine); - } - bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const override; - - bool hasFeature(MetaEngineFeature f) const override; - SaveStateList listSaves(const char *target) const override; - int getMaximumSaveSlot() const override; - void removeSaveState(const char *target, int slot) const override; - Common::String getSavegameFile(int saveGameIdx, const char *target = nullptr) const override; - SaveStateDescriptor querySaveMetaInfos(const char *target, int slot) const override; }; -bool CineMetaEngine::hasFeature(MetaEngineFeature f) const { - return - (f == kSupportsListSaves) || - (f == kSupportsLoadingDuringStartup) || - (f == kSupportsDeleteSave) || - (f == kSavesSupportMetaInfo) || - (f == kSavesSupportThumbnail) || - (f == kSavesSupportCreationDate) || - (f == kSavesSupportPlayTime) || - (f == kSavesUseExtendedFormat); -} - -bool Cine::CineEngine::hasFeature(EngineFeature f) const { - return - (f == kSupportsReturnToLauncher) || - (f == kSupportsLoadingDuringRuntime) || - (f == kSupportsSavingDuringRuntime); -} - -bool CineMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const { - const Cine::CINEGameDescription *gd = (const Cine::CINEGameDescription *)desc; - if (gd) { - *engine = new Cine::CineEngine(syst, gd); - } - return gd != 0; -} - -SaveStateList CineMetaEngine::listSaves(const char *target) const { - Common::SaveFileManager *saveFileMan = g_system->getSavefileManager(); - SaveStateList saveList; - - Common::String pattern; - - Common::StringArray::const_iterator file; - - Common::String filename = target; - filename += ".dir"; - Common::InSaveFile *in = saveFileMan->openForLoading(filename); - bool foundAutosave = false; - if (in) { - typedef char CommandeType[SAVEGAME_NAME_LEN]; - CommandeType saveNames[MAX_SAVEGAMES]; - - // Initialize all savegames' descriptions to empty strings - // so that if the savegames' descriptions can only be partially read from file - // then the missing ones are correctly set to empty strings. - memset(saveNames, 0, sizeof(saveNames)); - - in->read(saveNames, SAVELIST_SIZE); - CommandeType saveDesc; - - pattern = target; - pattern += ".#*"; - Common::StringArray filenames = saveFileMan->listSavefiles(pattern); - - for (file = filenames.begin(); file != filenames.end(); ++file) { - // Obtain the extension part of the filename, since it corresponds to the save slot number - Common::String ext = Common::lastPathComponent(*file, '.'); - int slotNum = (int)ext.asUint64(); - - if (ext.equals(Common::String::format("%d", slotNum)) && - slotNum >= 0 && slotNum < MAX_SAVEGAMES) { - // Copy the savegame description making sure it ends with a trailing zero - strncpy(saveDesc, saveNames[slotNum], SAVEGAME_NAME_LEN); - saveDesc[sizeof(CommandeType) - 1] = 0; - - SaveStateDescriptor saveStateDesc(slotNum, saveDesc); - saveStateDesc.setAutosave(slotNum == getAutosaveSlot()); - saveStateDesc.setWriteProtectedFlag(saveStateDesc.isAutosave()); - - if (saveStateDesc.getDescription().empty()) { - if (saveStateDesc.isAutosave()) { - saveStateDesc.setDescription(_("Unnamed autosave")); - } else { - saveStateDesc.setDescription(_("Unnamed savegame")); - } - } - - if (saveStateDesc.isAutosave()) { - foundAutosave = true; - } - - saveList.push_back(saveStateDesc); - } - } - } - - delete in; - - // No saving on empty autosave slot - if (!foundAutosave) { - SaveStateDescriptor desc; - desc.setDescription(_("Empty autosave")); - desc.setSaveSlot(getAutosaveSlot()); - desc.setWriteProtectedFlag(true); - saveList.push_back(desc); - } - - // Sort saves based on slot number. - Common::sort(saveList.begin(), saveList.end(), SaveStateDescriptorSlotComparator()); - return saveList; -} - -int CineMetaEngine::getMaximumSaveSlot() const { return MAX_SAVEGAMES - 1; } - -Common::String CineMetaEngine::getSavegameFile(int saveGameIdx, const char *target) const { - return Common::String::format("%s.%d", target == nullptr ? getEngineId() : target, saveGameIdx); -} - -SaveStateDescriptor CineMetaEngine::querySaveMetaInfos(const char *target, int slot) const { - if (slot < 0 || slot > getMaximumSaveSlot()) { - // HACK: Try to make SaveLoadChooserGrid::open() not use save slot - // numbers over the maximum save slot number for "New save". - SaveStateDescriptor desc; - desc.setWriteProtectedFlag(true); - return desc; - } - - Common::ScopedPtr f(g_system->getSavefileManager()->openForLoading( - getSavegameFile(slot, target))); - - if (f) { - // Create the return descriptor - SaveStateDescriptor desc; - - ExtendedSavegameHeader header; - if (readSavegameHeader(f.get(), &header, false)) { - parseSavegameHeader(&header, &desc); - desc.setThumbnail(header.thumbnail); - } else { - // Load savegame descriptions from index file - typedef char CommandeType[SAVEGAME_NAME_LEN]; - CommandeType saveNames[MAX_SAVEGAMES]; - memset(saveNames, 0, sizeof(saveNames)); - - Common::InSaveFile *in; - in = g_system->getSavefileManager()->openForLoading(Common::String::format("%s.dir", target)); - - if (in) { - in->read(saveNames, SAVELIST_SIZE); - delete in; - } - - saveNames[slot][SAVEGAME_NAME_LEN - 1] = 0; - Common::String saveNameStr((const char *)saveNames[slot]); - desc.setDescription(saveNameStr); - } - - if (desc.getDescription().empty()) { - desc.setDescription(_("Unnamed savegame")); - } - - desc.setSaveSlot(slot); - desc.setAutosave(slot == getAutosaveSlot()); - desc.setWriteProtectedFlag(desc.isAutosave()); - - return desc; - } - - // No saving on empty autosave slot - if (slot == getAutosaveSlot()) { - SaveStateDescriptor desc; - desc.setDescription(_("Empty autosave")); - desc.setSaveSlot(slot); - desc.setAutosave(true); - desc.setWriteProtectedFlag(true); - return desc; - } - - return SaveStateDescriptor(); -} - -void CineMetaEngine::removeSaveState(const char *target, int slot) const { - if (slot < 0 || slot >= MAX_SAVEGAMES) { - return; - } - - // Load savegame descriptions from index file - typedef char CommandeType[SAVEGAME_NAME_LEN]; - CommandeType saveNames[MAX_SAVEGAMES]; - - // Initialize all savegames' descriptions to empty strings - // so that if the savegames' descriptions can only be partially read from file - // then the missing ones are correctly set to empty strings. - memset(saveNames, 0, sizeof(saveNames)); - - Common::InSaveFile *in; - in = g_system->getSavefileManager()->openForLoading(Common::String::format("%s.dir", target)); - - if (!in) - return; - - in->read(saveNames, SAVELIST_SIZE); - delete in; - - // Set description for selected slot - char slotName[SAVEGAME_NAME_LEN]; - slotName[0] = 0; - Common::strlcpy(saveNames[slot], slotName, SAVEGAME_NAME_LEN); - - // Update savegame descriptions - Common::String indexFile = Common::String::format("%s.dir", target); - Common::OutSaveFile *out = g_system->getSavefileManager()->openForSaving(indexFile); - if (!out) { - warning("Unable to open file %s for saving", indexFile.c_str()); - return; - } - - out->write(saveNames, SAVELIST_SIZE); - delete out; - - // Delete save file - Common::String saveFileName = getSavegameFile(slot, target); - - g_system->getSavefileManager()->removeSavefile(saveFileName); -} - -#if PLUGIN_ENABLED_DYNAMIC(CINE) - REGISTER_PLUGIN_DYNAMIC(CINE, PLUGIN_TYPE_ENGINE, CineMetaEngine); -#else - REGISTER_PLUGIN_STATIC(CINE, PLUGIN_TYPE_ENGINE, CineMetaEngine); -#endif - -namespace Cine { - -Common::Error CineEngine::loadGameState(int slot) { - bool gameLoaded = makeLoad(getSaveStateName(slot)); - - return gameLoaded ? Common::kNoError : Common::kUnknownError; -} - -Common::Error CineEngine::saveGameState(int slot, const Common::String &desc, bool isAutosave) { - if (slot < 0 || slot >= MAX_SAVEGAMES) { - return Common::kCreatingFileFailed; - } - - // Load savegame descriptions from index file - loadSaveDirectory(); - - // Set description for selected slot making sure it ends with a trailing zero - strncpy(currentSaveName[slot], desc.c_str(), sizeof(CommandeType)); - currentSaveName[slot][sizeof(CommandeType) - 1] = 0; - - // Update savegame descriptions - Common::String indexFile = _targetName + ".dir"; - - Common::OutSaveFile *fHandle = _saveFileMan->openForSaving(indexFile); - if (!fHandle) { - warning("Unable to open file %s for saving", indexFile.c_str()); - return Common::kUnknownError; - } - - fHandle->write(currentSaveName, SAVELIST_SIZE); - delete fHandle; - - // Save game - makeSave(getSaveStateName(slot), getTotalPlayTime() / 1000, desc, isAutosave); - - checkDataDisk(-1); - - return Common::kNoError; -} - -Common::String CineEngine::getSaveStateName(int slot) const { - return getMetaEngine().getSavegameFile(slot, _targetName.c_str()); -} - -bool CineEngine::canLoadGameStateCurrently() { - return (!disableSystemMenu && !inMenu); -} - -bool CineEngine::canSaveGameStateCurrently() { - return (allowPlayerInput && !disableSystemMenu && !inMenu); -} - -} // End of namespace Cine +REGISTER_PLUGIN_STATIC(CINE_DETECTION, PLUGIN_TYPE_METAENGINE, CineMetaEngine); diff --git a/engines/cine/detection.h b/engines/cine/detection.h new file mode 100644 index 00000000000..5021d699344 --- /dev/null +++ b/engines/cine/detection.h @@ -0,0 +1,32 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +namespace Cine { + +struct CINEGameDescription { + ADGameDescription desc; + + int gameType; + uint32 features; +}; + +} // End of namespace Cine diff --git a/engines/cine/detection_enums.h b/engines/cine/detection_enums.h new file mode 100644 index 00000000000..3acc17b12b3 --- /dev/null +++ b/engines/cine/detection_enums.h @@ -0,0 +1,37 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +namespace Cine { + +enum CineGameType { + GType_FW = 1, + GType_OS +}; + +enum CineGameFeatures { + GF_CD = 1 << 0, + GF_DEMO = 1 << 1, + GF_ALT_FONT = 1 << 2, + GF_CRYPTED_BOOT_PRC = 1 << 3 +}; + +} // End of namespace Cine diff --git a/engines/cine/metaengine.cpp b/engines/cine/metaengine.cpp new file mode 100644 index 00000000000..12c2d0a7bc0 --- /dev/null +++ b/engines/cine/metaengine.cpp @@ -0,0 +1,346 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "base/plugins.h" + +#include "engines/advancedDetector.h" + +#include "common/system.h" +#include "common/textconsole.h" +#include "common/translation.h" +#include "common/util.h" + +#include "cine/cine.h" +#include "cine/various.h" + +#include "cine/detection.h" + +namespace Cine { + +#define MAX_SAVEGAMES (ARRAYSIZE(Cine::currentSaveName)) +#define SAVEGAME_NAME_LEN (sizeof(Cine::currentSaveName[0])) +#define SAVELIST_SIZE (MAX_SAVEGAMES * SAVEGAME_NAME_LEN) + +bool CineEngine::mayHave256Colors() const { return getGameType() == Cine::GType_OS && getPlatform() == Common::kPlatformDOS; } +int CineEngine::getGameType() const { return _gameDescription->gameType; } +uint32 CineEngine::getFeatures() const { return _gameDescription->features; } +Common::Language CineEngine::getLanguage() const { return _gameDescription->desc.language; } +Common::Platform CineEngine::getPlatform() const { return _gameDescription->desc.platform; } + +} // End of namespace Cine + +class CineMetaEngineConnect : public AdvancedMetaEngineConnect { +public: + const char *getName() const override { + return "cine"; + } + + Common::Error createInstance(OSystem *syst, Engine **engine) const override { + return AdvancedMetaEngineConnect::createInstance(syst, engine); + } + bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const override; + + bool hasFeature(MetaEngineFeature f) const override; + SaveStateList listSaves(const char *target) const override; + int getMaximumSaveSlot() const override; + void removeSaveState(const char *target, int slot) const override; + Common::String getSavegameFile(int saveGameIdx, const char *target = nullptr) const override; + SaveStateDescriptor querySaveMetaInfos(const char *target, int slot) const override; +}; + +bool CineMetaEngineConnect::hasFeature(MetaEngineFeature f) const { + return + (f == kSupportsListSaves) || + (f == kSupportsLoadingDuringStartup) || + (f == kSupportsDeleteSave) || + (f == kSavesSupportMetaInfo) || + (f == kSavesSupportThumbnail) || + (f == kSavesSupportCreationDate) || + (f == kSavesSupportPlayTime) || + (f == kSavesUseExtendedFormat); +} + +bool Cine::CineEngine::hasFeature(EngineFeature f) const { + return + (f == kSupportsReturnToLauncher) || + (f == kSupportsLoadingDuringRuntime) || + (f == kSupportsSavingDuringRuntime); +} + +bool CineMetaEngineConnect::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const { + const Cine::CINEGameDescription *gd = (const Cine::CINEGameDescription *)desc; + if (gd) { + *engine = new Cine::CineEngine(syst, gd); + } + return gd != 0; +} + +SaveStateList CineMetaEngineConnect::listSaves(const char *target) const { + Common::SaveFileManager *saveFileMan = g_system->getSavefileManager(); + SaveStateList saveList; + + Common::String pattern; + + Common::StringArray::const_iterator file; + + Common::String filename = target; + filename += ".dir"; + Common::InSaveFile *in = saveFileMan->openForLoading(filename); + bool foundAutosave = false; + if (in) { + typedef char CommandeType[SAVEGAME_NAME_LEN]; + CommandeType saveNames[MAX_SAVEGAMES]; + + // Initialize all savegames' descriptions to empty strings + // so that if the savegames' descriptions can only be partially read from file + // then the missing ones are correctly set to empty strings. + memset(saveNames, 0, sizeof(saveNames)); + + in->read(saveNames, SAVELIST_SIZE); + CommandeType saveDesc; + + pattern = target; + pattern += ".#*"; + Common::StringArray filenames = saveFileMan->listSavefiles(pattern); + + for (file = filenames.begin(); file != filenames.end(); ++file) { + // Obtain the extension part of the filename, since it corresponds to the save slot number + Common::String ext = Common::lastPathComponent(*file, '.'); + int slotNum = (int)ext.asUint64(); + + if (ext.equals(Common::String::format("%d", slotNum)) && + slotNum >= 0 && slotNum < MAX_SAVEGAMES) { + // Copy the savegame description making sure it ends with a trailing zero + strncpy(saveDesc, saveNames[slotNum], SAVEGAME_NAME_LEN); + saveDesc[sizeof(CommandeType) - 1] = 0; + + SaveStateDescriptor saveStateDesc(slotNum, saveDesc); + saveStateDesc.setAutosave(slotNum == getAutosaveSlot()); + saveStateDesc.setWriteProtectedFlag(saveStateDesc.isAutosave()); + + if (saveStateDesc.getDescription().empty()) { + if (saveStateDesc.isAutosave()) { + saveStateDesc.setDescription(_("Unnamed autosave")); + } else { + saveStateDesc.setDescription(_("Unnamed savegame")); + } + } + + if (saveStateDesc.isAutosave()) { + foundAutosave = true; + } + + saveList.push_back(saveStateDesc); + } + } + } + + delete in; + + // No saving on empty autosave slot + if (!foundAutosave) { + SaveStateDescriptor desc; + desc.setDescription(_("Empty autosave")); + desc.setSaveSlot(getAutosaveSlot()); + desc.setWriteProtectedFlag(true); + saveList.push_back(desc); + } + + // Sort saves based on slot number. + Common::sort(saveList.begin(), saveList.end(), SaveStateDescriptorSlotComparator()); + return saveList; +} + +int CineMetaEngineConnect::getMaximumSaveSlot() const { return MAX_SAVEGAMES - 1; } + +Common::String CineMetaEngineConnect::getSavegameFile(int saveGameIdx, const char *target) const { + return Common::String::format("%s.%d", target == nullptr ? getEngineId() : target, saveGameIdx); +} + +SaveStateDescriptor CineMetaEngineConnect::querySaveMetaInfos(const char *target, int slot) const { + if (slot < 0 || slot > getMaximumSaveSlot()) { + // HACK: Try to make SaveLoadChooserGrid::open() not use save slot + // numbers over the maximum save slot number for "New save". + SaveStateDescriptor desc; + desc.setWriteProtectedFlag(true); + return desc; + } + + Common::ScopedPtr f(g_system->getSavefileManager()->openForLoading( + getSavegameFile(slot, target))); + + if (f) { + // Create the return descriptor + SaveStateDescriptor desc; + + ExtendedSavegameHeader header; + if (readSavegameHeader(f.get(), &header, false)) { + parseSavegameHeader(&header, &desc); + desc.setThumbnail(header.thumbnail); + } else { + // Load savegame descriptions from index file + typedef char CommandeType[SAVEGAME_NAME_LEN]; + CommandeType saveNames[MAX_SAVEGAMES]; + memset(saveNames, 0, sizeof(saveNames)); + + Common::InSaveFile *in; + in = g_system->getSavefileManager()->openForLoading(Common::String::format("%s.dir", target)); + + if (in) { + in->read(saveNames, SAVELIST_SIZE); + delete in; + } + + saveNames[slot][SAVEGAME_NAME_LEN - 1] = 0; + Common::String saveNameStr((const char *)saveNames[slot]); + desc.setDescription(saveNameStr); + } + + if (desc.getDescription().empty()) { + desc.setDescription(_("Unnamed savegame")); + } + + desc.setSaveSlot(slot); + desc.setAutosave(slot == getAutosaveSlot()); + desc.setWriteProtectedFlag(desc.isAutosave()); + + return desc; + } + + // No saving on empty autosave slot + if (slot == getAutosaveSlot()) { + SaveStateDescriptor desc; + desc.setDescription(_("Empty autosave")); + desc.setSaveSlot(slot); + desc.setAutosave(true); + desc.setWriteProtectedFlag(true); + return desc; + } + + return SaveStateDescriptor(); +} + +void CineMetaEngineConnect::removeSaveState(const char *target, int slot) const { + if (slot < 0 || slot >= MAX_SAVEGAMES) { + return; + } + + // Load savegame descriptions from index file + typedef char CommandeType[SAVEGAME_NAME_LEN]; + CommandeType saveNames[MAX_SAVEGAMES]; + + // Initialize all savegames' descriptions to empty strings + // so that if the savegames' descriptions can only be partially read from file + // then the missing ones are correctly set to empty strings. + memset(saveNames, 0, sizeof(saveNames)); + + Common::InSaveFile *in; + in = g_system->getSavefileManager()->openForLoading(Common::String::format("%s.dir", target)); + + if (!in) + return; + + in->read(saveNames, SAVELIST_SIZE); + delete in; + + // Set description for selected slot + char slotName[SAVEGAME_NAME_LEN]; + slotName[0] = 0; + Common::strlcpy(saveNames[slot], slotName, SAVEGAME_NAME_LEN); + + // Update savegame descriptions + Common::String indexFile = Common::String::format("%s.dir", target); + Common::OutSaveFile *out = g_system->getSavefileManager()->openForSaving(indexFile); + if (!out) { + warning("Unable to open file %s for saving", indexFile.c_str()); + return; + } + + out->write(saveNames, SAVELIST_SIZE); + delete out; + + // Delete save file + Common::String saveFileName = getSavegameFile(slot, target); + + g_system->getSavefileManager()->removeSavefile(saveFileName); +} + +#if PLUGIN_ENABLED_DYNAMIC(CINE) + REGISTER_PLUGIN_DYNAMIC(CINE, PLUGIN_TYPE_ENGINE, CineMetaEngineConnect); +#else + REGISTER_PLUGIN_STATIC(CINE, PLUGIN_TYPE_ENGINE, CineMetaEngineConnect); +#endif + +namespace Cine { + +Common::Error CineEngine::loadGameState(int slot) { + bool gameLoaded = makeLoad(getSaveStateName(slot)); + + return gameLoaded ? Common::kNoError : Common::kUnknownError; +} + +Common::Error CineEngine::saveGameState(int slot, const Common::String &desc, bool isAutosave) { + if (slot < 0 || slot >= MAX_SAVEGAMES) { + return Common::kCreatingFileFailed; + } + + // Load savegame descriptions from index file + loadSaveDirectory(); + + // Set description for selected slot making sure it ends with a trailing zero + strncpy(currentSaveName[slot], desc.c_str(), sizeof(CommandeType)); + currentSaveName[slot][sizeof(CommandeType) - 1] = 0; + + // Update savegame descriptions + Common::String indexFile = _targetName + ".dir"; + + Common::OutSaveFile *fHandle = _saveFileMan->openForSaving(indexFile); + if (!fHandle) { + warning("Unable to open file %s for saving", indexFile.c_str()); + return Common::kUnknownError; + } + + fHandle->write(currentSaveName, SAVELIST_SIZE); + delete fHandle; + + // Save game + makeSave(getSaveStateName(slot), getTotalPlayTime() / 1000, desc, isAutosave); + + checkDataDisk(-1); + + return Common::kNoError; +} + +Common::String CineEngine::getSaveStateName(int slot) const { + return getMetaEngineConnect().getSavegameFile(slot, _targetName.c_str()); +} + +bool CineEngine::canLoadGameStateCurrently() { + return (!disableSystemMenu && !inMenu); +} + +bool CineEngine::canSaveGameStateCurrently() { + return (allowPlayerInput && !disableSystemMenu && !inMenu); +} + +} // End of namespace Cine + diff --git a/engines/cine/module.mk b/engines/cine/module.mk index 6e77449c599..510d3d00435 100644 --- a/engines/cine/module.mk +++ b/engines/cine/module.mk @@ -6,9 +6,9 @@ MODULE_OBJS := \ bg_list.o \ console.o \ cine.o \ - detection.o \ gfx.o \ main_loop.o \ + metaengine.o \ msg.o \ object.o \ pal.o \ @@ -30,3 +30,6 @@ endif # Include common rules include $(srcdir)/rules.mk + +# Detection objects +DETECT_OBJS += $(MODULE)/detection.o diff --git a/engines/cine/saveload.cpp b/engines/cine/saveload.cpp index 6b03f4fcd36..f5cd98cb7a4 100644 --- a/engines/cine/saveload.cpp +++ b/engines/cine/saveload.cpp @@ -879,7 +879,7 @@ bool CineEngine::makeLoad(const Common::String &saveName) { } ExtendedSavegameHeader header; - if (MetaEngine::readSavegameHeader(saveFile.get(), &header)) { + if (MetaEngineConnect::readSavegameHeader(saveFile.get(), &header)) { setTotalPlayTime(header.playtime * 1000); // Seconds to milliseconds } } @@ -1030,7 +1030,7 @@ void CineEngine::makeSave(const Common::String &saveFileName, uint32 playtime, renderer->popSavedBackBuffer(BEFORE_OPENING_MENU); } - MetaEngine::appendExtendedSave(fHandle.get(), playtime, desc, isAutosave); + MetaEngineConnect::appendExtendedSave(fHandle.get(), playtime, desc, isAutosave); renderer->restoreSavedBackBuffer(BEFORE_TAKING_THUMBNAIL);