aboutsummaryrefslogtreecommitdiff
path: root/common/advancedDetector.cpp
diff options
context:
space:
mode:
authorDavid Corrales2007-06-23 18:51:33 +0000
committerDavid Corrales2007-06-23 18:51:33 +0000
commitcacd7a28fd51d960947de88abbf30c487e66529d (patch)
treef3baa59853bfb307e452b86b9d93c4737b1fa6ab /common/advancedDetector.cpp
parent0ac96302fe9c04df79cb01a77d19535b45fe2db0 (diff)
parent90c2210dae8c91fa8babc6b05564e15c9d445d18 (diff)
downloadscummvm-rg350-cacd7a28fd51d960947de88abbf30c487e66529d.tar.gz
scummvm-rg350-cacd7a28fd51d960947de88abbf30c487e66529d.tar.bz2
scummvm-rg350-cacd7a28fd51d960947de88abbf30c487e66529d.zip
Merged the FSNode branch with trunk r27031:27680
svn-id: r27681
Diffstat (limited to 'common/advancedDetector.cpp')
-rw-r--r--common/advancedDetector.cpp125
1 files changed, 90 insertions, 35 deletions
diff --git a/common/advancedDetector.cpp b/common/advancedDetector.cpp
index d6b622451a..f3e8671025 100644
--- a/common/advancedDetector.cpp
+++ b/common/advancedDetector.cpp
@@ -87,7 +87,12 @@ static void upgradeTargetIfNecessary(const Common::ADParams &params) {
ConfMan.set("platform", Common::getPlatformCode(o->platform));
warning("Target upgraded from %s to %s", o->from, o->to);
- ConfMan.flushToDisk();
+
+ if (ConfMan.hasKey("id_came_from_command_line")) {
+ warning("Target came from command line. Skipping save");
+ } else {
+ ConfMan.flushToDisk();
+ }
break;
}
}
@@ -95,25 +100,31 @@ static void upgradeTargetIfNecessary(const Common::ADParams &params) {
GameDescriptor findGameID(
const char *gameid,
- const Common::ADParams &params
+ const PlainGameDescriptor *list,
+ const Common::ADObsoleteGameID *obsoleteList
) {
- const PlainGameDescriptor *g = params.list;
- while (g->gameid) {
- if (0 == scumm_stricmp(gameid, g->gameid))
- return GameDescriptor(*g);
- g++;
- }
-
- if (params.obsoleteList != 0) {
- const Common::ADObsoleteGameID *o = params.obsoleteList;
+ // First search the list of supported game IDs for a match.
+ const PlainGameDescriptor *g = findPlainGameDescriptor(gameid, list);
+ if (g)
+ return GameDescriptor(*g);
+
+ // If we didn't find the gameid in the main list, check if it
+ // is an obsolete game id.
+ if (obsoleteList != 0) {
+ const Common::ADObsoleteGameID *o = obsoleteList;
while (o->from) {
if (0 == scumm_stricmp(gameid, o->from)) {
- return GameDescriptor(gameid, "Obsolete game ID");
+ g = findPlainGameDescriptor(o->to, list);
+ if (g && g->description)
+ return GameDescriptor(gameid, "Obsolete game ID (" + Common::String(g->description) + ")");
+ else
+ return GameDescriptor(gameid, "Obsolete game ID");
}
o++;
}
}
+ // No match found
return GameDescriptor();
}
@@ -131,6 +142,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
@@ -155,38 +184,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;
+ // 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);
}
-
- if (params.flags & kADFlagAugmentPreferredTarget) {
- if (!desc.contains("preferredtarget"))
- desc["preferredtarget"] = desc["gameid"];
-
- desc["preferredtarget"] = generatePreferredTarget(desc["preferredtarget"], matches[i]);
- }
-
+ } 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;
@@ -210,11 +250,20 @@ 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
+ }
}
- return agdDesc;
+ if (result.realDesc != 0) {
+ debug(2, "Running %s", toGameDescriptor(result, params.list).description().c_str());
+ }
+
+ return result;
}
PluginError detectGameForEngineCreation(
@@ -243,6 +292,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;
}
@@ -281,6 +338,9 @@ static ADGameDescList detectGame(const FSList *fslist, const Common::ADParams &p
}
}
+ // TODO/FIXME: Fingolfin says: It's not good that we have two different code paths here,
+ // one using a FSList, one using File::open, as that will lead to discrepancies and subtle
+ // problems caused by those.
if (fslist != 0) {
// Get the information of the existing files
for (FSList::const_iterator file = fslist->begin(); file != fslist->end(); ++file) {
@@ -493,11 +553,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;
}