diff options
author | Filippos Karapetis | 2010-01-04 13:50:43 +0000 |
---|---|---|
committer | Filippos Karapetis | 2010-01-04 13:50:43 +0000 |
commit | 60ece55fb97eb9cd18a4803df174f2a28de55a86 (patch) | |
tree | 054cb520d54c507588e64a624e19bede68e7977f /engines | |
parent | 01ebbcf101efc6897ec11a18ca389aed24371e77 (diff) | |
download | scummvm-rg350-60ece55fb97eb9cd18a4803df174f2a28de55a86.tar.gz scummvm-rg350-60ece55fb97eb9cd18a4803df174f2a28de55a86.tar.bz2 scummvm-rg350-60ece55fb97eb9cd18a4803df174f2a28de55a86.zip |
Fallback detector:
- Added detection for SCI2 games (GK1, PQ4, QFG4)
- Rewrote the way demos are detected
- Games are no longer distinguished from the existence of certain files
svn-id: r46970
Diffstat (limited to 'engines')
-rw-r--r-- | engines/sci/detection.cpp | 2 | ||||
-rw-r--r-- | engines/sci/engine/game.cpp | 190 | ||||
-rw-r--r-- | engines/sci/engine/vm.h | 2 |
3 files changed, 104 insertions, 90 deletions
diff --git a/engines/sci/detection.cpp b/engines/sci/detection.cpp index 526b91acb1..e6804dd150 100644 --- a/engines/sci/detection.cpp +++ b/engines/sci/detection.cpp @@ -316,7 +316,7 @@ const ADGameDescription *SciMetaEngine::fallbackDetect(const Common::FSList &fsl reg_t game_obj = segMan->lookupScriptExport(0, 0); const char *gameId = segMan->getObjectName(game_obj); debug(2, "Detected ID: \"%s\" at %04x:%04x", gameId, PRINT_REG(game_obj)); - s_fallbackDesc.gameid = convertSierraGameId(gameId, &s_fallbackDesc.flags); + s_fallbackDesc.gameid = convertSierraGameId(gameId, &s_fallbackDesc.flags, resMan); delete segMan; // Try to determine the game language diff --git a/engines/sci/engine/game.cpp b/engines/sci/engine/game.cpp index 0434008a59..49652867a8 100644 --- a/engines/sci/engine/game.cpp +++ b/engines/sci/engine/game.cpp @@ -46,119 +46,133 @@ namespace Sci { struct OldNewIdTableEntry { const char *oldId; const char *newId; - bool demo; - const char *demoCheckFile; // if not empty and it doesn't exist, the demo flag is set + SciVersion version; }; static const OldNewIdTableEntry s_oldNewTable[] = { - { "arthur", "camelot", false, "resource.002" }, - { "demo", "christmas1988", false, "" }, - { "RH Budget", "cnick-longbow", false, "" }, + { "arthur", "camelot", SCI_VERSION_NONE }, + { "brain", "castlebrain", SCI_VERSION_1_MIDDLE }, // Amiga + { "brain", "castlebrain", SCI_VERSION_1_LATE }, + { "demo", "christmas1988", SCI_VERSION_NONE }, + { "card", "christmas1990", SCI_VERSION_1_EARLY, }, + { "card", "christmas1992", SCI_VERSION_1_1 }, + { "RH Budget", "cnick-longbow", SCI_VERSION_NONE }, // iceman is the same - { "icedemo", "iceman", true, "" }, + { "icedemo", "iceman", SCI_VERSION_NONE }, // longbow is the same - { "eco", "ecoquest", false, "resource.000" }, - { "eco2", "ecoquest2", true, "" }, // EcoQuest 2 demo - { "rain", "ecoquest2", false, "" }, // EcoQuest 2 full - { "fp", "freddypharkas", false, "" }, - { "emc", "funseeker", false, "" }, - { "gk", "gk1", false, "" }, - { "hoyledemo", "hoyle1", true, "" }, - { "cardgames", "hoyle1", false, "" }, - { "solitare", "hoyle2", false, "" }, + { "eco", "ecoquest", SCI_VERSION_NONE }, + { "eco2", "ecoquest2", SCI_VERSION_NONE }, // EcoQuest 2 demo + { "rain", "ecoquest2", SCI_VERSION_NONE }, // EcoQuest 2 full + { "fp", "freddypharkas", SCI_VERSION_NONE }, + { "emc", "funseeker", SCI_VERSION_NONE }, + { "gk", "gk1", SCI_VERSION_NONE }, + { "hoyledemo", "hoyle1", SCI_VERSION_NONE }, + { "cardgames", "hoyle1", SCI_VERSION_NONE }, + { "solitare", "hoyle2", SCI_VERSION_NONE }, // hoyle3 is the same // hoyle4 is the same - { "demo000", "kq1sci", true, "" }, - { "kq1", "kq1sci", false, "" }, - { "kq4", "kq4sci", false, "" }, - { "cb1", "laurabow", false, "" }, - { "lb2", "laurabow2", false, "resource.aud" }, - { "rh", "longbow", true, "" }, - { "ll1", "lsl1sci", true, "" }, + { "brain", "islandbrain", SCI_VERSION_1_1 }, + { "demo000", "kq1sci", SCI_VERSION_NONE }, + { "kq1", "kq1sci", SCI_VERSION_NONE }, + { "kq4", "kq4sci", SCI_VERSION_NONE }, + { "mm1", "laurabow", SCI_VERSION_NONE }, + { "cb1", "laurabow", SCI_VERSION_NONE }, + { "lb2", "laurabow2", SCI_VERSION_NONE }, + { "rh", "longbow", SCI_VERSION_NONE }, + { "ll1", "lsl1sci", SCI_VERSION_NONE }, + { "lsl1", "lsl1sci", SCI_VERSION_NONE }, // lsl2 is the same - { "lsl3", "lsl3", false, "resource.003" }, - { "ll5", "lsl5", true, "" }, + { "lsl3", "lsl3", SCI_VERSION_NONE }, + { "ll5", "lsl5", SCI_VERSION_NONE }, // lsl5 is the same // lsl6 is the same - { "mg", "mothergoose", false, "" }, - { "twisty", "pepper", false, "" }, - { "pq1", "pq1sci", false, "" }, - { "pq", "pq2", false, "" }, - { "tales", "fairytales", false, "resource.002" }, - { "trial", "qfg2", false, "" }, - { "hq2demo", "qfg2", true, "" }, - { "thegame", "slater", false, "" }, - { "sq1demo", "sq1sci", true, "" }, - { "sq1", "sq1sci", false, "" }, + { "mg", "mothergoose", SCI_VERSION_NONE }, + { "twisty", "pepper", SCI_VERSION_NONE }, + { "pq1", "pq1sci", SCI_VERSION_NONE }, + { "pq", "pq2", SCI_VERSION_NONE }, + // pq3 is the same + // pq4 is the same + { "tales", "fairytales", SCI_VERSION_NONE }, + { "hq", "qfg1", SCI_VERSION_NONE }, // QFG1 SCI0/EGA + { "glory", "qfg1", SCI_VERSION_0_LATE }, // QFG1 SCI0/EGA + { "trial", "qfg2", SCI_VERSION_NONE }, + { "hq2demo", "qfg2", SCI_VERSION_NONE }, + { "thegame", "slater", SCI_VERSION_NONE }, + { "sq1demo", "sq1sci", SCI_VERSION_NONE }, + { "sq1", "sq1sci", SCI_VERSION_NONE }, + // sq3 is the same + // sq4 is the same // sq5 is the same + // torin is the same - { "", "", false, "" } + // TODO: SCI2.1, SCI3 IDs + + { "", "", SCI_VERSION_NONE } }; -const char *convertSierraGameId(const char *gameId, uint32 *gameFlags) { +const char *convertSierraGameId(const char *gameId, uint32 *gameFlags, ResourceManager *resMan) { // Convert the id to lower case, so that we match all upper/lower case variants. Common::String sierraId = gameId; sierraId.toLowercase(); - // TODO: SCI32 IDs + // If the game has less than the expected scripts, it's a demo + uint32 demoThreshold = 100; + // ...but there are some exceptions + if (sierraId == "brain" || sierraId == "lsl1" || + sierraId == "mg" || sierraId == "pq" || + sierraId == "jones" || + sierraId == "cardgames" || sierraId == "solitare" || + sierraId == "hoyle3" || sierraId == "hoyle4") + demoThreshold = 40; + if (sierraId == "fp" || sierraId == "gk" || sierraId == "pq4") + demoThreshold = 150; + + Common::List<ResourceId> *resources = resMan->listResources(kResourceTypeScript, -1); + if (resources->size() < demoThreshold) { + *gameFlags |= ADGF_DEMO; + + // Crazy Nick's Picks + if (sierraId == "lsl1" && resources->size() == 34) + return "cnick-lsl"; + if (sierraId == "sq4" && resources->size() == 34) + return "cnick-sq"; + + // TODO: cnick-kq, cnick-laurabow and cnick-longbow (their resources can't be read) + + // Handle Astrochicken 1 (SQ3) and 2 (SQ4) + if (sierraId == "sq3" && resources->size() == 20) + return "astrochicken"; + if (sierraId == "sq4") + return "msastrochicken"; + } for (const OldNewIdTableEntry *cur = s_oldNewTable; cur->oldId[0]; ++cur) { if (sierraId == cur->oldId) { - if (cur->demo) - *gameFlags |= ADGF_DEMO; - if (cur->demoCheckFile[0]) - if (!Common::File::exists(cur->demoCheckFile)) - *gameFlags |= ADGF_DEMO; + // Distinguish same IDs from the SCI version + if (cur->version != SCI_VERSION_NONE && cur->version != getSciVersion()) + continue; + return cur->newId; } } - if (sierraId == "card") { - // This could either be christmas1990 or christmas1992 - // christmas1990 has a "resource.001" file, whereas - // christmas1992 has a "resource.000" file - return (Common::File::exists("resource.001")) ? "christmas1990" : "christmas1992"; - } - if (sierraId == "brain") { - // This could either be The Castle of Dr. Brain, or The Island of Dr. Brain - // castlebrain has resource.001, whereas islandbrain doesn't - return (Common::File::exists("resource.001")) ? "castlebrain" : "islandbrain"; - } - if (sierraId == "lsl1") { - // This could either be LSL1 full version, or LSL casino - // LSL1 full has resource.000, whereas LSL casino doesn't - return (Common::File::exists("resource.000")) ? "lsl1sci" : "cnick-lsl"; - } - // TODO: cnick-kq and cnick-longbow (their resources can't be read) - // TODO: cnick-sq (same files as Ms. Astro Chicken) - if (sierraId == "pq3") { - // The pq3 demo comes with resource.000 and resource.001 - // The full version was released with several resource.* files, - // or one big resource.000 file - if (Common::File::exists("resource.000") && Common::File::exists("resource.001") && - !Common::File::exists("resource.002")) - *gameFlags |= ADGF_DEMO; - return "pq3"; - } - if (sierraId == "glory" || sierraId == "hq") { - // This could either be qfg1 or qfg3 or qfg4 - // qfg3 has resource.aud, qfg4 has resource.sfx - if (Common::File::exists("resource.aud")) - return "qfg3"; - else if (Common::File::exists("resource.sfx")) - return "qfg4"; - else + if (sierraId == "glory") { + // This could either be qfg1 VGA, qfg3 or qfg4 demo (all SCI1.1), + // or qfg4 full (SCI2) + // qfg1 VGA doesn't have view 1 + if (!resMan->testResource(ResourceId(kResourceTypeView, 1))) return "qfg1"; - } - if (sierraId == "sq3") { - // This could either be SQ3 full version, or Astro Chicken - // SQ3 full has resource.002, whereas Astro Chicken doesn't - return (Common::File::exists("resource.002")) ? "sq3" : "astrochicken"; - } - if (sierraId == "sq4") { - // This could either be SQ4 full version, or Ms. Astro Chicken - // SQ4 full (floppy and CD) has resource.000, whereas Ms. Astro Chicken doesn't - return (Common::File::exists("resource.000")) ? "sq4" : "msastrochicken"; + + // qfg4 full is SCI2 + if (getSciVersion() == SCI_VERSION_2) + return "qfg4"; + + // qfg4 demo has less than 50 scripts + if (resources->size() < 50) + return "qfg4"; + + // Otherwise it's qfg3 + return "qfg3"; } // FIXME: Evil use of strdup here (we are leaking that memory, too) @@ -412,7 +426,7 @@ int game_init(EngineState *s) { // The first entry in the export table of script 0 points to the game object s->_gameObj = s->_segMan->lookupScriptExport(0, 0); uint32 gameFlags = 0; // unused - s->_gameId = convertSierraGameId(s->_segMan->getObjectName(s->_gameObj), &gameFlags); + s->_gameId = convertSierraGameId(s->_segMan->getObjectName(s->_gameObj), &gameFlags, s->resMan); debug(2, " \"%s\" at %04x:%04x", s->_gameId.c_str(), PRINT_REG(s->_gameObj)); diff --git a/engines/sci/engine/vm.h b/engines/sci/engine/vm.h index 69e77fc9ff..be53d6a94a 100644 --- a/engines/sci/engine/vm.h +++ b/engines/sci/engine/vm.h @@ -465,7 +465,7 @@ void script_uninstantiate(SegManager *segMan, int script_nr); * @param[in] gameFlags The game's flags, which are adjusted accordingly for demos * @return The equivalent ScummVM game id */ -const char *convertSierraGameId(const char *gameId, uint32 *gameFlags); +const char *convertSierraGameId(const char *gameId, uint32 *gameFlags, ResourceManager *resMan); /** * Initializes an SCI game |