Got rid of EncapsulatedADGameDesc
svn-id: r31130
This commit is contained in:
parent
dc319c719f
commit
05dd6cee3a
4 changed files with 119 additions and 155 deletions
|
@ -148,24 +148,6 @@ static GameDescriptor toGameDescriptor(const ADGameDescription &g, const PlainGa
|
|||
return gd;
|
||||
}
|
||||
|
||||
// Almost identical to the toGameDescriptor function that takes a ADGameDescription and PlainGameDescriptor.
|
||||
// Just a little fine tuning about accessing variables.
|
||||
// Used because of fallback detection and the dynamic string content it needs.
|
||||
static GameDescriptor toGameDescriptor(const EncapsulatedADGameDesc &g, const PlainGameDescriptor *sg) {
|
||||
const char *title = 0;
|
||||
|
||||
while (sg->gameid) {
|
||||
if (!scumm_stricmp(g.getGameID(), sg->gameid))
|
||||
title = sg->description;
|
||||
sg++;
|
||||
}
|
||||
|
||||
assert(g.realDesc);
|
||||
GameDescriptor gd(g.getGameID(), title, g.realDesc->language, g.realDesc->platform);
|
||||
gd.updateDesc(g.getExtra());
|
||||
return gd;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a preferred target value as
|
||||
* GAMEID-PLAFORM-LANG
|
||||
|
@ -213,10 +195,10 @@ GameList AdvancedMetaEngine::detectGames(const FSList &fslist) const {
|
|||
|
||||
// Use fallback detector if there were no matches by other means
|
||||
if (matches.empty()) {
|
||||
EncapsulatedADGameDesc fallbackDesc = fallbackDetect(&fslist);
|
||||
if (fallbackDesc.realDesc != 0) {
|
||||
GameDescriptor desc(toGameDescriptor(fallbackDesc, params.list));
|
||||
updateGameDescriptor(desc, fallbackDesc.realDesc, params);
|
||||
const Common::ADGameDescription *fallbackDesc = fallbackDetect(&fslist);
|
||||
if (fallbackDesc != 0) {
|
||||
GameDescriptor desc(toGameDescriptor(*fallbackDesc, params.list));
|
||||
updateGameDescriptor(desc, fallbackDesc, params);
|
||||
detectedGames.push_back(desc);
|
||||
}
|
||||
} else for (uint i = 0; i < matches.size(); i++) { // Otherwise use the found matches
|
||||
|
@ -233,7 +215,6 @@ PluginError AdvancedMetaEngine::createInstance(OSystem *syst, Engine **engine) c
|
|||
upgradeTargetIfNecessary(params);
|
||||
|
||||
const ADGameDescription *agdDesc = 0;
|
||||
EncapsulatedADGameDesc result;
|
||||
Common::Language language = Common::UNK_LANG;
|
||||
Common::Platform platform = Common::kPlatformUnknown;
|
||||
Common::String extra("");
|
||||
|
@ -261,22 +242,23 @@ PluginError AdvancedMetaEngine::createInstance(OSystem *syst, Engine **engine) c
|
|||
agdDesc = matches[0];
|
||||
}
|
||||
|
||||
if (agdDesc != 0) { // Check if we found a match without fallback detection
|
||||
result = EncapsulatedADGameDesc(agdDesc);
|
||||
} else {
|
||||
if (agdDesc == 0) {
|
||||
// Use fallback detector if there were no matches by other means
|
||||
EncapsulatedADGameDesc fallbackDesc = fallbackDetect(NULL);
|
||||
if (fallbackDesc.realDesc != 0 && (params.singleid != NULL || fallbackDesc.getGameID() == gameid)) {
|
||||
result = fallbackDesc; // Found a fallback match
|
||||
agdDesc = fallbackDetect(NULL);
|
||||
if (agdDesc != 0) {
|
||||
// Seems we found a fallback match. But first perform a basic
|
||||
// sanity check: the gameid must match.
|
||||
if (params.singleid == NULL && agdDesc->gameid != gameid)
|
||||
agdDesc = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (result.realDesc == 0) {
|
||||
if (agdDesc == 0) {
|
||||
return kNoGameDataFoundError;
|
||||
}
|
||||
|
||||
debug(2, "Running %s", toGameDescriptor(result, params.list).description().c_str());
|
||||
if (!createInstance(syst, engine, result.realDesc)) {
|
||||
debug(2, "Running %s", toGameDescriptor(*agdDesc, params.list).description().c_str());
|
||||
if (!createInstance(syst, engine, agdDesc)) {
|
||||
return kNoGameDataFoundError;
|
||||
}
|
||||
return kNoError;
|
||||
|
|
|
@ -64,31 +64,6 @@ struct ADGameDescription {
|
|||
uint32 flags;
|
||||
};
|
||||
|
||||
/**
|
||||
* Encapsulates ADGameDescription and makes gameid and extra strings dynamic.
|
||||
* Used in fallback detection when dynamically creating string content.
|
||||
*
|
||||
* @todo Get rid of this once the fallback detection is a member of AdvancedMetaEngine.
|
||||
*/
|
||||
struct EncapsulatedADGameDesc {
|
||||
Common::String gameid;
|
||||
Common::String extra;
|
||||
const ADGameDescription *realDesc;
|
||||
|
||||
// Constructor for the EncapsulatedADGameDesc
|
||||
EncapsulatedADGameDesc() : realDesc(0) {}
|
||||
EncapsulatedADGameDesc(const ADGameDescription *paramRealDesc,
|
||||
Common::String paramGameID = Common::String(),
|
||||
Common::String paramExtra = Common::String())
|
||||
: realDesc(paramRealDesc), gameid(paramGameID), extra(paramExtra) {
|
||||
assert(paramRealDesc != NULL);
|
||||
}
|
||||
|
||||
// Functions for getting the correct gameid and extra values from the struct
|
||||
const char *getGameID() const { return (gameid.empty() && realDesc != 0) ? realDesc->gameid : gameid.c_str(); }
|
||||
const char *getExtra() const { return (extra.empty() && realDesc != 0) ? realDesc->extra : extra.c_str(); }
|
||||
};
|
||||
|
||||
/**
|
||||
* A list of pointers to ADGameDescription structs (or subclasses thereof).
|
||||
*/
|
||||
|
@ -242,8 +217,8 @@ public:
|
|||
* @note The fslist parameter may be 0 -- in that case, it is assumed
|
||||
* that the callback searchs the current directory.
|
||||
*/
|
||||
EncapsulatedADGameDesc fallbackDetect(const FSList *fslist) const {
|
||||
return EncapsulatedADGameDesc();
|
||||
const Common::ADGameDescription *fallbackDetect(const FSList *fslist) const {
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -23,8 +23,6 @@
|
|||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include "base/plugins.h"
|
||||
|
||||
#include "common/advancedDetector.h"
|
||||
|
@ -2057,8 +2055,8 @@ static const AGIGameDescription gameDescriptions[] = {
|
|||
*/
|
||||
static AGIGameDescription g_fallbackDesc = {
|
||||
{
|
||||
"", // Not used by the fallback descriptor, it uses the EncapsulatedADGameDesc's gameid
|
||||
"", // Not used by the fallback descriptor, it uses the EncapsulatedADGameDesc's extra
|
||||
"",
|
||||
"",
|
||||
AD_ENTRY1(0, 0), // This should always be AD_ENTRY1(0, 0) in the fallback descriptor
|
||||
Common::UNK_LANG,
|
||||
Common::kPlatformPC,
|
||||
|
@ -2070,7 +2068,69 @@ static AGIGameDescription g_fallbackDesc = {
|
|||
0x2917,
|
||||
};
|
||||
|
||||
Common::EncapsulatedADGameDesc fallbackDetector(const FSList *fslist) {
|
||||
static const Common::ADParams detectionParams = {
|
||||
// Pointer to ADGameDescription or its superset structure
|
||||
(const byte *)Agi::gameDescriptions,
|
||||
// Size of that superset structure
|
||||
sizeof(Agi::AGIGameDescription),
|
||||
// Number of bytes to compute MD5 sum for
|
||||
5000,
|
||||
// List of all engine targets
|
||||
agiGames,
|
||||
// Structure for autoupgrading obsolete targets
|
||||
0,
|
||||
// Name of single gameid (optional)
|
||||
"agi",
|
||||
// List of files for file-based fallback detection (optional)
|
||||
0,
|
||||
// Flags
|
||||
Common::kADFlagAugmentPreferredTarget
|
||||
};
|
||||
|
||||
} // End of namespace Agi
|
||||
|
||||
using namespace Agi;
|
||||
|
||||
class AgiMetaEngine : public Common::AdvancedMetaEngine {
|
||||
mutable Common::String _gameid;
|
||||
mutable Common::String _extra;
|
||||
|
||||
public:
|
||||
AgiMetaEngine() : Common::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::ADGameDescription *desc) const;
|
||||
|
||||
const Common::ADGameDescription *fallbackDetect(const FSList *fslist) const;
|
||||
};
|
||||
|
||||
bool AgiMetaEngine::createInstance(OSystem *syst, Engine **engine, const Common::ADGameDescription *desc) const {
|
||||
const Agi::AGIGameDescription *gd = (const Agi::AGIGameDescription *)desc;
|
||||
bool res = true;
|
||||
|
||||
switch (gd->gameType) {
|
||||
case Agi::GType_PreAGI:
|
||||
*engine = new Agi::PreAgiEngine(syst, gd);
|
||||
break;
|
||||
case Agi::GType_V2:
|
||||
case Agi::GType_V3:
|
||||
*engine = new Agi::AgiEngine(syst, gd);
|
||||
break;
|
||||
default:
|
||||
res = false;
|
||||
error("AGI engine: unknown gameType");
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
const Common::ADGameDescription *AgiMetaEngine::fallbackDetect(const FSList *fslist) const {
|
||||
typedef Common::HashMap<Common::String, int32, Common::CaseSensitiveString_Hash, Common::CaseSensitiveString_EqualTo> IntMap;
|
||||
IntMap allFiles;
|
||||
bool matchedUsingFilenames = false;
|
||||
|
@ -2078,9 +2138,13 @@ Common::EncapsulatedADGameDesc fallbackDetector(const FSList *fslist) {
|
|||
int wagFileCount = 0;
|
||||
WagFileParser wagFileParser;
|
||||
Common::String wagFilePath;
|
||||
Common::String gameid("agi-fanmade"), description, extra; // Set the defaults for gameid, description and extra
|
||||
Common::String description;
|
||||
FSList fslistCurrentDir; // Only used if fslist == NULL
|
||||
|
||||
// // Set the defaults for gameid and extra
|
||||
_gameid = "agi-fanmade";
|
||||
_extra.clear();
|
||||
|
||||
// Use the current directory for searching if fslist == NULL
|
||||
if (fslist == NULL) {
|
||||
Common::String path = ConfMan.get("path");
|
||||
|
@ -2184,8 +2248,8 @@ Common::EncapsulatedADGameDesc fallbackDetector(const FSList *fslist) {
|
|||
|
||||
// Set gameid according to *.wag file information if it's present and it doesn't contain whitespace.
|
||||
if (wagGameID != NULL && !Common::String(wagGameID->getData()).contains(" ")) {
|
||||
gameid = wagGameID->getData();
|
||||
debug(3, "Agi::fallbackDetector: Using game id (%s) from WAG file", gameid.c_str());
|
||||
_gameid = wagGameID->getData();
|
||||
debug(3, "Agi::fallbackDetector: Using game id (%s) from WAG file", _gameid.c_str());
|
||||
}
|
||||
|
||||
// Set game description and extra according to *.wag file information if they're present
|
||||
|
@ -2195,14 +2259,14 @@ Common::EncapsulatedADGameDesc fallbackDetector(const FSList *fslist) {
|
|||
|
||||
// If there's game version in the *.wag file, set extra to it
|
||||
if (wagGameVer != NULL) {
|
||||
extra = wagGameVer->getData();
|
||||
_extra = wagGameVer->getData();
|
||||
debug(3, "Agi::fallbackDetector: Game version (%s) from WAG file", wagGameVer->getData());
|
||||
}
|
||||
|
||||
// If there's game last edit date in the *.wag file, add it to extra
|
||||
if (wagGameLastEdit != NULL) {
|
||||
if (!extra.empty() ) extra += " ";
|
||||
extra += wagGameLastEdit->getData();
|
||||
if (!_extra.empty() ) _extra += " ";
|
||||
_extra += wagGameLastEdit->getData();
|
||||
debug(3, "Agi::fallbackDetector: Game's last edit date (%s) from WAG file", wagGameLastEdit->getData());
|
||||
}
|
||||
}
|
||||
|
@ -2223,78 +2287,24 @@ Common::EncapsulatedADGameDesc fallbackDetector(const FSList *fslist) {
|
|||
g_fallbackDesc.gameType = GType_V3;
|
||||
|
||||
// Check if we found a match with any of the fallback methods
|
||||
Common::EncapsulatedADGameDesc result;
|
||||
if (matchedUsingWag || matchedUsingFilenames) {
|
||||
extra = description + (!extra.empty() ? " " : "") + extra; // Let's combine the description and extra
|
||||
result = Common::EncapsulatedADGameDesc((const Common::ADGameDescription *)&g_fallbackDesc, gameid, extra);
|
||||
_extra = description + (!_extra.empty() ? " " : "") + _extra; // Let's combine the description and extra
|
||||
|
||||
// Override the gameid & extra values in g_fallbackDesc.desc. This only works
|
||||
// until the fallback detector is called again, and while the MetaEngine instance
|
||||
// is alive (as else the string storage is modified/deleted).
|
||||
g_fallbackDesc.desc.gameid = _gameid.c_str();
|
||||
g_fallbackDesc.desc.extra = _extra.c_str();
|
||||
|
||||
printf("Your game version has been detected using fallback matching as a\n");
|
||||
printf("variant of %s (%s).\n", result.getGameID(), result.getExtra());
|
||||
printf("variant of %s (%s).\n", g_fallbackDesc.desc.gameid, g_fallbackDesc.desc.extra);
|
||||
printf("If this is an original and unmodified version or new made Fanmade game,\n");
|
||||
printf("please report any, information previously printed by ScummVM to the team.\n");
|
||||
|
||||
return (const Common::ADGameDescription *)&g_fallbackDesc;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
} // End of namespace Agi
|
||||
|
||||
static const Common::ADParams detectionParams = {
|
||||
// Pointer to ADGameDescription or its superset structure
|
||||
(const byte *)Agi::gameDescriptions,
|
||||
// Size of that superset structure
|
||||
sizeof(Agi::AGIGameDescription),
|
||||
// Number of bytes to compute MD5 sum for
|
||||
5000,
|
||||
// List of all engine targets
|
||||
agiGames,
|
||||
// Structure for autoupgrading obsolete targets
|
||||
0,
|
||||
// Name of single gameid (optional)
|
||||
"agi",
|
||||
// List of files for file-based fallback detection (optional)
|
||||
0,
|
||||
// Flags
|
||||
Common::kADFlagAugmentPreferredTarget
|
||||
};
|
||||
|
||||
class AgiMetaEngine : public Common::AdvancedMetaEngine {
|
||||
public:
|
||||
AgiMetaEngine() : Common::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::ADGameDescription *desc) const;
|
||||
|
||||
Common::EncapsulatedADGameDesc fallbackDetect(const FSList *fslist) const {
|
||||
return Agi::fallbackDetector(fslist);
|
||||
}
|
||||
};
|
||||
|
||||
bool AgiMetaEngine::createInstance(OSystem *syst, Engine **engine, const Common::ADGameDescription *desc) const {
|
||||
const Agi::AGIGameDescription *gd = (const Agi::AGIGameDescription *)desc;
|
||||
bool res = true;
|
||||
|
||||
switch (gd->gameType) {
|
||||
case Agi::GType_PreAGI:
|
||||
*engine = new Agi::PreAgiEngine(syst, gd);
|
||||
break;
|
||||
case Agi::GType_V2:
|
||||
case Agi::GType_V3:
|
||||
*engine = new Agi::AgiEngine(syst, gd);
|
||||
break;
|
||||
default:
|
||||
res = false;
|
||||
error("AGI engine: unknown gameType");
|
||||
}
|
||||
|
||||
return res;
|
||||
return 0;
|
||||
}
|
||||
|
||||
REGISTER_PLUGIN(AGI, PLUGIN_TYPE_ENGINE, AgiMetaEngine);
|
||||
|
|
|
@ -111,8 +111,8 @@ static const DrasculaGameDescription gameDescriptions[] = {
|
|||
*/
|
||||
static DrasculaGameDescription g_fallbackDesc = {
|
||||
{
|
||||
"", // Not used by the fallback descriptor, it uses the EncapsulatedADGameDesc's gameid
|
||||
"", // Not used by the fallback descriptor, it uses the EncapsulatedADGameDesc's extra
|
||||
"",
|
||||
"",
|
||||
AD_ENTRY1(0, 0), // This should always be AD_ENTRY1(0, 0) in the fallback descriptor
|
||||
Common::UNK_LANG,
|
||||
Common::kPlatformPC,
|
||||
|
@ -124,22 +124,6 @@ static DrasculaGameDescription g_fallbackDesc = {
|
|||
0,
|
||||
};
|
||||
|
||||
Common::EncapsulatedADGameDesc fallbackDetector(const FSList *fslist) {
|
||||
// Set the default values for the fallback descriptor's ADGameDescription part.
|
||||
g_fallbackDesc.desc.language = Common::UNK_LANG;
|
||||
g_fallbackDesc.desc.platform = Common::kPlatformPC;
|
||||
g_fallbackDesc.desc.flags = Common::ADGF_NO_FLAGS;
|
||||
|
||||
// Set default values for the fallback descriptor's DrasculaGameDescription part.
|
||||
g_fallbackDesc.gameID = 0;
|
||||
g_fallbackDesc.features = 0;
|
||||
g_fallbackDesc.version = 0;
|
||||
|
||||
Common::EncapsulatedADGameDesc result;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
} // End of namespace Drascula
|
||||
|
||||
static const Common::ADParams detectionParams = {
|
||||
|
@ -175,9 +159,8 @@ public:
|
|||
|
||||
virtual bool createInstance(OSystem *syst, Engine **engine, const Common::ADGameDescription *desc) const;
|
||||
|
||||
Common::EncapsulatedADGameDesc fallbackDetect(const FSList *fslist) const {
|
||||
return Drascula::fallbackDetector(fslist);
|
||||
}
|
||||
const Common::ADGameDescription *fallbackDetect(const FSList *fslist) const;
|
||||
|
||||
};
|
||||
|
||||
bool DrasculaMetaEngine::createInstance(OSystem *syst, Engine **engine, const Common::ADGameDescription *desc) const {
|
||||
|
@ -188,4 +171,18 @@ bool DrasculaMetaEngine::createInstance(OSystem *syst, Engine **engine, const Co
|
|||
return gd != 0;
|
||||
}
|
||||
|
||||
const Common::ADGameDescription *DrasculaMetaEngine::fallbackDetect(const FSList *fslist) const {
|
||||
// Set the default values for the fallback descriptor's ADGameDescription part.
|
||||
Drascula::g_fallbackDesc.desc.language = Common::UNK_LANG;
|
||||
Drascula::g_fallbackDesc.desc.platform = Common::kPlatformPC;
|
||||
Drascula::g_fallbackDesc.desc.flags = Common::ADGF_NO_FLAGS;
|
||||
|
||||
// Set default values for the fallback descriptor's DrasculaGameDescription part.
|
||||
Drascula::g_fallbackDesc.gameID = 0;
|
||||
Drascula::g_fallbackDesc.features = 0;
|
||||
Drascula::g_fallbackDesc.version = 0;
|
||||
|
||||
return (const Common::ADGameDescription *)&Drascula::g_fallbackDesc;
|
||||
}
|
||||
|
||||
REGISTER_PLUGIN(DRASCULA, PLUGIN_TYPE_ENGINE, DrasculaMetaEngine);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue