diff options
Diffstat (limited to 'engines/drascula/detection.cpp')
-rw-r--r-- | engines/drascula/detection.cpp | 305 |
1 files changed, 192 insertions, 113 deletions
diff --git a/engines/drascula/detection.cpp b/engines/drascula/detection.cpp index 760d8b7d98..1917bc879d 100644 --- a/engines/drascula/detection.cpp +++ b/engines/drascula/detection.cpp @@ -21,10 +21,13 @@ */ #include "base/plugins.h" +#include "common/file.h" +#include "common/translation.h" #include "engines/advancedDetector.h" #include "engines/savestate.h" -#include "common/file.h" + +#include "graphics/thumbnail.h" #include "drascula/drascula.h" @@ -65,34 +68,58 @@ static const PlainGameDescriptor drasculaGames[] = { namespace Drascula { static const DrasculaGameDescription gameDescriptions[] = { + + //// Packed versions ////////////////////////////////////////////////////// + { - // Drascula English version + // Drascula English version (original packed files) { "drascula", 0, - AD_ENTRY1s("14.ald", "09b2735953edcd43af115c65ae00b10e", 1595), + { + {"packet.001", 0, "c6a8697396e213a18472542d5f547cb4", 32847563}, + // HACK: List packet.001 twice to ensure this detector entry + // is ranked just as high as the others (which each have two + // detection files). + {"packet.001", 0, "c6a8697396e213a18472542d5f547cb4", 32847563}, + {NULL, 0, NULL, 0} + }, Common::EN_ANY, - Common::kPlatformPC, - ADGF_NO_FLAGS, + Common::kPlatformDOS, + GF_PACKED, GUIO0() }, }, { - // Drascula English version (original packed files) + // Drascula French version (original packed files) { "drascula", 0, { {"packet.001", 0, "c6a8697396e213a18472542d5f547cb4", 32847563}, - // HACK: List packet.001 twice to ensure this detector entry - // is ranked just as high as the others (which each have two - // detection files). + {"packet.002", 1, "4401123400f22f212b89f15fb4b43013", 721122}, + {NULL, 0, NULL, 0} + }, + Common::FR_FRA, + Common::kPlatformDOS, + GF_PACKED, + GUIO0() + }, + }, + + { + // Drascula French version (ScummVM repacked files) + { + "drascula", + 0, + { {"packet.001", 0, "c6a8697396e213a18472542d5f547cb4", 32847563}, + {"packet.002", 1, "7b83cedb9bb326ed5143e5c459508d43", 722383}, {NULL, 0, NULL, 0} }, - Common::EN_ANY, - Common::kPlatformPC, + Common::FR_FRA, + Common::kPlatformDOS, GF_PACKED, GUIO0() }, @@ -109,24 +136,37 @@ static const DrasculaGameDescription gameDescriptions[] = { {NULL, 0, NULL, 0} }, Common::DE_DEU, - Common::kPlatformPC, + Common::kPlatformDOS, GF_PACKED, GUIO0() }, }, { - // Drascula French version (original packed files) + // Drascula Italian version (original packed version) + { + "drascula", + 0, + AD_ENTRY1s("packet.001", "0253e924af223f5fe52537023385159b", 32564209), + Common::IT_ITA, + Common::kPlatformDOS, + GF_PACKED, + GUIO0() + }, + }, + + { + // Drascula Italian version (ScummVM repacked files) { "drascula", 0, { {"packet.001", 0, "c6a8697396e213a18472542d5f547cb4", 32847563}, - {"packet.002", 1, "4401123400f22f212b89f15fb4b43013", 721122}, + {"packet.005", 1, "58caac54b891f5d7f335e710e45e5d29", 16209623}, {NULL, 0, NULL, 0} }, - Common::FR_FRA, - Common::kPlatformPC, + Common::IT_ITA, + Common::kPlatformDOS, GF_PACKED, GUIO0() }, @@ -139,33 +179,39 @@ static const DrasculaGameDescription gameDescriptions[] = { 0, AD_ENTRY1s("packet.001", "3c971aba65a037d29d0b479cad6f5943", 31702652), Common::ES_ESP, - Common::kPlatformPC, + Common::kPlatformDOS, GF_PACKED, GUIO0() }, }, { - // Drascula Spanish version + // Drascula Spanish version (ScummVM repacked files) { "drascula", 0, - AD_ENTRY1s("14.ald", "0746ed1a5cc8d9728f790c29813f4b43", 23059), + { + {"packet.001", 0, "c6a8697396e213a18472542d5f547cb4", 32847563}, + {"packet.004", 1, "a289d3cf80d50f25ec569b653248437e", 17205838}, + {NULL, 0, NULL, 0} + }, Common::ES_ESP, - Common::kPlatformPC, - ADGF_NO_FLAGS, + Common::kPlatformDOS, + GF_PACKED, GUIO0() }, }, + //// Unpacked versions //////////////////////////////////////////////////// + { - // Drascula German version + // Drascula English version { "drascula", 0, - AD_ENTRY1s("14.ald", "72e46089033d56bad1c179ac36e2a9d2", 610), - Common::DE_DEU, - Common::kPlatformPC, + AD_ENTRY1s("14.ald", "09b2735953edcd43af115c65ae00b10e", 1595), + Common::EN_ANY, + Common::kPlatformDOS, ADGF_NO_FLAGS, GUIO0() }, @@ -178,84 +224,73 @@ static const DrasculaGameDescription gameDescriptions[] = { 0, AD_ENTRY1s("14.ald", "eeeee96b82169003630e08992248296c", 608), Common::FR_FRA, - Common::kPlatformPC, + Common::kPlatformDOS, ADGF_NO_FLAGS, GUIO0() }, }, { - // Drascula Italian version (original packed version) + // Drascula French version (updated - bug #3612236) { "drascula", 0, - AD_ENTRY1s("packet.001", "0253e924af223f5fe52537023385159b", 32564209), - Common::IT_ITA, - Common::kPlatformPC, - GF_PACKED, + AD_ENTRY1s("14.ald", "1f9fbded768bee061cc22bc5bdeab540", 611), + Common::FR_FRA, + Common::kPlatformDOS, + ADGF_NO_FLAGS, GUIO0() }, }, + { - // Drascula Italian version + // Drascula German version { "drascula", 0, - AD_ENTRY1s("14.ald", "02b49a18328d0bf2efe6ba658c9c7a1d", 2098), - Common::IT_ITA, - Common::kPlatformPC, + AD_ENTRY1s("14.ald", "72e46089033d56bad1c179ac36e2a9d2", 610), + Common::DE_DEU, + Common::kPlatformDOS, ADGF_NO_FLAGS, GUIO0() }, }, { - // Drascula Spanish version (ScummVM repacked files) + // Drascula Italian version { "drascula", 0, - { - {"packet.001", 0, "c6a8697396e213a18472542d5f547cb4", 32847563}, - {"packet.004", 1, "a289d3cf80d50f25ec569b653248437e", 17205838}, - {NULL, 0, NULL, 0} - }, - Common::ES_ESP, - Common::kPlatformPC, - GF_PACKED, + AD_ENTRY1s("14.ald", "02b49a18328d0bf2efe6ba658c9c7a1d", 2098), + Common::IT_ITA, + Common::kPlatformDOS, + ADGF_NO_FLAGS, GUIO0() }, }, { - // Drascula Italian version (ScummVM repacked files) + // Drascula Italian version (updated - bug #3612236) { "drascula", 0, - { - {"packet.001", 0, "c6a8697396e213a18472542d5f547cb4", 32847563}, - {"packet.005", 1, "58caac54b891f5d7f335e710e45e5d29", 16209623}, - {NULL, 0, NULL, 0} - }, + AD_ENTRY1s("14.ald", "ccaee939bb3b344c048f28f9205710d1", 2925), Common::IT_ITA, - Common::kPlatformPC, - GF_PACKED, + Common::kPlatformDOS, + ADGF_NO_FLAGS, GUIO0() }, }, { - // Drascula French version (ScummVM repacked files) + // Drascula Spanish version { "drascula", 0, - { - {"packet.001", 0, "c6a8697396e213a18472542d5f547cb4", 32847563}, - {"packet.002", 1, "7b83cedb9bb326ed5143e5c459508d43", 722383}, - {NULL, 0, NULL, 0} - }, - Common::FR_FRA, - Common::kPlatformPC, - GF_PACKED, + AD_ENTRY1s("14.ald", "0746ed1a5cc8d9728f790c29813f4b43", 23059), + Common::ES_ESP, + Common::kPlatformDOS, + ADGF_NO_FLAGS, GUIO0() }, }, @@ -263,81 +298,123 @@ static const DrasculaGameDescription gameDescriptions[] = { { AD_TABLE_END_MARKER } }; -} // End of namespace Drascula +static const ExtraGuiOption drasculaExtraGuiOption = { + _s("Use original save/load screens"), + _s("Use the original save/load screens, instead of the ScummVM ones"), + "originalsaveload", + false +}; + +SaveStateDescriptor loadMetaData(Common::ReadStream *s, int slot, bool setPlayTime); class DrasculaMetaEngine : public AdvancedMetaEngine { public: DrasculaMetaEngine() : AdvancedMetaEngine(Drascula::gameDescriptions, sizeof(Drascula::DrasculaGameDescription), drasculaGames) { _singleid = "drascula"; - _guioptions = GUIO2(GUIO_NOMIDI, GUIO_NOLAUNCHLOAD); + _guioptions = GUIO1(GUIO_NOMIDI); } - virtual bool hasFeature(MetaEngineFeature f) const { - return (f == kSupportsListSaves); + virtual const char *getName() const { + return "Drascula"; } - virtual SaveStateList listSaves(const char *target) const { - Common::SaveFileManager *saveFileMan = g_system->getSavefileManager(); - Common::String pattern = Common::String::format("%s??", target); + virtual const char *getOriginalCopyright() const { + return "Drascula Engine (C) 2000 Alcachofa Soft, (C) 1996 Digital Dreams Multimedia, (C) 1994 Emilio de Paz"; + } - // Get list of savefiles for target game - Common::StringArray filenames = saveFileMan->listSavefiles(pattern); - Common::Array<int> slots; - for (Common::StringArray::const_iterator file = filenames.begin(); file != filenames.end(); ++file) { + virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *gd) const; + virtual bool hasFeature(MetaEngineFeature f) const; + virtual const ExtraGuiOptions getExtraGuiOptions(const Common::String &target) const; + virtual SaveStateList listSaves(const char *target) const; + virtual int getMaximumSaveSlot() const; + virtual void removeSaveState(const char *target, int slot) const; + SaveStateDescriptor querySaveMetaInfos(const char *target, int slot) const; +}; - // Obtain the last 2 digits of the filename, since they correspond to the save slot - int slotNum = atoi(file->c_str() + file->size() - 2); +bool DrasculaMetaEngine::hasFeature(MetaEngineFeature f) const { + return + (f == kSupportsListSaves) || + (f == kSupportsLoadingDuringStartup) || + (f == kSupportsDeleteSave) || + (f == kSavesSupportMetaInfo) || + (f == kSavesSupportThumbnail) || + (f == kSavesSupportCreationDate) || + (f == kSavesSupportPlayTime); +} - // Ensure save slot is within valid range - if (slotNum >= 1 && slotNum <= 10) { - slots.push_back(slotNum); +const ExtraGuiOptions DrasculaMetaEngine::getExtraGuiOptions(const Common::String &target) const { + ExtraGuiOptions options; + options.push_back(drasculaExtraGuiOption); + return options; +} + +SaveStateList DrasculaMetaEngine::listSaves(const char *target) const { + Common::SaveFileManager *saveFileMan = g_system->getSavefileManager(); + Common::StringArray filenames; + Common::String pattern = target; + pattern += ".???"; + + filenames = saveFileMan->listSavefiles(pattern); + sort(filenames.begin(), filenames.end()); // Sort (hopefully ensuring we are sorted numerically..) + + SaveStateList saveList; + int slotNum = 0; + 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 + slotNum = atoi(file->c_str() + file->size() - 3); + + if (slotNum >= 0 && slotNum <= getMaximumSaveSlot()) { + Common::InSaveFile *in = saveFileMan->openForLoading(*file); + if (in) { + SaveStateDescriptor desc = loadMetaData(in, slotNum, false); + if (desc.getSaveSlot() != slotNum) { + // invalid + delete in; + continue; + } + saveList.push_back(desc); + delete in; } } + } - // Sort save slot ids - Common::sort<int>(slots.begin(), slots.end()); - - // Load save index - Common::String fileEpa = Common::String::format("%s.epa", target); - Common::InSaveFile *epa = saveFileMan->openForLoading(fileEpa); - - // Get savegame names from index - Common::String saveDesc; - SaveStateList saveList; - int line = 1; - for (size_t i = 0; i < slots.size(); i++) { - // ignore lines corresponding to unused saveslots - for (; line < slots[i]; line++) - epa->readLine(); + return saveList; +} - // copy the name in the line corresponding to the save slot and truncate to 22 characters - saveDesc = Common::String(epa->readLine().c_str(), 22); +SaveStateDescriptor DrasculaMetaEngine::querySaveMetaInfos(const char *target, int slot) const { + char fileName[MAXPATHLEN]; + sprintf(fileName, "%s.%03d", target, slot); - // handle cases where the save directory and save index are detectably out of sync - if (saveDesc == "*") - saveDesc = "No name specified."; + Common::InSaveFile *in = g_system->getSavefileManager()->openForLoading(fileName); - // increment line number to keep it in sync with slot number - line++; + SaveStateDescriptor desc; + // Do not allow save slot 0 (used for auto-saving) to be deleted or + // overwritten. + desc.setDeletableFlag(slot != 0); + desc.setWriteProtectedFlag(slot == 0); - // Insert savegame name into list - saveList.push_back(SaveStateDescriptor(slots[i], saveDesc)); + if (in) { + desc = Drascula::loadMetaData(in, slot, false); + if (desc.getSaveSlot() != slot) { + delete in; + return SaveStateDescriptor(); } - delete epa; - return saveList; - } + Graphics::Surface *const thumbnail = Graphics::loadThumbnail(*in); + desc.setThumbnail(thumbnail); - virtual const char *getName() const { - return "Drascula"; + delete in; } - virtual const char *getOriginalCopyright() const { - return "Drascula Engine (C) 2000 Alcachofa Soft, (C) 1996 Digital Dreams Multimedia, (C) 1994 Emilio de Paz"; - } + return desc; +} - virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const; -}; +int DrasculaMetaEngine::getMaximumSaveSlot() const { return 999; } + +void DrasculaMetaEngine::removeSaveState(const char *target, int slot) const { + Common::String fileName = Common::String::format("%s.%03d", target, slot); + g_system->getSavefileManager()->removeSavefile(fileName); +} bool DrasculaMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const { const Drascula::DrasculaGameDescription *gd = (const Drascula::DrasculaGameDescription *)desc; @@ -347,8 +424,10 @@ bool DrasculaMetaEngine::createInstance(OSystem *syst, Engine **engine, const AD return gd != 0; } +} // End of namespace Drascula + #if PLUGIN_ENABLED_DYNAMIC(DRASCULA) - REGISTER_PLUGIN_DYNAMIC(DRASCULA, PLUGIN_TYPE_ENGINE, DrasculaMetaEngine); + REGISTER_PLUGIN_DYNAMIC(DRASCULA, PLUGIN_TYPE_ENGINE, Drascula::DrasculaMetaEngine); #else - REGISTER_PLUGIN_STATIC(DRASCULA, PLUGIN_TYPE_ENGINE, DrasculaMetaEngine); + REGISTER_PLUGIN_STATIC(DRASCULA, PLUGIN_TYPE_ENGINE, Drascula::DrasculaMetaEngine); #endif |