diff options
author | Eugene Sandulenko | 2007-06-12 12:22:25 +0000 |
---|---|---|
committer | Eugene Sandulenko | 2007-06-12 12:22:25 +0000 |
commit | 6e5b70f5e9f8690b467ea8837e727e1048838788 (patch) | |
tree | 99421afdf99a4b66be53c398c048133bc79c614e /common | |
parent | 72cfa9d8293aa897a89d577d9844a2a286d8f0e2 (diff) | |
download | scummvm-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.cpp | 136 | ||||
-rw-r--r-- | common/advancedDetector.h | 27 |
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 ¶ms) { return GameList(params.list); } +static void upgradeTargetIfNecessary(const Common::ADParams ¶ms) { + 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 ¶ms @@ -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 ¶ms) { + 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 ¶ms ) { 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 ¶ms ) { 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 ¶ms ) { - 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 ¶ms); GameList detectAllGames(const FSList &fslist, const Common::ADParams ¶ms); // FIXME/TODO: Rename this function to something more sensible. -const ADGameDescription *detectBestMatchingGame(const Common::ADParams ¶ms); +EncapsulatedADGameDesc detectBestMatchingGame(const Common::ADParams ¶ms); // FIXME/TODO: Rename this function to something more sensible. // Only used by ADVANCED_DETECTOR_DEFINE_PLUGIN_WITH_FUNC |