AdvancedDetector now has built-in fallback detection based on file lists.
Currently only gob engine benefits from it. svn-id: r25374
This commit is contained in:
parent
0d01bdd799
commit
7b6bdd231d
9 changed files with 242 additions and 55 deletions
|
@ -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;
|
typedef HashMap<String, int32, Common::CaseSensitiveString_Hash, Common::CaseSensitiveString_EqualTo> IntMap;
|
||||||
StringMap filesMD5;
|
StringMap filesMD5;
|
||||||
IntMap filesSize;
|
IntMap filesSize;
|
||||||
|
IntMap allFiles;
|
||||||
|
|
||||||
String tstr, tstr2;
|
String tstr, tstr2;
|
||||||
|
|
||||||
|
@ -293,6 +294,8 @@ static ADList detectGame(const FSList *fslist, const Common::ADParams ¶ms, L
|
||||||
tstr.toLowercase();
|
tstr.toLowercase();
|
||||||
tstr2 = tstr + ".";
|
tstr2 = tstr + ".";
|
||||||
|
|
||||||
|
allFiles[tstr] = allFiles[tstr2] = 1;
|
||||||
|
|
||||||
debug(3, "+ %s", tstr.c_str());
|
debug(3, "+ %s", tstr.c_str());
|
||||||
|
|
||||||
if (!filesList.contains(tstr) && !filesList.contains(tstr2)) continue;
|
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)) {
|
(platform != kPlatformUnknown && g->platform != platform)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (g->filesDescriptions[0].fileName == 0) {
|
||||||
|
debug(5, "Skipping dummy entry: %s", g->gameid);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// Try to open all files for this game
|
// Try to open all files for this game
|
||||||
for (j = 0; g->filesDescriptions[j].fileName; j++) {
|
for (j = 0; g->filesDescriptions[j].fileName; j++) {
|
||||||
fileDesc = &g->filesDescriptions[j];
|
fileDesc = &g->filesDescriptions[j];
|
||||||
|
@ -357,28 +365,26 @@ static ADList detectGame(const FSList *fslist, const Common::ADParams ¶ms, L
|
||||||
tstr.toLowercase();
|
tstr.toLowercase();
|
||||||
tstr2 = tstr + ".";
|
tstr2 = tstr + ".";
|
||||||
|
|
||||||
|
if (!filesMD5.contains(tstr) && !filesMD5.contains(tstr2)) {
|
||||||
|
fileMissing = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
if (fileDesc->md5 != NULL) {
|
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())) {
|
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());
|
debug(3, "MD5 Mismatch. Skipping (%s) (%s)", fileDesc->md5, filesMD5[tstr].c_str());
|
||||||
fileMissing = true;
|
fileMissing = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fileDesc->fileSize != -1) {
|
if (fileDesc->fileSize != -1) {
|
||||||
if (!filesMD5.contains(tstr) && !filesMD5.contains(tstr2)) {
|
|
||||||
fileMissing = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (fileDesc->fileSize != filesSize[tstr] && fileDesc->fileSize != filesSize[tstr2]) {
|
if (fileDesc->fileSize != filesSize[tstr] && fileDesc->fileSize != filesSize[tstr2]) {
|
||||||
debug(3, "Size Mismatch. Skipping");
|
debug(3, "Size Mismatch. Skipping");
|
||||||
fileMissing = true;
|
fileMissing = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
debug(3, "Matched file: %s", tstr.c_str());
|
debug(3, "Matched file: %s", tstr.c_str());
|
||||||
}
|
}
|
||||||
if (!fileMissing) {
|
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]);
|
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;
|
return matched;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -52,7 +52,8 @@ struct ADObsoleteGameID {
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ADFlags {
|
enum ADFlags {
|
||||||
kADFlagComplexID = (1 << 0) // Generate complex suggested IDs
|
kADFlagComplexID = (1 << 0), // Generate complex suggested IDs
|
||||||
|
kADFlagFilebasedFallback = (1 << 1) // Use file based fallback detection
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ADParams {
|
struct ADParams {
|
||||||
|
@ -68,6 +69,8 @@ struct ADParams {
|
||||||
const Common::ADObsoleteGameID *obsoleteList;
|
const Common::ADObsoleteGameID *obsoleteList;
|
||||||
// Name of single gameid (optional)
|
// Name of single gameid (optional)
|
||||||
const char *singleid;
|
const char *singleid;
|
||||||
|
// List of files for file-based fallback detection (optional)
|
||||||
|
const char **fileBased;
|
||||||
// Flags
|
// Flags
|
||||||
uint32 flags;
|
uint32 flags;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1013,6 +1013,8 @@ static const Common::ADParams detectionParams = {
|
||||||
0,
|
0,
|
||||||
// Name of single gameid (optional)
|
// Name of single gameid (optional)
|
||||||
"agi",
|
"agi",
|
||||||
|
// List of files for file-based fallback detection (optional)
|
||||||
|
0,
|
||||||
// Flags
|
// Flags
|
||||||
Common::kADFlagComplexID
|
Common::kADFlagComplexID
|
||||||
};
|
};
|
||||||
|
|
|
@ -95,6 +95,8 @@ static const Common::ADParams detectionParams = {
|
||||||
obsoleteGameIDsTable,
|
obsoleteGameIDsTable,
|
||||||
// Name of single gameid (optional)
|
// Name of single gameid (optional)
|
||||||
0,
|
0,
|
||||||
|
// List of files for file-based fallback detection (optional)
|
||||||
|
0,
|
||||||
// Flags
|
// Flags
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
|
|
@ -450,6 +450,8 @@ static const Common::ADParams detectionParams = {
|
||||||
obsoleteGameIDsTable,
|
obsoleteGameIDsTable,
|
||||||
// Name of single gameid (optional)
|
// Name of single gameid (optional)
|
||||||
"cine",
|
"cine",
|
||||||
|
// List of files for file-based fallback detection (optional)
|
||||||
|
0,
|
||||||
// Flags
|
// Flags
|
||||||
Common::kADFlagComplexID
|
Common::kADFlagComplexID
|
||||||
};
|
};
|
||||||
|
|
|
@ -45,10 +45,13 @@ using namespace Common;
|
||||||
static const PlainGameDescriptor gobGames[] = {
|
static const PlainGameDescriptor gobGames[] = {
|
||||||
{"gob", "Gob engine game"},
|
{"gob", "Gob engine game"},
|
||||||
{"gob1", "Gobliiins"},
|
{"gob1", "Gobliiins"},
|
||||||
|
{"gob1cd", "Gobliiins CD"},
|
||||||
{"gob1-demo", "Gobliiins Demo"},
|
{"gob1-demo", "Gobliiins Demo"},
|
||||||
{"gob2", "Gobliins 2"},
|
{"gob2", "Gobliins 2"},
|
||||||
|
{"gob2cd", "Gobliins 2 CD"},
|
||||||
{"gob2-demo", "Gobliins 2 Demo"},
|
{"gob2-demo", "Gobliins 2 Demo"},
|
||||||
{"gob3", "Goblins Quest 3"},
|
{"gob3", "Goblins Quest 3"},
|
||||||
|
{"gob3cd", "Goblins Quest 3 CD"},
|
||||||
{"gob3-demo", "Goblins Quest 3 Demo"},
|
{"gob3-demo", "Goblins Quest 3 Demo"},
|
||||||
{"bargon", "Bargon Attack"},
|
{"bargon", "Bargon Attack"},
|
||||||
{"ween", "Ween: The Prohpecy"},
|
{"ween", "Ween: The Prohpecy"},
|
||||||
|
@ -66,6 +69,17 @@ static const ADObsoleteGameID obsoleteGameIDsTable[] = {
|
||||||
namespace Gob {
|
namespace Gob {
|
||||||
|
|
||||||
static const GOBGameDescription gameDescriptions[] = {
|
static const GOBGameDescription gameDescriptions[] = {
|
||||||
|
{ // Dummy entry for fallback detection
|
||||||
|
{
|
||||||
|
"gob1",
|
||||||
|
"unknown",
|
||||||
|
AD_ENTRY1(0, 0),
|
||||||
|
UNK_LANG,
|
||||||
|
kPlatformPC,
|
||||||
|
},
|
||||||
|
GF_GOB1,
|
||||||
|
"intro"
|
||||||
|
},
|
||||||
{ // Supplied by Florian Zeitz on scummvm-devel
|
{ // Supplied by Florian Zeitz on scummvm-devel
|
||||||
{
|
{
|
||||||
"gob1",
|
"gob1",
|
||||||
|
@ -99,10 +113,21 @@ static const GOBGameDescription gameDescriptions[] = {
|
||||||
GF_GOB1,
|
GF_GOB1,
|
||||||
"intro"
|
"intro"
|
||||||
},
|
},
|
||||||
{ // CD 1.000 version. Multilingual
|
{ // Dummy entry for fallback detection
|
||||||
{
|
{
|
||||||
"gob1",
|
"gob1cd",
|
||||||
"CD 1.000",
|
"unknown",
|
||||||
|
AD_ENTRY1(0, 0),
|
||||||
|
UNK_LANG,
|
||||||
|
kPlatformPC,
|
||||||
|
},
|
||||||
|
GF_GOB1 | GF_CD,
|
||||||
|
"intro"
|
||||||
|
},
|
||||||
|
{ // CD 1.000 version.
|
||||||
|
{
|
||||||
|
"gob1cd",
|
||||||
|
"v1.000",
|
||||||
AD_ENTRY1("intro.stk", "2fbf4b5b82bbaee87eb45d4404c28998"),
|
AD_ENTRY1("intro.stk", "2fbf4b5b82bbaee87eb45d4404c28998"),
|
||||||
UNK_LANG,
|
UNK_LANG,
|
||||||
kPlatformPC,
|
kPlatformPC,
|
||||||
|
@ -112,10 +137,43 @@ static const GOBGameDescription gameDescriptions[] = {
|
||||||
},
|
},
|
||||||
{ // CD 1.02 version. Multilingual
|
{ // CD 1.02 version. Multilingual
|
||||||
{
|
{
|
||||||
"gob1",
|
"gob1cd",
|
||||||
"CD 1.02",
|
"v1.02",
|
||||||
AD_ENTRY1("intro.stk", "8bd873137b6831c896ee8ad217a6a398"),
|
AD_ENTRY1("intro.stk", "8bd873137b6831c896ee8ad217a6a398"),
|
||||||
UNK_LANG,
|
EN_USA,
|
||||||
|
kPlatformPC,
|
||||||
|
},
|
||||||
|
GF_GOB1 | GF_CD,
|
||||||
|
"intro"
|
||||||
|
},
|
||||||
|
{ // CD 1.02 version. Multilingual
|
||||||
|
{
|
||||||
|
"gob1cd",
|
||||||
|
"v1.02",
|
||||||
|
AD_ENTRY1("intro.stk", "8bd873137b6831c896ee8ad217a6a398"),
|
||||||
|
FR_FRA,
|
||||||
|
kPlatformPC,
|
||||||
|
},
|
||||||
|
GF_GOB1 | GF_CD,
|
||||||
|
"intro"
|
||||||
|
},
|
||||||
|
{ // CD 1.02 version. Multilingual
|
||||||
|
{
|
||||||
|
"gob1cd",
|
||||||
|
"v1.02",
|
||||||
|
AD_ENTRY1("intro.stk", "8bd873137b6831c896ee8ad217a6a398"),
|
||||||
|
IT_ITA,
|
||||||
|
kPlatformPC,
|
||||||
|
},
|
||||||
|
GF_GOB1 | GF_CD,
|
||||||
|
"intro"
|
||||||
|
},
|
||||||
|
{ // CD 1.02 version. Multilingual
|
||||||
|
{
|
||||||
|
"gob1cd",
|
||||||
|
"v1.02",
|
||||||
|
AD_ENTRY1("intro.stk", "8bd873137b6831c896ee8ad217a6a398"),
|
||||||
|
ES_ESP,
|
||||||
kPlatformPC,
|
kPlatformPC,
|
||||||
},
|
},
|
||||||
GF_GOB1 | GF_CD,
|
GF_GOB1 | GF_CD,
|
||||||
|
@ -154,6 +212,17 @@ static const GOBGameDescription gameDescriptions[] = {
|
||||||
GF_GOB1,
|
GF_GOB1,
|
||||||
"intro"
|
"intro"
|
||||||
},
|
},
|
||||||
|
{ // Dummy entry for fallback detection
|
||||||
|
{
|
||||||
|
"gob2",
|
||||||
|
"unknown",
|
||||||
|
AD_ENTRY1(0, 0),
|
||||||
|
UNK_LANG,
|
||||||
|
kPlatformPC,
|
||||||
|
},
|
||||||
|
GF_GOB2,
|
||||||
|
"intro"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
"gob2",
|
"gob2",
|
||||||
|
@ -231,10 +300,21 @@ static const GOBGameDescription gameDescriptions[] = {
|
||||||
GF_GOB2,
|
GF_GOB2,
|
||||||
"intro"
|
"intro"
|
||||||
},
|
},
|
||||||
|
{ // Dummy entry for fallback detection
|
||||||
|
{
|
||||||
|
"gob2cd",
|
||||||
|
"unknown",
|
||||||
|
AD_ENTRY1(0, 0),
|
||||||
|
UNK_LANG,
|
||||||
|
kPlatformPC,
|
||||||
|
},
|
||||||
|
GF_GOB2 | GF_CD,
|
||||||
|
"intro"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
"gob2",
|
"gob2cd",
|
||||||
"CD 1.000",
|
"v1.000",
|
||||||
AD_ENTRY1("intro.stk", "9de5fbb41cf97182109e5fecc9d90347"),
|
AD_ENTRY1("intro.stk", "9de5fbb41cf97182109e5fecc9d90347"),
|
||||||
EN_USA,
|
EN_USA,
|
||||||
kPlatformPC,
|
kPlatformPC,
|
||||||
|
@ -244,8 +324,8 @@ static const GOBGameDescription gameDescriptions[] = {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
"gob2",
|
"gob2cd",
|
||||||
"CD 1.02",
|
"v1.02",
|
||||||
AD_ENTRY1("intro.stk", "24a6b32757752ccb1917ce92fd7c2a04"),
|
AD_ENTRY1("intro.stk", "24a6b32757752ccb1917ce92fd7c2a04"),
|
||||||
EN_ANY,
|
EN_ANY,
|
||||||
kPlatformPC,
|
kPlatformPC,
|
||||||
|
@ -255,8 +335,8 @@ static const GOBGameDescription gameDescriptions[] = {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
"gob2",
|
"gob2cd",
|
||||||
"CD 1.02",
|
"v1.02",
|
||||||
AD_ENTRY1("intro.stk", "24a6b32757752ccb1917ce92fd7c2a04"),
|
AD_ENTRY1("intro.stk", "24a6b32757752ccb1917ce92fd7c2a04"),
|
||||||
DE_DEU,
|
DE_DEU,
|
||||||
kPlatformPC,
|
kPlatformPC,
|
||||||
|
@ -266,8 +346,8 @@ static const GOBGameDescription gameDescriptions[] = {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
"gob2",
|
"gob2cd",
|
||||||
"CD 1.02",
|
"v1.02",
|
||||||
AD_ENTRY1("intro.stk", "24a6b32757752ccb1917ce92fd7c2a04"),
|
AD_ENTRY1("intro.stk", "24a6b32757752ccb1917ce92fd7c2a04"),
|
||||||
FR_FRA,
|
FR_FRA,
|
||||||
kPlatformPC,
|
kPlatformPC,
|
||||||
|
@ -277,8 +357,8 @@ static const GOBGameDescription gameDescriptions[] = {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
"gob2",
|
"gob2cd",
|
||||||
"CD 1.02",
|
"v1.02",
|
||||||
AD_ENTRY1("intro.stk", "24a6b32757752ccb1917ce92fd7c2a04"),
|
AD_ENTRY1("intro.stk", "24a6b32757752ccb1917ce92fd7c2a04"),
|
||||||
IT_ITA,
|
IT_ITA,
|
||||||
kPlatformPC,
|
kPlatformPC,
|
||||||
|
@ -288,8 +368,8 @@ static const GOBGameDescription gameDescriptions[] = {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
"gob2",
|
"gob2cd",
|
||||||
"CD 1.02",
|
"v1.02",
|
||||||
AD_ENTRY1("intro.stk", "24a6b32757752ccb1917ce92fd7c2a04"),
|
AD_ENTRY1("intro.stk", "24a6b32757752ccb1917ce92fd7c2a04"),
|
||||||
ES_ESP,
|
ES_ESP,
|
||||||
kPlatformPC,
|
kPlatformPC,
|
||||||
|
@ -453,8 +533,8 @@ static const GOBGameDescription gameDescriptions[] = {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
"gob3",
|
"gob3cd",
|
||||||
"CD 1.000",
|
"v1.000",
|
||||||
AD_ENTRY1("intro.stk", "6f2c226c62dd7ab0ab6f850e89d3fc47"),
|
AD_ENTRY1("intro.stk", "6f2c226c62dd7ab0ab6f850e89d3fc47"),
|
||||||
UNK_LANG,
|
UNK_LANG,
|
||||||
kPlatformPC,
|
kPlatformPC,
|
||||||
|
@ -464,8 +544,8 @@ static const GOBGameDescription gameDescriptions[] = {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
"gob3",
|
"gob3cd",
|
||||||
"CD 1.02",
|
"v1.02",
|
||||||
AD_ENTRY1("intro.stk", "c3e9132ea9dc0fb866b6d60dcda10261"),
|
AD_ENTRY1("intro.stk", "c3e9132ea9dc0fb866b6d60dcda10261"),
|
||||||
UNK_LANG,
|
UNK_LANG,
|
||||||
kPlatformPC,
|
kPlatformPC,
|
||||||
|
@ -542,6 +622,15 @@ static const GOBGameDescription gameDescriptions[] = {
|
||||||
{ { NULL, NULL, { { NULL, 0, NULL, 0 } }, UNK_LANG, kPlatformUnknown }, 0, NULL }
|
{ { NULL, NULL, { { NULL, 0, NULL, 0 } }, UNK_LANG, kPlatformUnknown }, 0, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const char *fileBased[] = {
|
||||||
|
"gob1", "intro.stk", "disk1.stk", "disk2.stk", "disk3.stk", "disk4.stk", 0,
|
||||||
|
"gob1cd", "intro.stk", "gob.lic", 0,
|
||||||
|
"gob2", "intro.stk", 0,
|
||||||
|
"gob2", "intro.stk", "disk2.stk", "disk3.stk", 0,
|
||||||
|
"gob2cd", "intro.stk", "gobnew.lic", 0,
|
||||||
|
0
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const ADParams detectionParams = {
|
static const ADParams detectionParams = {
|
||||||
|
@ -557,8 +646,10 @@ static const ADParams detectionParams = {
|
||||||
obsoleteGameIDsTable,
|
obsoleteGameIDsTable,
|
||||||
// Name of single gameid (optional)
|
// Name of single gameid (optional)
|
||||||
"gob",
|
"gob",
|
||||||
|
// List of files for file-based fallback detection (optional)
|
||||||
|
Gob::fileBased,
|
||||||
// Flags
|
// Flags
|
||||||
kADFlagComplexID
|
kADFlagComplexID | kADFlagFilebasedFallback
|
||||||
};
|
};
|
||||||
|
|
||||||
ADVANCED_DETECTOR_DEFINE_PLUGIN(GOB, Gob::GobEngine, Gob::GAME_detectGames, detectionParams);
|
ADVANCED_DETECTOR_DEFINE_PLUGIN(GOB, Gob::GobEngine, Gob::GAME_detectGames, detectionParams);
|
||||||
|
@ -593,28 +684,7 @@ bool GobEngine::detectGame() {
|
||||||
}
|
}
|
||||||
|
|
||||||
GameList GAME_detectGames(const FSList &fslist) {
|
GameList GAME_detectGames(const FSList &fslist) {
|
||||||
GameList gl(AdvancedDetector::detectAllGames(fslist, detectionParams));
|
return AdvancedDetector::detectAllGames(fslist, detectionParams);
|
||||||
|
|
||||||
if (gl.empty()) {
|
|
||||||
for (FSList::const_iterator file = fslist.begin(); file != fslist.end(); ++file) {
|
|
||||||
if (file->isDirectory()) continue;
|
|
||||||
|
|
||||||
if (!scumm_stricmp(file->name().c_str(), "intro.stk")) {
|
|
||||||
const PlainGameDescriptor *g = detectionParams.list;
|
|
||||||
while (g->gameid) {
|
|
||||||
if (0 == scumm_stricmp(detectionParams.singleid, g->gameid)) {
|
|
||||||
gl.push_back(GameDescriptor(g->gameid, g->description));
|
|
||||||
|
|
||||||
return gl;
|
|
||||||
}
|
|
||||||
|
|
||||||
g++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return gl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // End of namespace Parallaction
|
} // End of namespace Parallaction
|
||||||
|
|
|
@ -94,6 +94,8 @@ const Common::ADParams detectionParams = {
|
||||||
0,
|
0,
|
||||||
// Name of single gameid (optional)
|
// Name of single gameid (optional)
|
||||||
0,
|
0,
|
||||||
|
// List of files for file-based fallback detection (optional)
|
||||||
|
0,
|
||||||
// Flags
|
// Flags
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
|
|
@ -93,6 +93,8 @@ static const Common::ADParams detectionParams = {
|
||||||
0,
|
0,
|
||||||
// Name of single gameid (optional)
|
// Name of single gameid (optional)
|
||||||
"parallaction",
|
"parallaction",
|
||||||
|
// List of files for file-based fallback detection (optional)
|
||||||
|
0,
|
||||||
// Flags
|
// Flags
|
||||||
Common::kADFlagComplexID
|
Common::kADFlagComplexID
|
||||||
};
|
};
|
||||||
|
|
|
@ -114,6 +114,8 @@ static const Common::ADParams detectionParams = {
|
||||||
obsoleteGameIDsTable,
|
obsoleteGameIDsTable,
|
||||||
// Name of single gameid (optional)
|
// Name of single gameid (optional)
|
||||||
"saga",
|
"saga",
|
||||||
|
// List of files for file-based fallback detection (optional)
|
||||||
|
0,
|
||||||
// Flags
|
// Flags
|
||||||
Common::kADFlagComplexID
|
Common::kADFlagComplexID
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue