diff options
author | Eugene Sandulenko | 2007-02-04 03:10:27 +0000 |
---|---|---|
committer | Eugene Sandulenko | 2007-02-04 03:10:27 +0000 |
commit | 7b6bdd231d100110689a0e804ac53453d388e8d9 (patch) | |
tree | 4b6d953ae1b18601ed95cdcc4ac2f42b26a39f11 /common/advancedDetector.cpp | |
parent | 0d01bdd7996c07f93428f84a77e1a45c8c4af45a (diff) | |
download | scummvm-rg350-7b6bdd231d100110689a0e804ac53453d388e8d9.tar.gz scummvm-rg350-7b6bdd231d100110689a0e804ac53453d388e8d9.tar.bz2 scummvm-rg350-7b6bdd231d100110689a0e804ac53453d388e8d9.zip |
AdvancedDetector now has built-in fallback detection based on file lists.
Currently only gob engine benefits from it.
svn-id: r25374
Diffstat (limited to 'common/advancedDetector.cpp')
-rw-r--r-- | common/advancedDetector.cpp | 120 |
1 files changed, 111 insertions, 9 deletions
diff --git a/common/advancedDetector.cpp b/common/advancedDetector.cpp index 1193b1c72e..faca7184d0 100644 --- a/common/advancedDetector.cpp +++ b/common/advancedDetector.cpp @@ -251,6 +251,7 @@ static ADList detectGame(const FSList *fslist, const Common::ADParams ¶ms, L typedef HashMap<String, int32, Common::CaseSensitiveString_Hash, Common::CaseSensitiveString_EqualTo> IntMap; StringMap filesMD5; IntMap filesSize; + IntMap allFiles; String tstr, tstr2; @@ -293,6 +294,8 @@ static ADList detectGame(const FSList *fslist, const Common::ADParams ¶ms, L tstr.toLowercase(); tstr2 = tstr + "."; + allFiles[tstr] = allFiles[tstr2] = 1; + debug(3, "+ %s", tstr.c_str()); if (!filesList.contains(tstr) && !filesList.contains(tstr2)) continue; @@ -349,7 +352,12 @@ static ADList detectGame(const FSList *fslist, const Common::ADParams ¶ms, L (platform != kPlatformUnknown && g->platform != platform)) { continue; } - + + if (g->filesDescriptions[0].fileName == 0) { + debug(5, "Skipping dummy entry: %s", g->gameid); + continue; + } + // Try to open all files for this game for (j = 0; g->filesDescriptions[j].fileName; j++) { fileDesc = &g->filesDescriptions[j]; @@ -357,28 +365,26 @@ static ADList detectGame(const FSList *fslist, const Common::ADParams ¶ms, L tstr.toLowercase(); tstr2 = tstr + "."; + if (!filesMD5.contains(tstr) && !filesMD5.contains(tstr2)) { + fileMissing = true; + break; + } if (fileDesc->md5 != NULL) { - if (!filesMD5.contains(tstr) && !filesMD5.contains(tstr2)) { - fileMissing = true; - break; - } if (strcmp(fileDesc->md5, filesMD5[tstr].c_str()) && strcmp(fileDesc->md5, filesMD5[tstr2].c_str())) { debug(3, "MD5 Mismatch. Skipping (%s) (%s)", fileDesc->md5, filesMD5[tstr].c_str()); fileMissing = true; break; } } + if (fileDesc->fileSize != -1) { - if (!filesMD5.contains(tstr) && !filesMD5.contains(tstr2)) { - fileMissing = true; - break; - } if (fileDesc->fileSize != filesSize[tstr] && fileDesc->fileSize != filesSize[tstr2]) { debug(3, "Size Mismatch. Skipping"); fileMissing = true; break; } } + debug(3, "Matched file: %s", tstr.c_str()); } if (!fileMissing) { @@ -416,6 +422,102 @@ static ADList detectGame(const FSList *fslist, const Common::ADParams ¶ms, L printf("%s: \"%s\", %d\n", file->_key.c_str(), file->_value.c_str(), filesSize[file->_key]); } + if (params.flags & kADFlagFilebasedFallback) { + if (params.fileBased == NULL) { + error("Engine %s has FilebasedFallback flag set but list fileBased is empty", + params.singleid); // We may get 0 as singleid here, but let's ignore it + } + + const char **ptr = params.fileBased; + + // First we create list of files required for detection + if (allFiles.empty()) { + File testFile; + + while (*ptr) { + ptr++; + + while (*ptr) { + tstr = String(*ptr); + tstr.toLowercase(); + + if (!allFiles.contains(tstr)) { + if (testFile.open(tstr)) { + tstr2 = tstr + "."; + allFiles[tstr] = allFiles[tstr2] = 1; + testFile.close(); + } + } + + ptr++; + } + + ptr++; + } + } + + int maxFiles = 0; + int matchFiles; + const char **matchEntry = 0; + const char **entryStart; + + ptr = params.fileBased; + + while (*ptr) { + entryStart = ptr; + fileMissing = false; + matchFiles = 0; + + ptr++; + + while (*ptr) { + if (fileMissing) { + ptr++; + continue; + } + + tstr = String(*ptr); + + tstr.toLowercase(); + tstr2 = tstr + "."; + + debug(3, "++ %s", *ptr); + if (!allFiles.contains(tstr) && !allFiles.contains(tstr2)) { + fileMissing = true; + ptr++; + continue; + } + + matchFiles++; + ptr++; + } + + if (!fileMissing) + debug(4, "Matched: %s", *entryStart); + + if (!fileMissing && matchFiles > maxFiles) { + matchEntry = entryStart; + maxFiles = matchFiles; + + debug(4, "and overrided"); + } + + ptr++; + } + + if (matchEntry) { // We got a match + for (i = 0; i < gameDescriptions.size(); i++) { + if (gameDescriptions[i]->filesDescriptions[0].fileName == 0) { + if (!scumm_stricmp(gameDescriptions[i]->gameid, *matchEntry)) { + warning("But it looks like unknown variant of %s", *matchEntry); + + matched.push_back(i); + } + } + } + } + } + return matched; } |