aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common/advancedDetector.h40
-rw-r--r--engines/agi/detection.cpp18
-rw-r--r--engines/metaengine.h81
-rw-r--r--engines/saga/detection.cpp2
-rw-r--r--engines/scumm/detection.cpp39
-rw-r--r--engines/sword1/sword1.cpp28
-rw-r--r--engines/sword2/sword2.cpp32
-rw-r--r--engines/touche/detection.cpp19
8 files changed, 238 insertions, 21 deletions
diff --git a/common/advancedDetector.h b/common/advancedDetector.h
index f0d6c88e4e..171673771c 100644
--- a/common/advancedDetector.h
+++ b/common/advancedDetector.h
@@ -26,10 +26,11 @@
#define COMMON_ADVANCED_DETECTOR_H
#include "common/fs.h"
+#include "common/error.h"
#include "base/game.h" // For PlainGameDescriptor and GameList
-#include "base/plugins.h" // For PluginError
+#include "engines/metaengine.h"
namespace Common {
@@ -273,4 +274,41 @@ void reportUnknown(StringList &files, int md5Bytes);
} // End of namespace Common
+/**
+ * A MetaEngine implementation based around the advanced detector code.
+ */
+class AdvancedMetaEngine : public MetaEngine {
+ const Common::ADParams &params;
+public:
+ AdvancedMetaEngine(const Common::ADParams &dp) : params(dp) {}
+
+ // To be provided by subclasses
+ virtual bool createInstance(OSystem *syst, Engine **engine, const Common::EncapsulatedADGameDesc &encapsulatedDesc) const = 0;
+
+
+protected:
+ virtual GameList getSupportedGames() const {
+ return Common::AdvancedDetector::gameIDList(params);
+ }
+ virtual GameDescriptor findGame(const char *gameid) const {
+ return Common::AdvancedDetector::findGameID(gameid, params.list, params.obsoleteList);
+ }
+ virtual GameList detectGames(const FSList &fslist) const {
+ return Common::AdvancedDetector::detectAllGames(fslist, params);
+ }
+
+ virtual PluginError createInstance(OSystem *syst, Engine **engine) const {
+ assert(engine);
+ Common::AdvancedDetector::upgradeTargetIfNecessary(params);
+ Common::EncapsulatedADGameDesc encapsulatedDesc = Common::AdvancedDetector::detectBestMatchingGame(params);
+ if (encapsulatedDesc.realDesc == 0) {
+ return kNoGameDataFoundError;
+ }
+ if (!createInstance(syst,engine,encapsulatedDesc)) {
+ return kNoGameDataFoundError;
+ }
+ return kNoError;
+ }
+};
+
#endif
diff --git a/engines/agi/detection.cpp b/engines/agi/detection.cpp
index 9c0a5c3585..8c88906a99 100644
--- a/engines/agi/detection.cpp
+++ b/engines/agi/detection.cpp
@@ -2250,7 +2250,21 @@ static const Common::ADParams detectionParams = {
Common::kADFlagAugmentPreferredTarget
};
-bool engineCreateAgi(OSystem *syst, Engine **engine, Common::EncapsulatedADGameDesc encapsulatedDesc) {
+class AgiMetaEngine : public AdvancedMetaEngine {
+public:
+ AgiMetaEngine() : AdvancedMetaEngine(detectionParams) {}
+
+ virtual const char *getName() const {
+ return "AGI preAGI + v2 + v3 Engine";
+ }
+ virtual const char *getCopyright() const {
+ return "Sierra AGI Engine (C) Sierra On-Line Software";
+ }
+
+ virtual bool createInstance(OSystem *syst, Engine **engine, const Common::EncapsulatedADGameDesc &encapsulatedDesc) const;
+};
+
+bool AgiMetaEngine::createInstance(OSystem *syst, Engine **engine, const Common::EncapsulatedADGameDesc &encapsulatedDesc) const {
const Agi::AGIGameDescription *gd = (const Agi::AGIGameDescription *)(encapsulatedDesc.realDesc);
bool res = true;
@@ -2270,7 +2284,7 @@ bool engineCreateAgi(OSystem *syst, Engine **engine, Common::EncapsulatedADGameD
return res;
}
-ADVANCED_DETECTOR_DEFINE_PLUGIN(AGI, engineCreateAgi, detectionParams);
+META_COMPATIBLITY_WRAPPER(AGI, AgiMetaEngine);
REGISTER_PLUGIN(AGI, "AGI preAGI + v2 + v3 Engine", "Sierra AGI Engine (C) Sierra On-Line Software");
diff --git a/engines/metaengine.h b/engines/metaengine.h
new file mode 100644
index 0000000000..a290044d2b
--- /dev/null
+++ b/engines/metaengine.h
@@ -0,0 +1,81 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ */
+
+#ifndef ENGINES_METAENGINE_H
+#define ENGINES_METAENGINE_H
+
+#include "common/scummsys.h"
+#include "common/str.h"
+#include "common/error.h"
+
+#include "base/game.h"
+
+class Engine;
+class OSystem;
+
+/**
+ * A meta engine is essentially a factory for Engine instances with the
+ * added ability of listing and detecting supported games.
+ * Every engine "plugin" provides a hook to get an instance of a MetaEngine
+ * subclass for that "engine plugin". E.g. SCUMM povides ScummMetaEngine.
+ * This is then in turn used by the frontend code to detect games,
+ * and instantiate actual Engine objects.
+ */
+class MetaEngine {
+public:
+ virtual ~MetaEngine() {}
+
+ virtual const char *getName() const = 0;
+ virtual const char *getCopyright() const = 0;
+// virtual int getVersion() const = 0; // TODO!
+
+ virtual GameList getSupportedGames() const = 0;
+ virtual GameDescriptor findGame(const char *gameid) const = 0;
+ virtual GameList detectGames(const FSList &fslist) const = 0;
+
+ virtual PluginError createInstance(OSystem *syst, Engine **engine) const = 0;
+};
+
+
+/**
+ * The META_COMPATIBLITY_WRAPPER macro is there to ease the transition from the
+ * old plugin API to the new MetaEngine class. Ultimately, this macro will go
+ * and REGISTER_PLUGIN will be changedd to simply take an ID and a METACLASS.
+ * Until then, use META_COMPATIBLITY_WRAPPER + REGISTER_PLUGIN.
+ */
+#define META_COMPATIBLITY_WRAPPER(ID,METACLASS) \
+ static MetaEngine &getMetaEngine() { \
+ static MetaEngine *meta = 0; \
+ if (!meta) meta = new METACLASS(); \
+ return *meta; \
+ } \
+ GameList Engine_##ID##_gameIDList() { return getMetaEngine().getSupportedGames(); } \
+ GameDescriptor Engine_##ID##_findGameID(const char *gameid) { return getMetaEngine().findGame(gameid); } \
+ PluginError Engine_##ID##_create(OSystem *syst, Engine **engine) { return getMetaEngine().createInstance(syst, engine); } \
+ GameList Engine_##ID##_detectGames(const FSList &fslist) { return getMetaEngine().detectGames(fslist); } \
+ void dummyFuncToAllowTrailingSemicolon()
+
+
+
+#endif
diff --git a/engines/saga/detection.cpp b/engines/saga/detection.cpp
index aeac536af3..74acdf0743 100644
--- a/engines/saga/detection.cpp
+++ b/engines/saga/detection.cpp
@@ -27,6 +27,8 @@
#include "saga/saga.h"
+#include "base/plugins.h"
+
#include "common/config-manager.h"
#include "common/advancedDetector.h"
diff --git a/engines/scumm/detection.cpp b/engines/scumm/detection.cpp
index 8eb59ea66a..c85500fcc9 100644
--- a/engines/scumm/detection.cpp
+++ b/engines/scumm/detection.cpp
@@ -36,6 +36,9 @@
#include "scumm/intern.h"
#include "scumm/he/intern_he.h"
+#include "engines/metaengine.h"
+
+
namespace Scumm {
enum {
@@ -662,20 +665,33 @@ static bool testGame(const GameSettings *g, const DescMap &fileMD5Map, const Com
using namespace Scumm;
-GameList Engine_SCUMM_gameIDList() {
+class ScummMetaEngine : public MetaEngine {
+public:
+ virtual const char *getName() const;
+ virtual const char *getCopyright() const;
+// virtual int getVersion() const { return 0; } // TODO!
+
+ virtual GameList getSupportedGames() const;
+ virtual GameDescriptor findGame(const char *gameid) const;
+ virtual GameList detectGames(const FSList &fslist) const;
+
+ virtual PluginError createInstance(OSystem *syst, Engine **engine) const;
+};
+
+GameList ScummMetaEngine::getSupportedGames() const {
return GameList(gameDescriptions);
}
-GameDescriptor Engine_SCUMM_findGameID(const char *gameid) {
+GameDescriptor ScummMetaEngine::findGame(const char *gameid) const {
return Common::AdvancedDetector::findGameID(gameid, gameDescriptions, obsoleteGameIDsTable);
}
-GameList Engine_SCUMM_detectGames(const FSList &fslist) {
+GameList ScummMetaEngine::detectGames(const FSList &fslist) const {
GameList detectedGames;
Common::List<DetectorResult> results;
- detectGames(fslist, results, 0);
+ ::detectGames(fslist, results, 0);
// TODO: We still don't handle the FM-TOWNS demos (like zakloom) very well.
// In particular, they are detected as ZakTowns, which is bad.
@@ -724,7 +740,7 @@ GameList Engine_SCUMM_detectGames(const FSList &fslist) {
*
* This is heavily based on our MD5 detection scheme.
*/
-PluginError Engine_SCUMM_create(OSystem *syst, Engine **engine) {
+PluginError ScummMetaEngine::createInstance(OSystem *syst, Engine **engine) const {
assert(syst);
assert(engine);
const char *gameid = ConfMan.get("gameid").c_str();
@@ -756,7 +772,7 @@ PluginError Engine_SCUMM_create(OSystem *syst, Engine **engine) {
// Invoke the detector, but fixed to the specified gameid.
Common::List<DetectorResult> results;
- detectGames(fslist, results, gameid);
+ ::detectGames(fslist, results, gameid);
// Unable to locate game data
if (results.empty()) {
@@ -904,6 +920,17 @@ PluginError Engine_SCUMM_create(OSystem *syst, Engine **engine) {
return kNoError;
}
+const char *ScummMetaEngine::getName() const {
+ return "Scumm Engine";
+}
+
+const char *ScummMetaEngine::getCopyright() const {
+ return "LucasArts SCUMM Games (C) LucasArts\n"
+ "Humongous SCUMM Games (C) Humongous";
+}
+
+META_COMPATIBLITY_WRAPPER(SCUMM, ScummMetaEngine);
+
REGISTER_PLUGIN(SCUMM, "Scumm Engine",
"LucasArts SCUMM Games (C) LucasArts\n"
"Humongous SCUMM Games (C) Humongous" );
diff --git a/engines/sword1/sword1.cpp b/engines/sword1/sword1.cpp
index dd64833584..faee215904 100644
--- a/engines/sword1/sword1.cpp
+++ b/engines/sword1/sword1.cpp
@@ -34,6 +34,8 @@
#include "common/events.h"
#include "common/system.h"
+#include "engines/metaengine.h"
+
#include "sword1/resman.h"
#include "sword1/objectman.h"
#include "sword1/mouse.h"
@@ -83,7 +85,23 @@ static const char *g_filesToCheck[NUM_FILES_TO_CHECK] = { // these files have to
// the engine needs several more files to work, but checking these should be sufficient
};
-GameList Engine_SWORD1_gameIDList() {
+class SwordMetaEngine : public MetaEngine {
+public:
+ virtual const char *getName() const {
+ return "Broken Sword";
+ }
+ virtual const char *getCopyright() const {
+ return "Broken Sword Games (C) Revolution";
+ }
+
+ virtual GameList getSupportedGames() const;
+ virtual GameDescriptor findGame(const char *gameid) const;
+ virtual GameList detectGames(const FSList &fslist) const;
+
+ virtual PluginError createInstance(OSystem *syst, Engine **engine) const;
+};
+
+GameList SwordMetaEngine::getSupportedGames() const {
GameList games;
games.push_back(sword1FullSettings);
games.push_back(sword1DemoSettings);
@@ -92,7 +110,7 @@ GameList Engine_SWORD1_gameIDList() {
return games;
}
-GameDescriptor Engine_SWORD1_findGameID(const char *gameid) {
+GameDescriptor SwordMetaEngine::findGame(const char *gameid) const {
if (0 == scumm_stricmp(gameid, sword1FullSettings.gameid))
return sword1FullSettings;
if (0 == scumm_stricmp(gameid, sword1DemoSettings.gameid))
@@ -122,7 +140,7 @@ void Sword1CheckDirectory(const FSList &fslist, bool *filesFound) {
}
}
-GameList Engine_SWORD1_detectGames(const FSList &fslist) {
+GameList SwordMetaEngine::detectGames(const FSList &fslist) const {
int i, j;
GameList detectedGames;
bool filesFound[NUM_FILES_TO_CHECK];
@@ -163,12 +181,14 @@ GameList Engine_SWORD1_detectGames(const FSList &fslist) {
return detectedGames;
}
-PluginError Engine_SWORD1_create(OSystem *syst, Engine **engine) {
+PluginError SwordMetaEngine::createInstance(OSystem *syst, Engine **engine) const {
assert(engine);
*engine = new SwordEngine(syst);
return kNoError;
}
+META_COMPATIBLITY_WRAPPER(SWORD1, SwordMetaEngine);
+
REGISTER_PLUGIN(SWORD1, "Broken Sword", "Broken Sword Games (C) Revolution");
namespace Sword1 {
diff --git a/engines/sword2/sword2.cpp b/engines/sword2/sword2.cpp
index e8c3166948..af4474cd87 100644
--- a/engines/sword2/sword2.cpp
+++ b/engines/sword2/sword2.cpp
@@ -35,6 +35,8 @@
#include "common/events.h"
#include "common/system.h"
+#include "engines/metaengine.h"
+
#include "sword2/sword2.h"
#include "sword2/defs.h"
#include "sword2/header.h"
@@ -68,7 +70,23 @@ static const GameSettings sword2_settings[] = {
} // End of namespace Sword2
-GameList Engine_SWORD2_gameIDList() {
+class Sword2MetaEngine : public MetaEngine {
+public:
+ virtual const char *getName() const {
+ return "Broken Sword 2";
+ }
+ virtual const char *getCopyright() const {
+ return "Broken Sword Games (C) Revolution";
+ }
+
+ virtual GameList getSupportedGames() const;
+ virtual GameDescriptor findGame(const char *gameid) const;
+ virtual GameList detectGames(const FSList &fslist) const;
+
+ virtual PluginError createInstance(OSystem *syst, Engine **engine) const;
+};
+
+GameList Sword2MetaEngine::getSupportedGames() const {
const Sword2::GameSettings *g = Sword2::sword2_settings;
GameList games;
while (g->gameid) {
@@ -78,7 +96,7 @@ GameList Engine_SWORD2_gameIDList() {
return games;
}
-GameDescriptor Engine_SWORD2_findGameID(const char *gameid) {
+GameDescriptor Sword2MetaEngine::findGame(const char *gameid) const {
const Sword2::GameSettings *g = Sword2::sword2_settings;
while (g->gameid) {
if (0 == scumm_stricmp(gameid, g->gameid))
@@ -88,7 +106,7 @@ GameDescriptor Engine_SWORD2_findGameID(const char *gameid) {
return GameDescriptor(g->gameid, g->description);
}
-GameList Engine_SWORD2_detectGames(const FSList &fslist) {
+GameList Sword2MetaEngine::detectGames(const FSList &fslist) const {
GameList detectedGames;
const Sword2::GameSettings *g;
FSList::const_iterator file;
@@ -123,7 +141,7 @@ GameList Engine_SWORD2_detectGames(const FSList &fslist) {
if (0 == scumm_stricmp("clusters", fileName)) {
FSList recList;
if (file->getChildren(recList, FilesystemNode::kListAll)) {
- GameList recGames(Engine_SWORD2_detectGames(recList));
+ GameList recGames(detectGames(recList));
if (!recGames.empty()) {
detectedGames.push_back(recGames);
break;
@@ -138,7 +156,7 @@ GameList Engine_SWORD2_detectGames(const FSList &fslist) {
return detectedGames;
}
-PluginError Engine_SWORD2_create(OSystem *syst, Engine **engine) {
+PluginError Sword2MetaEngine::createInstance(OSystem *syst, Engine **engine) const {
assert(syst);
assert(engine);
@@ -150,7 +168,7 @@ PluginError Engine_SWORD2_create(OSystem *syst, Engine **engine) {
// Invoke the detector
Common::String gameid = ConfMan.get("gameid");
- GameList detectedGames = Engine_SWORD2_detectGames(fslist);
+ GameList detectedGames = detectGames(fslist);
for (uint i = 0; i < detectedGames.size(); i++) {
if (detectedGames[i].gameid() == gameid) {
@@ -162,6 +180,8 @@ PluginError Engine_SWORD2_create(OSystem *syst, Engine **engine) {
return kNoGameDataFoundError;
}
+META_COMPATIBLITY_WRAPPER(SWORD2, Sword2MetaEngine);
+
REGISTER_PLUGIN(SWORD2, "Broken Sword 2", "Broken Sword Games (C) Revolution");
namespace Sword2 {
diff --git a/engines/touche/detection.cpp b/engines/touche/detection.cpp
index 41b2062ffc..d6ba2d0667 100644
--- a/engines/touche/detection.cpp
+++ b/engines/touche/detection.cpp
@@ -124,7 +124,22 @@ static const Common::ADParams detectionParams = {
Common::kADFlagAugmentPreferredTarget | Common::kADFlagPrintWarningOnFileBasedFallback
};
-static bool Engine_TOUCHE_createInstance(OSystem *syst, Engine **engine, const Common::EncapsulatedADGameDesc &encapsulatedDesc) {
+class ToucheMetaEngine : public AdvancedMetaEngine {
+public:
+ ToucheMetaEngine() : AdvancedMetaEngine(detectionParams) {}
+
+ virtual const char *getName() const {
+ return "Touche Engine";
+ }
+ virtual const char *getCopyright() const {
+ return "Touche: The Adventures of the 5th Musketeer (C) Clipper Software";
+ }
+
+ virtual bool createInstance(OSystem *syst, Engine **engine, const Common::EncapsulatedADGameDesc &encapsulatedDesc) const;
+};
+
+
+bool ToucheMetaEngine::createInstance(OSystem *syst, Engine **engine, const Common::EncapsulatedADGameDesc &encapsulatedDesc) const {
const Common::ADGameDescription *gd = encapsulatedDesc.realDesc;
if (gd) {
*engine = new Touche::ToucheEngine(syst, gd->language);
@@ -132,6 +147,6 @@ static bool Engine_TOUCHE_createInstance(OSystem *syst, Engine **engine, const C
return gd != 0;
}
-ADVANCED_DETECTOR_DEFINE_PLUGIN(TOUCHE, Engine_TOUCHE_createInstance, detectionParams);
+META_COMPATIBLITY_WRAPPER(TOUCHE, ToucheMetaEngine);
REGISTER_PLUGIN(TOUCHE, "Touche Engine", "Touche: The Adventures of the 5th Musketeer (C) Clipper Software");