1 /* ScummVM - Graphic Adventure Engine 2 * 3 * ScummVM is the legal property of its developers, whose names 4 * are too numerous to list here. Please refer to the COPYRIGHT 5 * file distributed with this source distribution. 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 * 21 */ 22 23 /* 24 * Based on the Reverse Engineering work of Christophe Fontanel, 25 * maintainer of the Dungeon Master Encyclopaedia (http://dmweb.free.fr/) 26 */ 27 28 #include "common/config-manager.h" 29 #include "common/error.h" 30 #include "common/fs.h" 31 #include "common/system.h" 32 33 #include "engines/advancedDetector.h" 34 35 #include "dm/dm.h" 36 37 namespace DM { 38 39 class DMMetaEngine : public AdvancedMetaEngine { 40 public: getName() const41 const char *getName() const override { 42 return "dm"; 43 } 44 createInstance(OSystem * syst,Engine ** engine,const ADGameDescription * desc) const45 Common::Error createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const override { 46 *engine = new DM::DMEngine(syst, (const DMADGameDescription*)desc); 47 return Common::kNoError; 48 } 49 hasFeature(MetaEngineFeature f) const50 bool hasFeature(MetaEngineFeature f) const override { 51 return 52 (f == kSupportsListSaves) || 53 (f == kSupportsLoadingDuringStartup) || 54 (f == kSavesSupportThumbnail) || 55 (f == kSavesSupportMetaInfo) || 56 (f == kSimpleSavesNames) || 57 (f == kSavesSupportCreationDate); 58 } 59 getMaximumSaveSlot() const60 int getMaximumSaveSlot() const override { return 99; } 61 listSaves(const char * target) const62 SaveStateList listSaves(const char *target) const override { 63 Common::SaveFileManager *saveFileMan = g_system->getSavefileManager(); 64 SaveGameHeader header; 65 Common::String pattern = target; 66 pattern += ".###"; 67 68 Common::StringArray filenames; 69 filenames = saveFileMan->listSavefiles(pattern.c_str()); 70 71 SaveStateList saveList; 72 73 for (Common::StringArray::const_iterator file = filenames.begin(); file != filenames.end(); ++file) { 74 // Obtain the last 3 digits of the filename, since they correspond to the save slot 75 int slotNum = atoi(file->c_str() + file->size() - 3); 76 77 if ((slotNum >= 0) && (slotNum <= 999)) { 78 Common::InSaveFile *in = saveFileMan->openForLoading(file->c_str()); 79 if (in) { 80 if (DM::readSaveGameHeader(in, &header)) 81 saveList.push_back(SaveStateDescriptor(this, slotNum, header._descr.getDescription())); 82 delete in; 83 } 84 } 85 } 86 87 // Sort saves based on slot number. 88 Common::sort(saveList.begin(), saveList.end(), SaveStateDescriptorSlotComparator()); 89 return saveList; 90 } 91 querySaveMetaInfos(const char * target,int slot) const92 SaveStateDescriptor querySaveMetaInfos(const char *target, int slot) const override { 93 Common::String filename = Common::String::format("%s.%03u", target, slot); 94 Common::InSaveFile *in = g_system->getSavefileManager()->openForLoading(filename.c_str()); 95 96 if (in) { 97 DM::SaveGameHeader header; 98 99 bool successfulRead = DM::readSaveGameHeader(in, &header); 100 delete in; 101 102 if (successfulRead) { 103 SaveStateDescriptor desc(this, slot, header._descr.getDescription()); 104 105 return header._descr; 106 } 107 } 108 109 return SaveStateDescriptor(); 110 } 111 removeSaveState(const char * target,int slot) const112 void removeSaveState(const char *target, int slot) const override {} 113 114 }; 115 116 } // End of namespace DM 117 118 #if PLUGIN_ENABLED_DYNAMIC(DM) 119 REGISTER_PLUGIN_DYNAMIC(DM, PLUGIN_TYPE_ENGINE, DM::DMMetaEngine); 120 #else 121 REGISTER_PLUGIN_STATIC(DM, PLUGIN_TYPE_ENGINE, DM::DMMetaEngine); 122 #endif 123