Ticket #8690: fallback-alternate.patch
File fallback-alternate.patch, 8.0 KB (added by , 16 years ago) |
---|
-
common/advancedDetector.h
64 64 }; 65 65 66 66 /** 67 * Encapsulates ADGameDescription and makes gameid and extra strings dynamic. 68 * Used in fallback detection when dynamically creating string content. 69 */ 70 struct EncapsulatedADGameDesc : ADGameDescription { 71 Common::String gameid; 72 Common::String extra; 73 74 EncapsulatedADGameDesc() { 75 } 76 EncapsulatedADGameDesc(const ADGameDescription &realDesc, 77 Common::String paramGameID = Common::String(""), 78 Common::String paramExtra = Common::String("")) 79 : ADGameDescription(realDesc), gameid(paramGameID), extra(paramExtra) { 80 } 81 82 // Functions for getting the correct gameid and extra values from the struct 83 const char *getGameID() const { return gameid.empty() ? ((ADGameDescription *)this)->gameid : gameid.c_str(); } 84 const char *getExtra() const { return extra.empty() ? ((ADGameDescription *)this)->extra : extra.c_str(); } 85 }; 86 87 /** 67 88 * A list of pointers to ADGameDescription structs (or subclasses thereof). 68 89 */ 69 90 typedef Array<const ADGameDescription*> ADGameDescList; … … 175 196 * @note The fslist parameter may be 0 -- in that case, it is assumed 176 197 * that the callback searchs the current directory. 177 198 * 199 * @note You need to handle deleting the returned pointer if it's not NULL. 200 * You don't need to delete the memory pointed to by the realDesc 201 * pointer inside the struct though because it should be statically 202 * allocated. 203 * 204 * @return A pointer to a single EncapsulatedADGameDesc if there was a 205 * match, otherwise NULL. 206 * 178 207 * @todo 179 208 */ 180 ADGameDescList(*fallbackDetectFunc)(const FSList *fslist);209 EncapsulatedADGameDesc (*fallbackDetectFunc)(const FSList *fslist); 181 210 182 211 /** 183 212 * A bitmask of flags which can be used to configure the behavior … … 206 235 // FIXME/TODO: Rename this function to something more sensible. 207 236 GameList detectAllGames(const FSList &fslist, const Common::ADParams ¶ms); 208 237 209 // FIXME/TODO: Rename this function to something more sensible. 210 const ADGameDescription *detectBestMatchingGame(const Common::ADParams ¶ms); 238 /** 239 * Detect the best matching game. 240 * 241 * FIXME/TODO: Rename this function to something more sensible. 242 * 243 * @note You need to handle deleting the returned pointer if it's not NULL. 244 * You don't need to delete the memory pointed to by the realDesc 245 * pointer inside the struct though because it should be statically 246 * allocated. 247 */ 248 EncapsulatedADGameDesc detectBestMatchingGame(const Common::ADParams ¶ms); 211 249 212 250 // FIXME/TODO: Rename this function to something more sensible. 213 251 // Only used by ADVANCED_DETECTOR_DEFINE_PLUGIN_WITH_FUNC -
common/advancedDetector.cpp
110 110 return gd; 111 111 } 112 112 113 // Almost identical to the toGameDescriptor function that takes a ADGameDescription and PlainGameDescriptor. 114 // Just a little fine tuning about accessing variables. 115 // Used because of fallback detection and the dynamic string content it needs. 116 static GameDescriptor toGameDescriptor(const EncapsulatedADGameDesc &g, const PlainGameDescriptor *sg) { 117 const char *title = 0; 118 119 while (sg->gameid) { 120 if (!scumm_stricmp(g.getGameID(), sg->gameid)) 121 title = sg->description; 122 sg++; 123 } 124 125 GameDescriptor gd(g.getGameID(), title, g.language, g.platform); 126 gd.updateDesc(g.getExtra()); 127 return gd; 128 } 129 113 130 /** 114 131 * Generate a preferred target value as 115 132 * GAMEID-PLAFORM-LANG … … 139 156 const Common::ADParams ¶ms 140 157 ) { 141 158 ADGameDescList matches = detectGame(&fslist, params, Common::UNK_LANG, Common::kPlatformUnknown); 142 143 159 GameList detectedGames; 144 for (uint i = 0; i < matches.size(); i++) { 145 GameDescriptor desc(toGameDescriptor(*matches[i], params.list)); 160 EncapsulatedADGameDesc fallbackDesc; 146 161 162 // Use fallback detector if there were no matches by other means 163 if (matches.empty() && params.fallbackDetectFunc != NULL) { 164 fallbackDesc = (*params.fallbackDetectFunc)(&fslist); 165 if (!fallbackDesc.gameid.empty()) detectedGames.push_back(toGameDescriptor(fallbackDesc, params.list)); 166 } else for (uint i = 0; i < matches.size(); i++) // Otherwise use the found matches 167 detectedGames.push_back(toGameDescriptor(*matches[i], params.list)); 168 169 for (uint i = 0; i < detectedGames.size(); i++) { 147 170 if (params.singleid != NULL) { 148 de sc["preferredtarget"] = desc["gameid"];149 de sc["gameid"] = params.singleid;171 detectedGames[i]["preferredtarget"] = detectedGames[i]["gameid"]; 172 detectedGames[i]["gameid"] = params.singleid; 150 173 } 151 174 152 175 if (params.flags & kADFlagAugmentPreferredTarget) { 153 if (!de sc.contains("preferredtarget"))154 de sc["preferredtarget"] = desc["gameid"];176 if (!detectedGames[i].contains("preferredtarget")) 177 detectedGames[i]["preferredtarget"] = detectedGames[i]["gameid"]; 155 178 156 desc["preferredtarget"] = generatePreferredTarget(desc["preferredtarget"], matches[i]); 179 if (!matches.empty()) { // If found a match or matches without fallback detection 180 detectedGames[i]["preferredtarget"] = generatePreferredTarget(detectedGames[i]["preferredtarget"], matches[i]); 181 } else if (!fallbackDesc.gameid.empty()) { // If found match with the fallback detection 182 // This assumes that generatePreferredTarget doesn't need gameid or extra fields from the fallbackDesc, 183 // so we can just give it the ADGameDescription from inside the *fallbackDesc. 184 detectedGames[i]["preferredtarget"] = generatePreferredTarget(detectedGames[i]["preferredtarget"], &fallbackDesc); 185 } 157 186 } 158 159 detectedGames.push_back(desc);160 187 } 161 188 162 189 return detectedGames; 163 190 } 164 191 165 const ADGameDescription *detectBestMatchingGame(192 EncapsulatedADGameDesc detectBestMatchingGame( 166 193 const Common::ADParams ¶ms 167 194 ) { 168 const ADGameDescription *agdDesc = 0; 195 const ADGameDescription *agdDesc = NULL; 196 EncapsulatedADGameDesc result; 169 197 Common::Language language = Common::UNK_LANG; 170 198 Common::Platform platform = Common::kPlatformUnknown; 171 199 … … 176 204 177 205 Common::String gameid = ConfMan.get("gameid"); 178 206 179 ADGameDescList matches = detectGame( 0, params, language, platform);207 ADGameDescList matches = detectGame(NULL, params, language, platform); 180 208 181 209 if (params.singleid == NULL) { 182 210 for (uint i = 0; i < matches.size(); i++) { … … 189 217 agdDesc = matches[0]; 190 218 } 191 219 192 if (agdDesc != 0) { 193 debug(2, "Running %s", toGameDescriptor(*agdDesc, params.list).description().c_str()); 220 // Use fallback detector if there were no matches by other means 221 if (matches.empty() && params.fallbackDetectFunc != NULL) { 222 EncapsulatedADGameDesc fallbackDesc = (*params.fallbackDetectFunc)(NULL); 223 if (!fallbackDesc.gameid.empty() && (params.singleid != NULL || fallbackDesc.getGameID() == gameid)) { 224 result = fallbackDesc; // Found a fallback match 225 } 194 226 } 195 227 196 return agdDesc; 228 // If we found a match without fallback detection 229 // then let's convert it to this function's return format 230 if (agdDesc != NULL) { 231 result = EncapsulatedADGameDesc(*agdDesc); 232 } 233 234 if (!result.gameid.empty()) { 235 debug(2, "Running %s", toGameDescriptor(result, params.list).description().c_str()); 236 } 237 238 return result; 197 239 } 198 240 199 241 PluginError detectGameForEngineCreation( … … 236 278 } 237 279 } 238 280 281 // Use fallback detector if there were no matches by other means 282 if (matches.empty() && params.fallbackDetectFunc != NULL) { 283 EncapsulatedADGameDesc fallbackDesc = (*params.fallbackDetectFunc)(&fslist); 284 if (!fallbackDesc.gameid.empty()) { 285 bool foundFallbackMatch = (params.singleid != NULL || fallbackDesc.getGameID() == gameid); 286 if (foundFallbackMatch) return kNoError; 287 } 288 } 289 239 290 return kNoGameDataFoundError; 240 291 } 241 292 … … 486 537 } 487 538 } 488 539 489 // If we still haven't got a match, try to use the fallback callback :-)490 if (matched.empty() && params.fallbackDetectFunc != 0) {491 matched = (*params.fallbackDetectFunc)(fslist);492 }493 494 540 return matched; 495 541 } 496 542