diff options
Diffstat (limited to 'engines/dm/detection.cpp')
-rw-r--r-- | engines/dm/detection.cpp | 175 |
1 files changed, 175 insertions, 0 deletions
diff --git a/engines/dm/detection.cpp b/engines/dm/detection.cpp new file mode 100644 index 0000000000..71528710fb --- /dev/null +++ b/engines/dm/detection.cpp @@ -0,0 +1,175 @@ +/* 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. +* +*/ + +/* +* Based on the Reverse Engineering work of Christophe Fontanel, +* maintainer of the Dungeon Master Encyclopaedia (http://dmweb.free.fr/) +*/ + + +#include "common/config-manager.h" +#include "common/error.h" +#include "common/fs.h" +#include "common/system.h" + +#include "engines/advancedDetector.h" + +#include "dm/dm.h" + +namespace DM { +static const PlainGameDescriptor DMGames[] = { + {"dm", "Dungeon Master"}, + {0, 0} +}; + +static const DMADGameDescription gameDescriptions[] = { + { + {"dm", "Amiga 2.0v English", + { + {"graphics.dat", 0, "c2205f6225bde728417de29394f97d55", 411960}, + {"Dungeon.dat", 0, "43a213da8eda413541dd12f90ce202f6", 25006}, + AD_LISTEND + }, + Common::EN_ANY, Common::kPlatformAmiga, ADGF_NO_FLAGS, GUIO1(GUIO_NONE) + }, + k_saveTarget_DM21, k_saveFormat_dm_amiga__2_x_pc98_x68000_fm_towns_csb_atari_st, k_savePlatform_amiga, + { k_saveTarget_DM21, k_saveTarget_endOfList }, + { k_saveFormat_dm_amiga__2_x_pc98_x68000_fm_towns_csb_atari_st, k_saveFormat_endOfList}, + { k_savePlatform_accept_any} + }, + { + {"dm", "Atari ???v English", + { + {"graphics.dat", 0, "6ffff2a17e2df0effa9a12fb4b1bf6b6", 271911}, + {"Dungeon.dat", 0, "be9468b460515741babec9a70501e2e9", 33286}, + AD_LISTEND + }, + Common::EN_ANY, Common::kPlatformAtariST, ADGF_NO_FLAGS, GUIO1(GUIO_NONE), + }, + k_saveTarget_DM21, k_saveFormat_dm_amiga__2_x_pc98_x68000_fm_towns_csb_atari_st, k_savePlatform_atari_st, + { k_saveTarget_DM21, k_saveTarget_endOfList}, + { k_saveFormat_dm_amiga__2_x_pc98_x68000_fm_towns_csb_atari_st, k_saveFormat_endOfList}, + { k_savePlatform_accept_any } + }, + + { + AD_TABLE_END_MARKER, k_saveTarget_none, k_saveFormat_none, k_savePlatform_none, + {k_saveTarget_none}, {k_saveFormat_none}, {k_savePlatform_none} + } +}; + + +static const ADExtraGuiOptionsMap optionsList[] = { + AD_EXTRA_GUI_OPTIONS_TERMINATOR +}; + + +class DMMetaEngine : public AdvancedMetaEngine { +public: + DMMetaEngine() : AdvancedMetaEngine(DM::gameDescriptions, sizeof(DMADGameDescription), DMGames, optionsList) { + _singleId = "dm"; + } + + virtual const char *getName() const { + return "Dungeon Master"; + } + + virtual const char *getOriginalCopyright() const { + return "Dungeon Master (C) 1987 FTL Games"; + } + + virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const { + if (desc) + *engine = new DM::DMEngine(syst, (const DMADGameDescription*)desc); + return desc != nullptr; + } + + virtual bool hasFeature(MetaEngineFeature f) const { + return + (f == kSupportsListSaves) || + (f == kSupportsLoadingDuringStartup) || + (f == kSavesSupportThumbnail) || + (f == kSavesSupportMetaInfo) || + (f == kSavesSupportCreationDate); + } + + virtual int getMaximumSaveSlot() const { return 99; } + + virtual SaveStateList listSaves(const char *target) const { + Common::SaveFileManager *saveFileMan = g_system->getSavefileManager(); + SaveGameHeader header; + Common::String pattern = target; + pattern += ".###"; + + Common::StringArray filenames; + filenames = saveFileMan->listSavefiles(pattern.c_str()); + + SaveStateList saveList; + + for (Common::StringArray::const_iterator file = filenames.begin(); file != filenames.end(); ++file) { + // Obtain the last 3 digits of the filename, since they correspond to the save slot + int slotNum = atoi(file->c_str() + file->size() - 3); + + if ((slotNum >= 0) && (slotNum <= 999)) { + Common::InSaveFile *in = saveFileMan->openForLoading(file->c_str()); + if (in) { + if (DM::readSaveGameHeader(in, &header)) + saveList.push_back(SaveStateDescriptor(slotNum, header._descr.getDescription())); + delete in; + } + } + } + + // Sort saves based on slot number. + Common::sort(saveList.begin(), saveList.end(), SaveStateDescriptorSlotComparator()); + return saveList; + } + + SaveStateDescriptor querySaveMetaInfos(const char *target, int slot) const { + Common::String filename = Common::String::format("%s.%03u", target, slot); + Common::InSaveFile *in = g_system->getSavefileManager()->openForLoading(filename.c_str()); + + if (in) { + DM::SaveGameHeader header; + + bool successfulRead = DM::readSaveGameHeader(in, &header); + delete in; + + if (successfulRead) { + SaveStateDescriptor desc(slot, header._descr.getDescription()); + + return header._descr; + } + } + + return SaveStateDescriptor(); + } + + virtual void removeSaveState(const char *target, int slot) const {} +}; + +} +#if PLUGIN_ENABLED_DYNAMIC(DM) +REGISTER_PLUGIN_DYNAMIC(DM, PLUGIN_TYPE_ENGINE, DM::DMMetaEngine); +#else +REGISTER_PLUGIN_STATIC(DM, PLUGIN_TYPE_ENGINE, DM::DMMetaEngine); +#endif |