New MetaEngine class (work in progress to replace the current Engine plugin API with a more object oriented approach)
svn-id: r30726
This commit is contained in:
parent
249877fa82
commit
dc979b03cf
8 changed files with 238 additions and 21 deletions
|
@ -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 ¶ms;
|
||||
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
|
||||
|
|
|
@ -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");
|
||||
|
||||
|
|
81
engines/metaengine.h
Normal file
81
engines/metaengine.h
Normal file
|
@ -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
|
|
@ -27,6 +27,8 @@
|
|||
|
||||
#include "saga/saga.h"
|
||||
|
||||
#include "base/plugins.h"
|
||||
|
||||
#include "common/config-manager.h"
|
||||
#include "common/advancedDetector.h"
|
||||
|
||||
|
|
|
@ -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" );
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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");
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue