aboutsummaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authorEugene Sandulenko2007-06-12 12:22:25 +0000
committerEugene Sandulenko2007-06-12 12:22:25 +0000
commit6e5b70f5e9f8690b467ea8837e727e1048838788 (patch)
tree99421afdf99a4b66be53c398c048133bc79c614e /common
parent72cfa9d8293aa897a89d577d9844a2a286d8f0e2 (diff)
downloadscummvm-rg350-6e5b70f5e9f8690b467ea8837e727e1048838788.tar.gz
scummvm-rg350-6e5b70f5e9f8690b467ea8837e727e1048838788.tar.bz2
scummvm-rg350-6e5b70f5e9f8690b467ea8837e727e1048838788.zip
Patch #1733764: "Fallback detection patch". GSoC student.
svn-id: r27375
Diffstat (limited to 'common')
-rw-r--r--common/advancedDetector.cpp136
-rw-r--r--common/advancedDetector.h27
2 files changed, 117 insertions, 46 deletions
diff --git a/common/advancedDetector.cpp b/common/advancedDetector.cpp
index f0f77ee26e..7d7cadbade 100644
--- a/common/advancedDetector.cpp
+++ b/common/advancedDetector.cpp
@@ -72,6 +72,32 @@ GameList gameIDList(const Common::ADParams &params) {
return GameList(params.list);
}
+static void upgradeTargetIfNecessary(const Common::ADParams &params) {
+ if (params.obsoleteList == 0)
+ return;
+
+ const char *gameid = ConfMan.get("gameid").c_str();
+
+ for (const Common::ADObsoleteGameID *o = params.obsoleteList; o->from; ++o) {
+ if (!scumm_stricmp(gameid, o->from)) {
+ gameid = o->to;
+ ConfMan.set("gameid", o->to);
+
+ if (o->platform != Common::kPlatformUnknown)
+ ConfMan.set("platform", Common::getPlatformCode(o->platform));
+
+ warning("Target upgraded from %s to %s", o->from, o->to);
+
+ if (ConfMan.hasKey("id_came_from_command_line")) {
+ warning("Target came from command line. Skipping save");
+ } else {
+ ConfMan.flushToDisk();
+ }
+ break;
+ }
+ }
+}
+
GameDescriptor findGameID(
const char *gameid,
const Common::ADParams &params
@@ -110,6 +136,24 @@ 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
@@ -134,38 +178,49 @@ static String generatePreferredTarget(const String &id, const ADGameDescription
return res;
}
+static void updateGameDescriptor(GameDescriptor &desc, const ADGameDescription *realDesc, const Common::ADParams &params) {
+ if (params.singleid != NULL) {
+ desc["preferredtarget"] = desc["gameid"];
+ desc["gameid"] = params.singleid;
+ }
+
+ if (params.flags & kADFlagAugmentPreferredTarget) {
+ if (!desc.contains("preferredtarget"))
+ desc["preferredtarget"] = desc["gameid"];
+
+ desc["preferredtarget"] = generatePreferredTarget(desc["preferredtarget"], realDesc);
+ }
+}
+
GameList detectAllGames(
const FSList &fslist,
const Common::ADParams &params
) {
ADGameDescList matches = detectGame(&fslist, params, Common::UNK_LANG, Common::kPlatformUnknown);
-
GameList detectedGames;
- for (uint i = 0; i < matches.size(); i++) {
- GameDescriptor desc(toGameDescriptor(*matches[i], params.list));
-
- if (params.singleid != NULL) {
- desc["preferredtarget"] = desc["gameid"];
- desc["gameid"] = params.singleid;
- }
- if (params.flags & kADFlagAugmentPreferredTarget) {
- if (!desc.contains("preferredtarget"))
- desc["preferredtarget"] = desc["gameid"];
-
- desc["preferredtarget"] = generatePreferredTarget(desc["preferredtarget"], matches[i]);
+ // Use fallback detector if there were no matches by other means
+ if (matches.empty() && params.fallbackDetectFunc != NULL) {
+ EncapsulatedADGameDesc fallbackDesc = (*params.fallbackDetectFunc)(&fslist);
+ if (fallbackDesc.realDesc != 0) {
+ GameDescriptor desc(toGameDescriptor(fallbackDesc, params.list));
+ updateGameDescriptor(desc, fallbackDesc.realDesc, params);
+ detectedGames.push_back(desc);
}
-
+ } else for (uint i = 0; i < matches.size(); i++) { // Otherwise use the found matches
+ GameDescriptor desc(toGameDescriptor(*matches[i], params.list));
+ updateGameDescriptor(desc, matches[i], params);
detectedGames.push_back(desc);
}
return detectedGames;
}
-const ADGameDescription *detectBestMatchingGame(
+EncapsulatedADGameDesc detectBestMatchingGame(
const Common::ADParams &params
) {
const ADGameDescription *agdDesc = 0;
+ EncapsulatedADGameDesc result;
Common::Language language = Common::UNK_LANG;
Common::Platform platform = Common::kPlatformUnknown;
@@ -189,39 +244,29 @@ const ADGameDescription *detectBestMatchingGame(
agdDesc = matches[0];
}
- if (agdDesc != 0) {
- debug(2, "Running %s", toGameDescriptor(*agdDesc, params.list).description().c_str());
+ if (agdDesc != 0) { // Check if we found a match without fallback detection
+ result = EncapsulatedADGameDesc(agdDesc);
+ } else if (params.fallbackDetectFunc != NULL) { // Use fallback detector if there were no matches by other means
+ EncapsulatedADGameDesc fallbackDesc = (*params.fallbackDetectFunc)(NULL);
+ if (fallbackDesc.realDesc != 0 && (params.singleid != NULL || fallbackDesc.getGameID() == gameid)) {
+ result = fallbackDesc; // Found a fallback match
+ }
+ }
+
+ if (result.realDesc != 0) {
+ debug(2, "Running %s", toGameDescriptor(result, params.list).description().c_str());
}
- return agdDesc;
+ return result;
}
PluginError detectGameForEngineCreation(
const Common::ADParams &params
) {
- Common::String gameid = ConfMan.get("gameid");
+ upgradeTargetIfNecessary(params);
- if (params.obsoleteList != 0) {
- for (const Common::ADObsoleteGameID *o = params.obsoleteList; o->from; ++o) {
- if (!scumm_stricmp(gameid.c_str(), o->from)) {
- gameid = o->to;
- ConfMan.set("gameid", o->to);
-
- if (o->platform != Common::kPlatformUnknown)
- ConfMan.set("platform", Common::getPlatformCode(o->platform));
-
- warning("Target upgraded from %s to %s", o->from, o->to);
-
- if (ConfMan.hasKey("id_came_from_command_line")) {
- warning("Target came from command line. Skipping save");
- } else {
- ConfMan.flushToDisk();
- }
- break;
- }
- }
- }
+ Common::String gameid = ConfMan.get("gameid");
FSList fslist;
FilesystemNode dir(ConfMan.get("path"));
@@ -241,6 +286,14 @@ PluginError detectGameForEngineCreation(
}
}
+ // Use fallback detector if there were no matches by other means
+ if (params.fallbackDetectFunc != NULL) {
+ EncapsulatedADGameDesc fallbackDesc = (*params.fallbackDetectFunc)(&fslist);
+ if (fallbackDesc.realDesc != 0 && (params.singleid != NULL || fallbackDesc.getGameID() == gameid)) {
+ return kNoError;
+ }
+ }
+
return kNoGameDataFoundError;
}
@@ -491,11 +544,6 @@ static ADGameDescList detectGame(const FSList *fslist, const Common::ADParams &p
}
}
- // If we still haven't got a match, try to use the fallback callback :-)
- if (matched.empty() && params.fallbackDetectFunc != 0) {
- matched = (*params.fallbackDetectFunc)(fslist);
- }
-
return matched;
}
diff --git a/common/advancedDetector.h b/common/advancedDetector.h
index fab847e671..2031f001a9 100644
--- a/common/advancedDetector.h
+++ b/common/advancedDetector.h
@@ -64,6 +64,29 @@ struct ADGameDescription {
};
/**
+ * Encapsulates ADGameDescription and makes gameid and extra strings dynamic.
+ * Used in fallback detection when dynamically creating string content.
+ */
+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).
*/
typedef Array<const ADGameDescription*> ADGameDescList;
@@ -177,7 +200,7 @@ struct ADParams {
*
* @todo
*/
- ADGameDescList (*fallbackDetectFunc)(const FSList *fslist);
+ EncapsulatedADGameDesc (*fallbackDetectFunc)(const FSList *fslist);
/**
* A bitmask of flags which can be used to configure the behavior
@@ -207,7 +230,7 @@ GameDescriptor findGameID(const char *gameid, const Common::ADParams &params);
GameList detectAllGames(const FSList &fslist, const Common::ADParams &params);
// FIXME/TODO: Rename this function to something more sensible.
-const ADGameDescription *detectBestMatchingGame(const Common::ADParams &params);
+EncapsulatedADGameDesc detectBestMatchingGame(const Common::ADParams &params);
// FIXME/TODO: Rename this function to something more sensible.
// Only used by ADVANCED_DETECTOR_DEFINE_PLUGIN_WITH_FUNC