diff --git a/configure b/configure index fcd78d328bf..7f1edc1c2e5 100755 --- a/configure +++ b/configure @@ -6161,7 +6161,7 @@ EOF done declare -a static_detect_engines=("PLUMBERS" "AGI" "SCUMM" "SKY" "DREAMWEB" "DRASCULA" "LURE" - "SWORD1" "SWORD2" "SWORD25") + "SWORD1" "SWORD2" "SWORD25" "ADL") detectId="_DETECTION" echo "Creating engines/plugins_table.h" diff --git a/engines/adl/adl.h b/engines/adl/adl.h index 00611cc9ad1..5dd7f047379 100644 --- a/engines/adl/adl.h +++ b/engines/adl/adl.h @@ -34,6 +34,7 @@ #include "common/scummsys.h" #include "engines/engine.h" +#include "engines/advancedDetector.h" #include "audio/mixer.h" #include "audio/softsynth/pcspk.h" diff --git a/engines/adl/detection.cpp b/engines/adl/detection.cpp index 2ff63f0a38f..e4f9a1a349d 100644 --- a/engines/adl/detection.cpp +++ b/engines/adl/detection.cpp @@ -20,15 +20,11 @@ * */ -#include "common/system.h" -#include "common/savefile.h" #include "common/translation.h" #include "common/file.h" #include "common/md5.h" #include "common/debug.h" -#include "graphics/thumbnail.h" - #include "engines/advancedDetector.h" #include "adl/detection.h" @@ -112,12 +108,6 @@ static const PlainGameDescriptor adlGames[] = { { 0, 0 } }; -struct AdlGameDescription { - ADGameDescription desc; - GameType gameType; - GameVersion version; -}; - static const AdlGameDescription gameFileDescriptions[] = { { // Hi-Res Adventure #1: Mystery House - Apple II - Contains Simi Valley address { @@ -376,137 +366,11 @@ public: return "Copyright (C) Sierra On-Line"; } - bool hasFeature(MetaEngineFeature f) const override; - SaveStateDescriptor querySaveMetaInfos(const char *target, int slot) const override; - int getMaximumSaveSlot() const override { return 'O' - 'A'; } - SaveStateList listSaves(const char *target) const override; - void removeSaveState(const char *target, int slot) const override; ADDetectedGames detectGame(const Common::FSNode &parent, const FileMap &allFiles, Common::Language language, Common::Platform platform, const Common::String &extra) const override; bool addFileProps(const FileMap &allFiles, Common::String fname, FilePropertiesMap &filePropsMap) const; - - bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *gd) const override; }; -bool AdlMetaEngine::hasFeature(MetaEngineFeature f) const { - switch(f) { - case kSupportsListSaves: - case kSupportsLoadingDuringStartup: - case kSupportsDeleteSave: - case kSavesSupportMetaInfo: - case kSavesSupportThumbnail: - case kSavesSupportCreationDate: - case kSavesSupportPlayTime: - case kSimpleSavesNames: - return true; - default: - return false; - } -} - -SaveStateDescriptor AdlMetaEngine::querySaveMetaInfos(const char *target, int slot) const { - Common::String fileName = Common::String::format("%s.s%02d", target, slot); - Common::InSaveFile *inFile = g_system->getSavefileManager()->openForLoading(fileName); - - if (!inFile) - return SaveStateDescriptor(); - - if (inFile->readUint32BE() != MKTAG('A', 'D', 'L', ':')) { - delete inFile; - return SaveStateDescriptor(); - } - - byte saveVersion = inFile->readByte(); - if (saveVersion != SAVEGAME_VERSION) { - delete inFile; - return SaveStateDescriptor(); - } - - char name[SAVEGAME_NAME_LEN] = { }; - inFile->read(name, sizeof(name) - 1); - inFile->readByte(); - - if (inFile->eos() || inFile->err()) { - delete inFile; - return SaveStateDescriptor(); - } - - SaveStateDescriptor sd(slot, name); - - int year = inFile->readUint16BE(); - int month = inFile->readByte(); - int day = inFile->readByte(); - sd.setSaveDate(year + 1900, month + 1, day); - - int hour = inFile->readByte(); - int minutes = inFile->readByte(); - sd.setSaveTime(hour, minutes); - - uint32 playTime = inFile->readUint32BE(); - sd.setPlayTime(playTime); - - if (inFile->eos() || inFile->err()) { - delete inFile; - return SaveStateDescriptor(); - } - - Graphics::Surface *thumbnail; - if (!Graphics::loadThumbnail(*inFile, thumbnail)) { - delete inFile; - return SaveStateDescriptor(); - } - sd.setThumbnail(thumbnail); - - delete inFile; - return sd; -} - -SaveStateList AdlMetaEngine::listSaves(const char *target) const { - Common::SaveFileManager *saveFileMan = g_system->getSavefileManager(); - Common::StringArray files = saveFileMan->listSavefiles(Common::String(target) + ".s##"); - - SaveStateList saveList; - - for (uint i = 0; i < files.size(); ++i) { - const Common::String &fileName = files[i]; - Common::InSaveFile *inFile = saveFileMan->openForLoading(fileName); - if (!inFile) { - warning("Cannot open save file '%s'", fileName.c_str()); - continue; - } - - if (inFile->readUint32BE() != MKTAG('A', 'D', 'L', ':')) { - warning("No header found in '%s'", fileName.c_str()); - delete inFile; - continue; - } - - byte saveVersion = inFile->readByte(); - if (saveVersion != SAVEGAME_VERSION) { - warning("Unsupported save game version %i found in '%s'", saveVersion, fileName.c_str()); - delete inFile; - continue; - } - - char name[SAVEGAME_NAME_LEN] = { }; - inFile->read(name, sizeof(name) - 1); - delete inFile; - - int slotNum = atoi(fileName.c_str() + fileName.size() - 2); - SaveStateDescriptor sd(slotNum, name); - saveList.push_back(sd); - } - - // Sort saves based on slot number. - Common::sort(saveList.begin(), saveList.end(), SaveStateDescriptorSlotComparator()); - return saveList; -} - -void AdlMetaEngine::removeSaveState(const char *target, int slot) const { - Common::String fileName = Common::String::format("%s.s%02d", target, slot); - g_system->getSavefileManager()->removeSavefile(fileName); -} - Common::String getDiskImageName(const AdlGameDescription &adlDesc, byte volume) { const ADGameDescription &desc = adlDesc.desc; for (uint i = 0; desc.filesDescriptions[i].fileName; ++i) { @@ -655,53 +519,6 @@ ADDetectedGames AdlMetaEngine::detectGame(const Common::FSNode &parent, const Fi return matched; } -Engine *HiRes1Engine_create(OSystem *syst, const AdlGameDescription *gd); -Engine *HiRes2Engine_create(OSystem *syst, const AdlGameDescription *gd); -Engine *HiRes0Engine_create(OSystem *syst, const AdlGameDescription *gd); -Engine *HiRes3Engine_create(OSystem *syst, const AdlGameDescription *gd); -Engine *HiRes4Engine_create(OSystem *syst, const AdlGameDescription *gd); -Engine *HiRes5Engine_create(OSystem *syst, const AdlGameDescription *gd); -Engine *HiRes6Engine_create(OSystem *syst, const AdlGameDescription *gd); - -bool AdlMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *gd) const { - if (!gd) - return false; - - const AdlGameDescription *adlGd = (const AdlGameDescription *)gd; - - switch (adlGd->gameType) { - case GAME_TYPE_HIRES1: - *engine = HiRes1Engine_create(syst, adlGd); - break; - case GAME_TYPE_HIRES2: - *engine = HiRes2Engine_create(syst, adlGd); - break; - case GAME_TYPE_HIRES0: - *engine = HiRes0Engine_create(syst, adlGd); - break; - case GAME_TYPE_HIRES3: - *engine = HiRes3Engine_create(syst, adlGd); - break; - case GAME_TYPE_HIRES4: - *engine = HiRes4Engine_create(syst, adlGd); - break; - case GAME_TYPE_HIRES5: - *engine = HiRes5Engine_create(syst, adlGd); - break; - case GAME_TYPE_HIRES6: - *engine = HiRes6Engine_create(syst, adlGd); - break; - default: - error("Unknown GameType"); - } - - return true; -} - } // End of namespace Adl -#if PLUGIN_ENABLED_DYNAMIC(ADL) - REGISTER_PLUGIN_DYNAMIC(ADL, PLUGIN_TYPE_ENGINE, Adl::AdlMetaEngine); -#else - REGISTER_PLUGIN_STATIC(ADL, PLUGIN_TYPE_ENGINE, Adl::AdlMetaEngine); -#endif +REGISTER_PLUGIN_STATIC(ADL_DETECTION, PLUGIN_TYPE_METAENGINE, Adl::AdlMetaEngine); diff --git a/engines/adl/detection.h b/engines/adl/detection.h index bd009d2cb25..acc89bfb2ce 100644 --- a/engines/adl/detection.h +++ b/engines/adl/detection.h @@ -62,7 +62,11 @@ enum GameVersion { GAME_VER_HR1_PD }; -struct AdlGameDescription; +struct AdlGameDescription { + ADGameDescription desc; + GameType gameType; + GameVersion version; +}; Common::String getDiskImageName(const AdlGameDescription &adlDesc, byte volume); GameType getGameType(const AdlGameDescription &desc); diff --git a/engines/adl/metaengine.cpp b/engines/adl/metaengine.cpp new file mode 100644 index 00000000000..08e8f18c14f --- /dev/null +++ b/engines/adl/metaengine.cpp @@ -0,0 +1,219 @@ +/* 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 "engines/advancedDetector.h" + +#include "common/system.h" +#include "common/savefile.h" + +#include "graphics/thumbnail.h" + +#include "adl/detection.h" + + +namespace Adl { + +class AdlMetaEngineConnect : public AdvancedMetaEngineConnect { +public: + const char *getName() const override { + return "adl"; + } + + bool hasFeature(MetaEngineFeature f) const override; + SaveStateDescriptor querySaveMetaInfos(const char *target, int slot) const override; + int getMaximumSaveSlot() const override { return 'O' - 'A'; } + SaveStateList listSaves(const char *target) const override; + void removeSaveState(const char *target, int slot) const override; + + bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *gd) const override; +}; + +bool AdlMetaEngineConnect::hasFeature(MetaEngineFeature f) const { + switch(f) { + case kSupportsListSaves: + case kSupportsLoadingDuringStartup: + case kSupportsDeleteSave: + case kSavesSupportMetaInfo: + case kSavesSupportThumbnail: + case kSavesSupportCreationDate: + case kSavesSupportPlayTime: + case kSimpleSavesNames: + return true; + default: + return false; + } +} + +SaveStateDescriptor AdlMetaEngineConnect::querySaveMetaInfos(const char *target, int slot) const { + Common::String fileName = Common::String::format("%s.s%02d", target, slot); + Common::InSaveFile *inFile = g_system->getSavefileManager()->openForLoading(fileName); + + if (!inFile) + return SaveStateDescriptor(); + + if (inFile->readUint32BE() != MKTAG('A', 'D', 'L', ':')) { + delete inFile; + return SaveStateDescriptor(); + } + + byte saveVersion = inFile->readByte(); + if (saveVersion != SAVEGAME_VERSION) { + delete inFile; + return SaveStateDescriptor(); + } + + char name[SAVEGAME_NAME_LEN] = { }; + inFile->read(name, sizeof(name) - 1); + inFile->readByte(); + + if (inFile->eos() || inFile->err()) { + delete inFile; + return SaveStateDescriptor(); + } + + SaveStateDescriptor sd(slot, name); + + int year = inFile->readUint16BE(); + int month = inFile->readByte(); + int day = inFile->readByte(); + sd.setSaveDate(year + 1900, month + 1, day); + + int hour = inFile->readByte(); + int minutes = inFile->readByte(); + sd.setSaveTime(hour, minutes); + + uint32 playTime = inFile->readUint32BE(); + sd.setPlayTime(playTime); + + if (inFile->eos() || inFile->err()) { + delete inFile; + return SaveStateDescriptor(); + } + + Graphics::Surface *thumbnail; + if (!Graphics::loadThumbnail(*inFile, thumbnail)) { + delete inFile; + return SaveStateDescriptor(); + } + sd.setThumbnail(thumbnail); + + delete inFile; + return sd; +} + +SaveStateList AdlMetaEngineConnect::listSaves(const char *target) const { + Common::SaveFileManager *saveFileMan = g_system->getSavefileManager(); + Common::StringArray files = saveFileMan->listSavefiles(Common::String(target) + ".s##"); + + SaveStateList saveList; + + for (uint i = 0; i < files.size(); ++i) { + const Common::String &fileName = files[i]; + Common::InSaveFile *inFile = saveFileMan->openForLoading(fileName); + if (!inFile) { + warning("Cannot open save file '%s'", fileName.c_str()); + continue; + } + + if (inFile->readUint32BE() != MKTAG('A', 'D', 'L', ':')) { + warning("No header found in '%s'", fileName.c_str()); + delete inFile; + continue; + } + + byte saveVersion = inFile->readByte(); + if (saveVersion != SAVEGAME_VERSION) { + warning("Unsupported save game version %i found in '%s'", saveVersion, fileName.c_str()); + delete inFile; + continue; + } + + char name[SAVEGAME_NAME_LEN] = { }; + inFile->read(name, sizeof(name) - 1); + delete inFile; + + int slotNum = atoi(fileName.c_str() + fileName.size() - 2); + SaveStateDescriptor sd(slotNum, name); + saveList.push_back(sd); + } + + // Sort saves based on slot number. + Common::sort(saveList.begin(), saveList.end(), SaveStateDescriptorSlotComparator()); + return saveList; +} + +void AdlMetaEngineConnect::removeSaveState(const char *target, int slot) const { + Common::String fileName = Common::String::format("%s.s%02d", target, slot); + g_system->getSavefileManager()->removeSavefile(fileName); +} + +Engine *HiRes1Engine_create(OSystem *syst, const AdlGameDescription *gd); +Engine *HiRes2Engine_create(OSystem *syst, const AdlGameDescription *gd); +Engine *HiRes0Engine_create(OSystem *syst, const AdlGameDescription *gd); +Engine *HiRes3Engine_create(OSystem *syst, const AdlGameDescription *gd); +Engine *HiRes4Engine_create(OSystem *syst, const AdlGameDescription *gd); +Engine *HiRes5Engine_create(OSystem *syst, const AdlGameDescription *gd); +Engine *HiRes6Engine_create(OSystem *syst, const AdlGameDescription *gd); + +bool AdlMetaEngineConnect::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *gd) const { + if (!gd) + return false; + + const AdlGameDescription *adlGd = (const AdlGameDescription *)gd; + + switch (adlGd->gameType) { + case GAME_TYPE_HIRES1: + *engine = HiRes1Engine_create(syst, adlGd); + break; + case GAME_TYPE_HIRES2: + *engine = HiRes2Engine_create(syst, adlGd); + break; + case GAME_TYPE_HIRES0: + *engine = HiRes0Engine_create(syst, adlGd); + break; + case GAME_TYPE_HIRES3: + *engine = HiRes3Engine_create(syst, adlGd); + break; + case GAME_TYPE_HIRES4: + *engine = HiRes4Engine_create(syst, adlGd); + break; + case GAME_TYPE_HIRES5: + *engine = HiRes5Engine_create(syst, adlGd); + break; + case GAME_TYPE_HIRES6: + *engine = HiRes6Engine_create(syst, adlGd); + break; + default: + error("Unknown GameType"); + } + + return true; +} + +} // End of namespace Adl + +#if PLUGIN_ENABLED_DYNAMIC(ADL) + REGISTER_PLUGIN_DYNAMIC(ADL, PLUGIN_TYPE_ENGINE, Adl::AdlMetaEngineConnect); +#else + REGISTER_PLUGIN_STATIC(ADL, PLUGIN_TYPE_ENGINE, Adl::AdlMetaEngineConnect); +#endif + diff --git a/engines/adl/module.mk b/engines/adl/module.mk index 450720654b6..da28b7016bf 100644 --- a/engines/adl/module.mk +++ b/engines/adl/module.mk @@ -7,7 +7,6 @@ MODULE_OBJS := \ adl_v4.o \ adl_v5.o \ console.o \ - detection.o \ disk.o \ display.o \ display_a2.o \ @@ -16,6 +15,7 @@ MODULE_OBJS := \ hires4.o \ hires5.o \ hires6.o \ + metaengine.o \ sound.o MODULE_DIRS += \ @@ -28,3 +28,13 @@ endif # Include common rules include $(srcdir)/rules.mk + +# Detection objects +DETECT_OBJS += $(MODULE)/detection.o + +# Only include if building as a dynamic module. +# Static module already has the contents. +ifeq ($(ENABLE_ADL), DYNAMIC_PLUGIN) +# External dependencies for detection. +DETECT_OBJS += $(MODULE)/disk.o +endif