diff options
Diffstat (limited to 'engines/sci')
70 files changed, 2714 insertions, 1330 deletions
diff --git a/engines/sci/console.cpp b/engines/sci/console.cpp index 2f69d5caa1..571d2f834b 100644 --- a/engines/sci/console.cpp +++ b/engines/sci/console.cpp @@ -1498,10 +1498,22 @@ bool Console::cmdDrawPic(int argc, const char **argv) { return true; } - uint16 resourceId = atoi(argv[1]); +#ifndef USE_TEXT_CONSOLE_FOR_DEBUGGER + // If a graphical debugger overlay is used, hide it here, so that the + // results can be drawn. + g_system->hideOverlay(); +#endif + uint16 resourceId = atoi(argv[1]); _engine->_gfxPaint->kernelDrawPicture(resourceId, 100, false, false, false, 0); _engine->_gfxScreen->copyToScreen(); + _engine->sleep(2000); + +#ifndef USE_TEXT_CONSOLE_FOR_DEBUGGER + // Show the graphical debugger overlay + g_system->showOverlay(); +#endif + return true; } @@ -1864,16 +1876,17 @@ bool Console::segmentInfo(int nr) { DebugPrintf(" Synonyms: %4d\n", scr->getSynonymsNr()); - if (scr->_localsBlock) - DebugPrintf(" Locals : %4d in segment 0x%x\n", scr->_localsBlock->_locals.size(), scr->_localsSegment); + if (scr->getLocalsCount() > 0) + DebugPrintf(" Locals : %4d in segment 0x%x\n", scr->getLocalsCount(), scr->getLocalsSegment()); else DebugPrintf(" Locals : none\n"); - DebugPrintf(" Objects: %4d\n", scr->_objects.size()); + ObjMap objects = scr->getObjectMap(); + DebugPrintf(" Objects: %4d\n", objects.size()); ObjMap::iterator it; - const ObjMap::iterator end = scr->_objects.end(); - for (it = scr->_objects.begin(); it != end; ++it) { + const ObjMap::iterator end = objects.end(); + for (it = objects.begin(); it != end; ++it) { DebugPrintf(" "); // Object header const Object *obj = _engine->_gamestate->_segMan->getObject(it->_value.getPos()); @@ -2930,9 +2943,10 @@ void Console::printKernelCallsFound(int kernelFuncNum, bool showFoundScripts) { script = customSegMan->getScript(scriptSegment); // Iterate through all the script's objects + ObjMap objects = script->getObjectMap(); ObjMap::iterator it; - const ObjMap::iterator end = script->_objects.end(); - for (it = script->_objects.begin(); it != end; ++it) { + const ObjMap::iterator end = objects.end(); + for (it = objects.begin(); it != end; ++it) { const Object *obj = customSegMan->getObject(it->_value.getPos()); const char *objName = customSegMan->getObjectName(it->_value.getPos()); @@ -2964,7 +2978,8 @@ void Console::printKernelCallsFound(int kernelFuncNum, bool showFoundScripts) { // there is a jump after a ret, we don't stop processing if (opcode == op_bt || opcode == op_bnt || opcode == op_jmp) { uint16 curJmpOffset = offset + (uint16)opparams[0]; - if (curJmpOffset > maxJmpOffset) + // QFG2 has invalid jumps outside the script buffer in script 260 + if (curJmpOffset > maxJmpOffset && curJmpOffset < script->getScriptSize()) maxJmpOffset = curJmpOffset; } diff --git a/engines/sci/detection.cpp b/engines/sci/detection.cpp index 56da696592..80f45b4325 100644 --- a/engines/sci/detection.cpp +++ b/engines/sci/detection.cpp @@ -373,7 +373,7 @@ static ADGameDescription s_fallbackDesc = { Common::UNK_LANG, Common::kPlatformPC, ADGF_NO_FLAGS, - Common::GUIO_NONE + GUIO0() }; static char s_fallbackGameIdBuf[256]; @@ -435,7 +435,7 @@ const ADGameDescription *SciMetaEngine::fallbackDetect(const FileMap &allFiles, s_fallbackDesc.flags = ADGF_NO_FLAGS; s_fallbackDesc.platform = Common::kPlatformPC; // default to PC platform s_fallbackDesc.gameid = "sci"; - s_fallbackDesc.guioptions = Common::GUIO_NONE; + s_fallbackDesc.guioptions = GUIO0(); if (allFiles.contains("resource.map") || allFiles.contains("Data1") || allFiles.contains("resmap.001") || allFiles.contains("resmap.001")) { @@ -565,7 +565,7 @@ const ADGameDescription *SciMetaEngine::fallbackDetect(const FileMap &allFiles, const bool isCD = (s_fallbackDesc.flags & ADGF_CD); if (!isCD) - s_fallbackDesc.guioptions |= Common::GUIO_NOSPEECH; + s_fallbackDesc.guioptions = GUIO1(GUIO_NOSPEECH); if (gameId.hasSuffix("sci")) { s_fallbackDesc.extra = "SCI"; diff --git a/engines/sci/detection_tables.h b/engines/sci/detection_tables.h index 455223a086..63eda1c348 100644 --- a/engines/sci/detection_tables.h +++ b/engines/sci/detection_tables.h @@ -29,15 +29,11 @@ namespace Sci { {"sci-fanmade", name, { \ {"resource.map", 0, resMapMd5, resMapSize}, \ {"resource.001", 0, resMd5, resSize}, \ - AD_LISTEND}, lang, Common::kPlatformPC, 0, GUIO_NOSPEECH \ + AD_LISTEND}, lang, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) \ } #define FANMADE(name, resMapMd5, resMapSize, resMd5, resSize) FANMADE_L(name, resMapMd5, resMapSize, resMd5, resSize, Common::EN_ANY) -using Common::GUIO_NONE; -using Common::GUIO_NOSPEECH; -using Common::GUIO_MIDIGM; - // Game descriptions static const struct ADGameDescription SciGameDescriptions[] = { // Astro Chicken - English DOS @@ -46,7 +42,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "f3d1be7752d30ba60614533d531e2e98", 474}, {"resource.001", 0, "6fd05926c2199af0af6f72f90d0d7260", 126895}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, // Castle of Dr. Brain - English Amiga (from www.back2roots.org) // Executable scanning reports "1.005.000" @@ -58,7 +54,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.002", 0, "d226d7d3b4f77c4a566913fc310487fc", 792380}, {"resource.003", 0, "d226d7d3b4f77c4a566913fc310487fc", 464348}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO1(GUIO_NOSPEECH) }, // Castle of Dr. Brain - German Amiga (from www.back2roots.org, also includes English language) // Executable scanning reports "1.005.001" @@ -70,7 +66,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.002", 0, "85e51acb5f9c539d66e3c8fe40e17da5", 826309}, {"resource.003", 0, "85e51acb5f9c539d66e3c8fe40e17da5", 493638}, AD_LISTEND}, - Common::DE_DEU, Common::kPlatformAmiga, ADGF_ADDENGLISH, GUIO_NOSPEECH }, + Common::DE_DEU, Common::kPlatformAmiga, ADGF_ADDENGLISH, GUIO1(GUIO_NOSPEECH) }, // Castle of Dr. Brain Macintosh (from omer_mor, bug report #3328251) {"castlebrain", "", { @@ -80,7 +76,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.002", 0, "e1a6b6f1060f60be9dcb6d28ad7a2a20", 1168310}, {"resource.003", 0, "6c3d1bb26ad532c94046bc9ac49b5ff4", 891295}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformMacintosh, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformMacintosh, 0, GUIO1(GUIO_NOSPEECH) }, // Castle of Dr. Brain - English DOS Non-Interactive Demo // SCI interpreter version 1.000.005 @@ -89,7 +85,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.000", 0, "9780f040d58182994e22d2e34fab85b0", 67367}, {"resource.001", 0, "2af49dbd8f2e1db4ab09f9310dc91259", 570553}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO1(GUIO_NOSPEECH) }, // Castle of Dr. Brain - English DOS 5.25" Floppy EGA (from omer_mor, bug report #3035349) {"castlebrain", "EGA", { @@ -102,7 +98,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.005", 0, "8a5ed3ba96e2eaf18e36fedfaab89419", 297838}, {"resource.006", 0, "dceed92e709cad1bd9582809a235b0a0", 266682}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, // Castle of Dr. Brain - English DOS 3.5" Floppy EGA (from nozomi77, bug report #3405307) {"castlebrain", "EGA", { @@ -112,7 +108,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.002", 0, "de2f182529efaad2c4b510b452ab77ac", 633662}, {"resource.003", 0, "38b4b37febc6b4f5061c461a283df148", 430388}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, // Castle of Dr. Brain - English DOS Floppy (from jvprat) // Executable scanning reports "1.000.044", Floppy label reports "1.0, 10.30.91", VERSION file reports "1.000" @@ -123,7 +119,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.001", 0, "d2f5a1be74ed963fa849a76892be5290", 794832}, {"resource.002", 0, "c0c29c51af66d65cb53f49e785a2d978", 1280907}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) }, // Castle of Dr. Brain - English DOS Floppy 1.1 {"castlebrain", "", { @@ -132,7 +128,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.001", 0, "13e81e1839cd7b216d2bb5615c1ca160", 796776}, {"resource.002", 0, "930e416bec196b9703a331d81b3d66f2", 1283812}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) }, // Castle of Dr. Brain - English DOS Floppy 1.000 // Reported by graxer in bug report #3037942 @@ -147,7 +143,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.006", 0, "1d778a0c65cac9ddbab65495e50a94ee", 335281}, {"resource.007", 0, "063bb8ce4157c778cf30d1c912c006f1", 335631}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) }, // Castle of Dr. Brain - Spanish DOS (also includes english language) // SCI interpreter version 1.000.510 @@ -156,7 +152,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.000", 0, "27ec5fa09cd12a7fd16e86d96a2ed245", 1197694}, {"resource.001", 0, "735be4e58957180cfc807d5e18fdffcd", 1433302}, AD_LISTEND}, - Common::ES_ESP, Common::kPlatformPC, ADGF_ADDENGLISH, GUIO_NOSPEECH }, + Common::ES_ESP, Common::kPlatformPC, ADGF_ADDENGLISH, GUIO1(GUIO_NOSPEECH) }, // Christmas Card 1988 - English DOS // SCI interpreter version 0.000.294 @@ -164,7 +160,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "39485580d34a72997f3d5b3aba4d24f1", 426}, {"resource.001", 0, "11391434f41c834090d7a1e9488ce936", 129739}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, // Christmas Card 1990: The Seasoned Professional - English DOS (16 Colors) // SCI interpreter version 1.000.172 @@ -172,7 +168,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "8f656714a05b94423ac6eb10ee8797d0", 600}, {"resource.001", 0, "acde93e58fca4f7a2a5a220558a94aa8", 272629}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) }, // Christmas Card 1990: The Seasoned Professional - English DOS (256 Colors) // SCI interpreter version 1.000.174 @@ -180,7 +176,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "44b8f45b841b9b5e17e939a35e443988", 600}, {"resource.001", 0, "acde93e58fca4f7a2a5a220558a94aa8", 335362}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) }, // Christmas Card 1992 - English DOS // SCI interpreter version 1.001.055 @@ -188,7 +184,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "f1f8c8a8443f523422af70b4ec85b71c", 318}, {"resource.000", 0, "62fb9256f8e7e6e65a6875efdb7939ac", 203396}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) }, // Codename: Iceman - English Amiga (from www.back2roots.org) // Executable scanning reports "1.002.031" @@ -202,7 +198,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.004", 0, "8613c45fc771d658e5a505b9a4a54f31", 713382}, {"resource.005", 0, "605b67a9ef199a9bb015745e7c004cf4", 478384}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, // Codename: Iceman - English DOS Non-Interactive Demo // Executable scanning reports "0.000.685" @@ -210,7 +206,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "782974f29d8a824782d2d4aea39964e3", 1056}, {"resource.001", 0, "d4b75e280d1c3a97cfef1b0bebff387c", 573647}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, // Codename: Iceman - English DOS (from jvprat) // Executable scanning reports "0.000.685", Floppy label reports "1.033, 6.8.90", VERSION file reports "1.033" @@ -223,7 +219,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.003", 0, "d97a96f1ab91b41cf46a02cc89b0a04e", 624303}, {"resource.004", 0, "8613c45fc771d658e5a505b9a4a54f31", 670883}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, // Codename: Iceman - English DOS (from FRG) // SCI interpreter version 0.000.668 @@ -235,7 +231,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.003", 0, "dc7c5280e7acfaffe6ef2a6c963c5f94", 622118}, {"resource.004", 0, "64f342463f6f35ba71b3509ef696ae3f", 669188}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, // Codename: Iceman - English DOS (supplied by ssburnout in bug report #3049193) // 1.022 9x5.25" (label: Int#0.000.668) @@ -250,7 +246,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.006", 0, "08050329aa113a9f14ed99cbfe3536ec", 232942}, {"resource.007", 0, "64f342463f6f35ba71b3509ef696ae3f", 267811}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, // Codename: Iceman - English DOS 1.023 (from abevi, bug report #2612718) {"iceman", "", { @@ -264,7 +260,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.006", 0, "08050329aa113a9f14ed99cbfe3536ec", 232942}, {"resource.007", 0, "64f342463f6f35ba71b3509ef696ae3f", 267702}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) }, // Conquests of Camelot - English Amiga (from www.back2roots.org) // Executable scanning reports "1.002.030" @@ -279,7 +275,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.005", 0, "c6e551bdc24f0acc193159038d4ca767", 605882}, {"resource.006", 0, "8f880a536908ab496bbc552f7f5c3738", 585255}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, // Conquests of Camelot - English DOS Non-Interactive Demo // SCI interpreter version 0.000.668 @@ -287,7 +283,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "f4cd75c15be75e04cdca3acda2c0b0ea", 468}, {"resource.001", 0, "4930708722f34bfbaa4945fb08f55f61", 232523}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, // Conquests of Camelot - English DOS (from jvprat) // Executable scanning reports "0.000.685", Floppy label reports "1.001, 0.000.685", VERSION file reports "1.001.000" @@ -299,7 +295,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.003", 0, "8e1a3a8c588007404b532b8dfacc1460", 723712}, {"resource.004", 0, "8e1a3a8c588007404b532b8dfacc1460", 729143}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, // Conquests of Camelot - English DOS // SCI interpreter version 0.000.685 @@ -313,7 +309,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.006", 0, "8e1a3a8c588007404b532b8dfacc1460", 332446}, {"resource.007", 0, "8e1a3a8c588007404b532b8dfacc1460", 358182}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, // Conquests of the Longbow - English Amiga (from www.back2roots.org) // Executable scanning reports "1.005.001" @@ -328,7 +324,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.005", 0, "1c3804e56b114028c5873a35c2f06d13", 653002}, {"resource.006", 0, "f9487732289a4f4966b4e34eea413325", 842817}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO1(GUIO_NOSPEECH) }, // Conquests of the Longbow - English DOS // SCI interpreter version 1.000.510 @@ -342,7 +338,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.005", 0, "d036df0872f2db19bca34601276be2d7", 1154950}, {"resource.006", 0, "b367a6a59f29ee30dde1d88a5a41152d", 1042966}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) }, // Conquests of the Longbow - English DOS Floppy (from jvprat) // Executable scanning reports "1.000.168", Floppy label reports "1.1, 1.13.92", VERSION file reports "1.1" @@ -356,7 +352,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.004", 0, "9cfce07e204a329e94fda8b5657621da", 1261462}, {"resource.005", 0, "21ebe6b39b57a73fc449f67f013765aa", 1284720}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) }, // Conquests of the Longbow - English DOS // SCI interpreter version 1.000.510 @@ -369,7 +365,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.004", 0, "9cfce07e204a329e94fda8b5657621da", 1260237}, {"resource.005", 0, "21ebe6b39b57a73fc449f67f013765aa", 1284609}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) }, // Conquests of the Longbow EGA - English DOS // SCI interpreter version 1.000.510 @@ -382,7 +378,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.004", 0, "b7bb35c027bb424ecefcd122768e5e60", 705631}, {"resource.005", 0, "58942b1aa6d6ffeb66e9f8897fd4435f", 469243}, {"resource.006", 0, "8c767b3939add63d11274065e46aad04", 713158}, - AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, // Conquests of the Longbow DOS 1.0 EGA (4 x 5.25" disks) // Provided by ssburnout in bug report #3046802 @@ -392,7 +388,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.001", 0, "76c729e563809170e6cc8b2f3f6cf0a4", 1196133}, {"resource.002", 0, "8c767b3939add63d11274065e46aad04", 1152478}, {"resource.003", 0, "7025b87e735b1df3f0e9488a621f4333", 1171439}, - AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + AD_LISTEND}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, // Conquests of the Longbow - English DOS Non-Interactive Demo // SCI interpreter version 1.000.510 @@ -400,7 +396,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "cbc5cb73341de1bff1b1e20a640af220", 588}, {"resource.001", 0, "f05a20cc07eee85da8e999d0ac0f596b", 869916}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO1(GUIO_NOSPEECH) }, // Conquests of the Longbow - German DOS (suplied by markcoolio in bug report #2727681, also includes english language) // SCI interpreter version 1.000.510 @@ -414,7 +410,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.005", 0, "d036df0872f2db19bca34601276be2d7", 1176914}, {"resource.006", 0, "b367a6a59f29ee30dde1d88a5a41152d", 1123585}, AD_LISTEND}, - Common::DE_DEU, Common::kPlatformPC, ADGF_ADDENGLISH, GUIO_NOSPEECH }, + Common::DE_DEU, Common::kPlatformPC, ADGF_ADDENGLISH, GUIO1(GUIO_NOSPEECH) }, // Eco Quest - English DOS Non-Interactive Demo (from FRG) // Executable scanning reports "x.yyy.zzz" @@ -423,7 +419,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "c819e171359b7c95f4c13b846d5c034e", 873}, {"resource.001", 0, "baf9393a9bfa73098adb501e5bc5487b", 657518}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO1(GUIO_NOSPEECH) }, // Eco Quest - English DOS CD 1.1 // SCI interpreter version 1.001.064 @@ -431,7 +427,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "a4b73d5d2b55bdb6e44345e99c8fbdd0", 4804}, {"resource.000", 0, "d908dbef56816ac6c60dd145fdeafb2b", 3536046}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_CD, GUIO_NONE }, + Common::EN_ANY, Common::kPlatformPC, ADGF_CD, GUIO0() }, // Eco Quest - English DOS CD 1.1 // SCI interpreter version 1.001.064 @@ -441,7 +437,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "a4b73d5d2b55bdb6e44345e99c8fbdd0", 4804}, {"resource.000", 0, "d908dbef56816ac6c60dd145fdeafb2b", 3536046}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformWindows, ADGF_CD, GUIO_MIDIGM }, + Common::EN_ANY, Common::kPlatformWindows, ADGF_CD, GUIO1(GUIO_MIDIGM) }, // Eco Quest - English DOS Floppy // SCI interpreter version 1.000.510 @@ -452,7 +448,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.002", 0, "28fe9b4f0567e71feb198bc9f3a2c605", 1241816}, {"resource.003", 0, "f3146df0ad4297f5ce35aa8c4753bf6c", 586832}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) }, // Eco Quest - English DOS Floppy // SCI interpreter version 1.000.510 @@ -463,7 +459,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.002", 0, "323b3b12f43d53f27d259beb225f0aa7", 1129316}, {"resource.003", 0, "83ac03e4bddb2c1ac2d36d2a587d0536", 1145616}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) }, // Eco Quest - German DOS Floppy (supplied by markcoolio in bug report #2723744, also includes english language) // SCI interpreter version 1.000.510 @@ -474,7 +470,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.002", 0, "02d7d0411f7903aacb3bc8b0f8ca8a9a", 1202581}, {"resource.003", 0, "84dd11b6825255671c703aee5ceff620", 1175835}, AD_LISTEND}, - Common::DE_DEU, Common::kPlatformPC, ADGF_ADDENGLISH, GUIO_NOSPEECH }, + Common::DE_DEU, Common::kPlatformPC, ADGF_ADDENGLISH, GUIO1(GUIO_NOSPEECH) }, // Eco Quest - Spanish DOS Floppy (from jvprat, also includes english language) // Executable scanning reports "1.ECO.013", VERSION file reports "1.000, 11.12.92" @@ -486,7 +482,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.002", 0, "2d21a1d2dcbffa551552e3e0725d2284", 1186033}, {"resource.003", 0, "84dd11b6825255671c703aee5ceff620", 1174993}, AD_LISTEND}, - Common::ES_ESP, Common::kPlatformPC, ADGF_ADDENGLISH, GUIO_NOSPEECH }, + Common::ES_ESP, Common::kPlatformPC, ADGF_ADDENGLISH, GUIO1(GUIO_NOSPEECH) }, // Eco Quest - French DOS Floppy (from Strangerke, also includes english language) // SCI interpreter version 1.ECO.013 @@ -497,7 +493,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.002", 0, "b836c6ee9de67d814ac5d1b05f5b9858", 1173872}, {"resource.003", 0, "f8f767f9d6351432621c6e54c1b2ba8c", 1141520}, AD_LISTEND}, - Common::FR_FRA, Common::kPlatformPC, ADGF_ADDENGLISH, GUIO_NOSPEECH }, + Common::FR_FRA, Common::kPlatformPC, ADGF_ADDENGLISH, GUIO1(GUIO_NOSPEECH) }, // Eco Quest 2 - English DOS Non-Interactive Demo // SCI interpreter version 1.001.055 @@ -505,7 +501,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "607cfa0d8a03b7d348c06ee727e3d939", 1321}, {"resource.000", 0, "dd6f614c43c029f063e93cd243af90a4", 525992}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO1(GUIO_NOSPEECH) }, // Eco Quest 2 - English DOS Floppy (supplied by markcoolio in bug report #2723761) // SCI interpreter version 1.001.065 @@ -513,7 +509,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "28fb7b6abb9fc1cb8882d7c2e701b63f", 5658}, {"resource.000", 0, "cc1d17e5637528dbe4a812699e1cbfc6", 4208192}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) }, // Eco Quest 2 - French DOS Floppy (from Strangerke) // SCI interpreter version 1.001.081 @@ -521,7 +517,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "c22ab8b33c339c138b6b1697b77b9e79", 5588}, {"resource.000", 0, "1c4093f7248240329121fdf8c0d59152", 4231946}, AD_LISTEND}, - Common::FR_FRA, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::FR_FRA, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) }, // Eco Quest 2 - Spanish DOS Floppy (supplied by umbrio in bug report #3313962) {"ecoquest2", "Floppy", { @@ -529,7 +525,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.000", 0, "1c4093f7248240329121fdf8c0d59152", 4209150}, {"resource.msg", 0, "eff8be1925d42288de55e405983e9314", 117810}, AD_LISTEND}, - Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::ES_ESP, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) }, // Freddy Pharkas - English DOS demo (from FRG) // SCI interpreter version 1.001.069 @@ -537,7 +533,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "97aa9fcfe84c9993a64debd28c32393a", 1909}, {"resource.000", 0, "5ea8e7a3ea10cce6efd5c106dc62fd8c", 867724}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO1(GUIO_NOSPEECH) }, // Freddy Pharkas - English CD DOS (from FRG) // SCI interpreter version 1.001.132 @@ -545,7 +541,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "d46b282f228a67ba13bd4b4009e95f8f", 6058}, {"resource.000", 0, "ee3c64ffff0ba9fb08bea2624631c598", 5490246}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_CD, GUIO_NONE }, + Common::EN_ANY, Common::kPlatformPC, ADGF_CD, GUIO0() }, // Freddy Pharkas - English DOS Floppy (updated information from markcoolio in bug reports #2723773 and #2724720) // Executable scanning reports "1.cfs.081" @@ -555,7 +551,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.000", 0, "96b07e9b914dba1c8dc6c78a176326df", 5233230}, {"resource.msg", 0, "554f65315d851184f6e38211489fdd8f", -1}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) }, // Freddy Pharkas - Windows (supplied by abevi in bug report #2612718) // Executable scanning reports "1.cfs.081" @@ -564,7 +560,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "a32674e7fbf7b213b4a066c8037f16b6", 5816}, {"resource.000", 0, "fed4808fdb72486908ac7ad0044b14d8", 5233230}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformWindows, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformWindows, 0, GUIO1(GUIO_NOSPEECH) }, // Freddy Pharkas - German DOS Floppy (from Tobis87, updated information from markcoolio in bug reports #2723772 and #2724720) // Executable scanning reports "1.cfs.081" @@ -574,7 +570,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.000", 0, "96b07e9b914dba1c8dc6c78a176326df", 5233230}, {"resource.msg", 0, "304b5a5781800affd2235152a5794fa8", -1}, AD_LISTEND}, - Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::DE_DEU, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) }, // Freddy Pharkas - Spanish DOS (from jvprat) // Executable scanning reports "1.cfs.081", VERSION file reports "1.000, March 30, 1995" @@ -587,7 +583,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.003", 0, "05acdc256c742e79c50b9fe7ec2cc898", 863310}, {"resource.msg", 0, "45b5bf74933ac3727e4cc844446dc052", 796156}, AD_LISTEND}, - Common::ES_ESP, Common::kPlatformPC, ADGF_CD, GUIO_NONE }, + Common::ES_ESP, Common::kPlatformPC, ADGF_CD, GUIO0() }, // Freddy Pharkas - Spanish DOS (from jvprat) // Executable scanning reports "1.cfs.081", VERSION file reports "1.000, March 30, 1995" @@ -597,7 +593,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.000", 0, "96b07e9b914dba1c8dc6c78a176326df", 5233230}, {"resource.msg", 0, "45b5bf74933ac3727e4cc844446dc052", 796156}, AD_LISTEND}, - Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::ES_ESP, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) }, // Freddy Pharkas - English DOS CD Demo // SCI interpreter version 1.001.095 @@ -605,14 +601,14 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "a62a7eae85dd1e6b07f39662b278437e", 1918}, {"resource.000", 0, "4962a3c4dd44e36e78ea4a7a374c2220", 957382}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NONE }, + Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO0() }, // Freddy Pharkas - English Macintosh {"freddypharkas", "", { {"Data1", 0, "ef7cbd62727989818f1cfae69c9fd61d", 3038492}, {"Data2", 0, "2424b418f7d52c385cea4701f529c69a", 4721732}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformMacintosh, ADGF_MACRESFORK, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformMacintosh, ADGF_MACRESFORK, GUIO1(GUIO_NOSPEECH) }, // Fun Seeker's Guide - English DOS // SCI interpreter version 0.000.506 @@ -620,7 +616,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "7ee6859ef74314f6d91938c3595348a9", 282}, {"resource.001", 0, "f1e680095424e31f7fae1255d36bacba", 40692}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, // Gabriel Knight - English DOS CD Demo // SCI interpreter version 1.001.092 @@ -628,7 +624,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "39645952ae0ed8072c7e838f31b75464", 2490}, {"resource.000", 0, "eb3ed7477ca4110813fe1fcf35928561", 1718450}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NONE }, + Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO0() }, #ifdef ENABLE_SCI32 // Gabriel Knight - English DOS Floppy @@ -637,7 +633,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "372d059f75856afa6d73dd84cbb8913d", 10783}, {"resource.000", 0, "69b7516962510f780d38519cc15fcc7c", 13022630}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE, GUIO1(GUIO_NOSPEECH) }, // Gabriel Knight - English DOS Floppy (supplied my markcoolio in bug report #2723777) // SCI interpreter version 2.000.000 @@ -645,7 +641,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "65e8c14092e4c9b3b3538b7602c8c5ec", 10783}, {"resource.000", 0, "69b7516962510f780d38519cc15fcc7c", 13022630}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE, GUIO1(GUIO_NOSPEECH) }, // Gabriel Knight - English DOS Floppy // SCI interpreter version 2.000.000, VERSION file reports "1.0\nGabriel Knight\n11/22/10:33 pm\n\x1A" @@ -653,7 +649,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "ef41df08cf2c1f680216cdbeed0f8311", 10783}, {"resource.000", 0, "69b7516962510f780d38519cc15fcc7c", 13022630}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE, GUIO1(GUIO_NOSPEECH) }, // Gabriel Knight - German DOS Floppy (supplied my markcoolio in bug report #2723775) // SCI interpreter version 2.000.000 @@ -661,7 +657,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "ad6508b0296b25c07b1f58828dc33696", 10789}, {"resource.000", 0, "091cf08910780feabc56f8551b09cb36", 13077029}, AD_LISTEND}, - Common::DE_DEU, Common::kPlatformPC, ADGF_UNSTABLE, GUIO_NOSPEECH }, + Common::DE_DEU, Common::kPlatformPC, ADGF_UNSTABLE, GUIO1(GUIO_NOSPEECH) }, // Gabriel Knight - English DOS CD (from jvprat) // Executable scanning reports "2.000.000", VERSION file reports "01.100.000" @@ -669,7 +665,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "372d059f75856afa6d73dd84cbb8913d", 10996}, {"resource.000", 0, "69b7516962510f780d38519cc15fcc7c", 12581736}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_CD | ADGF_UNSTABLE, GUIO_NONE }, + Common::EN_ANY, Common::kPlatformPC, ADGF_CD | ADGF_UNSTABLE, GUIO0() }, // Gabriel Knight - English Windows CD (from jvprat) // Executable scanning reports "2.000.000", VERSION file reports "01.100.000" @@ -677,7 +673,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "372d059f75856afa6d73dd84cbb8913d", 10996}, {"resource.000", 0, "69b7516962510f780d38519cc15fcc7c", 12581736}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformWindows, ADGF_CD | ADGF_UNSTABLE, GUIO_NONE }, + Common::EN_ANY, Common::kPlatformWindows, ADGF_CD | ADGF_UNSTABLE, GUIO1(GUIO_NOASPECT) }, // Gabriel Knight - German DOS CD (from Tobis87) // SCI interpreter version 2.000.000 @@ -685,7 +681,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "a7d3e55114c65647310373cb390815ba", 11392}, {"resource.000", 0, "091cf08910780feabc56f8551b09cb36", 13400497}, AD_LISTEND}, - Common::DE_DEU, Common::kPlatformPC, ADGF_CD | ADGF_UNSTABLE, GUIO_NONE }, + Common::DE_DEU, Common::kPlatformPC, ADGF_CD | ADGF_UNSTABLE, GUIO0() }, // Gabriel Knight - Spanish DOS CD (from jvprat) // Executable scanning reports "2.000.000", VERSION file reports "1.000.000, April 13, 1995" @@ -693,7 +689,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "7cb6e9bba15b544ec7a635c45bde9953", 11404}, {"resource.000", 0, "091cf08910780feabc56f8551b09cb36", 13381599}, AD_LISTEND}, - Common::ES_ESP, Common::kPlatformPC, ADGF_CD | ADGF_UNSTABLE, GUIO_NONE }, + Common::ES_ESP, Common::kPlatformPC, ADGF_CD | ADGF_UNSTABLE, GUIO0() }, // Gabriel Knight - French DOS CD (from Hkz) // VERSION file reports "1.000.000, May 3, 1994" @@ -701,7 +697,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "55f909ba93a2515042a08d8a2da8414e", 11392}, {"resource.000", 0, "091cf08910780feabc56f8551b09cb36", 13325145}, AD_LISTEND}, - Common::FR_FRA, Common::kPlatformPC, ADGF_CD | ADGF_UNSTABLE, GUIO_NONE }, + Common::FR_FRA, Common::kPlatformPC, ADGF_CD | ADGF_UNSTABLE, GUIO0() }, // Gabriel Knight - German Windows CD (from Tobis87) // SCI interpreter version 2.000.000 @@ -709,7 +705,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "a7d3e55114c65647310373cb390815ba", 11392}, {"resource.000", 0, "091cf08910780feabc56f8551b09cb36", 13400497}, AD_LISTEND}, - Common::DE_DEU, Common::kPlatformWindows, ADGF_CD | ADGF_UNSTABLE, GUIO_NONE }, + Common::DE_DEU, Common::kPlatformWindows, ADGF_CD | ADGF_UNSTABLE, GUIO1(GUIO_NOASPECT) }, // Gabriel Knight - Spanish Windows CD (from jvprat) // Executable scanning reports "2.000.000", VERSION file reports "1.000.000, April 13, 1995" @@ -717,7 +713,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "7cb6e9bba15b544ec7a635c45bde9953", 11404}, {"resource.000", 0, "091cf08910780feabc56f8551b09cb36", 13381599}, AD_LISTEND}, - Common::ES_ESP, Common::kPlatformWindows, ADGF_CD | ADGF_UNSTABLE, GUIO_NONE }, + Common::ES_ESP, Common::kPlatformWindows, ADGF_CD | ADGF_UNSTABLE, GUIO1(GUIO_NOASPECT) }, // Gabriel Knight - English Macintosh {"gk1", "", { @@ -726,7 +722,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"Data3", 0, "f25068b408b09275d8b698866462f578", 3677599}, {"Data4", 0, "1cceebbe411b26c860a74f91c337fdf3", 3230086}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformMacintosh, ADGF_MACRESFORK | ADGF_UNSTABLE, GUIO_NONE }, + Common::EN_ANY, Common::kPlatformMacintosh, ADGF_MACRESFORK | ADGF_UNSTABLE, GUIO1(GUIO_NOASPECT) }, // Gabriel Knight 2 - English Windows Non-Interactive Demo // Executable scanning reports "2.100.002" @@ -734,7 +730,15 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "e0effce11c4908f4b91838741716c83d", 1351}, {"resource.000", 0, "d04cfc7f04b6f74d13025378be49ec2b", 4640330}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO | ADGF_UNSTABLE, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO | ADGF_UNSTABLE, GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) }, + + // Gabriel Knight 2 - English DOS (GOG version) - ressci.* merged in ressci.000 + // using Enrico Rolfi's HD/DVD installer: http://gkpatches.vogons.zetafleet.com/ + {"gk2", "", { + {"resmap.000", 0, "b996fa1e57389a1e179a00a0049de1f4", 8110}, + {"ressci.000", 0, "a19fc3604c6e5407abcf03d59ee87217", 168522221}, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE, GUIO1(GUIO_NOASPECT) }, // Gabriel Knight 2 - English DOS (from jvprat) // Executable scanning reports "2.100.002", VERSION file reports "1.1" @@ -752,7 +756,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resmap.006", 0, "ce9359037277b7d7976da185c2fa0aad", 2977}, {"ressci.006", 0, "8e44e03890205a7be12f45aaba9644b4", 60659424}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE, GUIO1(GUIO_NOASPECT) }, // Gabriel Knight 2 - French DOS (6-CDs Sierra Originals reedition) // Executable scanning reports "2.100.002", VERSION file reports "1.0" @@ -770,8 +774,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resmap.006", 0, "11b2e722170b8c93fdaa5428e2c7676f", 3001}, {"ressci.006", 0, "4037d941aec39d2e654e20960429aefc", 60568486}, AD_LISTEND}, - Common::FR_FRA, Common::kPlatformPC, ADGF_UNSTABLE, - GUIO_NOSPEECH }, + Common::FR_FRA, Common::kPlatformPC, ADGF_UNSTABLE, GUIO1(GUIO_NOASPECT) }, // Gabriel Knight 2 - English Macintosh // NOTE: This only contains disc 1 files (as well as the persistent file: @@ -783,7 +786,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"Data4", 0, "8b843c62eb53136a855d6e0087e3cb0d", 5889553}, {"Data5", 0, "f9fcf9ab2eb13b2125c33a1cda03a093", 14349984}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformMacintosh, ADGF_MACRESFORK | ADGF_UNSTABLE, GUIO_NONE }, + Common::EN_ANY, Common::kPlatformMacintosh, ADGF_MACRESFORK | ADGF_UNSTABLE, GUIO1(GUIO_NOASPECT) }, #endif // ENABLE_SCI32 @@ -795,7 +798,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.002", 0, "e0dd44069a62a463fd124974b915f10d", 342149}, {"resource.003", 0, "e0dd44069a62a463fd124974b915f10d", 328925}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) }, // Hoyle 1 - English DOS (supplied by wibble92 in bug report #2644547) // SCI interpreter version 0.000.530 @@ -805,7 +808,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.002", 0, "e0dd44069a62a463fd124974b915f10d", 342309}, {"resource.003", 0, "e0dd44069a62a463fd124974b915f10d", 328912}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, // Hoyle 1 - English DOS (supplied by merkur in bug report #2719227) // SCI interpreter version 0.000.530 @@ -813,14 +816,14 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "1034a218943d12f1f36e753fa10c95b8", 4386}, {"resource.001", 0, "e0dd44069a62a463fd124974b915f10d", 518308}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, // Hoyle 1 3.5' - English DOS (supplied by eddydrama in bug report #3052366 and dinnerx in bug report #3090841) {"hoyle1", "", { {"resource.map", 0, "0af9a3dcd72a091960de070432e1f524", 4386}, {"resource.001", 0, "e0dd44069a62a463fd124974b915f10d", 518127}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, #if 0 // TODO: unknown if these files are corrupt // Hoyle 1 - English Amiga (from www.back2roots.org) @@ -830,7 +833,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.001", 0, "e0dd44069a62a463fd124974b915f10d", 218755}, {"resource.002", 0, "e0dd44069a62a463fd124974b915f10d", 439502}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO1(GUIO_NOSPEECH) }, #endif // Hoyle 2 - English DOS @@ -840,7 +843,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.001", 0, "8f2dd70abe01112eca464cda818b5eb6", 98138}, {"resource.002", 0, "8f2dd70abe01112eca464cda818b5eb6", 196631}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, // Hoyle 2 - English DOS (supplied by ssburnout in bug report #3049193) // 1.000.011 1x3.5" (label:Int#6.21.90) @@ -848,7 +851,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "db0ba08b953e9904a4960ad99cd29c20", 1356}, {"resource.001", 0, "8f2dd70abe01112eca464cda818b5eb6", 216315}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, // Hoyle 2 - English Amiga (from www.back2roots.org) // Executable scanning reports "1.002.032" @@ -857,7 +860,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "62ed48d20c580e5a98f102f7cd93706a", 1356}, {"resource.001", 0, "8f2dd70abe01112eca464cda818b5eb6", 222704}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO1(GUIO_NOSPEECH) }, // Hoyle 2 - English Macintosh // Executable scanning reports "x.yyy.zzz" @@ -865,7 +868,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "1af1d3aa3cf564f93477c9f87e53f495", 1728}, {"resource.001", 0, "b73b8131669d69d41a326415e4519138", 482882}, {NULL, 0, NULL, 0}}, - Common::EN_ANY, Common::kPlatformMacintosh, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformMacintosh, 0, GUIO1(GUIO_NOSPEECH) }, #if 0 // TODO: unknown if these files are corrupt // Hoyle 3 - English Amiga (from www.back2roots.org) @@ -876,7 +879,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.000", 0, "595b6039ea1356e7f96a52c58eedcf22", 355791}, {"resource.001", 0, "143df8aef214a2db34c2d48190742012", 632273}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO1(GUIO_NOSPEECH) }, #endif // Hoyle 3 - English DOS Non-Interactive Demo @@ -886,7 +889,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "0d06cacc87dc21a08cd017e73036f905", 735}, {"resource.001", 0, "24db2bccda0a3c43ac4a7b5edb116c7e", 797678}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO1(GUIO_NOSPEECH) }, // Hoyle 3 - English DOS Floppy (from jvprat) // Executable scanning reports "x.yyy.zzz", Floppy label reports "1.0, 11.2.91", VERSION file reports "1.000" @@ -896,7 +899,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.000", 0, "6ef28cac094dcd97fdb461662ead6f92", 541845}, {"resource.001", 0, "0a98a268ee99b92c233a0d7187c1f0fa", 845795}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) }, // Hoyle 3 - English DOS Floppy (supplied by eddydrama in bug report #3038837) {"hoyle3", "", { @@ -907,7 +910,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.003", 0, "97cfd72633f8f9b2a0b1d4116cf3ee81", 346116}, {"resource.004", 0, "2884fb91b225fabd9ca87ea231293b48", 351218}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) }, // Hoyle 3 EGA - English DOS Floppy 1.0 (supplied by abevi in bug report #2612718) {"hoyle3", "EGA", { @@ -915,14 +918,14 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.000", 0, "6ef28cac094dcd97fdb461662ead6f92", 319905}, {"resource.001", 0, "0a98a268ee99b92c233a0d7187c1f0fa", 526438}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, // Hoyle 4 (Hoyle Classic Card Games) - English DOS Demo {"hoyle4", "Demo", { {"resource.map", 0, "60f764020a6b788bbbe415dbc2ccb9f3", 931}, {"resource.000", 0, "5fe3670e3ddcd4f85c10013b5453141a", 615522}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO1(GUIO_NOSPEECH) }, // Hoyle 4 (Hoyle Classic Card Games) - English DOS Demo // SCI interpreter version 1.001.200 (just a guess) @@ -931,7 +934,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "662087cb383e52e3cc4ae7ecb10e20aa", 938}, {"resource.000", 0, "24c10844792c54d476d272213cbac300", 675252}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO1(GUIO_NOSPEECH) }, // Hoyle 4 (Hoyle Classic Card Games) - English DOS/Win // Supplied by abevi in bug report #3039291 @@ -939,7 +942,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "2b577c975cc8d8d43f61b6a756129fe3", 4352}, {"resource.000", 0, "43e2c15ce436aab611a462ad0603e12d", 2000132}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) }, // Hoyle 4 (Hoyle Classic Card Games) - English Macintosh Floppy // VERSION file reports "2.0" @@ -947,7 +950,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"Data1", 0, "99575fae4579540a314bbedd72d51e8c", 7682887}, {"Data2", 0, "7d4bf5bdf3c02edbf35cb8471c84ec13", 1539134}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformMacintosh, ADGF_MACRESFORK, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformMacintosh, ADGF_MACRESFORK, GUIO1(GUIO_NOSPEECH) }, // Jones in the Fast Lane EGA - English DOS // SCI interpreter version 1.000.172 (not 100% sure FIXME) @@ -956,14 +959,14 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.001", 0, "bac3ec6cb3e3920984ab0f32becf5163", 202105}, {"resource.002", 0, "b86daa3ba2784d1502da881eedb80d9b", 341771}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, // Jones in the Fast Lane EGA - English DOS (supplied by EddyDrama in bug report #3038761) {"jones", "EGA", { {"resource.map", 0, "8e92cf319180cc8b5b87b2ce93a4fe22", 1602}, {"resource.001", 0, "bac3ec6cb3e3920984ab0f32becf5163", 511528}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, // Jones in the Fast Lane VGA - English DOS // SCI interpreter version 1.000.172 @@ -972,7 +975,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.001", 0, "bac3ec6cb3e3920984ab0f32becf5163", 313476}, {"resource.002", 0, "b86daa3ba2784d1502da881eedb80d9b", 719747}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) }, // Jones in the Fast Lane VGA - English DOS (supplied by omer_mor in bug report #3037054) // VERSION file reports "1.000.060" @@ -980,14 +983,14 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "db175ab494ab0666f19ab8f2597a8e49", 1602}, {"resource.001", 0, "bac3ec6cb3e3920984ab0f32becf5163", 994487}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) }, // Jones in the Fast Lane - English DOS CD {"jones", "CD", { {"resource.map", 0, "459f5b04467bc2107aec02f5c4b71b37", 4878}, {"resource.001", 0, "3876da2ce16fb7dea2f5d943d946fa84", 1652150}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_CD, GUIO_NONE }, + Common::EN_ANY, Common::kPlatformPC, ADGF_CD, GUIO0() }, // Jones in the Fast Lane - English DOS CD // Same entry as the DOS version above. This one is used for the alternate @@ -996,7 +999,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "459f5b04467bc2107aec02f5c4b71b37", 4878}, {"resource.001", 0, "3876da2ce16fb7dea2f5d943d946fa84", 1652150}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformWindows, ADGF_CD, GUIO_MIDIGM }, + Common::EN_ANY, Common::kPlatformWindows, ADGF_CD, GUIO1(GUIO_MIDIGM) }, // King's Quest 1 SCI Remake - English Amiga (from www.back2roots.org) // Executable scanning reports "1.003.007" @@ -1008,7 +1011,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.003", 0, "9ae2a13708d691cd42f9129173c4b39d", 763224}, {"resource.004", 0, "9ae2a13708d691cd42f9129173c4b39d", 820443}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO1(GUIO_NOSPEECH) }, // King's Quest 1 SCI Remake - English DOS Non-Interactive Demo // Executable scanning reports "S.old.010" @@ -1016,7 +1019,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "59b13619078bd47011421468959ee5d4", 954}, {"resource.001", 0, "4cfb9040db152868f7cb6a1e8151c910", 296555}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, // King's Quest 1 SCI Remake - English DOS (from the King's Quest Collection) // Executable scanning reports "S.old.010", VERSION file reports "1.000.051" @@ -1027,7 +1030,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.002", 0, "fed9e0072ffd511d248674e60dee2099", 714062}, {"resource.003", 0, "fed9e0072ffd511d248674e60dee2099", 717478}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, // King's Quest 1 SCI Remake - English DOS (supplied by ssburnout in bug report #3049193) // 1.000.051 9x5.25" (label: INT#9.19.90) @@ -1041,7 +1044,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.006", 0, "fed9e0072ffd511d248674e60dee2099", 351062}, {"resource.007", 0, "fed9e0072ffd511d248674e60dee2099", 330472}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) }, // King's Quest 4 - English Amiga (from www.back2roots.org) // Executable scanning reports "1.002.032" @@ -1054,7 +1057,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.003", 0, "fd16c9c223f7dc5b65f06447615224ff", 683016}, {"resource.004", 0, "3fac034c7d130e055d05bc43a1f8d5f8", 549993}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, // King's Quest 4 - English DOS Non-Interactive Demo // Executable scanning reports "0.000.494" @@ -1062,7 +1065,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "992ac7cc31d3717fe53818a9bb6d1dae", 594}, {"resource.001", 0, "143e1c14f15ad0fbfc714f648a65f661", 205330}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, // King's Quest 4 - English DOS (original boxed release, 3 1/2" disks) // SCI interpreter version 0.000.247 @@ -1073,7 +1076,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.003", 0, "851a62d00972dc4002f472cc0d84e71d", 683145}, {"resource.004", 0, "851a62d00972dc4002f472cc0d84e71d", 649441}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, // King's Quest 4 - English DOS (from the King's Quest Collection) // Executable scanning reports "0.000.502" @@ -1085,7 +1088,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.003", 0, "77615c595388acf3d1df8e107bfb6b52", 707591}, {"resource.004", 0, "77615c595388acf3d1df8e107bfb6b52", 479562}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, // King's Quest 4 - English DOS (supplied by ssburnout in bug report #3049193) // 1.006.003 8x5.25" (label: Int.#0.000.502) @@ -1099,7 +1102,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.006", 0, "6db7de6f93c6ea62dca78abee677f8c0", 324789}, {"resource.007", 0, "6db7de6f93c6ea62dca78abee677f8c0", 334441}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, // King's Quest 4 - English DOS // SCI interpreter version 0.000.274 @@ -1113,7 +1116,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.006", 0, "851a62d00972dc4002f472cc0d84e71d", 333777}, {"resource.007", 0, "851a62d00972dc4002f472cc0d84e71d", 341038}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, // King's Quest 4 - English DOS // SCI interpreter version 0.000.253 @@ -1127,7 +1130,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.006", 0, "0c8566848a76eea19a6d6220914030a7", 337288}, {"resource.007", 0, "0c8566848a76eea19a6d6220914030a7", 343882}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, // King's Quest 4 - English Atari ST (double-sided diskettes) // Game version 1.003.006 (January 12, 1989) @@ -1140,7 +1143,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.003", 0, "a3cdb4848fb859fdd302976fff56490f", 705074}, {"resource.004", 0, "a3cdb4848fb859fdd302976fff56490f", 478366}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformAtariST, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformAtariST, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, // King's Quest 5 - English Amiga (from www.back2roots.org) // Executable scanning reports "1.004.018" @@ -1156,7 +1159,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.006", 0, "26c0c25399b6715fec03fc3e12544fe3", 823048}, {"resource.007", 0, "b914b5901e786327213e779725d30dd1", 778772}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO1(GUIO_NOSPEECH) }, // King's Quest 5 - German Amiga (also includes english language) // Executable scanning reports "1.004.024" @@ -1172,7 +1175,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.006", 0, "56546b20db11a4836f900efa6d3a3e74", 672099}, {"resource.007", 0, "56546b20db11a4836f900efa6d3a3e74", 794194}, AD_LISTEND}, - Common::DE_DEU, Common::kPlatformAmiga, ADGF_ADDENGLISH, GUIO_NOSPEECH }, + Common::DE_DEU, Common::kPlatformAmiga, ADGF_ADDENGLISH, GUIO1(GUIO_NOSPEECH) }, // King's Quest 5 - Italian Amiga (also includes english language) // Executable scanning reports "1.004.024" @@ -1188,7 +1191,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.006", 0, "11cb750f5f816445ad0f4b9f50a4f59a", 672527}, {"resource.007", 0, "11cb750f5f816445ad0f4b9f50a4f59a", 794259}, AD_LISTEND}, - Common::IT_ITA, Common::kPlatformAmiga, ADGF_ADDENGLISH, GUIO_NOSPEECH }, + Common::IT_ITA, Common::kPlatformAmiga, ADGF_ADDENGLISH, GUIO1(GUIO_NOSPEECH) }, // King's Quest 5 - English DOS CD (from the King's Quest Collection) // Executable scanning reports "x.yyy.zzz", VERSION file reports "1.000.052" @@ -1198,7 +1201,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.000", 0, "449471bfd77be52f18a3773c7f7d843d", 571368}, {"resource.001", 0, "b45a581ff8751e052c7e364f58d3617f", 16800210}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_CD, GUIO_NONE }, + Common::EN_ANY, Common::kPlatformPC, ADGF_CD, GUIO0() }, // King's Quest 5 - English DOS CD (from the King's Quest Collection) // Executable scanning reports "x.yyy.zzz", VERSION file reports "1.000.052" @@ -1210,7 +1213,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.000", 0, "449471bfd77be52f18a3773c7f7d843d", 571368}, {"resource.001", 0, "b45a581ff8751e052c7e364f58d3617f", 16800210}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformWindows, ADGF_CD, GUIO_MIDIGM }, + Common::EN_ANY, Common::kPlatformWindows, ADGF_CD, GUIO1(GUIO_MIDIGM) }, // King's Quest 5 - English DOS Floppy // SCI interpreter version 1.000.060 @@ -1225,7 +1228,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.006", 0, "672ede1136e9e401658538e51bd5dc22", 1172619}, {"resource.007", 0, "2f48faf27666b58c276dda20f91f4a93", 1240456}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) }, // King's Quest 5 - English DOS Floppy (supplied by omer_mor in bug report #3036996) // VERSION file reports "0.000.051" @@ -1240,7 +1243,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.006", 0, "06cb3f689836086ebe08b1efc0126592", 921113}, {"resource.007", 0, "252249753c6e850eacceb8af634986d3", 1133608}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) }, // King's Quest 5 EGA (supplied by markcoolio in bug report #2829470) // SCI interpreter version 1.000.060 @@ -1256,7 +1259,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.006", 0, "698c698570cde9015e4d51eb8d2e9db1", 666527}, {"resource.007", 0, "703d8df30e89541af337d7706540d5c4", 541743}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, // King's Quest 5 EGA 1.2M disk version (from LordHoto) // VERSION file reports "0.000.055" @@ -1268,7 +1271,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "53206afb4fd73871a484e83acab80f31", 7608}, {"resource.004", 0, "83568edf7fde18b3eed988bc5d22ceb1", 1188053}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, // King's Quest 5 EGA (supplied by omer_mor in bug report #3035421) // VERSION file reports "0.000.062" @@ -1283,7 +1286,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.006", 0, "698c698570cde9015e4d51eb8d2e9db1", 666541}, {"resource.007", 0, "703d8df30e89541af337d7706540d5c4", 541762}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, // King's Quest V DOS 0.000.062 EGA (5 x 5.25" disks) // Supplied by ssburnout in bug report #3046780 @@ -1295,7 +1298,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.003", 0, "3cca5b2dae8afe94532edfdc98d7edbe", 1092325}, {"resource.004", 0, "8e5c1bc4d738cf7316ff506f59d265e2", 1187803}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, // King's Quest 5 - German DOS Floppy (supplied by markcoolio in bug report #2727101, also includes english language) // SCI interpreter version 1.000.060 @@ -1310,7 +1313,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.006", 0, "d1a75fdc01840664d00366cff6919366", 1208972}, {"resource.007", 0, "c07494f0cce7c05210893938786a955b", 1337361}, AD_LISTEND}, - Common::DE_DEU, Common::kPlatformPC, ADGF_ADDENGLISH, GUIO_NOSPEECH }, + Common::DE_DEU, Common::kPlatformPC, ADGF_ADDENGLISH, GUIO1(GUIO_NOSPEECH) }, // King's Quest 5 - French DOS Floppy (from the King's Quest Collector's Edition 1994, also includes english language) // Supplied by aroenai in bug report #2812611 @@ -1326,7 +1329,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.006", 0, "f7dc85307632ef657ceb1651204f6f51", 1210081}, {"resource.007", 0, "7db4d0a1d8d547c0019cb7d2a6acbdd4", 1338473}, AD_LISTEND}, - Common::FR_FRA, Common::kPlatformPC, ADGF_ADDENGLISH, GUIO_NOSPEECH }, + Common::FR_FRA, Common::kPlatformPC, ADGF_ADDENGLISH, GUIO1(GUIO_NOSPEECH) }, // King's Quest 5 - Italian DOS Floppy (from glorifindel, includes english language) // SCI interpreter version 1.000.060 @@ -1341,7 +1344,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.006", 0, "8eeabd92af71e766e323db2100879102", 1209325}, {"resource.007", 0, "dc10c107e0923b902326a040b9c166b9", 1337859}, AD_LISTEND}, - Common::IT_ITA, Common::kPlatformPC, ADGF_ADDENGLISH, GUIO_NOSPEECH }, + Common::IT_ITA, Common::kPlatformPC, ADGF_ADDENGLISH, GUIO1(GUIO_NOSPEECH) }, // King's Quest 5 - Polish DOS Floppy (supplied by jacek909 in bug report #2725722, includes english language?!) // SCI interpreter version 1.000.060 @@ -1356,7 +1359,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.006", 0, "da82e4beb744731d0a151f1d4922fafa", 1170456}, {"resource.007", 0, "431def14ca29cdb5e6a5e84d3f38f679", 1240176}, AD_LISTEND}, - Common::PL_POL, Common::kPlatformPC, ADGF_ADDENGLISH, GUIO_NOSPEECH }, + Common::PL_POL, Common::kPlatformPC, ADGF_ADDENGLISH, GUIO1(GUIO_NOSPEECH) }, // King's Quest 5 - English Macintosh // VERSION file reports "1.000.055" @@ -1371,7 +1374,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.006", 0, "3d22904a374c192f51e5665b74364133", 1264079}, {"resource.007", 0, "ffe17e23d5833a79f3695addfc149a56", 1361965}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformMacintosh, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformMacintosh, 0, GUIO1(GUIO_NOSPEECH) }, // King's Quest 5 - FM-Towns (supplied by abevi in bug report #3038720) {"kq5", "", { @@ -1379,7 +1382,13 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.000", 0, "71afd220d46bde1109c58e6acc0f3a01", 469094}, {"resource.001", 0, "72a569f46f1abf2d9d2b1526ad3799c3", 12808839}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformFMTowns, 0, GUIO_NONE }, + Common::EN_ANY, Common::kPlatformFMTowns, 0, GUIO2(GUIO_NOASPECT, GUIO_MIDITOWNS) }, + {"kq5", "", { + {"resource.map", 0, "20c7cd248ff1a349ed354568eebd972b", 12733}, + {"resource.000", 0, "71afd220d46bde1109c58e6acc0f3a01", 469094}, + {"resource.001", 0, "72a569f46f1abf2d9d2b1526ad3799c3", 12808839}, + AD_LISTEND}, + Common::JA_JPN, Common::kPlatformFMTowns, 0, GUIO2(GUIO_NOASPECT, GUIO_MIDITOWNS) }, // King's Quest 5 - Japanese PC-98 Floppy 0.000.015 (supplied by omer_mor in bug report #3073583) {"kq5", "", { @@ -1391,7 +1400,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.004", 0, "e114ce8f884601c43308fb5cbbea4874", 1174129}, {"resource.005", 0, "349ad9438172265d00680075c5a988d0", 1019669}, AD_LISTEND}, - Common::JA_JPN, Common::kPlatformPC98, ADGF_ADDENGLISH, GUIO_NOSPEECH }, + Common::JA_JPN, Common::kPlatformPC98, ADGF_ADDENGLISH, GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) }, // King's Quest 6 - English DOS Non-Interactive Demo // Executable scanning reports "1.001.055", VERSION file reports "1.000.000" @@ -1401,7 +1410,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.000", 0, "535b1b920441ec73f42eaa4ccfd47b89", 264116}, {"resource.msg", 0, "54d1fdc936f98c81f9e4c19e04fb1510", 8260}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO1(GUIO_NOSPEECH) }, // King's Quest 6 - English DOS Floppy // SCI interpreter version 1.001.054 @@ -1410,7 +1419,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.000", 0, "f2b7f753992c56a0c7a08d6a5077c895", 7863324}, {"resource.msg", 0, "3cf5de44de36191f109d425b8450efc8", 258590}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) }, // King's Quest 6 - German DOS Floppy (supplied by markcoolio in bug report #2727156) // SCI interpreter version 1.001.054 @@ -1419,7 +1428,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.000", 0, "f2b7f753992c56a0c7a08d6a5077c895", 7863324}, {"resource.msg", 0, "756297b2155db9e43f621c6f6fb763c3", 282822}, AD_LISTEND}, - Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::DE_DEU, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) }, // King's Quest 6 - English DOS CD (from the King's Quest Collection) // Executable scanning reports "1.cfs.158", VERSION file reports "1.034 9/11/94 - KQ6 version 1.000.00G" @@ -1428,7 +1437,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "7a550ebfeae2575ca00d47703a6a774c", 9215}, {"resource.000", 0, "233394a5f33b475ae5975e7e9a420865", 8376352}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_CD, GUIO_NONE }, + Common::EN_ANY, Common::kPlatformPC, ADGF_CD, GUIO0() }, // King's Quest 6 - English Windows CD (from the King's Quest Collection) // Executable scanning reports "1.cfs.158", VERSION file reports "1.034 9/11/94 - KQ6 version 1.000.00G" @@ -1437,7 +1446,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "7a550ebfeae2575ca00d47703a6a774c", 9215}, {"resource.000", 0, "233394a5f33b475ae5975e7e9a420865", 8376352}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformWindows, ADGF_CD, GUIO_NONE }, + Common::EN_ANY, Common::kPlatformWindows, ADGF_CD, GUIO1(GUIO_NOASPECT) }, // King's Quest 6 - Spanish DOS CD (from jvprat) // Executable scanning reports "1.cfs.158", VERSION file reports "1.000.000, July 5, 1994" @@ -1447,7 +1456,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.000", 0, "4da3ad5868a775549a7cc4f72770a58e", 8537260}, {"resource.msg", 0, "41eed2d3893e1ca6c3695deba4e9d2e8", 267102}, AD_LISTEND}, - Common::ES_ESP, Common::kPlatformPC, ADGF_CD, GUIO_NONE }, + Common::ES_ESP, Common::kPlatformPC, ADGF_CD, GUIO0() }, // King's Quest 6 - English Macintosh Floppy // VERSION file reports "1.0" @@ -1455,7 +1464,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"Data1", 0, "a183fc0c22fcbd9be4c8800d974b5599", 3892124}, {"Data2", 0, "b3722460dfd3097a1fbaf99a21ad8ea5", 15031272}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformMacintosh, ADGF_MACRESFORK, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformMacintosh, ADGF_MACRESFORK, GUIO1(GUIO_NOSPEECH) }, #ifdef ENABLE_SCI32 @@ -1466,7 +1475,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.000", 0, "4948e4e1506f1e1c4e1d47abfa06b7f8", 204385195}, {"resource.map", 0, "40ccafb2195301504eba2e4f4f2c7f3d", 18925}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) }, // King's Quest 7 - English Windows (from the King's Quest Collection) // Executable scanning reports "2.100.002", VERSION file reports "1.4" @@ -1474,7 +1483,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "2be9ab94429c721af8e05c507e048a15", 18697}, {"resource.000", 0, "eb63ea3a2c2469dc2d777d351c626404", 203882535}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) }, // King's Quest 7 - English DOS (from FRG) // SCI interpreter version 2.100.002, VERSION file reports "2.00b" @@ -1482,7 +1491,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "8676b0fbbd7362989a029fe72fea14c6", 18709}, {"resource.000", 0, "51c1ead1163e19a2de8f121c39df7a76", 200764100}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE, GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) }, // King's Quest 7 - English Windows (from FRG) // SCI interpreter version 2.100.002, VERSION file reports "2.00b" @@ -1490,7 +1499,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "8676b0fbbd7362989a029fe72fea14c6", 18709}, {"resource.000", 0, "51c1ead1163e19a2de8f121c39df7a76", 200764100}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) }, // King's Quest 7 - German Windows (supplied by markcoolio in bug report #2727402) // SCI interpreter version 2.100.002 @@ -1498,7 +1507,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "838b9ff132bd6962026fee832e8a7ddb", 18697}, {"resource.000", 0, "eb63ea3a2c2469dc2d777d351c626404", 206626576}, AD_LISTEND}, - Common::DE_DEU, Common::kPlatformPC, ADGF_UNSTABLE, GUIO_NOSPEECH }, + Common::DE_DEU, Common::kPlatformPC, ADGF_UNSTABLE, GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) }, // King's Quest 7 - Spanish DOS (from jvprat) // Executable scanning reports "2.100.002", VERSION file reports "2.00" @@ -1506,7 +1515,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "0b62693cbe87e3aaca3e8655a437f27f", 18709}, {"resource.000", 0, "51c1ead1163e19a2de8f121c39df7a76", 200764100}, AD_LISTEND}, - Common::ES_ESP, Common::kPlatformPC, ADGF_UNSTABLE, GUIO_NOSPEECH }, + Common::ES_ESP, Common::kPlatformPC, ADGF_UNSTABLE, GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) }, // King's Quest 7 - English DOS Non-Interactive Demo // SCI interpreter version 2.100.002 @@ -1514,7 +1523,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "b44f774108d63faa1d021101221c5a54", 1690}, {"resource.000", 0, "d9659d2cf0c269c6a9dc776707f5bea0", 2433827}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO | ADGF_UNSTABLE, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO | ADGF_UNSTABLE, GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) }, #endif // ENABLE_SCI32 @@ -1530,7 +1539,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.004", 0, "aa553977f7e5804081de293800d3bcce", 695067}, {"resource.005", 0, "bfd870d51dc97729f0914095f58e6957", 676881}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, // Laura Bow - English Atari ST (from jvprat) // Executable scanning reports "1.002.030", Floppy label reports "1.000.062, 9.23.90" @@ -1542,7 +1551,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.003", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 667365}, {"resource.004", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 683737}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformAtariST, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformAtariST, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, // Laura Bow - English DOS Non-Interactive Demo // Executable scanning reports "x.yyy.zzz" @@ -1550,7 +1559,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "e625726268ff4e123ada11f31f0249f3", 768}, {"resource.001", 0, "0c8912290af0890f8d95faeb4ddb2d68", 333031}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, // Laura Bow - English DOS 3.5" Floppy (from "The Roberta Williams Anthology"/1996) // SCI interpreter version 0.000.631 @@ -1561,7 +1570,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.003", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 667468}, {"resource.004", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 683807}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, // Laura Bow - English DOS (from FRG) // SCI interpreter version 0.000.631 @@ -1575,7 +1584,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.006", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 328390}, {"resource.007", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 317687}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, // Laura Bow 2 - English DOS Non-Interactive Demo (from FRG) // Executable scanning reports "x.yyy.zzz" @@ -1584,7 +1593,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "24dffc5db1d88c7999f13e8767ed7346", 855}, {"resource.000", 0, "2b2b1b4f7584f9b38fd13f6ab95634d1", 781912}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO1(GUIO_NOSPEECH) }, // Laura Bow 2 - English DOS Floppy // Executable scanning reports "2.000.274" @@ -1593,7 +1602,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "610bfd9a852004222f0faaf5fc9e630a", 6489}, {"resource.000", 0, "57084910bc923bff5d6d9bc1b56e9604", 5035964}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) }, // Laura Bow 2 - English DOS CD (from "The Roberta Williams Antology"/1996) // Executable scanning reports "1.001.072", VERSION file reports "1.1" (from jvprat) @@ -1602,7 +1611,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "a70945e61ba7ac7bfea6b7bd72c6aec5", 7274}, {"resource.000", 0, "82578b8d5a7e09c4c58891ca49fae35b", 5598672}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_CD, GUIO_NONE }, + Common::EN_ANY, Common::kPlatformPC, ADGF_CD, GUIO0() }, // Laura Bow 2 v1.1 - French DOS Floppy (from Hkz) {"laurabow2", "", { @@ -1610,7 +1619,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.000", 0, "57084910bc923bff5d6d9bc1b56e9604", 5028766}, {"resource.msg", 0, "0fceedfbdd85a4bc7851fdd9dd2d2f19", 278253}, AD_LISTEND}, - Common::FR_FRA, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::FR_FRA, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) }, // Laura Bow 2 v1.1 - German DOS Floppy (from Tobis87, updated info from markcoolio in bug report #2723787, updated info from #2797962)) // Executable scanning reports "2.000.274" @@ -1619,7 +1628,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.000", 0, "57084910bc923bff5d6d9bc1b56e9604", 5028766}, {"resource.msg", 0, "795c928cd00dfec9fbc62ebcd12e1f65", 303185}, AD_LISTEND}, - Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::DE_DEU, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) }, // Laura Bow 2 - Spanish DOS CD (from jvprat) // Executable scanning reports "2.000.274", VERSION file reports "1.000.000, May 10, 1994" @@ -1628,7 +1637,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.000", 0, "57084910bc923bff5d6d9bc1b56e9604", 5028766}, {"resource.msg", 0, "71f1f0cd9f082da2e750c793a8ed9d84", 286141}, AD_LISTEND}, - Common::ES_ESP, Common::kPlatformPC, ADGF_CD, GUIO_NONE }, + Common::ES_ESP, Common::kPlatformPC, ADGF_CD, GUIO0() }, // Larry 1 EGA Remake - English DOS (from spookypeanut) // SCI interpreter version 0.000.510 (or 0.000.577?) @@ -1639,7 +1648,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.002", 0, "24c958bc922b07f91e25e8c93aa01fcf", 491230}, {"resource.003", 0, "685cd6c1e05a695ab1e0db826337ee2a", 553279}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, #if 0 // The resource.002 file, contained in disk 3, is broken in this version @@ -1657,7 +1666,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.002", 0, "5790ac0505f7ca98d4567132b875eb1e", 681041}, {"resource.003", 0, "4a34c3367c2fe7eb380d741374da1989", 572251}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO1(GUIO_NOSPEECH) }, #endif // Larry 1 VGA Remake - English DOS (from spookypeanut) @@ -1668,7 +1677,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.001", 0, "ec20246209d7b19f38989261e5c8f5b8", 1111226}, {"resource.002", 0, "85d6935ef77e6b0e16bc307640a0d913", 1088312}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) }, // Larry 1 VGA Remake - English DOS (from FRG) // SCI interpreter version 1.000.510 @@ -1678,7 +1687,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.001", 0, "d34cadb11e1aefbb497cf91bc1d3baa7", 1114688}, {"resource.002", 0, "85b030bb66d5342b0a068f1208c431a8", 1078443}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) }, // Larry 1 VGA Remake - English Macintosh (from omer_mor, bug report #3328262) {"lsl1sci", "SCI", { @@ -1687,7 +1696,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.001", 0, "aa6f153f70f1e32d1bde465fff08eecf", 1137418}, {"resource.002", 0, "b22c616aa789ebef990290c7ffd86548", 1097477}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformMacintosh, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformMacintosh, 0, GUIO1(GUIO_NOSPEECH) }, // Larry 1 VGA Remake - English DOS Non-Interactive Demo // SCI interpreter version 1.000.084 @@ -1695,7 +1704,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "434e1f6c39d71647b34f0ee57b2bbd68", 444}, {"resource.001", 0, "0c0768215c562d9dace4a5ca53696cf3", 359913}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO1(GUIO_NOSPEECH) }, // Larry 1 VGA Remake - Spanish DOS (from the Leisure Suit Larry Collection, also includes english language) // Executable scanning reports "1.SQ4.057", VERSION file reports "1.000" @@ -1708,7 +1717,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.002", 0, "3fe2a3aec0ed53c7d6db1845a67e3aa2", 1095908}, {"resource.003", 0, "ac175df0ea9a2cba57f0248651856d27", 376556}, AD_LISTEND}, - Common::ES_ESP, Common::kPlatformPC, ADGF_ADDENGLISH, GUIO_NOSPEECH }, + Common::ES_ESP, Common::kPlatformPC, ADGF_ADDENGLISH, GUIO1(GUIO_NOSPEECH) }, // Larry 1 VGA Remake - Russian DOS (also includes english language?!) // Executable scanning reports "1.000.510", VERSION file reports "2.0" @@ -1719,7 +1728,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.001", 0, "bc8ca10c807515d959cbd91f9ba47735", 1123759}, {"resource.002", 0, "b7409ab32bc3bee2d6cce887cd33f2b6", 1092160}, AD_LISTEND}, - Common::RU_RUS, Common::kPlatformPC, ADGF_ADDENGLISH, GUIO_NOSPEECH }, + Common::RU_RUS, Common::kPlatformPC, ADGF_ADDENGLISH, GUIO1(GUIO_NOSPEECH) }, // Larry 1 VGA Remake - Polish DOS (from Polish Leisure Suit Larry Collection, official release) // SCI interpreter version 1.000.577, VERSION file reports "2.1" (this release does NOT include english text) @@ -1727,7 +1736,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "58330a85767e42a2487129913283ab5b", 3228}, {"resource.000", 0, "b6097ff35cdc8469f02150fe2f824198", 4781210}, AD_LISTEND}, - Common::PL_POL, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::PL_POL, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) }, // Larry 2 - English Amiga (from www.back2roots.org) // Executable scanning reports "x.yyy.zzz" @@ -1739,7 +1748,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.003", 0, "a0d4a625311d307257da7fc43d00459d", 570356}, {"resource.004", 0, "a0d4a625311d307257da7fc43d00459d", 717844}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, // Larry 2 - English DOS Non-Interactive Demo // Executable scanning reports "x.yyy.zzz" @@ -1748,7 +1757,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "03dba704bb77da55a91ad27b5a3cac09", 528}, {"resource.001", 0, "9f5520f0297206928df0b0b36493cd33", 127532}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, // Larry 2 - English DOS // SCI interpreter version 0.000.409 @@ -1761,7 +1770,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.005", 0, "4a24443a25e2b1492462a52809605dc2", 277732}, {"resource.006", 0, "4a24443a25e2b1492462a52809605dc2", 345683}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, // Larry 2 - English DOS // SCI interpreter version 0.000.343 @@ -1776,7 +1785,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { //{"resource.006", 0, "96033f57accfca903750413fd09193c8", 345818}, {"resource.006", 0, "96033f57accfca903750413fd09193c8", -1}, // 345818 or 208739 AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, // Larry 2 - English DOS (supplied by ssburnout in bug report #3049193) // 1.000.011 3x3.5" (label: Int. #0.000.343) @@ -1786,7 +1795,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.002", 0, "96033f57accfca903750413fd09193c8", 407014}, {"resource.003", 0, "96033f57accfca903750413fd09193c8", 592834}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, // Larry 2 - English DOS (supplied by ssburnout in bug report #3049193) // 1.002.000 3x3.5" (label: INT#0.000.409) @@ -1796,7 +1805,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.002", 0, "4a24443a25e2b1492462a52809605dc2", 406935}, {"resource.003", 0, "4a24443a25e2b1492462a52809605dc2", 592533}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, // Larry 3 - English Amiga (from www.back2roots.org) // Executable scanning reports "1.002.032" @@ -1810,7 +1819,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.004", 0, "f408e59cbee1457f042e5773b8c53951", 651634}, {"resource.005", 0, "433911eb764089d493aed1f958a5615a", 524259}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO1(GUIO_NOSPEECH) }, // Larry 3 - English DOS // SCI interpreter version 0.000.572 @@ -1821,7 +1830,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.003", 0, "f18441027154292836b973c655fa3175", 506807}, {"resource.004", 0, "f18441027154292836b973c655fa3175", 513651}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, // Larry 3 - English DOS (supplied by ssburnout in bug report #3049193) // 1.021 8x5.25" (label: Int#5.15.90) @@ -1835,7 +1844,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.006", 0, "f18441027154292836b973c655fa3175", 282649}, {"resource.007", 0, "f18441027154292836b973c655fa3175", 257178}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, // Larry 3 - English DOS // SCI interpreter version 0.000.572 @@ -1849,7 +1858,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.006", 0, "f18441027154292836b973c655fa3175", 282465}, {"resource.007", 0, "f18441027154292836b973c655fa3175", 257174}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, // Larry 3 - English DOS Non-Interactive Demo // SCI interpreter version 0.000.530 @@ -1858,7 +1867,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.001", 0, "f773d79b93dfd4052ec8c1cc64c1e6ab", 76525}, {"resource.002", 0, "f773d79b93dfd4052ec8c1cc64c1e6ab", 268299}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, // Larry 3 - German DOS (from Tobis87, updated info from markcoolio in bug report #2723832, also includes english language) // Executable scanning reports "S.old.123" @@ -1870,7 +1879,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.003", 0, "3827a9b17b926e12dcc336860f50612a", 587036}, {"resource.004", 0, "3827a9b17b926e12dcc336860f50612a", 691932}, AD_LISTEND}, - Common::DE_DEU, Common::kPlatformPC, ADGF_ADDENGLISH, GUIO_NOSPEECH }, + Common::DE_DEU, Common::kPlatformPC, ADGF_ADDENGLISH, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, // Larry 3 - French DOS (provided by richiefs in bug report #2670691, also includes english language) // Executable scanning reports "S.old.123" @@ -1882,7 +1891,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.003", 0, "65f1bdaa20f6d0470e9d969f22473873", 586921}, {"resource.004", 0, "65f1bdaa20f6d0470e9d969f22473873", 690826}, AD_LISTEND}, - Common::FR_FRA, Common::kPlatformPC, ADGF_ADDENGLISH, GUIO_NOSPEECH }, + Common::FR_FRA, Common::kPlatformPC, ADGF_ADDENGLISH, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, // Larry 3 1.050 Fr/En (9 x 5.25" disks) // Provided by ssburnout in bug report #3046779 @@ -1896,7 +1905,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.006", 0, "65f1bdaa20f6d0470e9d969f22473873", 325292}, {"resource.007", 0, "65f1bdaa20f6d0470e9d969f22473873", 308982}, AD_LISTEND}, - Common::FR_FRA, Common::kPlatformPC, ADGF_ADDENGLISH, GUIO_NOSPEECH }, + Common::FR_FRA, Common::kPlatformPC, ADGF_ADDENGLISH, GUIO1(GUIO_NOSPEECH) }, // Larry 5 - English Amiga // Executable scanning reports "1.004.023" @@ -1911,7 +1920,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.005", 0, "f8b2d1137bb767e5d232056b99dd69eb", 623621}, {"resource.006", 0, "bafc64e3144f115dc58c6aee02de98fb", 715598}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO1(GUIO_NOSPEECH) }, // Larry 5 - German Amiga (also includes english language) // Executable scanning reports "1.004.024" @@ -1927,7 +1936,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.006", 0, "bafc64e3144f115dc58c6aee02de98fb", 754966}, {"resource.007", 0, "59eba83ad465b08d763b44f86afa86f6", 683135}, AD_LISTEND}, - Common::DE_DEU, Common::kPlatformAmiga, ADGF_ADDENGLISH, GUIO_NOSPEECH }, + Common::DE_DEU, Common::kPlatformAmiga, ADGF_ADDENGLISH, GUIO1(GUIO_NOSPEECH) }, // Larry 5 - English DOS Non-Interactive Demo (from FRG) // SCI interpreter version 1.000.181 @@ -1935,7 +1944,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "efe8d3f45ce4f6bd9a6643e0ac8d2a97", 504}, {"resource.001", 0, "8bd8d9c0b5f455ee1269d63ce86c50dd", 531380}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO1(GUIO_NOSPEECH) }, // Larry 5 - English DOS (from spookypeanut) // SCI interpreter version 1.000.510 @@ -1950,7 +1959,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.006", 0, "dda27ce00682aa76198dac124bbbe334", 1024810}, {"resource.007", 0, "ac443fae1285fb359bf2b2bc6a7301ae", 1030656}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) }, // Larry 5 - English Macintosh (from omer_mor, bug report #3328257) {"lsl5", "", { @@ -1964,7 +1973,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.006", 0, "dda27ce00682aa76198dac124bbbe334", 1110043}, {"resource.007", 0, "ac443fae1285fb359bf2b2bc6a7301ae", 989801}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformMacintosh, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformMacintosh, 0, GUIO1(GUIO_NOSPEECH) }, // Larry 5 - German DOS (from Tobis87) // SCI interpreter version T.A00.196 @@ -1979,7 +1988,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.006", 0, "dda27ce00682aa76198dac124bbbe334", 1021774}, {"resource.007", 0, "ac443fae1285fb359bf2b2bc6a7301ae", 993408}, AD_LISTEND}, - Common::DE_DEU, Common::kPlatformPC, ADGF_ADDENGLISH, GUIO_NOSPEECH }, + Common::DE_DEU, Common::kPlatformPC, ADGF_ADDENGLISH, GUIO1(GUIO_NOSPEECH) }, // Larry 5 - French DOS (provided by richiefs in bug report #2670691) // Executable scanning reports "1.lsl5.019" @@ -1995,7 +2004,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.006", 0, "dda27ce00682aa76198dac124bbbe334", 946540}, {"resource.007", 0, "ac443fae1285fb359bf2b2bc6a7301ae", 958842}, AD_LISTEND}, - Common::FR_FRA, Common::kPlatformPC, ADGF_ADDENGLISH, GUIO_NOSPEECH }, + Common::FR_FRA, Common::kPlatformPC, ADGF_ADDENGLISH, GUIO1(GUIO_NOSPEECH) }, // Larry 5 - Spanish DOS (from the Leisure Suit Larry Collection) // Executable scanning reports "1.ls5.006", VERSION file reports "1.000, 4/21/92" @@ -2011,7 +2020,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.006", 0, "dda27ce00682aa76198dac124bbbe334", 1015136}, {"resource.007", 0, "ac443fae1285fb359bf2b2bc6a7301ae", 987222}, AD_LISTEND}, - Common::ES_ESP, Common::kPlatformPC, ADGF_ADDENGLISH, GUIO_NOSPEECH }, + Common::ES_ESP, Common::kPlatformPC, ADGF_ADDENGLISH, GUIO1(GUIO_NOSPEECH) }, // Larry 5 - Italian DOS Floppy (from glorifindel) // SCI interpreter version 1.000.510 (just a guess) @@ -2019,7 +2028,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "a99776df795127f387cb35dae872d4e4", 5919}, {"resource.000", 0, "a8989a5a89e7d4f702b26b378c7a357a", 7001981}, AD_LISTEND}, - Common::IT_ITA, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::IT_ITA, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) }, // Larry 5 1.0 EGA DOS (8 x 3.5" disks) // Provided by ssburnout in bug report #3046806 @@ -2034,7 +2043,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.006", 0, "f6046a8445422f17d40b1b10ab21ebf3", 568551}, {"resource.007", 0, "640ee65595d40372ef95462f2c1ae28a", 593429}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, // Larry 5 EGA // Supplied by omer_mor in bug report #3049771 @@ -2045,7 +2054,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.002", 0, "5a55af4e40728b1a8103dc47ad2afa8d", 1100539}, {"resource.003", 0, "16f4d8fb1b526125edaca4fc6cbb7530", 1064563}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, // Larry 6 - English DOS (from spookypeanut) // SCI interpreter version 1.001.113 @@ -2053,7 +2062,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "bb8a39d9e2a77ba449a1e591109ad9a8", 6973}, {"resource.000", 0, "4462fe48c7452d98fddcec327a3e738d", 5789138}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) }, // Larry 6 - English/German/French DOS CD - LOWRES // SCI interpreter version 1.001.115 @@ -2061,7 +2070,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "0b91234b7112782962cb480b7791b6e2", 7263}, {"resource.000", 0, "57d5fe8bb9e044158514476ea7678eb0", 5754790}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_CD, GUIO_NONE }, + Common::EN_ANY, Common::kPlatformPC, ADGF_CD, GUIO0() }, // Larry 6 - German DOS CD - LOWRES (provided by richiefs in bug report #2670691) // SCI interpreter version 1.001.115 @@ -2069,7 +2078,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "bafe85f32738854135991d4324ad147e", 7268}, {"resource.000", 0, "f6cbc6da7b90ea135883e0759848ca2c", 5773160}, AD_LISTEND}, - Common::DE_DEU, Common::kPlatformPC, ADGF_CD, GUIO_NONE }, + Common::DE_DEU, Common::kPlatformPC, ADGF_CD, GUIO0() }, // Larry 6 - French DOS CD - LOWRES (provided by richiefs in bug report #2670691) // SCI interpreter version 1.001.115 @@ -2077,7 +2086,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "97797ea775baaf18a1907d357d3c0ea6", 7268}, {"resource.000", 0, "f6cbc6da7b90ea135883e0759848ca2c", 5776092}, AD_LISTEND}, - Common::FR_FRA, Common::kPlatformPC, ADGF_CD, GUIO_NONE }, + Common::FR_FRA, Common::kPlatformPC, ADGF_CD, GUIO0() }, // Larry 6 - Spanish DOS - LOWRES (from the Leisure Suit Larry Collection) // Executable scanning reports "1.001.113", VERSION file reports "1.000, 11.06.93, FIVE PATCHES ADDED TO DISK 6 ON 11-18-93" @@ -2085,7 +2094,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "633bf8f42170b6271019917c8009989b", 6943}, {"resource.000", 0, "7884a8db9253e29e6b37a2651fd90ba3", 5733116}, AD_LISTEND}, - Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::ES_ESP, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) }, // Crazy Nick's Software Picks: Leisure Suit Larry's Casino - English DOS (from the Leisure Suit Larry Collection) // Executable scanning reports "1.001.029", VERSION file reports "1.000" @@ -2093,60 +2102,60 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "194f1578f2624db813c9072359ad1639", 783}, {"resource.001", 0, "3733433b517ec3d14a3331d9ab3842ae", 344830}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) }, // Crazy Nick's Software Picks: King Graham's Board Game Challenge {"cnick-kq", "", { {"resource.map", 0, "44bc538a5cd24b39ffccc967c0ebf84d", 1137}, {"resource.001", 0, "470e7a4a3504635e70b623c44461e1ac", 451272}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) }, // Crazy Nick's Software Picks: Parlor Games with Laura Bow {"cnick-laurabow", "", { {"resource.map", 0, "3b826bfe64f8ff1ccf30eef93cd2f727", 999}, {"resource.001", 0, "985ac8db6f636f2b4334c04b0fbb44fb", 336698}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) }, // Crazy Nick's Software Picks: Robin Hood's Game of Skill and Chance {"cnick-longbow", "", { {"resource.map", 0, "4a5c81f485a2416bde12978506f2fb5f", 897}, {"resource.001", 0, "ef16dc9e867eb8eeb5b13e110b90bd4b", 571466}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) }, // Crazy Nick's Software Picks: Roger Wilco's Spaced Out Game Pack {"cnick-sq", "", { {"resource.map", 0, "b4d95b02d84e297441bd999d34eaa6b1", 879}, {"resource.001", 0, "82ff2b64a60117886fbcd6a3a8c977c6", 364921}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) }, #ifdef ENABLE_SCI32 // Larry 6 - English/German DOS CD - HIRES // SCI interpreter version 2.100.002 - {"lsl6hires", "", { + {"lsl6hires", "Hi-res", { {"resource.map", 0, "0c0804434ea62278dd15032b1947426c", 8872}, {"resource.000", 0, "9a9f4870504444cda863dd14d077a680", 18520872}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE, GUIO_NONE }, + Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE, GUIO1(GUIO_NOASPECT) }, // Larry 6 - German DOS CD - HIRES (provided by richiefs in bug report #2670691) // SCI interpreter version 2.100.002 - {"lsl6hires", "", { + {"lsl6hires", "Hi-res", { {"resource.map", 0, "badfdf446ffed569a310d2c63a249421", 8896}, {"resource.000", 0, "bd944d2b06614a5b39f1586906f0ee88", 18534274}, AD_LISTEND}, - Common::DE_DEU, Common::kPlatformPC, ADGF_UNSTABLE, GUIO_NONE }, + Common::DE_DEU, Common::kPlatformPC, ADGF_UNSTABLE, GUIO1(GUIO_NOASPECT) }, // Larry 6 - French DOS CD - HIRES (provided by richiefs in bug report #2670691) // SCI interpreter version 2.100.002 - {"lsl6hires", "", { + {"lsl6hires", "Hi-res", { {"resource.map", 0, "d184e9aa4f2d4b5670ddb3669db82cda", 8896}, {"resource.000", 0, "bd944d2b06614a5b39f1586906f0ee88", 18538987}, AD_LISTEND}, - Common::FR_FRA, Common::kPlatformPC, ADGF_UNSTABLE, GUIO_NONE }, + Common::FR_FRA, Common::kPlatformPC, ADGF_UNSTABLE, GUIO1(GUIO_NOASPECT) }, // Larry 7 - English DOS Demo (provided by richiefs in bug report #2670691) // SCI interpreter version 2.100.002 @@ -2154,7 +2163,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"ressci.000", 0, "5cc6159688b2dc03790a67c90ccc67f9", 10195878}, {"resmap.000", 0, "6a2b2811eef82e87cde91cf1de845af8", 2695}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO | ADGF_UNSTABLE, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO | ADGF_UNSTABLE, GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) }, #ifdef ENABLE_SCI3_GAMES // Larry 7 - English DOS CD (from spookypeanut) @@ -2163,7 +2172,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resmap.000", 0, "eae93e1b1d1ccc58b4691c371281c95d", 8188}, {"ressci.000", 0, "89353723488219e25589165d73ed663e", 66965678}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE, GUIO_NONE }, + Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE, GUIO1(GUIO_NOASPECT) }, // Larry 7 - German DOS (from Tobis87) // SCI interpreter version 3.000.000 @@ -2171,7 +2180,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resmap.000", 0, "c11e6bfcfc2f2d05da47e5a7df3e9b1a", 8188}, {"ressci.000", 0, "a8c6817bb94f332ff498a71c8b47f893", 66971724}, AD_LISTEND}, - Common::DE_DEU, Common::kPlatformPC, ADGF_UNSTABLE, GUIO_NOSPEECH }, + Common::DE_DEU, Common::kPlatformPC, ADGF_UNSTABLE, GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) }, // Larry 7 - French DOS (provided by richiefs in bug report #2670691) // SCI interpreter version 3.000.000 @@ -2179,7 +2188,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resmap.000", 0, "4407849fd52fe3efb0c30fba60cd5cd4", 8206}, {"ressci.000", 0, "dc37c3055fffbefb494ff22b145d377b", 66964472}, AD_LISTEND}, - Common::DE_DEU, Common::kPlatformPC, ADGF_UNSTABLE, GUIO_NOSPEECH }, + Common::DE_DEU, Common::kPlatformPC, ADGF_UNSTABLE, GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) }, // Larry 7 - Italian DOS CD (from glorifindel) // SCI interpreter version 3.000.000 @@ -2187,7 +2196,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resmap.000", 0, "9852a97141f789413f29bf956052acdb", 8212}, {"ressci.000", 0, "440b9fed89590abb4e4386ed6f948ee2", 67140181}, AD_LISTEND}, - Common::IT_ITA, Common::kPlatformPC, ADGF_UNSTABLE, GUIO_NONE }, + Common::IT_ITA, Common::kPlatformPC, ADGF_UNSTABLE, GUIO1(GUIO_NOASPECT) }, // Larry 7 - Spanish DOS (from the Leisure Suit Larry Collection) // Executable scanning reports "3.000.000", VERSION file reports "1.0s" @@ -2195,7 +2204,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resmap.000", 0, "8f3d603e1acc834a5d598b30cdfc93f3", 8188}, {"ressci.000", 0, "32792f9bc1bf3633a88b382bb3f6e40d", 67071418}, AD_LISTEND}, - Common::ES_ESP, Common::kPlatformPC, ADGF_UNSTABLE, GUIO_NOSPEECH }, + Common::ES_ESP, Common::kPlatformPC, ADGF_UNSTABLE, GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) }, #endif // Lighthouse - English Windows Demo (from jvprat) @@ -2204,7 +2213,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "543124606352bfa5e07696ddf2a669be", 64}, {"resource.000", 0, "5d7714416b612463d750fb9c5690c859", 28952}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO | ADGF_UNSTABLE, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO | ADGF_UNSTABLE, GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) }, #ifdef ENABLE_SCI3_GAMES // Lighthouse - English Windows Demo @@ -2213,7 +2222,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resmap.000", 0, "3bdee7a16926975a4729f75cf6b80a92", 1525}, {"ressci.000", 0, "3c585827fa4a82f4c04a56a0bc52ccee", 11494351}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO | ADGF_UNSTABLE, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO | ADGF_UNSTABLE, GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) }, // Lighthouse - English DOS (from jvprat) // Executable scanning reports "3.000.000", VERSION file reports "1.1" @@ -2223,7 +2232,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resmap.002", 0, "c68db5333f152fea6ca2dfc75cad8b34", 7573}, {"ressci.002", 0, "175468431a979b9f317c294ce3bc1430", 94628315}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE, GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) }, // Lighthouse - Spanish DOS (from jvprat) // Executable scanning reports "3.000.000", VERSION file reports "1.1" @@ -2233,7 +2242,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resmap.002", 0, "e7dc85884a2417e2eff9de0c63dd65fa", 7630}, {"ressci.002", 0, "3c8d627c555b0e3e4f1d9955bc0f0df4", 94631127}, AD_LISTEND}, - Common::ES_ESP, Common::kPlatformPC, ADGF_UNSTABLE, GUIO_NOSPEECH }, + Common::ES_ESP, Common::kPlatformPC, ADGF_UNSTABLE, GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) }, #endif // ENABLE_SCI3_GAMES #endif // ENABLE_SCI32 @@ -2244,7 +2253,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.000", 0, "8be56a3a88c065ee00c02c0e29199f3a", 14643}, {"resource.001", 0, "9e33566515b18bee7915db448063bba2", 871853}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO1(GUIO_NOSPEECH) }, // Mixed-Up Fairy Tales - English DOS Floppy EGA (from omer_mor, bug report #3035350) {"fairytales", "EGA", { @@ -2255,7 +2264,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.003", 0, "509b2467ba779100d5933ed51a9ae32f", 560255}, {"resource.004", 0, "93afc85d5ffa60ea555d6cc336d22c03", 651109}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, // Mixed-Up Fairy Tales v1.000 - English DOS (supplied by markcoolio in bug report #2723791) // Executable scanning reports "1.000.145" @@ -2267,7 +2276,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.003", 0, "b1288e0821ee358d1ffe877e5900c8ec", 1047565}, {"resource.004", 0, "f79daa70390d73746742ffcfc3dc4471", 937580}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) }, // Mixed-Up Fairy Tales - English DOS Floppy (from jvprat) // Executable scanning reports "1.000.145", Floppy label reports "1.0, 11.13.91", VERSION file reports "1.000" @@ -2278,7 +2287,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.002", 0, "564f516d991032e781492592a4eaa275", 1414142}, {"resource.003", 0, "dd6cef0c592eadb7e6be9a25307c57a2", 1344719}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) }, // Mixed-Up Mother Goose - English Amiga (from www.back2roots.org) // Executable scanning reports "1.003.009" @@ -2288,7 +2297,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.001", 0, "fb552ae550ca1dac19ed8f6a3767612d", 262885}, {"resource.002", 0, "fb552ae550ca1dac19ed8f6a3767612d", 817191}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO1(GUIO_NOSPEECH) }, // Mixed-Up Mother Goose - English DOS Floppy EGA (from omer_mor, bug report #3035354) {"mothergoose", "EGA", { @@ -2296,7 +2305,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.001", 0, "d893892d62b3f061357291d66775e360", 239906}, {"resource.002", 0, "d893892d62b3f061357291d66775e360", 719398}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, // Mixed-Up Mother Goose - English DOS Floppy EGA (supplied by ssburnout in bug report #3049193) // 1.011 5x5.25" (label: Int#8.2.90) @@ -2309,7 +2318,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.004", 0, "dbbc22f124533ce308bc386b08956326", 146251}, {"resource.005", 0, "2ba5348e7fad641b9c4c7ff7c7cf4e68", 110979}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, // Mixed-Up Mother Goose v2.000 - English DOS Floppy (supplied by markcoolio in bug report #2723795) // Executable scanning reports "1.001.031" @@ -2317,7 +2326,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "52aae15e493cafd1da7e1c9b657a5bb9", 7026}, {"resource.000", 0, "b7ecd8ae9e254e80310b5a668b276e6e", 2948975}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) }, // Mixed-Up Mother Goose - English DOS CD (from jvprat) // Executable scanning reports "x.yyy.zzz" @@ -2326,7 +2335,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "1c7f311b0a2c927b2fbe81ae341fb2f6", 5790}, {"resource.001", 0, "5a0ed1d745855148364de1b3be099bac", 4369438}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_CD, GUIO_NONE }, + Common::EN_ANY, Common::kPlatformPC, ADGF_CD, GUIO0() }, // Mixed-Up Mother Goose - English Windows Interactive Demo // Executable scanning reports "x.yyy.zzz" @@ -2334,14 +2343,19 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "87f9dc1cafc4d4fa835fb2f00cf3a6ef", 4560}, {"resource.001", 0, "5a0ed1d745855148364de1b3be099bac", 2070072}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO, GUIO1(GUIO_NOSPEECH) }, // Mixed-Up Mother Goose - FM-Towns (supplied by abevi in bug report #3038720) {"mothergoose256", "", { {"resource.map", 0, "b11e971ccd2040bebba59dfb409a08ef", 5772}, {"resource.001", 0, "d49625d9b8005ec01c852f8322a82867", 4330713}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformFMTowns, 0, GUIO_NONE }, + Common::EN_ANY, Common::kPlatformFMTowns, 0, GUIO1(GUIO_NOASPECT) }, + {"mothergoose256", "", { + {"resource.map", 0, "b11e971ccd2040bebba59dfb409a08ef", 5772}, + {"resource.001", 0, "d49625d9b8005ec01c852f8322a82867", 4330713}, + AD_LISTEND}, + Common::JA_JPN, Common::kPlatformFMTowns, 0, GUIO1(GUIO_NOASPECT) }, #ifdef ENABLE_SCI32 // Mixed-Up Mother Goose Deluxe - English Windows/DOS CD (supplied by markcoolio in bug report #2723810) @@ -2350,7 +2364,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "5159a1578c4306bfe070a3e4d8c2e1d3", 4741}, {"resource.000", 0, "1926925c95d82f0999590e93b02887c5", 15150768}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE, GUIO_NONE }, + Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE, GUIO1(GUIO_NOASPECT) }, // Mixed-Up Mother Goose Deluxe - Multilingual Windows CD (English/French/German/Spanish) // Executable scanning reports "2.100.002" @@ -2358,7 +2372,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resmap.000", 0, "ef611af561898dcfea87846919ebf3eb", 4969}, {"ressci.000", 0, "227685bc59d90821978d330713e44a7a", 17205800}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE, GUIO_NONE }, + Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE, GUIO1(GUIO_NOASPECT) }, #endif // ENABLE_SCI32 // Ms. Astro Chicken - English DOS @@ -2367,7 +2381,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "5b457cbe5042f557e5b610148171f6c0", 1158}, {"resource.001", 0, "453ea81ef66a50cbe33ce06302afe47f", 229737}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) }, #ifdef ENABLE_SCI32 // Phantasmagoria - English DOS (from jvprat) @@ -2388,7 +2402,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resmap.007", 0, "afbd16ea77869a720afa1c5371de107d", 7972}, //{"ressci.007", 0, "3aae6559aa1df273bc542d5ac6330d75", 25859038}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE, GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) }, // Phantasmagoria - English DOS Demo // Executable scanning reports "2.100.002" @@ -2396,7 +2410,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resmap.001", 0, "416138651ea828219ca454cae18341a3", 11518}, {"ressci.001", 0, "3aae6559aa1df273bc542d5ac6330d75", 65844612}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO | ADGF_UNSTABLE, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO | ADGF_UNSTABLE, GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) }, // Phantasmagoria - English DOS/Windows (GOG version) - ressci.* merged in ressci.000 // Windows executable scanning reports "2.100.002" - "Sep 19 1995 15:09:43" @@ -2407,7 +2421,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"ressci.000", 0, "cd5967f9b9586e3380645961c0765be3", 116822037}, {"resmap.000", 0, "3cafc1c6a53945c1f3babbfd6380c64c", 16468}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE, GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) }, // Phantasmagoria - English Macintosh // NOTE: This only contains disc 1 files (as well as the two persistent files: @@ -2423,7 +2437,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { // Data8-12 are empty {"Data13", 0, "6d2c450fca19a69b5af74ed5b03c0a17", 14923328}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformMacintosh, ADGF_MACRESFORK | ADGF_UNSTABLE, GUIO_NONE }, + Common::EN_ANY, Common::kPlatformMacintosh, ADGF_MACRESFORK | ADGF_UNSTABLE, GUIO1(GUIO_NOASPECT) }, #ifdef ENABLE_SCI3_GAMES // Phantasmagoria 2 - English Windows (from jvprat) @@ -2440,7 +2454,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resmap.005", 0, "8bd5ceeedcbe16dfe55d1b90dcd4be84", 1942}, {"ressci.005", 0, "05f9fe2bee749659acb3cd2c90252fc5", 67905112}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) }, // Phantasmagoria 2 - English DOS (GOG version) - ressci.* merged in ressci.000 // Executable scanning reports "3.000.000" - "Dec 07 1996 09:29:03" @@ -2450,7 +2464,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"ressci.000", 0, "c54f26d9f43f908151263254b6d97053", 108134481}, {"resmap.000", 0, "de154a223a9ef4ea7358b76adc38ef5b", 2956}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) }, #endif // ENABLE_SCI3_GAMES #endif // ENABLE_SCI32 @@ -2461,7 +2475,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "72726dc81c1b4c1110c486be77369bc8", 5179}, {"resource.000", 0, "670d0c53622429f4b11275caf7f8d292", 5459574}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) }, // Pepper - English DOS Non-Interactive Demo // Executable scanning reports "1.001.060", VERSION file reports "1.000" @@ -2469,7 +2483,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "379bb4fb896630b14f2d91ed21e36ba1", 984}, {"resource.000", 0, "118f6c31a93ec7fd9a231c61125229e3", 645494}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO1(GUIO_NOSPEECH) }, // Pepper - English DOS/Windows Interactive Demo // Executable scanning reports "1.001.069", VERSION file reports ".001" @@ -2477,7 +2491,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "975e8df76106a5c13d12ab674f906a02", 2514}, {"resource.000", 0, "e6a918a2dd7a4bcecd8fb389f43287c2", 1698164}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO1(GUIO_NOSPEECH) }, // Pepper - English DOS Interactive Demo // Executable scanning reports "1.001.072", VERSION file reports "1.000" @@ -2485,7 +2499,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "9c9b7b900651a370dd3fb38d478b1798", 2524}, {"resource.000", 0, "e6a918a2dd7a4bcecd8fb389f43287c2", 1713544}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO1(GUIO_NOSPEECH) }, // Police Quest 1 VGA Remake - English DOS (from the Police Quest Collection) // Executable scanning reports "1.001.029", VERSION file reports "2.000" @@ -2493,7 +2507,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "35efa814fb994b1cbdac9611e401da67", 5013}, {"resource.000", 0, "e0d5ddf34eda903a38f0837e2aa7145b", 6401433}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) }, // Police Quest 2 - English Amiga (from www.back2roots.org) // SCI interpreter version 0.000.685 (just a guess) @@ -2504,7 +2518,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.002", 0, "499737c21a28ac026e11ab817100d610", 511099}, {"resource.003", 0, "e008f5d6e2a7c4d4a0da0173e4fa8f8b", 553970}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, // Police Quest 2 - English DOS Non-Interactive Demo // Executable scanning reports "0.000.413" @@ -2512,7 +2526,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "8b77d0d4650c2052b356cece28294b58", 576}, {"resource.001", 0, "376ef6d6eaaeed66e1424bd219c4b9ab", 215398}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, // Police Quest 2 - English DOS (provided by richiefs in bug report #2670691) // SCI interpreter version 0.000.395 @@ -2525,7 +2539,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.005", 0, "77f02def3094af804fd2371db25b7100", 349899}, {"resource.006", 0, "77f02def3094af804fd2371db25b7100", 354991}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, // Police Quest 2 - English DOS (from the Police Quest Collection) // Executable scanning reports "0.000.490" @@ -2535,7 +2549,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.002", 0, "77f02def3094af804fd2371db25b7100", 546000}, {"resource.003", 0, "77f02def3094af804fd2371db25b7100", 591851}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, // Police Quest 2 - English DOS (from FRG) // SCI interpreter version 0.000.395 @@ -2545,7 +2559,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.002", 0, "77f02def3094af804fd2371db25b7100", 542897}, {"resource.003", 0, "77f02def3094af804fd2371db25b7100", 586857}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, // Police Quest 2 English DOS 1.001.006 (supplied by merkur-kun in bug report #3028479) {"pq2", "", { @@ -2554,7 +2568,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.002", 0, "77f02def3094af804fd2371db25b7100", 541261}, {"resource.003", 0, "77f02def3094af804fd2371db25b7100", 587511}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, // Police Quest 2 - Japanese PC-98 (also includes english language) // SCI interpreter version unknown @@ -2564,7 +2578,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.002", 0, "05fdee43a228dd6ea4d1a92ccae3f788", 637662}, {"resource.003", 0, "05fdee43a228dd6ea4d1a92ccae3f788", 684395}, AD_LISTEND}, - Common::JA_JPN, Common::kPlatformPC98, ADGF_ADDENGLISH, GUIO_NOSPEECH }, + Common::JA_JPN, Common::kPlatformPC98, ADGF_ADDENGLISH, GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) }, // Police Quest 3 - English Amiga // Executable scanning reports "1.004.024" @@ -2577,7 +2591,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.003", 0, "630bfa65beb05f743552704ac2899dae", 759891}, {"resource.004", 0, "7b229fbdf30d670d0728cede3e984a7e", 838663}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO1(GUIO_NOSPEECH) }, // Police Quest 3 - German Amiga (also includes english language) // Executable scanning reports "1.004.024" @@ -2591,7 +2605,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.004", 0, "6258d5dd85898d8e218eb8113ebc9059", 722738}, {"resource.005", 0, "6258d5dd85898d8e218eb8113ebc9059", 704485}, AD_LISTEND}, - Common::DE_DEU, Common::kPlatformAmiga, ADGF_ADDENGLISH, GUIO_NOSPEECH }, + Common::DE_DEU, Common::kPlatformAmiga, ADGF_ADDENGLISH, GUIO1(GUIO_NOSPEECH) }, // Police Quest 3 - English DOS (from the Police Quest Collection) // Executable scanning reports "T.A00.178", VERSION file reports "1.00" @@ -2604,7 +2618,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.003", 0, "8791b9eef53edf77c2dac950142221d3", 1159791}, {"resource.004", 0, "1b91e891a3c60a941dac0eecdf83375b", 1143606}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) }, // Police Quest 3 - English DOS Non-Interactive Demo // Executable scanning reports "T.A00.052" @@ -2614,7 +2628,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.000", 0, "277f97771f7a6d89677141f02da313d6", 65150}, {"resource.001", 0, "5c5a551b6c86cce2ee75becb90e0b586", 624411}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO1(GUIO_NOSPEECH) }, // Police Quest 3 - German DOS (supplied by markcoolio in bug report #2723837, also includes english language) // Executable scanning reports "T.A00.178" @@ -2627,7 +2641,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.003", 0, "4836f460f4cfc8de61e2df4c45775504", 1180956}, {"resource.004", 0, "0c3eb84b9755852d9e795e0d5c9373c7", 1171760}, AD_LISTEND}, - Common::DE_DEU, Common::kPlatformPC, ADGF_ADDENGLISH, GUIO_NOSPEECH }, + Common::DE_DEU, Common::kPlatformPC, ADGF_ADDENGLISH, GUIO1(GUIO_NOSPEECH) }, // Police Quest 3 EGA // Reported by musiclyinspired in bug report #3046573 @@ -2640,7 +2654,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.004", 0, "b96a86ab681769e4cbb439670d967ca6", 449682}, {"resource.005", 0, "9e6c53a0e7eef53694d260fade8b1fc7", 724000}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, // Police Quest 4 - English DOS Non-Interactive Demo (from FRG) // SCI interpreter version 1.001.096 @@ -2648,7 +2662,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "be56f87a1c4a13062a30a362df860c2f", 1472}, {"resource.000", 0, "527d5684016e6816157cd15d9071b11b", 1121310}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO1(GUIO_NOSPEECH) }, #ifdef ENABLE_SCI32 // Police Quest 4 - English DOS CD (from the Police Quest Collection) @@ -2657,7 +2671,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "379dfe80ed6bd16c47e4b950c4722eac", 11374}, {"resource.000", 0, "fd316a09b628b7032248139003369022", 18841068}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_CD | ADGF_UNSTABLE, GUIO_NONE }, + Common::EN_ANY, Common::kPlatformPC, ADGF_CD | ADGF_UNSTABLE, GUIO0() }, // Police Quest 4 - German DOS CD (German text, English speech) // Supplied by markcoolio in bug report #3392955 @@ -2665,7 +2679,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "a398076371ed0e1e706c8f9fb9fc7ac5", 11386}, {"resource.000", 0, "6ff21954e0a2c5992279e7eb787c8d56", 18918747}, AD_LISTEND}, - Common::DE_DEU, Common::kPlatformPC, ADGF_CD | ADGF_UNSTABLE, GUIO_NONE }, + Common::DE_DEU, Common::kPlatformPC, ADGF_CD | ADGF_UNSTABLE, GUIO0() }, // Police Quest 4 - English DOS // SCI interpreter version 2.000.000 (a guess?) @@ -2673,7 +2687,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "aed9643158ccf01b71f359db33137f82", 9895}, {"resource.000", 0, "da383857b3be1e4514daeba2524359e0", 15141432}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE, GUIO1(GUIO_NOSPEECH) }, // Police Quest 4 - French DOS (supplied by abevi in bug report #2612718) // SCI interpreter version 2.000.000 @@ -2681,7 +2695,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "008030846edcc7c5c7a812c7f4ae4ceb", 9256}, {"resource.000", 0, "6ba98bd2e436739d87ecd2a9b99cabb4", 14730153}, AD_LISTEND}, - Common::FR_FRA, Common::kPlatformPC, ADGF_UNSTABLE, GUIO_NOSPEECH }, + Common::FR_FRA, Common::kPlatformPC, ADGF_UNSTABLE, GUIO1(GUIO_NOSPEECH) }, // Police Quest 4 - German DOS (supplied by markcoolio in bug report #2723840) // SCI interpreter version 2.000.000 (a guess?) @@ -2689,7 +2703,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "2393ee728ab930b2762cb5889f9b5aff", 9256}, {"resource.000", 0, "6ba98bd2e436739d87ecd2a9b99cabb4", 14730155}, AD_LISTEND}, - Common::DE_DEU, Common::kPlatformPC, ADGF_UNSTABLE, GUIO_NOSPEECH }, + Common::DE_DEU, Common::kPlatformPC, ADGF_UNSTABLE, GUIO1(GUIO_NOSPEECH) }, // Police Quest: SWAT - English DOS/Windows Demo (from jvprat) // Executable scanning reports "2.100.002", VERSION file reports "0.001.200" @@ -2697,7 +2711,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "8c96733ef94c21526792f7ca4e3f2120", 1648}, {"resource.000", 0, "d8892f1b8c56c8f7704325460f49b300", 3676175}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO | ADGF_UNSTABLE, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO | ADGF_UNSTABLE, GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) }, // Police Quest: SWAT - English DOS (from GOG.com) // Executable scanning reports "2.100.002", VERSION file reports "1.0c" @@ -2705,7 +2719,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resmap.000", 0, "1c2563fee189885e29d9348f37306d94", 12175}, {"ressci.000", 0, "b2e1826ca81ce2e7e764587f5a14eee9", 127149181}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE, GUIO_NONE }, + Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE, GUIO1(GUIO_NOASPECT) }, // Police Quest: SWAT - English Windows (from the Police Quest Collection) // Executable scanning reports "2.100.002", VERSION file reports "1.0c" @@ -2720,7 +2734,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resmap.004", 0, "4228038906f041623e65789500b22285", 6835}, {"ressci.004", 0, "b7e619e6ecf62fe65d5116a3a422e5f0", 46223872}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO_NONE }, + Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO1(GUIO_NOASPECT) }, #endif // ENABLE_SCI32 // Quest for Glory 1 / Hero's Quest - English DOS 3.5" Floppy (supplied by merkur in bug report #2718784) @@ -2733,7 +2747,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.003", 0, "7ab2bf8e224b57f75e0cd6e4ba790761", 642203}, {"resource.004", 0, "7ab2bf8e224b57f75e0cd6e4ba790761", 641688}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, // Quest for Glory 1 / Hero's Quest - English DOS 3.5" Floppy (supplied by alonzotg in bug report #3206006) {"qfg1", "", { @@ -2744,7 +2758,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.003", 0, "7ab2bf8e224b57f75e0cd6e4ba790761", 642203}, {"resource.004", 0, "7ab2bf8e224b57f75e0cd6e4ba790761", 641688}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, // Quest for Glory 1 / Hero's Quest - English DOS 5.25" Floppy (supplied by markcoolio in bug report #2723843) // Executable scanning reports "0.000.566" @@ -2759,7 +2773,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.006", 0, "69366c2a2f99917199fe1b60a4fee19d", 267852}, {"resource.007", 0, "7ab2bf8e224b57f75e0cd6e4ba790761", 272747}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, // Quest for Glory 1 / Hero's Quest - English DOS 5.25" Floppy (supplied by ssburnout in bug report #3049193) // 1.001 10x5.25" (label: INT.#0.000.566) @@ -2774,7 +2788,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.006", 0, "69366c2a2f99917199fe1b60a4fee19d", 267852}, {"resource.007", 0, "7ab2bf8e224b57f75e0cd6e4ba790761", 272747}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, // Quest for Glory 1 / Hero's Quest - English DOS 5.25" Floppy (supplied by ssburnout in bug report #3049193) // 1.200 10x5.25" (label: INT#9.10.90) @@ -2789,7 +2803,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.006", 0, "f46690dca714abc8c89357d30e363dd3", 278387}, {"resource.007", 0, "951299a82a8134ed12c5c18118d45c2f", 269173}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, // Quest for Glory 1 / Hero's Quest - English DOS Demo // Executable scanning reports "0.000.685" @@ -2797,7 +2811,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "df34c758cbb9026da175793ff686b0e6", 882}, {"resource.001", 0, "73fbaafdd313b39aeedb80fbf85ecef1", 389884}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, // Quest for Glory 1 - Japanese PC-98 5.25" Floppy (also includes English language) // Executable scanning reports "S.old.201" @@ -2807,7 +2821,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.002", 0, "a21451ef6fa8179bd4b22c4950004c44", 1136968}, {"resource.003", 0, "a21451ef6fa8179bd4b22c4950004c44", 769897}, AD_LISTEND}, - Common::JA_JPN, Common::kPlatformPC98, ADGF_ADDENGLISH, GUIO_NOSPEECH }, + Common::JA_JPN, Common::kPlatformPC98, ADGF_ADDENGLISH, GUIO3(GUIO_NOSPEECH, GUIO_NOASPECT, GUIO_EGAUNDITHER) }, // Quest for Glory 1 - Japanese PC-98 5.25" Floppy (also includes English language) // Executable scanning reports "S.old.201" @@ -2817,7 +2831,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.002", 0, "a21451ef6fa8179bd4b22c4950004c44", 1147121}, {"resource.003", 0, "a21451ef6fa8179bd4b22c4950004c44", 777575}, AD_LISTEND}, - Common::JA_JPN, Common::kPlatformPC98, ADGF_ADDENGLISH, GUIO_NOSPEECH }, + Common::JA_JPN, Common::kPlatformPC98, ADGF_ADDENGLISH, GUIO3(GUIO_NOSPEECH, GUIO_NOASPECT, GUIO_EGAUNDITHER) }, // Quest for Glory 1 - English Amiga // Executable scanning reports "1.002.020" @@ -2831,7 +2845,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.004", 0, "16cd4414c37ae3bb6d6da33dce8e25e8", 689124}, {"resource.005", 0, "5f3386ef2f2b1254e4a066f5d9027324", 609529}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, // Quest for Glory 1 (from abevi, bug report #2612718) {"qfg1", "", { @@ -2842,7 +2856,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.003", 0, "f0af87c60ec869946da442833aa5afa8", 640502}, {"resource.004", 0, "f0af87c60ec869946da442833aa5afa8", 644575}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, // Quest for Glory 1 - English DOS // SCI interpreter version 0.000.629 @@ -2854,7 +2868,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.003", 0, "951299a82a8134ed12c5c18118d45c2f", 640483}, {"resource.004", 0, "951299a82a8134ed12c5c18118d45c2f", 644443}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, // Quest for Glory 1 VGA Remake - English DOS // Executable scanning reports "2.000.411" @@ -2862,7 +2876,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "a731fb6c9c0b282443f7027bc8694d4c", 8469}, {"resource.000", 0, "ecace1a2771846b1a8aa1afdd44111a0", 6570147}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) }, // Quest for Glory 1 VGA Remake - English DOS Non-Interactive Demo (from FRG) // SCI interpreter version 1.001.029 @@ -2870,7 +2884,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "ac0257051c95a59c0cdc0be24d9b11fa", 729}, {"resource.000", 0, "ec6f5cf369054dd3e5392995e9975b9e", 768218}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO1(GUIO_NOSPEECH) }, // Quest for Glory 1 VGA Remake - English Macintosh Floppy // VERSION file reports "2.0" @@ -2878,7 +2892,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"Data1", 0, "106527ff8756e4e1a795d63d23e8b833", 1752358}, {"Data2", 0, "5cdd92033231159c6e9c71d43e9f194d", 6574746}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformMacintosh, ADGF_MACRESFORK, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformMacintosh, ADGF_MACRESFORK, GUIO1(GUIO_NOSPEECH) }, // Quest for Glory 2 - English Amiga // Executable scanning reports "1.003.004" @@ -2894,7 +2908,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.006", 0, "ccf5dba33e5cab6d5872838c0f8db44c", 500039}, {"resource.007", 0, "4c9fc1587545879295cb9627f56a2cb8", 575056}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO1(GUIO_NOSPEECH) }, // Quest for Glory 2 - English (supplied by ssburnout in bug report #3049193) // 1.000 5x5.25" (label: INT#10.31.90) @@ -2906,7 +2920,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.003", 0, "0790f67d87642132be515cab05026baa", 972144}, {"resource.004", 0, "2ac1e6fea9aa1f5b91a06693a67b9766", 982830}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) }, // Quest for Glory 2 - English (supplied by ssburnout in bug report #3049193) // 1.000 9x3.5" (label: INT#10.31.90) @@ -2921,7 +2935,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.006", 0, "5e9deacbdb17198ad844988e04833520", 498593}, {"resource.007", 0, "2ac1e6fea9aa1f5b91a06693a67b9766", 490151}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) }, // Quest for Glory 2 - English (from FRG) // Executable scanning reports "1.000.072" @@ -2933,7 +2947,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.003", 0, "b192607c42f6960ecdf2ad2e4f90e9bc", 972804}, {"resource.004", 0, "cd2de58e27665d5853530de93fae7cd6", 983617}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) }, // Quest for Glory 2 - English DOS // Executable scanning reports "1.000.072" @@ -2948,7 +2962,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.006", 0, "b1944bd664ddbd2859cdaa0c4a0d6281", 507489}, {"resource.007", 0, "cd2de58e27665d5853530de93fae7cd6", 490794}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) }, // Quest for Glory 2 - English DOS Non-Interactive Demo // Executable scanning reports "1.000.046" @@ -2956,7 +2970,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "e75eb86bdd517b3ef709058249986a87", 906}, {"resource.001", 0, "9b098f9e1008abe30e56c93b896494e6", 362123}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO1(GUIO_NOSPEECH) }, // Quest for Glory 3 - English DOS Non-Interactive Demo (from FRG) // Executable scanning reports "1.001.021", VERSION file reports "1.000, 0.001.059, 6.12.92" @@ -2964,7 +2978,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "fd71de9b588a45f085317caacf050e91", 687}, {"resource.000", 0, "b6c69bf6c18bf177492249fe81fc6a6d", 648702}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO1(GUIO_NOSPEECH) }, // Quest for Glory 3 - English DOS // SCI interpreter version 1.001.050 @@ -2972,7 +2986,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "19e2bf9b693932b5e2bb59b9f9ab86c9", 5958}, {"resource.000", 0, "6178ad2e83e58e4671ca03315f7a6498", 5868000}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) }, // Quest for Glory 3 - English DOS (supplied by abevi in bug report #2612718) // SCI interpreter version 1.001.050 @@ -2980,7 +2994,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "62c185d190363d7df06330fa0cc45b36", 5958}, {"resource.000", 0, "6178ad2e83e58e4671ca03315f7a6498", 5867442}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) }, // Quest for Glory 3 - English DOS (supplied by dknute in bug report #3125559) {"qfg3", "", { @@ -2988,7 +3002,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.000", 0, "6178ad2e83e58e4671ca03315f7a6498", 5868042}, {"resource.msg", 0, "27e5419c98ce444253f88c95dced14a9", 246888}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) }, // Quest for Glory 3 - German DOS (supplied by markcoolio in bug report #2723846) // Executable scanning reports "L.rry.083" @@ -2996,7 +3010,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "19e2bf9b693932b5e2bb59b9f9ab86c9", 5958}, {"resource.000", 0, "6178ad2e83e58e4671ca03315f7a6498", 5868042}, AD_LISTEND}, - Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::DE_DEU, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) }, // Quest for Glory 3 - Spanish DOS CD (from jvprat) // Executable scanning reports "L.rry.083", VERSION file reports "1.000.000, June 30, 1994" @@ -3005,7 +3019,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.000", 0, "ba7ac86155e4c531e46cd73c86daa80a", 5884098}, {"resource.msg", 0, "a63974730d294dec0bea10057c36e506", 256014}, AD_LISTEND}, - Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NONE }, + Common::ES_ESP, Common::kPlatformPC, 0, GUIO0() }, // Quest for Glory 3 - Italian DOS // Supplied by ghoost in bug report #3053457 @@ -3014,7 +3028,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.000", 0, "6178ad2e83e58e4671ca03315f7a6498", 5868000}, {"resource.msg", 0, "5a0a896ff3e4a628db38a75eb6c84114", 259018}, AD_LISTEND}, - Common::IT_ITA, Common::kPlatformPC, 0, GUIO_NONE }, + Common::IT_ITA, Common::kPlatformPC, 0, GUIO0() }, // Quest for Glory 4 - English DOS Non-Interactive Demo (from FRG) // SCI interpreter version 1.001.069 (just a guess) @@ -3022,7 +3036,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "1ba7c7ae1efb315326d45cb931569b1b", 922}, {"resource.000", 0, "41ba03f0b188b029132daa3ece0d3e14", 623154}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO1(GUIO_NOSPEECH) }, #ifdef ENABLE_SCI32 // Quest for Glory 4 1.1 Floppy - English DOS (supplied by markcool in bug report #2723852) @@ -3031,7 +3045,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "685bdb1ed47bbbb0e5e25db392da83ce", 9301}, {"resource.000", 0, "f64fd6aa3977939a86ff30783dd677e1", 11004993}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE, GUIO1(GUIO_NOSPEECH) }, // Quest for Glory 4 1.1 Floppy - English DOS (supplied by abevi in bug report #2612718) // SCI interpreter version 2.000.000 @@ -3039,7 +3053,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "d10a4cc177d2091d744e2ad8c049b0ae", 9295}, {"resource.000", 0, "f64fd6aa3977939a86ff30783dd677e1", 11003589}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, ADGF_UNSTABLE, GUIO1(GUIO_NOSPEECH) }, // Quest for Glory 4 1.1 Floppy - German DOS (supplied by markcool in bug report #2723850) // Executable scanning reports "2.000.000", VERSION file reports "1.1" @@ -3047,7 +3061,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "9e0abba8746f40565bc7eb5720522ecd", 9301}, {"resource.000", 0, "57f22cdc54eeb35fce1f26b31b5c3ee1", 11076197}, AD_LISTEND}, - Common::DE_DEU, Common::kPlatformPC, ADGF_UNSTABLE, GUIO_NOSPEECH }, + Common::DE_DEU, Common::kPlatformPC, ADGF_UNSTABLE, GUIO1(GUIO_NOSPEECH) }, // Quest for Glory 4 CD - English DOS/Windows (from jvprat) // Executable scanning reports "2.100.002", VERSION file reports "1.0" @@ -3055,7 +3069,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "aba367f2102e81782d961b14fbe3d630", 10246}, {"resource.000", 0, "263dce4aa34c49d3ad29bec889007b1c", 11571394}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_CD | ADGF_UNSTABLE, GUIO_NONE }, + Common::EN_ANY, Common::kPlatformPC, ADGF_CD | ADGF_UNSTABLE, GUIO1(GUIO_NOASPECT) }, // RAMA - English DOS/Windows Demo // Executable scanning reports "2.100.002", VERSION file reports "000.000.008" @@ -3063,7 +3077,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resmap.001", 0, "775304e9b2a545156be4d94209550094", 1393}, {"ressci.001", 0, "259437fd75fdf51e8207fda8c01fa4fd", 2334384}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO | ADGF_UNSTABLE, GUIO_NONE }, + Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO | ADGF_UNSTABLE, GUIO1(GUIO_NOASPECT) }, #ifdef ENABLE_SCI3_GAMES // RAMA - English Windows (from jvprat) @@ -3076,7 +3090,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resmap.003", 0, "31ef4c0621711585d031f0ae81707251", 1636}, {"ressci.003", 0, "2a68edd064e5e4937b5e9c74b38f2082", 6860492}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO_NONE }, + Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO1(GUIO_NOASPECT) }, // RAMA - English Windows (from Quietust, in bug report #2850645) {"rama", "", { @@ -3087,7 +3101,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resmap.003", 0, "48841e4b84ef1b98b48d43566fda9e13", 1636}, {"ressci.003", 0, "2a68edd064e5e4937b5e9c74b38f2082", 6870356}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO_NONE }, + Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO1(GUIO_NOASPECT) }, // RAMA - Italian Windows CD (from glorifindel) // SCI interpreter version 3.000.000 (a guess?) @@ -3095,7 +3109,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"ressci.001", 0, "2a68edd064e5e4937b5e9c74b38f2082", 70611091}, {"resmap.001", 0, "70ba2ff04a2b7fb2c52420ba7fbd47c2", 8338}, AD_LISTEND}, - Common::IT_ITA, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO_NONE }, + Common::IT_ITA, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO1(GUIO_NOASPECT) }, #endif // ENABLE_SCI3_GAMES // Shivers - English Windows (from jvprat) @@ -3104,14 +3118,14 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resmap.000", 0, "f2ead37749ed8f6535a2445a7d05a0cc", 46525}, {"ressci.000", 0, "4294c6d7510935f2e0a52e302073c951", 262654836}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO_NONE }, + Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO1(GUIO_NOASPECT) }, // Shivers - German Windows (from Tobis87) {"shivers", "", { {"resmap.000", 0, "f483d0a1f78334c18052e92785c3086e", 46537}, {"ressci.000", 0, "6751b144671e2deed919eb9d284b07eb", 262390692}, AD_LISTEND}, - Common::DE_DEU, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO_NONE }, + Common::DE_DEU, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO1(GUIO_NOASPECT) }, // Shivers - English Windows Demo // Executable scanning reports "2.100.002" @@ -3119,7 +3133,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resmap.000", 0, "d9e0bc5eddefcbe47f528760085d8927", 1186}, {"ressci.000", 0, "3a93c6340b54e07e65d0e5583354d186", 10505469}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO | ADGF_UNSTABLE, GUIO_NONE }, + Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO | ADGF_UNSTABLE, GUIO1(GUIO_NOASPECT) }, // Shivers 2 doesn't contain SCI scripts. The whole game logic has // been reimplemented from SCI in native code placed in DLL files. @@ -3137,7 +3151,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resmap.000", 0, "d8659188b84beaef076bd869837cd530", 634}, {"ressci.000", 0, "7fbac0807a044c9543e8ac376d200e59", 4925003}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO | ADGF_UNSTABLE, GUIO_NONE }, + Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO | ADGF_UNSTABLE, GUIO1(GUIO_NOASPECT) }, // Shivers 2 - English Windows (from abevi) // VERSION.TXT Version 1.0 (3/25/97) @@ -3145,7 +3159,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"ressci.001", 0, "a79d03d6eb75be0a79324f14e3d2ace4", 95346793}, {"resmap.001", 0, "a4804d436d90c4ec2e46b537f5e954db", 6268}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) }, #endif @@ -3158,7 +3172,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.msg", 0, "1aeafe2b495de288d002109650b66614", 1364}, {"resource.000", 0, "8e10d4f05c1fd9f883384fa38a898489", 377394}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO1(GUIO_NOSPEECH) }, // Slater & Charlie Go Camping - English DOS/Windows {"slater", "", { @@ -3166,7 +3180,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "21f85414124dc23e54544a5536dc35cd", 4044}, {"resource.msg", 0, "c44f51fb955eae266fecf360ebcd5ad2", 1132}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) }, // Slater & Charlie Go Camping - English DOS/Windows (Sierra Originals) @@ -3175,7 +3189,14 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "21f85414124dc23e54544a5536dc35cd", 4044}, {"resource.msg", 0, "c44f51fb955eae266fecf360ebcd5ad2", 1132}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) }, + + // Slater & Charlie Go Camping - English Macintosh + {"slater", "", { + {"Data1", 0, "7243b4390e5f0182d8133fbcae4b50c5", 2298853}, + {"Data2", 0, "6b6f18f9b502dc0923eeae0ef47f02d5", 2276956}, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformMacintosh, ADGF_MACRESFORK, GUIO1(GUIO_NONE) }, // Space Quest 1 VGA Remake - English Amiga (from www.back2roots.org) // SCI interpreter version 1.000.510 (just a guess) @@ -3188,7 +3209,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.004", 0, "b25a1539c71701f7715f738c5037e9a6", 775515}, {"resource.005", 0, "640ffe1a9acde392cc33cc1b1a528328", 806324}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO1(GUIO_NOSPEECH) }, // Space Quest 1 VGA Remake - English DOS (from the Space Quest Collection) // Executable scanning reports "T.A00.081", VERSION file reports "2.000" @@ -3201,7 +3222,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.003", 0, "c47600e50c6fc591957ae0c5020ee7b8", 1213262}, {"resource.004", 0, "e19ea4ad131472f9238590f2e1d40289", 1203051}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) }, // Space Quest 1 VGA Remake - English Mac (from Fingolfin) {"sq1sci", "SCI", { @@ -3212,7 +3233,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.003", 0, "ae46e195e66df5a131917f0aa80b5669", 1242794}, {"resource.004", 0, "91d58a9eb2187c38424990afe4c12bc6", 1250949}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformMacintosh, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformMacintosh, 0, GUIO1(GUIO_NOSPEECH) }, // Space Quest 1 VGA Remake - English Non-Interactive Demo (from FRG) // SCI interpreter version 1.000.181 @@ -3220,7 +3241,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "5af709ac5e0e923e0b8174f49978c30e", 636}, {"resource.001", 0, "fd99ea43f57576ded7c86036996346cf", 507642}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO1(GUIO_NOSPEECH) }, // Space Quest 1 VGA Remake - Spanish DOS Floppy (from jvprat) // Executable scanning reports "T.A00.081", VERSION file reports "2.000" @@ -3234,7 +3255,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.004", 0, "9b78228ad4f9f335fedf74f1812dcfca", 513325}, {"resource.005", 0, "7d4ebcb745c0bf8fc42e4013f52ecd49", 1101812}, AD_LISTEND}, - Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::ES_ESP, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) }, // Space Quest I 2.0 EGA DOS (6 x 3.5" disks) // Provided by ssburnout in bug report #3046805 @@ -3247,7 +3268,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.004", 0, "975c6e81194ae6b65e960a248129ecaa", 684119}, {"resource.005", 0, "13d96f7905637552c0647175ff816145", 695589}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, // Space Quest 3 - English Amiga (from www.back2roots.org) // SCI interpreter version 0.000.453 (just a guess) @@ -3258,7 +3279,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.003", 0, "ceeda7202b96e5c85ecaa88a40a540fc", 746496}, {"resource.004", 0, "ceeda7202b96e5c85ecaa88a40a540fc", 761984}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, // Space Quest 3 - German Amiga (also includes english language) // Executable scanning reports "1.004.006" @@ -3271,7 +3292,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.004", 0, "6d8f34090503ce937e7dbef6cb6cdb6a", 545053}, {"resource.005", 0, "6d8f34090503ce937e7dbef6cb6cdb6a", 687507}, AD_LISTEND}, - Common::DE_DEU, Common::kPlatformAmiga, ADGF_ADDENGLISH, GUIO_NOSPEECH }, + Common::DE_DEU, Common::kPlatformAmiga, ADGF_ADDENGLISH, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, // Space Quest 3 - English DOS Non-Interactive Demo // SCI interpreter version 0.000.453 @@ -3279,7 +3300,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "ec66ac2b1ce58b2575ba00b65058de1a", 612}, {"resource.001", 0, "ceeda7202b96e5c85ecaa88a40a540fc", 180245}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, // Space Quest 3 - English DOS (provided by richiefs in bug report #2670691) // SCI interpreter version 0.000.453 @@ -3289,7 +3310,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.002", 0, "ceeda7202b96e5c85ecaa88a40a540fc", 720244}, {"resource.003", 0, "ceeda7202b96e5c85ecaa88a40a540fc", 688367}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, // Space Quest 3 - English DOS (from the Space Quest Collection) // Executable scanning reports "0.000.685", VERSION file reports "1.018" @@ -3299,7 +3320,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.002", 0, "8b55c4875298f45ea5696a5ee8f6a7fe", 715777}, {"resource.003", 0, "8b55c4875298f45ea5696a5ee8f6a7fe", 703370}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, // Space Quest 3 - English DOS (from abevi, bug report #2612718) {"sq3", "", { @@ -3311,7 +3332,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.005", 0, "ceeda7202b96e5c85ecaa88a40a540fc", 328278}, {"resource.006", 0, "ceeda7202b96e5c85ecaa88a40a540fc", 356702}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, // Space Quest 3 - English Mac (from Fingolfin) {"sq3", "", { @@ -3320,7 +3341,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.002", 0, "0d8dfe42683b46f3131823233a91ce6a", 794072}, {"resource.003", 0, "0d8dfe42683b46f3131823233a91ce6a", 776536}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformMacintosh, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformMacintosh, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, // Space Quest 3 - German DOS (from Tobis87, also includes english language) // SCI interpreter version 0.000.453 (?) @@ -3334,7 +3355,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.006", 0, "9107c2aa5398e28b5c5406df13491f85", 320643}, {"resource.007", 0, "9107c2aa5398e28b5c5406df13491f85", 344287}, AD_LISTEND}, - Common::DE_DEU, Common::kPlatformPC, ADGF_ADDENGLISH, GUIO_NOSPEECH }, + Common::DE_DEU, Common::kPlatformPC, ADGF_ADDENGLISH, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, // Space Quest 3 v1.052 - German DOS (supplied by markcoolio in bug report #2723860, also includes english language) // Executable scanning reports "S.old.114" @@ -3344,7 +3365,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.002", 0, "9107c2aa5398e28b5c5406df13491f85", 596768}, {"resource.003", 0, "9107c2aa5398e28b5c5406df13491f85", 693573}, AD_LISTEND}, - Common::DE_DEU, Common::kPlatformPC, ADGF_ADDENGLISH, GUIO_NOSPEECH }, + Common::DE_DEU, Common::kPlatformPC, ADGF_ADDENGLISH, GUIO1(GUIO_NOSPEECH) }, // Space Quest 4 - English Amiga // Executable scanning reports "1.004.024" @@ -3359,7 +3380,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.005", 0, "3540d1cc84d674cf4b2c898b88a3b563", 790296}, {"resource.006", 0, "ade814bc4d56244c156d9e9bcfebbc11", 664085}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO1(GUIO_NOSPEECH) }, // Space Quest 4 - German Amiga (from www.back2roots.org, also includes english language) // SCI interpreter version 1.000.200 (just a guess) @@ -3373,7 +3394,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.005", 0, "10ee1709e6559c724676d058199b75b5", 818745}, {"resource.006", 0, "67fb188b191d88efe8414af6ea297b93", 672675}, AD_LISTEND}, - Common::DE_DEU, Common::kPlatformAmiga, ADGF_ADDENGLISH, GUIO_NOSPEECH }, + Common::DE_DEU, Common::kPlatformAmiga, ADGF_ADDENGLISH, GUIO1(GUIO_NOSPEECH) }, // Space Quest 4 - English DOS - THIS VERSION IS PIRATED/CRACKED AND REPACKAGED =DO NOT RE-ADD= // Executable scanning reports "1.000.753" @@ -3382,7 +3403,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "a18088c8aceb06025dbc945f29e02935", 5124}, {"resource.000", 0, "e1f46832cd2458796028e054a0466031", 5502009}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_PIRATED, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, ADGF_PIRATED, GUIO1(GUIO_NOSPEECH) }, // Space Quest 4 - English DOS // Executable scanning reports "1.000.753" @@ -3391,7 +3412,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "71ccf4f82ac4efb588731acfb7bf2603", 5646}, {"resource.000", 0, "e1f46832cd2458796028e054a0466031", 933928}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) }, // Space Quest 4 1.052 - English DOS Floppy (supplied by markcoolio in bug report #2723865) // Executable scanning reports "1.000.753" @@ -3405,7 +3426,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.004", 0, "ff9c87da3bc53473fdee8b9d3edbc93c", 1200631}, {"resource.005", 0, "e33019ac19f755ae33fbf49b4fc9066c", 1053294}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) }, // Space Quest 4 1.000 - English DOS Floppy (from abevi, bug report #2612718) {"sq4", "", { @@ -3417,7 +3438,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.004", 0, "c06350184a490c10eb4585fff0aa3192", 1254368}, {"resource.005", 0, "b8d6efbd3235329bfe844c794097b2c9", 1098717}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) }, // Space Quest IV DOS 1.060 EGA (6 x 3.5" disks) // Supplied by ssburnout in bug report #3046781 @@ -3430,7 +3451,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.004", 0, "9a673e33c3f6dd560b993ffed77eeb49", 534994}, {"resource.005", 0, "3c4841d0a3ebba4404af588c93620c22", 595465}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO2(GUIO_NOSPEECH, GUIO_EGAUNDITHER) }, // Space Quest 4 - German DOS (from Tobis87, also includes english language) // SCI interpreter version 1.000.200 (just a guess) @@ -3444,7 +3465,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.005", 0, "47ee647b5b12232d27e63cc627c25899", 1156765}, {"resource.006", 0, "dfb023e4e2a1e7a00fa18f9ede72a91b", 924059}, AD_LISTEND}, - Common::DE_DEU, Common::kPlatformPC, ADGF_ADDENGLISH, GUIO_NOSPEECH }, + Common::DE_DEU, Common::kPlatformPC, ADGF_ADDENGLISH, GUIO1(GUIO_NOSPEECH) }, // Space Quest 4 - Italian DOS Floppy (from glorifindel, also includes english language) // SCI interpreter version 1.000.200 (just a guess) @@ -3457,7 +3478,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.004", 0, "4277c61bed40a50dadc4b5a344520af2", 1251000}, {"resource.005", 0, "5f885abd335978e2fd4e5f886d7676c8", 1102880}, AD_LISTEND}, - Common::IT_ITA, Common::kPlatformPC, ADGF_ADDENGLISH, GUIO_NOSPEECH }, + Common::IT_ITA, Common::kPlatformPC, ADGF_ADDENGLISH, GUIO1(GUIO_NOSPEECH) }, // Space Quest 4 - Japanese PC-98 5.25" Floppy (also includes english language) // SCI interpreter version 1.000.1068 @@ -3467,7 +3488,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.001", 0, "454684e3a7a68cbca073945e50778447", 1187088}, {"resource.002", 0, "6dc668326cc22cb9e8bd8ca9e68d2a66", 1181249}, AD_LISTEND}, - Common::JA_JPN, Common::kPlatformPC98, ADGF_ADDENGLISH, GUIO_NOSPEECH }, + Common::JA_JPN, Common::kPlatformPC98, ADGF_ADDENGLISH, GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) }, // Space Quest 4 - Japanese PC-98 5.25" Floppy (also includes english language) // SCI interpreter version 1.000.1068 @@ -3477,7 +3498,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.001", 0, "454684e3a7a68cbca073945e50778447", 1187088}, {"resource.002", 0, "6dc668326cc22cb9e8bd8ca9e68d2a66", 1181249}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC98, ADGF_ADDENGLISH, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC98, ADGF_ADDENGLISH, GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) }, // Space Quest 4 - English DOS CD (from the Space Quest Collection) // Executable scanning reports "1.001.064", VERSION file reports "1.0" @@ -3485,7 +3506,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "ed90a8e3ccc53af6633ff6ab58392bae", 7054}, {"resource.000", 0, "63247e3901ab8963d4eece73747832e0", 5157378}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_CD, GUIO_NONE }, + Common::EN_ANY, Common::kPlatformPC, ADGF_CD, GUIO0() }, // Space Quest 4 - English Windows CD (from the Space Quest Collection) // Executable scanning reports "1.001.064", VERSION file reports "1.0" @@ -3495,7 +3516,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "ed90a8e3ccc53af6633ff6ab58392bae", 7054}, {"resource.000", 0, "63247e3901ab8963d4eece73747832e0", 5157378}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformWindows, ADGF_CD, GUIO_MIDIGM }, + Common::EN_ANY, Common::kPlatformWindows, ADGF_CD, GUIO1(GUIO_MIDIGM) }, // Space Quest 4 - Spanish DOS CD (from jvprat, is still text only, not talkie, also includes english language) // Executable scanning reports "1.SQ4.057", VERSION file reports "1.000" @@ -3509,7 +3530,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.004", 0, "776fba81c110d1908776232cbe190e20", 1253752}, {"resource.005", 0, "55fae26c2a92f16ef72c1e216e827c0f", 1098328}, AD_LISTEND}, - Common::ES_ESP, Common::kPlatformPC, ADGF_ADDENGLISH, GUIO_NONE }, + Common::ES_ESP, Common::kPlatformPC, ADGF_ADDENGLISH, GUIO0() }, // Space Quest 4 - Spanish DOS Floppy (from jvprat, also includes english language) // Executable scanning reports "1.SQ4.056", VERSION file reports "1.000" @@ -3521,7 +3542,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.002", 0, "74c62fa2146ff3b3b2ea2b3fb95b9af9", 1140801}, {"resource.003", 0, "42a307941edeb1a3be31daeb2e4be90b", 1088408}, AD_LISTEND}, - Common::ES_ESP, Common::kPlatformPC, ADGF_ADDENGLISH, GUIO_NOSPEECH }, + Common::ES_ESP, Common::kPlatformPC, ADGF_ADDENGLISH, GUIO1(GUIO_NOSPEECH) }, // Space Quest 4 1.000 - German DOS Floppy (supplied by markcoolio in bug report #2723862, also includes english language) // Executable scanning reports "1.SQ4.030" @@ -3535,7 +3556,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.004", 0, "c06350184a490c10eb4585fff0aa3192", 1254368}, {"resource.005", 0, "b8d6efbd3235329bfe844c794097b2c9", 1098717}, AD_LISTEND}, - Common::DE_DEU, Common::kPlatformPC, ADGF_ADDENGLISH, GUIO_NOSPEECH }, + Common::DE_DEU, Common::kPlatformPC, ADGF_ADDENGLISH, GUIO1(GUIO_NOSPEECH) }, // Space Quest 4 - English Macintosh // Executable scanning reports "x.yyy.zzz" @@ -3550,7 +3571,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.005", 0, "869d16cab6641c80b06f4dcee18f86bc", 1426228}, {"resource.006", 0, "91d23407bc0447a3722fbeb952d7edee", 1402451}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformMacintosh, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformMacintosh, 0, GUIO1(GUIO_NOSPEECH) }, // Space Quest 4 - Russian DOS // Executable scanning reports "1.000.753", VERSION file reports "1.994" @@ -3563,7 +3584,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.004", 0, "2763fe4f0cb74df716ec8b0c464b0988", 1217428}, {"resource.005", 0, "d608713197c5ba1cd8c6ed46299c3069", 1057924}, AD_LISTEND}, - Common::RU_RUS, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::RU_RUS, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) }, // Space Quest 5 - English DOS (from the Space Quest Collection) // Executable scanning reports "1.001.068", VERSION file reports "1.04" @@ -3572,7 +3593,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.000", 0, "4147edc5045e6d62998018b5614c58ec", 5496486}, {"resource.msg", 0, "bb8ad78793c26bdb3f77498b1d6515a9", 125988}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) }, // Space Quest 5 - English DOS - THIS IS THE UNOFFICIAL BETA VERSION, WHICH IS OBVIOUSLY PIRATED AND CONTAINS MANY BUGS // ffs. http://www.akril15.com/sr/sq5alt/sq5alt.html =DO NOT RE-ADD= @@ -3581,7 +3602,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "8bde0a9adb9a3e9aaa861826874c9834", 6473}, {"resource.000", 0, "f4a48705764544d7cc64a7bb22a610df", 6025184}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_PIRATED, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, ADGF_PIRATED, GUIO1(GUIO_NOSPEECH) }, // Space Quest 5 v1.04 - German DOS (from Tobis87, updated information by markcool from bug reports #2723935 and #2724762) // SCI interpreter version 1.001.068 @@ -3590,7 +3611,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.000", 0, "4147edc5045e6d62998018b5614c58ec", 5496486}, {"resource.msg", 0, "7c71cfc36153cfe07b450423a51f7e68", 146282}, AD_LISTEND}, - Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::DE_DEU, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) }, // Space Quest 5 v1.04 - French DOS (from Hkz, Included in Space Quest Collector's Edition, with chapters I-V) {"sq5", "", { @@ -3598,7 +3619,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.000", 0, "4147edc5045e6d62998018b5614c58ec", 5496486}, {"resource.msg", 0, "877c42380320eb1db7dad83ccd261214", 140374}, AD_LISTEND}, - Common::FR_FRA, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::FR_FRA, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) }, // Space Quest 5 - Italian DOS Floppy (from glorifindel) // SCI interpreter version 1.001.068 (just a guess) @@ -3606,7 +3627,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.000", 0, "5040026519f37199f3616fb1d4704dff", 6047170}, {"resource.map", 0, "5b09168baa2f6e2e22787429b2d72f54", 6492}, AD_LISTEND}, - Common::IT_ITA, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::IT_ITA, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) }, // Space Quest 5 - Spanish DOS Floppy (from mirir, bug report #3090664) {"sq5", "", { @@ -3614,7 +3635,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "5714a899033bdebf2d61ad333c8c6637", 6492}, {"resource.msg", 0, "46deca7ef9cf057f7d442df98c1a2ae2", 134612}, AD_LISTEND}, - Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::ES_ESP, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) }, // Space Quest 5 - Russian DOS // Executable scanning reports "1.001.068", VERSION file reports "1.994" @@ -3623,7 +3644,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.000", 0, "6f9ed21e1001526b4137f6703ed476af", 6103778}, {"resource.msg", 0, "0a8931990cd2eac1691602391c68ab85", 147580}, AD_LISTEND}, - Common::RU_RUS, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::RU_RUS, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) }, #ifdef ENABLE_SCI32 // Space Quest 6 - English DOS/Win3.11 CD (from the Space Quest Collection) @@ -3632,7 +3653,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "6dddfa3a8f3a3a513ec9dfdfae955005", 10528}, {"resource.000", 0, "c4259ab7355aead07773397b1052827d", 41150806}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_CD | ADGF_UNSTABLE, GUIO_NONE }, + Common::EN_ANY, Common::kPlatformPC, ADGF_CD | ADGF_UNSTABLE, GUIO1(GUIO_NOASPECT) }, // Space Quest 6 - English DOS/Win3.11 CD ver 1.11 (from FRG) // SCI interpreter version 2.100.002 (just a guess) @@ -3640,7 +3661,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "e0615d6e4e10e37ae42e6a2a95aaf145", 10528}, {"resource.000", 0, "c4259ab7355aead07773397b1052827d", 41150806}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_CD | ADGF_UNSTABLE, GUIO_NONE }, + Common::EN_ANY, Common::kPlatformPC, ADGF_CD | ADGF_UNSTABLE, GUIO1(GUIO_NOASPECT) }, // Space Quest 6 - French DOS/Win3.11 CD (from French magazine Joystick - September 1997) // Executable scanning reports "2.100.002", VERSION file reports "1.0" @@ -3648,7 +3669,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "3c831625931d5079b73ae8c275f52c95", 10534}, {"resource.000", 0, "4195ca940f759424f62b90e262cc1737", 40932397}, AD_LISTEND}, - Common::FR_FRA, Common::kPlatformPC, ADGF_CD | ADGF_UNSTABLE, GUIO_NONE }, + Common::FR_FRA, Common::kPlatformPC, ADGF_CD | ADGF_UNSTABLE, GUIO1(GUIO_NOASPECT) }, // Space Quest 6 - German DOS (from Tobis87, updated info from markcoolio in bug report #2723884) // SCI interpreter version 2.100.002 (just a guess) @@ -3656,7 +3677,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "664d797415484f85c90b1b45aedc7686", 10534}, {"resource.000", 0, "ba87ba91e5bdabb4169dd0df75777722", 40933685}, AD_LISTEND}, - Common::DE_DEU, Common::kPlatformPC, ADGF_CD | ADGF_UNSTABLE, GUIO_NONE }, + Common::DE_DEU, Common::kPlatformPC, ADGF_CD | ADGF_UNSTABLE, GUIO1(GUIO_NOASPECT) }, // Space Quest 6 - English DOS/Win3.11 Interactive Demo (from FRG) // SCI interpreter version 2.100.002 (just a guess) @@ -3664,7 +3685,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "368f07b07433db3f819fa3fa0e5efee5", 2572}, {"resource.000", 0, "ab12724e078dea34b624e0d2a38dcd7c", 2272050}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO | ADGF_UNSTABLE, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO | ADGF_UNSTABLE, GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) }, #endif // ENABLE_SCI32 // The Island of Dr. Brain - English DOS CD (from jvprat) @@ -3673,7 +3694,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "2388efef8430b041b0f3b00b9050e4a2", 3281}, {"resource.000", 0, "b3acd9b9dd7fe53c4ee133ac9a1acfab", 2103560}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NONE }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO0() }, // The Island of Dr. Brain - English DOS (from Quietust) // Executable scanning reports "1.001.053", VERSION file reports "1.1 2.3.93" @@ -3681,7 +3702,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "3c07da06bdd1689f9d07af78fb94d0ec", 3101}, {"resource.000", 0, "ecc686e0034fb4d41de077ac7167b3cf", 1947866}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, 0, GUIO1(GUIO_NOSPEECH) }, // The Island of Dr. Brain - English DOS Non-Interactive Demo // SCI interpreter version 1.001.053 (just a guess) @@ -3689,7 +3710,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resource.map", 0, "a8e5ca8ed1996974afa59f4c45e06195", 986}, {"resource.000", 0, "b3acd9b9dd7fe53c4ee133ac9a1acfab", 586560}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO1(GUIO_NOSPEECH) }, #ifdef ENABLE_SCI32 // Torin's Passage - English Windows Interactive Demo @@ -3698,7 +3719,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resmap.000", 0, "9a3e172cde9963d0a969f26469318cec", 3403}, {"ressci.000", 0, "db3e290481c35c3224e9602e71e4a1f1", 5073868}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO | ADGF_UNSTABLE, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO | ADGF_UNSTABLE, GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) }, // Torin's Passage - English Windows // SCI interpreter version 2.100.002 (just a guess) @@ -3706,7 +3727,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resmap.000", 0, "bb3b0b22ff08df54fbe2d06263409be6", 9799}, {"ressci.000", 0, "693a259d346c9360f4a0c11fdaae430a", 55973887}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO_NOSPEECH }, + Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) }, // Torin's Passage - Spanish Windows (from jvprat) // Executable scanning reports "2.100.002", VERSION file reports "1.0" @@ -3715,7 +3736,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"ressci.000", 0, "693a259d346c9360f4a0c11fdaae430a", 55973887}, // TODO: depend on one of the patches? AD_LISTEND}, - Common::ES_ESP, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO_NOSPEECH }, + Common::ES_ESP, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) }, // Torin's Passage - French Windows // SCI interpreter version 2.100.002 (just a guess) @@ -3723,7 +3744,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resmap.000", 0, "bb3b0b22ff08df54fbe2d06263409be6", 9799}, {"ressci.000", 0, "693a259d346c9360f4a0c11fdaae430a", 55973887}, AD_LISTEND}, - Common::FR_FRA, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO_NOSPEECH }, + Common::FR_FRA, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) }, // Torin's Passage - German Windows // SCI interpreter version 2.100.002 (just a guess) @@ -3731,7 +3752,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resmap.000", 0, "bb3b0b22ff08df54fbe2d06263409be6", 9799}, {"ressci.000", 0, "693a259d346c9360f4a0c11fdaae430a", 55973887}, AD_LISTEND}, - Common::DE_DEU, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO_NOSPEECH }, + Common::DE_DEU, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) }, // Torin's Passage - Italian Windows CD (from glorifindel) // SCI interpreter version 2.100.002 (just a guess) @@ -3739,7 +3760,7 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"resmap.000", 0, "bb3b0b22ff08df54fbe2d06263409be6", 9799}, {"ressci.000", 0, "693a259d346c9360f4a0c11fdaae430a", 55973887}, AD_LISTEND}, - Common::IT_ITA, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO_NONE }, + Common::IT_ITA, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO1(GUIO_NOASPECT) }, #endif // ENABLE_SCI32 // SCI Fanmade Games diff --git a/engines/sci/engine/kernel.cpp b/engines/sci/engine/kernel.cpp index a83a026762..c99bc4fe47 100644 --- a/engines/sci/engine/kernel.cpp +++ b/engines/sci/engine/kernel.cpp @@ -828,7 +828,8 @@ void Kernel::setDefaultKernelNames(GameFeatures *features) { enum { kKernelEntriesSci2 = 0x8b, kKernelEntriesGk2Demo = 0xa0, - kKernelEntriesSci21 = 0x9d + kKernelEntriesSci21 = 0x9d, + kKernelEntriesSci3 = 0xa1 }; void Kernel::setKernelNamesSci2() { @@ -856,8 +857,11 @@ void Kernel::setKernelNamesSci21(GameFeatures *features) { // OnMe is IsOnMe here, but they should be compatible _kernelNames[0x23] = "Robot"; // Graph in SCI2 _kernelNames[0x2e] = "Priority"; // DisposeTextBitmap in SCI2 - } else + } else if (getSciVersion() != SCI_VERSION_3) { _kernelNames = Common::StringArray(sci21_default_knames, kKernelEntriesSci21); + } else if (getSciVersion() == SCI_VERSION_3) { + _kernelNames = Common::StringArray(sci21_default_knames, kKernelEntriesSci3); + } } #endif @@ -910,28 +914,32 @@ Common::String Kernel::lookupText(reg_t address, int index) { // TODO: script_adjust_opcode_formats should probably be part of the // constructor (?) of a VirtualMachine or a ScriptManager class. void script_adjust_opcode_formats() { + + g_sci->_opcode_formats = new opcode_format[128][4]; + memcpy(g_sci->_opcode_formats, g_base_opcode_formats, 128*4*sizeof(opcode_format)); + if (g_sci->_features->detectLofsType() != SCI_VERSION_0_EARLY) { - g_opcode_formats[op_lofsa][0] = Script_Offset; - g_opcode_formats[op_lofss][0] = Script_Offset; + g_sci->_opcode_formats[op_lofsa][0] = Script_Offset; + g_sci->_opcode_formats[op_lofss][0] = Script_Offset; } #ifdef ENABLE_SCI32 // In SCI32, some arguments are now words instead of bytes if (getSciVersion() >= SCI_VERSION_2) { - g_opcode_formats[op_calle][2] = Script_Word; - g_opcode_formats[op_callk][1] = Script_Word; - g_opcode_formats[op_super][1] = Script_Word; - g_opcode_formats[op_send][0] = Script_Word; - g_opcode_formats[op_self][0] = Script_Word; - g_opcode_formats[op_call][1] = Script_Word; - g_opcode_formats[op_callb][1] = Script_Word; + g_sci->_opcode_formats[op_calle][2] = Script_Word; + g_sci->_opcode_formats[op_callk][1] = Script_Word; + g_sci->_opcode_formats[op_super][1] = Script_Word; + g_sci->_opcode_formats[op_send][0] = Script_Word; + g_sci->_opcode_formats[op_self][0] = Script_Word; + g_sci->_opcode_formats[op_call][1] = Script_Word; + g_sci->_opcode_formats[op_callb][1] = Script_Word; } if (getSciVersion() >= SCI_VERSION_3) { // TODO: There are also opcodes in // here to get the superclass, and possibly the species too. - g_opcode_formats[0x4d/2][0] = Script_None; - g_opcode_formats[0x4e/2][0] = Script_None; + g_sci->_opcode_formats[0x4d/2][0] = Script_None; + g_sci->_opcode_formats[0x4e/2][0] = Script_None; } #endif } diff --git a/engines/sci/engine/kernel.h b/engines/sci/engine/kernel.h index b605908dc1..e549c1f8ae 100644 --- a/engines/sci/engine/kernel.h +++ b/engines/sci/engine/kernel.h @@ -442,11 +442,11 @@ reg_t kUpdateScreenItem(EngineState *s, int argc, reg_t *argv); reg_t kDeleteScreenItem(EngineState *s, int argc, reg_t *argv); // Text reg_t kCreateTextBitmap(EngineState *s, int argc, reg_t *argv); +reg_t kDisposeTextBitmap(EngineState *s, int argc, reg_t *argv); // "Planes" in SCI32 are pictures reg_t kAddPlane(EngineState *s, int argc, reg_t *argv); reg_t kDeletePlane(EngineState *s, int argc, reg_t *argv); reg_t kUpdatePlane(EngineState *s, int argc, reg_t *argv); -reg_t kRepaintPlane(EngineState *s, int argc, reg_t *argv); reg_t kSetShowStyle(EngineState *s, int argc, reg_t *argv); reg_t kGetHighPlanePri(EngineState *s, int argc, reg_t *argv); reg_t kFrameOut(EngineState *s, int argc, reg_t *argv); @@ -456,6 +456,8 @@ reg_t kListEachElementDo(EngineState *s, int argc, reg_t *argv); reg_t kListFirstTrue(EngineState *s, int argc, reg_t *argv); reg_t kListAllTrue(EngineState *s, int argc, reg_t *argv); reg_t kInPolygon(EngineState *s, int argc, reg_t *argv); +reg_t kObjectIntersect(EngineState *s, int argc, reg_t *argv); +reg_t kEditText(EngineState *s, int argc, reg_t *argv); // SCI2.1 Kernel Functions reg_t kText(EngineState *s, int argc, reg_t *argv); @@ -477,6 +479,9 @@ reg_t kScrollWindow(EngineState *s, int argc, reg_t *argv); reg_t kSetFontRes(EngineState *s, int argc, reg_t *argv); reg_t kFont(EngineState *s, int argc, reg_t *argv); reg_t kBitmap(EngineState *s, int argc, reg_t *argv); + +// SCI3 Kernel functions +reg_t kPlayDuck(EngineState *s, int argc, reg_t *argv); #endif reg_t kDoSoundInit(EngineState *s, int argc, reg_t *argv); diff --git a/engines/sci/engine/kernel_tables.h b/engines/sci/engine/kernel_tables.h index d3adcaccbf..fe0c9fc2ef 100644 --- a/engines/sci/engine/kernel_tables.h +++ b/engines/sci/engine/kernel_tables.h @@ -24,7 +24,7 @@ #define SCI_ENGINE_KERNEL_TABLES_H #include "sci/engine/workarounds.h" -#include "sci/engine/vm.h" // for opcode_formats +#include "sci/engine/vm_types.h" // for opcode_formats namespace Sci { @@ -477,6 +477,7 @@ static SciKernelMapEntry s_kernelMap[] = { { MAP_CALL(CreateTextBitmap), SIG_EVERYWHERE, "i(.*)", NULL, NULL }, { MAP_CALL(DeletePlane), SIG_EVERYWHERE, "o", NULL, NULL }, { MAP_CALL(DeleteScreenItem), SIG_EVERYWHERE, "o", NULL, NULL }, + { MAP_CALL(DisposeTextBitmap), SIG_EVERYWHERE, "r", NULL, NULL }, { MAP_CALL(FrameOut), SIG_EVERYWHERE, "", NULL, NULL }, { MAP_CALL(GetHighPlanePri), SIG_EVERYWHERE, "", NULL, NULL }, { MAP_CALL(InPolygon), SIG_EVERYWHERE, "iio", NULL, NULL }, @@ -493,25 +494,46 @@ static SciKernelMapEntry s_kernelMap[] = { // our own memory manager and garbage collector, thus we simply call FlushResources, which in turn invokes // our garbage collector (i.e. the SCI0-SCI1.1 semantics). { "Purge", kFlushResources, SIG_EVERYWHERE, "i", NULL, NULL }, - { MAP_CALL(RepaintPlane), SIG_EVERYWHERE, "o", NULL, NULL }, { MAP_CALL(SetShowStyle), SIG_EVERYWHERE, "ioiiiii([ri])(i)", NULL, NULL }, { MAP_CALL(String), SIG_EVERYWHERE, "(.*)", NULL, NULL }, { MAP_CALL(UpdatePlane), SIG_EVERYWHERE, "o", NULL, NULL }, { MAP_CALL(UpdateScreenItem), SIG_EVERYWHERE, "o", NULL, NULL }, + { MAP_CALL(ObjectIntersect), SIG_EVERYWHERE, "oo", NULL, NULL }, + { MAP_CALL(EditText), SIG_EVERYWHERE, "o", NULL, NULL }, // SCI2 unmapped functions - TODO! - // SetScroll - // AddMagnify // most probably similar to the SCI1.1 functions. We need a test case - // DeleteMagnify - // EditText - // DisposeTextBitmap - // VibrateMouse - used in QFG4 floppy - // PalCycle - // ObjectIntersect - used in QFG4 floppy - // MakeSaveCatName - used in the Save/Load dialog of GK1CD (SRDialog, script 64990) - // MakeSaveFileName - used in the Save/Load dialog of GK1CD (SRDialog, script 64990) + + // SetScroll - called by script 64909, Styler::doit() + // PalCycle - called by Game::newRoom. Related to RemapColors. + // VibrateMouse - used in QFG4 + + // SCI2 Empty functions + + // Debug function used to track resources + { MAP_EMPTY(ResourceTrack), SIG_EVERYWHERE, "(.*)", NULL, NULL }, + + // SCI2 functions that are used in the original save/load menus. Marked as dummy, so + // that the engine errors out on purpose. TODO: Implement once the original save/load + // menus are implemented. + + // Creates the name of the save catalogue/directory to save into. + // TODO: Implement once the original save/load menus are implemented. + { MAP_DUMMY(MakeSaveCatName), SIG_EVERYWHERE, "(.*)", NULL, NULL }, + + // Creates the name of the save file to save into + // TODO: Implement once the original save/load menus are implemented. + { MAP_DUMMY(MakeSaveFileName), SIG_EVERYWHERE, "(.*)", NULL, NULL }, // Unused / debug SCI2 unused functions, always mapped to kDummy + + // AddMagnify/DeleteMagnify are both called by script 64979 (the Magnifier + // object) in GK1 only. There is also an associated empty magnifier view + // (view 1), however, it doesn't seem to be used anywhere, as all the + // magnifier closeups (e.g. in scene 470) are normal views. Thus, these + // are marked as dummy, so if they're ever used the engine will error out. + { MAP_DUMMY(AddMagnify), SIG_EVERYWHERE, "(.*)", NULL, NULL }, + { MAP_DUMMY(DeleteMagnify), SIG_EVERYWHERE, "(.*)", NULL, NULL }, + { MAP_DUMMY(RepaintPlane), SIG_EVERYWHERE, "o", NULL, NULL }, { MAP_DUMMY(InspectObject), SIG_EVERYWHERE, "(.*)", NULL, NULL }, // Profiler (same as SCI0-SCI1.1) // Record (same as SCI0-SCI1.1) @@ -590,7 +612,6 @@ static SciKernelMapEntry s_kernelMap[] = { // SCI2.1 unmapped functions - TODO! - // Bitmap // MovePlaneItems - used by SQ6 to scroll through the inventory via the up/down buttons // AddLine - used by Torin's Passage to highlight the chapter buttons // DeleteLine - used by Torin's Passage to delete the highlight from the chapter buttons @@ -599,6 +620,9 @@ static SciKernelMapEntry s_kernelMap[] = { // (inclusive) are set to 0 // MorphOn - used by SQ6, script 900, the datacorder reprogramming puzzle (from room 270) // SetHotRectangles - used by Phantasmagoria 1 + + // SCI3 Kernel Functions + { MAP_CALL(PlayDuck), SIG_EVERYWHERE, "(.*)", NULL, NULL }, #endif { NULL, NULL, SIG_EVERYWHERE, NULL, NULL, NULL } @@ -771,7 +795,7 @@ static const char *const sci2_default_knames[] = { /*0x0d*/ "CelWide", /*0x0e*/ "CelHigh", /*0x0f*/ "GetHighPlanePri", - /*0x10*/ "GetHighItemPri", + /*0x10*/ "GetHighItemPri", // unused function /*0x11*/ "ShakeScreen", /*0x12*/ "OnMe", /*0x13*/ "ShowMovie", @@ -783,9 +807,9 @@ static const char *const sci2_default_knames[] = { /*0x19*/ "AddPlane", /*0x1a*/ "DeletePlane", /*0x1b*/ "UpdatePlane", - /*0x1c*/ "RepaintPlane", + /*0x1c*/ "RepaintPlane", // unused function /*0x1d*/ "SetShowStyle", - /*0x1e*/ "ShowStylePercent", + /*0x1e*/ "ShowStylePercent", // unused function /*0x1f*/ "SetScroll", /*0x20*/ "AddMagnify", /*0x21*/ "DeleteMagnify", @@ -799,7 +823,7 @@ static const char *const sci2_default_knames[] = { /*0x29*/ "Dummy", /*0x2a*/ "SetQuitStr", /*0x2b*/ "EditText", - /*0x2c*/ "InputText", + /*0x2c*/ "InputText", // unused function /*0x2d*/ "CreateTextBitmap", /*0x2e*/ "DisposeTextBitmap", /*0x2f*/ "GetEvent", @@ -944,8 +968,8 @@ static const char *const sci21_default_knames[] = { /*0x15*/ "NumLoops", /*0x16*/ "NumCels", /*0x17*/ "IsOnMe", - /*0x18*/ "AddMagnify", - /*0x19*/ "DeleteMagnify", + /*0x18*/ "AddMagnify", // dummy in SCI3 + /*0x19*/ "DeleteMagnify", // dummy in SCI3 /*0x1a*/ "CelRect", /*0x1b*/ "BaseLineSpan", /*0x1c*/ "CelWide", @@ -965,10 +989,10 @@ static const char *const sci21_default_knames[] = { /*0x2a*/ "UpdatePlane", /*0x2b*/ "RepaintPlane", /*0x2c*/ "GetHighPlanePri", - /*0x2d*/ "GetHighItemPri", + /*0x2d*/ "GetHighItemPri", // unused function /*0x2e*/ "SetShowStyle", - /*0x2f*/ "ShowStylePercent", - /*0x30*/ "SetScroll", + /*0x2f*/ "ShowStylePercent", // unused function + /*0x30*/ "SetScroll", // dummy in SCI3 /*0x31*/ "MovePlaneItems", /*0x32*/ "ShakeScreen", /*0x33*/ "Dummy", @@ -977,7 +1001,7 @@ static const char *const sci21_default_knames[] = { /*0x36*/ "Dummy", /*0x37*/ "IsHiRes", /*0x38*/ "SetVideoMode", - /*0x39*/ "ShowMovie", + /*0x39*/ "ShowMovie", // dummy in SCI3 /*0x3a*/ "Robot", /*0x3b*/ "CreateTextBitmap", /*0x3c*/ "Random", @@ -995,7 +1019,7 @@ static const char *const sci21_default_knames[] = { /*0x48*/ "Message", /*0x49*/ "Font", /*0x4a*/ "EditText", - /*0x4b*/ "InputText", + /*0x4b*/ "InputText", // unused function /*0x4c*/ "ScrollWindow", // Dummy in SCI3 /*0x4d*/ "Dummy", /*0x4e*/ "Dummy", @@ -1020,9 +1044,9 @@ static const char *const sci21_default_knames[] = { /*0x61*/ "InitBresen", /*0x62*/ "DoBresen", /*0x63*/ "SetJump", - /*0x64*/ "AvoidPath", + /*0x64*/ "AvoidPath", // dummy in SCI3 /*0x65*/ "InPolygon", - /*0x66*/ "MergePoly", + /*0x66*/ "MergePoly", // dummy in SCI3 /*0x67*/ "ObjectIntersect", /*0x68*/ "Dummy", /*0x69*/ "MemoryInfo", @@ -1051,7 +1075,7 @@ static const char *const sci21_default_knames[] = { /*0x80*/ "Dummy", /*0x81*/ "Dummy", // called when changing rooms in most SCI2.1 games (e.g. KQ7, GK2, MUMG deluxe, Phant1) /*0x82*/ "Dummy", - /*0x83*/ "PrintDebug", // debug function, used by Shivers 2 (demo and full) + /*0x83*/ "PrintDebug", // debug function, used by Shivers (demo and full) /*0x84*/ "Dummy", /*0x85*/ "Dummy", /*0x86*/ "Dummy", @@ -1086,7 +1110,9 @@ static const char *const sci21_default_knames[] = { #endif -opcode_format g_opcode_formats[128][4] = { +// Base set of opcode formats. They're copied and adjusted slightly in +// script_adjust_opcode_format depending on SCI version. +static const opcode_format g_base_opcode_formats[128][4] = { /*00*/ {Script_None}, {Script_None}, {Script_None}, {Script_None}, /*04*/ diff --git a/engines/sci/engine/kfile.cpp b/engines/sci/engine/kfile.cpp index 0c73125bdb..ce903626e7 100644 --- a/engines/sci/engine/kfile.cpp +++ b/engines/sci/engine/kfile.cpp @@ -22,6 +22,7 @@ #include "common/archive.h" #include "common/config-manager.h" +#include "common/debug-channels.h" #include "common/file.h" #include "common/str.h" #include "common/savefile.h" @@ -52,9 +53,10 @@ struct SavegameDesc { * arbitrary data files, simply because many of our target platforms do not * support this. The only files one can create are savestates. But SCI has an * opcode to create and write to seemingly 'arbitrary' files. This is mainly - * used in LSL3 for LARRY3.DRV (which is a game data file, not a driver) and - * in LSL5 for MEMORY.DRV (which is again a game data file and contains the - * game's password). + * used in LSL3 for LARRY3.DRV (which is a game data file, not a driver, used + * for persisting the results of the "age quiz" across restarts) and in LSL5 + * for MEMORY.DRV (which is again a game data file and contains the game's + * password, XOR encrypted). * To implement that opcode, we combine the SaveFileManager with regular file * code, similarly to how the SCUMM HE engine does it. * @@ -115,20 +117,6 @@ reg_t file_open(EngineState *s, const Common::String &filename, int mode, bool u if (!inFile) inFile = SearchMan.createReadStreamForMember(englishName); - // Special case for LSL3: It tries to create a new dummy file, - // LARRY3.DRV. Apparently, if the file doesn't exist here, it should be - // created. The game scripts then go ahead and fill its contents with - // data. It seems to be a similar case as the dummy MEMORY.DRV file in - // LSL5, but LSL5 creates the file if it can't find it with a separate - // call to file_open(). - if (!inFile && englishName == "LARRY3.DRV") { - outFile = saveFileMan->openForSaving(wrappedName); - outFile->finalize(); - delete outFile; - outFile = 0; - inFile = SearchMan.createReadStreamForMember(wrappedName); - } - if (!inFile) debugC(kDebugLevelFile, " -> file_open(_K_FILE_MODE_OPEN_OR_FAIL): failed to open file '%s'", englishName.c_str()); } else if (mode == _K_FILE_MODE_CREATE) { @@ -365,9 +353,12 @@ reg_t kDeviceInfo(EngineState *s, int argc, reg_t *argv) { reg_t kGetSaveDir(EngineState *s, int argc, reg_t *argv) { #ifdef ENABLE_SCI32 - // TODO: SCI32 uses a parameter here. - if (argc > 0) - warning("kGetSaveDir called with %d parameter(s): %04x:%04x", argc, PRINT_REG(argv[0])); + // SCI32 uses a parameter here. It is used to modify a string, stored in a + // global variable, so that game scripts store the save directory. We + // don't really set a save game directory, thus not setting the string to + // anything is the correct thing to do here. + //if (argc > 0) + // warning("kGetSaveDir called with %d parameter(s): %04x:%04x", argc, PRINT_REG(argv[0])); #endif return s->_segMan->getSaveDirPtr(); } @@ -1057,6 +1048,18 @@ reg_t kFileIOExists(EngineState *s, int argc, reg_t *argv) { exists = !saveFileMan->listSavefiles(wrappedName).empty(); } + // SCI2+ debug mode + if (DebugMan.isDebugChannelEnabled(kDebugLevelDebugMode)) { + if (!exists && name == "1.scr") // PQ4 + exists = true; + if (!exists && name == "18.scr") // QFG4 + exists = true; + if (!exists && name == "99.scr") // GK1, KQ7 + exists = true; + if (!exists && name == "classes") // GK2, SQ6, LSL7 + exists = true; + } + // Special case for non-English versions of LSL5: The English version of // LSL5 calls kFileIO(), case K_FILEIO_OPEN for reading to check if // memory.drv exists (which is where the game's password is stored). If @@ -1164,8 +1167,17 @@ reg_t kSave(EngineState *s, int argc, reg_t *argv) { return kRestoreGame(s, argc - 1,argv + 1); case 2: return kGetSaveDir(s, argc - 1, argv + 1); + case 3: + return kCheckSaveGame(s, argc - 1, argv + 1); case 5: return kGetSaveFiles(s, argc - 1, argv + 1); + case 6: + // This is used in Shivers to delete saved games, however it + // always passes the same file name (SHIVER), so it doesn't + // actually delete anything... + // TODO: Check why this happens + // argv[1] is a string (most likely the save game directory) + return kFileIOUnlink(s, argc - 2, argv + 2); case 8: // TODO // This is a timer callback, with 1 parameter: the timer object @@ -1176,10 +1188,9 @@ reg_t kSave(EngineState *s, int argc, reg_t *argv) { // This function has to return something other than 0 to proceed return s->r_acc; default: - warning("Unknown/unhandled kSave subop %d", argv[0].toUint16()); + kStub(s, argc, argv); + return NULL_REG; } - - return NULL_REG; } #endif diff --git a/engines/sci/engine/kgraphics.cpp b/engines/sci/engine/kgraphics.cpp index 9f309aeab7..76c6778f0a 100644 --- a/engines/sci/engine/kgraphics.cpp +++ b/engines/sci/engine/kgraphics.cpp @@ -39,7 +39,7 @@ #include "sci/graphics/animate.h" #include "sci/graphics/cache.h" #include "sci/graphics/compare.h" -#include "sci/graphics/controls.h" +#include "sci/graphics/controls16.h" #include "sci/graphics/cursor.h" #include "sci/graphics/palette.h" #include "sci/graphics/paint16.h" @@ -49,9 +49,10 @@ #include "sci/graphics/text16.h" #include "sci/graphics/view.h" #ifdef ENABLE_SCI32 +#include "sci/graphics/controls32.h" +#include "sci/graphics/font.h" // TODO: remove once kBitmap is moved in a separate class #include "sci/graphics/text32.h" #include "sci/graphics/frameout.h" -#include "sci/video/robot_decoder.h" #endif namespace Sci { @@ -354,11 +355,9 @@ reg_t kTextSize(EngineState *s, int argc, reg_t *argv) { textWidth = dest[3].toUint16(); textHeight = dest[2].toUint16(); #ifdef ENABLE_SCI32 - if (!g_sci->_gfxText16) { - // TODO: Implement this - textWidth = 0; textHeight = 0; - warning("TODO: implement kTextSize for SCI32"); - } else + if (g_sci->_gfxText32) + g_sci->_gfxText32->kernelTextSize(g_sci->strSplit(text.c_str(), sep).c_str(), font_nr, maxwidth, &textWidth, &textHeight); + else #endif g_sci->_gfxText16->kernelTextSize(g_sci->strSplit(text.c_str(), sep).c_str(), font_nr, maxwidth, &textWidth, &textHeight); @@ -381,8 +380,13 @@ reg_t kTextSize(EngineState *s, int argc, reg_t *argv) { } debugC(kDebugLevelStrings, "GetTextSize '%s' -> %dx%d", text.c_str(), textWidth, textHeight); - dest[2] = make_reg(0, textHeight); - dest[3] = make_reg(0, textWidth); + if (getSciVersion() <= SCI_VERSION_1_1) { + dest[2] = make_reg(0, textHeight); + dest[3] = make_reg(0, textWidth); + } else { + dest[2] = make_reg(0, textWidth); + dest[3] = make_reg(0, textHeight); + } return s->r_acc; } @@ -807,13 +811,13 @@ void _k_GenericDrawControl(EngineState *s, reg_t controlObject, bool hilite) { switch (type) { case SCI_CONTROLS_TYPE_BUTTON: debugC(kDebugLevelGraphics, "drawing button %04x:%04x to %d,%d", PRINT_REG(controlObject), x, y); - g_sci->_gfxControls->kernelDrawButton(rect, controlObject, g_sci->strSplit(text.c_str(), NULL).c_str(), fontId, style, hilite); + g_sci->_gfxControls16->kernelDrawButton(rect, controlObject, g_sci->strSplit(text.c_str(), NULL).c_str(), fontId, style, hilite); return; case SCI_CONTROLS_TYPE_TEXT: alignment = readSelectorValue(s->_segMan, controlObject, SELECTOR(mode)); debugC(kDebugLevelGraphics, "drawing text %04x:%04x ('%s') to %d,%d, mode=%d", PRINT_REG(controlObject), text.c_str(), x, y, alignment); - g_sci->_gfxControls->kernelDrawText(rect, controlObject, g_sci->strSplit(text.c_str()).c_str(), fontId, alignment, style, hilite); + g_sci->_gfxControls16->kernelDrawText(rect, controlObject, g_sci->strSplit(text.c_str()).c_str(), fontId, alignment, style, hilite); s->r_acc = g_sci->_gfxText16->allocAndFillReferenceRectArray(); return; @@ -827,7 +831,7 @@ void _k_GenericDrawControl(EngineState *s, reg_t controlObject, bool hilite) { writeSelectorValue(s->_segMan, controlObject, SELECTOR(cursor), cursorPos); } debugC(kDebugLevelGraphics, "drawing edit control %04x:%04x (text %04x:%04x, '%s') to %d,%d", PRINT_REG(controlObject), PRINT_REG(textReference), text.c_str(), x, y); - g_sci->_gfxControls->kernelDrawTextEdit(rect, controlObject, g_sci->strSplit(text.c_str(), NULL).c_str(), fontId, mode, style, cursorPos, maxChars, hilite); + g_sci->_gfxControls16->kernelDrawTextEdit(rect, controlObject, g_sci->strSplit(text.c_str(), NULL).c_str(), fontId, mode, style, cursorPos, maxChars, hilite); return; case SCI_CONTROLS_TYPE_ICON: @@ -844,7 +848,7 @@ void _k_GenericDrawControl(EngineState *s, reg_t controlObject, bool hilite) { priority = -1; } debugC(kDebugLevelGraphics, "drawing icon control %04x:%04x to %d,%d", PRINT_REG(controlObject), x, y - 1); - g_sci->_gfxControls->kernelDrawIcon(rect, controlObject, viewId, loopNo, celNo, priority, style, hilite); + g_sci->_gfxControls16->kernelDrawIcon(rect, controlObject, viewId, loopNo, celNo, priority, style, hilite); return; case SCI_CONTROLS_TYPE_LIST: @@ -892,7 +896,7 @@ void _k_GenericDrawControl(EngineState *s, reg_t controlObject, bool hilite) { } debugC(kDebugLevelGraphics, "drawing list control %04x:%04x to %d,%d, diff %d", PRINT_REG(controlObject), x, y, SCI_MAX_SAVENAME_LENGTH); - g_sci->_gfxControls->kernelDrawList(rect, controlObject, maxChars, listCount, listEntries, fontId, style, upperPos, cursorPos, isAlias, hilite); + g_sci->_gfxControls16->kernelDrawList(rect, controlObject, maxChars, listCount, listEntries, fontId, style, upperPos, cursorPos, isAlias, hilite); free(listEntries); delete[] listStrings; return; @@ -972,7 +976,10 @@ reg_t kEditControl(EngineState *s, int argc, reg_t *argv) { switch (controlType) { case SCI_CONTROLS_TYPE_TEXTEDIT: // Only process textedit controls in here - g_sci->_gfxControls->kernelTexteditChange(controlObject, eventObject); + g_sci->_gfxControls16->kernelTexteditChange(controlObject, eventObject); + break; + default: + break; } } return s->r_acc; @@ -1285,7 +1292,10 @@ reg_t kCantBeHere32(EngineState *s, int argc, reg_t *argv) { } reg_t kAddScreenItem(EngineState *s, int argc, reg_t *argv) { - g_sci->_gfxFrameout->kernelAddScreenItem(argv[0]); + if (g_sci->_gfxFrameout->findScreenItem(argv[0]) == NULL) + g_sci->_gfxFrameout->kernelAddScreenItem(argv[0]); + else + g_sci->_gfxFrameout->kernelUpdateScreenItem(argv[0]); return s->r_acc; } @@ -1314,11 +1324,6 @@ reg_t kUpdatePlane(EngineState *s, int argc, reg_t *argv) { return s->r_acc; } -reg_t kRepaintPlane(EngineState *s, int argc, reg_t *argv) { - g_sci->_gfxFrameout->kernelRepaintPlane(argv[0]); - return s->r_acc; -} - reg_t kAddPicAt(EngineState *s, int argc, reg_t *argv) { reg_t planeObj = argv[0]; GuiResourceId pictureId = argv[1].toUint16(); @@ -1338,30 +1343,23 @@ reg_t kFrameOut(EngineState *s, int argc, reg_t *argv) { return NULL_REG; } +reg_t kObjectIntersect(EngineState *s, int argc, reg_t *argv) { + Common::Rect objRect1 = g_sci->_gfxCompare->getNSRect(argv[0]); + Common::Rect objRect2 = g_sci->_gfxCompare->getNSRect(argv[1]); + return make_reg(0, objRect1.intersects(objRect2)); +} + // Tests if the coordinate is on the passed object reg_t kIsOnMe(EngineState *s, int argc, reg_t *argv) { uint16 x = argv[0].toUint16(); uint16 y = argv[1].toUint16(); reg_t targetObject = argv[2]; uint16 illegalBits = argv[3].offset; - Common::Rect nsRect; + Common::Rect nsRect = g_sci->_gfxCompare->getNSRect(targetObject, true); // we assume that x, y are local coordinates - // Get the bounding rectangle of the object - nsRect.left = readSelectorValue(s->_segMan, targetObject, SELECTOR(nsLeft)); - nsRect.top = readSelectorValue(s->_segMan, targetObject, SELECTOR(nsTop)); - nsRect.right = readSelectorValue(s->_segMan, targetObject, SELECTOR(nsRight)); - nsRect.bottom = readSelectorValue(s->_segMan, targetObject, SELECTOR(nsBottom)); - - // nsRect top/left may be negative, adjust accordingly - Common::Rect checkRect = nsRect; - if (checkRect.top < 0) - checkRect.top = 0; - if (checkRect.left < 0) - checkRect.left = 0; - - bool contained = checkRect.contains(x, y); + bool contained = nsRect.contains(x, y); if (contained && illegalBits) { // If illegalbits are set, we check the color of the pixel that got clicked on // for now, we return false if the pixel is transparent @@ -1387,70 +1385,29 @@ reg_t kCreateTextBitmap(EngineState *s, int argc, reg_t *argv) { debugC(kDebugLevelStrings, "kCreateTextBitmap case 0 (%04x:%04x, %04x:%04x, %04x:%04x)", PRINT_REG(argv[1]), PRINT_REG(argv[2]), PRINT_REG(argv[3])); debugC(kDebugLevelStrings, "%s", text.c_str()); - // TODO: arguments 1 and 2 - g_sci->_gfxText32->createTextBitmap(object); - break; + uint16 maxWidth = argv[1].toUint16(); // nsRight - nsLeft + 1 + uint16 maxHeight = argv[2].toUint16(); // nsBottom - nsTop + 1 + return g_sci->_gfxText32->createTextBitmap(object, maxWidth, maxHeight); } case 1: { if (argc != 2) { - warning("kCreateTextBitmap(0): expected 2 arguments, got %i", argc); + warning("kCreateTextBitmap(1): expected 2 arguments, got %i", argc); return NULL_REG; } reg_t object = argv[1]; Common::String text = s->_segMan->getString(readSelector(s->_segMan, object, SELECTOR(text))); debugC(kDebugLevelStrings, "kCreateTextBitmap case 1 (%04x:%04x)", PRINT_REG(argv[1])); debugC(kDebugLevelStrings, "%s", text.c_str()); - g_sci->_gfxText32->createTextBitmap(object); - break; + return g_sci->_gfxText32->createTextBitmap(object); } default: warning("CreateTextBitmap(%d)", argv[0].toUint16()); + return NULL_REG; } - - return NULL_REG; } -reg_t kRobot(EngineState *s, int argc, reg_t *argv) { - - int16 subop = argv[0].toUint16(); - - switch (subop) { - case 0: { // init - int id = argv[1].toUint16(); - reg_t obj = argv[2]; - int16 flag = argv[3].toSint16(); - int16 x = argv[4].toUint16(); - int16 y = argv[5].toUint16(); - warning("kRobot(init), id %d, obj %04x:%04x, flag %d, x=%d, y=%d", id, PRINT_REG(obj), flag, x, y); - g_sci->_robotDecoder->load(id); - g_sci->_robotDecoder->setPos(x, y); - } - break; - case 1: // LSL6 hires (startup) - // TODO - return NULL_REG; // an integer is expected - case 4: { // start - we don't really have a use for this one - //int id = argv[1].toUint16(); - //warning("kRobot(start), id %d", id); - } - break; - case 7: // unknown, called e.g. by Phantasmagoria - warning("kRobot(%d)", subop); - break; - case 8: // sync - if ((uint32)g_sci->_robotDecoder->getCurFrame() != g_sci->_robotDecoder->getFrameCount() - 1) { - writeSelector(s->_segMan, argv[1], SELECTOR(signal), NULL_REG); - } else { - g_sci->_robotDecoder->close(); - // Signal the engine scripts that the video is done - writeSelector(s->_segMan, argv[1], SELECTOR(signal), SIGNAL_REG); - } - break; - default: - warning("kRobot(%d)", subop); - break; - } - +reg_t kDisposeTextBitmap(EngineState *s, int argc, reg_t *argv) { + g_sci->_gfxText32->disposeTextBitmap(argv[0]); return s->r_acc; } @@ -1484,22 +1441,30 @@ reg_t kWinHelp(EngineState *s, int argc, reg_t *argv) { } /** - * Used to programmatically mass set properties of the target plane + * Used for scene transitions, replacing (but reusing parts of) the old + * transition code. */ reg_t kSetShowStyle(EngineState *s, int argc, reg_t *argv) { - // TODO: This is all a stub/skeleton, thus we're invoking kStub() for now - kStub(s, argc, argv); - // Can be called with 7 or 8 parameters - // showStyle matches the style selector of the associated plane object + // The style defines which transition to perform. Related to the transition + // tables inside graphics/transitions.cpp uint16 showStyle = argv[0].toUint16(); // 0 - 15 - reg_t planeObj = argv[1]; - //argv[2] // seconds - //argv[3] // back + reg_t planeObj = argv[1]; // the affected plane + //argv[2] // seconds that the transition lasts + //argv[3] // back color to be used(?) //int16 priority = argv[4].toSint16(); - //argv[5] // animate + //argv[5] // boolean, animate or not while the transition lasts //argv[6] // refFrame - //int16 unk7 = (argc >= 8) ? argv[7].toSint16() : 0; // divisions + + // If the game has the pFadeArray selector, another parameter is used here, + // before the optional last parameter + /*bool hasFadeArray = g_sci->getKernel()->findSelector("pFadeArray") > 0; + if (hasFadeArray) { + // argv[7] + //int16 unk7 = (argc >= 9) ? argv[8].toSint16() : 0; // divisions (transition steps?) + } else { + //int16 unk7 = (argc >= 8) ? argv[7].toSint16() : 0; // divisions (transition steps?) + }*/ if (showStyle > 15) { warning("kSetShowStyle: Illegal style %d for plane %04x:%04x", showStyle, PRINT_REG(planeObj)); @@ -1508,36 +1473,36 @@ reg_t kSetShowStyle(EngineState *s, int argc, reg_t *argv) { // TODO: Check if the plane is in the list of planes to draw - return s->r_acc; -} - -reg_t kCelInfo(EngineState *s, int argc, reg_t *argv) { // TODO: This is all a stub/skeleton, thus we're invoking kStub() for now kStub(s, argc, argv); - // Used by Shivers 1, room 23601 - - // 6 arguments, all integers: - // argv[0] - subop (0 - 4). It's constantly called with 4 in Shivers 1 - // argv[1] - view (used with view 23602 in Shivers 1) - // argv[2] - loop - // argv[3] - cel - // argv[4] - unknown (row?) - // argv[5] - unknown (column?) - - // Subops: - // 0 - return the view - // 1 - return the loop - // 2, 3 - nop - // 4 - returns some kind of hash (?) based on the view and the two last params - - // This seems to be a debug function, but it could be used to check if - // the jigsaw pieces "stick" together (they currently don't, unless I'm missing - // something) - return s->r_acc; } +reg_t kCelInfo(EngineState *s, int argc, reg_t *argv) { + // Used by Shivers 1, room 23601 to determine what blocks on the red door puzzle board + // are occupied by pieces already + + switch (argv[0].toUint16()) { // subops 0 - 4 + // 0 - return the view + // 1 - return the loop + // 2, 3 - nop + case 4: { + GuiResourceId viewId = argv[1].toSint16(); + int16 loopNo = argv[2].toSint16(); + int16 celNo = argv[3].toSint16(); + int16 x = argv[4].toUint16(); + int16 y = argv[5].toUint16(); + byte color = g_sci->_gfxCache->kernelViewGetColorAtCoordinate(viewId, loopNo, celNo, x, y); + return make_reg(0, color); + } + default: { + kStub(s, argc, argv); + return s->r_acc; + } + } +} + reg_t kScrollWindow(EngineState *s, int argc, reg_t *argv) { // Used by Phantasmagoria 1 and SQ6. In SQ6, it is used for the messages // shown in the scroll window at the bottom of the screen. @@ -1670,6 +1635,11 @@ reg_t kFont(EngineState *s, int argc, reg_t *argv) { return s->r_acc; } +// TODO: Eventually, all of the kBitmap operations should be put +// in a separate class + +#define BITMAP_HEADER_SIZE 46 + reg_t kBitmap(EngineState *s, int argc, reg_t *argv) { // Used for bitmap operations in SCI2.1 and SCI3. // This is the SCI2.1 version, the functionality seems to have changed in SCI3. @@ -1681,21 +1651,28 @@ reg_t kBitmap(EngineState *s, int argc, reg_t *argv) { // script 64890 and TransView::init() in script 64884 uint16 width = argv[1].toUint16(); uint16 height = argv[2].toUint16(); - uint16 skip = argv[3].toUint16(); - uint16 back = argv[4].toUint16(); - uint16 width2 = (argc >= 6) ? argv[5].toUint16() : 0; - uint16 height2 = (argc >= 7) ? argv[6].toUint16() : 0; - uint16 transparent = (argc >= 8) ? argv[7].toUint16() : 0; - warning("kBitmap(0): width %d, height %d, skip %d, back %d, width2 %d, height2 %d, transparent %d", - width, height, skip, back, width2, height2, transparent); - // returns a pointer to a bitmap + //uint16 skip = argv[3].toUint16(); + uint16 back = argv[4].toUint16(); // usually equals skip + //uint16 width2 = (argc >= 6) ? argv[5].toUint16() : 0; + //uint16 height2 = (argc >= 7) ? argv[6].toUint16() : 0; + //uint16 transparentFlag = (argc >= 8) ? argv[7].toUint16() : 0; + + // TODO: skip, width2, height2, transparentFlag + // (used for transparent bitmaps) + int entrySize = width * height + BITMAP_HEADER_SIZE; + reg_t memoryId = s->_segMan->allocateHunkEntry("Bitmap()", entrySize); + byte *memoryPtr = s->_segMan->getHunkPointer(memoryId); + memset(memoryPtr, 0, BITMAP_HEADER_SIZE); // zero out the bitmap header + memset(memoryPtr + BITMAP_HEADER_SIZE, back, width * height); + // Save totalWidth, totalHeight + // TODO: Save the whole bitmap header, like SSCI does + WRITE_LE_UINT16(memoryPtr, width); + WRITE_LE_UINT16(memoryPtr + 2, height); + return memoryId; } break; - case 1: // dispose bitmap surface - // 1 param, bitmap pointer, called e.g. from MenuItem::dispose - // in Torin's Passage, script 64893 - warning("kBitmap(1), bitmap ptr %04x:%04x", PRINT_REG(argv[1])); - break; + case 1: // dispose text bitmap surface + return kDisposeTextBitmap(s, argc - 1, argv + 1); case 2: // dispose bitmap surface, with extra param // 2 params, called e.g. from MenuItem::dispose in Torin's Passage, // script 64893 @@ -1705,50 +1682,113 @@ reg_t kBitmap(EngineState *s, int argc, reg_t *argv) { { // 6 params, called e.g. from TiledBitmap::resize() in Torin's Passage, // script 64869 - reg_t bitmapPtr = argv[1]; // obtained from kBitmap(0) + reg_t hunkId = argv[1]; // obtained from kBitmap(0) // The tiled view seems to always have 2 loops. // These loops need to have 1 cel in loop 0 and 8 cels in loop 1. - uint16 view = argv[2].toUint16(); // vTiles selector + uint16 viewNum = argv[2].toUint16(); // vTiles selector uint16 loop = argv[3].toUint16(); uint16 cel = argv[4].toUint16(); uint16 x = argv[5].toUint16(); uint16 y = argv[6].toUint16(); - warning("kBitmap(3): bitmap ptr %04x:%04x, view %d, loop %d, cel %d, x %d, y %d", - PRINT_REG(bitmapPtr), view, loop, cel, x, y); + + byte *memoryPtr = s->_segMan->getHunkPointer(hunkId); + // Get totalWidth, totalHeight + uint16 totalWidth = READ_LE_UINT16(memoryPtr); + uint16 totalHeight = READ_LE_UINT16(memoryPtr + 2); + byte *bitmap = memoryPtr + BITMAP_HEADER_SIZE; + + GfxView *view = g_sci->_gfxCache->getView(viewNum); + uint16 tileWidth = view->getWidth(loop, cel); + uint16 tileHeight = view->getHeight(loop, cel); + const byte *tileBitmap = view->getBitmap(loop, cel); + uint16 width = MIN<uint16>(totalWidth - x, tileWidth); + uint16 height = MIN<uint16>(totalHeight - y, tileHeight); + + for (uint16 curY = 0; curY < height; curY++) { + for (uint16 curX = 0; curX < width; curX++) { + bitmap[(curY + y) * totalWidth + (curX + x)] = tileBitmap[curY * tileWidth + curX]; + } + } + } break; - case 4: // process text + case 4: // add text to bitmap { // 13 params, called e.g. from TextButton::createBitmap() in Torin's Passage, // script 64894 - reg_t bitmapPtr = argv[1]; // obtained from kBitmap(0) + reg_t hunkId = argv[1]; // obtained from kBitmap(0) Common::String text = s->_segMan->getString(argv[2]); - // unk3 - // unk4 - // unk5 - // unk6 - // skip? - // back? - uint16 font = argv[9].toUint16(); - uint16 mode = argv[10].toUint16(); - // unk + uint16 textX = argv[3].toUint16(); + uint16 textY = argv[4].toUint16(); + //reg_t unk5 = argv[5]; + //reg_t unk6 = argv[6]; + //reg_t unk7 = argv[7]; // skip? + //reg_t unk8 = argv[8]; // back? + //reg_t unk9 = argv[9]; + uint16 fontId = argv[10].toUint16(); + //uint16 mode = argv[11].toUint16(); uint16 dimmed = argv[12].toUint16(); - warning("kBitmap(4): bitmap ptr %04x:%04x, font %d, mode %d, dimmed %d - text: \"%s\"", - PRINT_REG(bitmapPtr), font, mode, dimmed, text.c_str()); + //warning("kBitmap(4): bitmap ptr %04x:%04x, font %d, mode %d, dimmed %d - text: \"%s\"", + // PRINT_REG(bitmapPtr), font, mode, dimmed, text.c_str()); + uint16 foreColor = 255; // TODO + + byte *memoryPtr = s->_segMan->getHunkPointer(hunkId); + // Get totalWidth, totalHeight + uint16 totalWidth = READ_LE_UINT16(memoryPtr); + uint16 totalHeight = READ_LE_UINT16(memoryPtr + 2); + byte *bitmap = memoryPtr + BITMAP_HEADER_SIZE; + + GfxFont *font = g_sci->_gfxCache->getFont(fontId); + + int16 charCount = 0; + uint16 curX = textX, curY = textY; + const char *txt = text.c_str(); + + while (*txt) { + charCount = g_sci->_gfxText32->GetLongest(txt, totalWidth, font); + if (charCount == 0) + break; + + for (int i = 0; i < charCount; i++) { + unsigned char curChar = txt[i]; + font->drawToBuffer(curChar, curY, curX, foreColor, dimmed, bitmap, totalWidth, totalHeight); + curX += font->getCharWidth(curChar); + } + + curX = textX; + curY += font->getHeight(); + txt += charCount; + while (*txt == ' ') + txt++; // skip over breaking spaces + } + } break; - case 5: + case 5: // fill with color { // 6 params, called e.g. from TextView::init() and TextView::draw() // in Torin's Passage, script 64890 - reg_t bitmapPtr = argv[1]; // obtained from kBitmap(0) - uint16 unk1 = argv[2].toUint16(); // unknown, usually 0, judging from scripts? - uint16 unk2 = argv[3].toUint16(); // unknown, usually 0, judging from scripts? - uint16 width = argv[4].toUint16(); // width - 1 - uint16 height = argv[5].toUint16(); // height - 1 + reg_t hunkId = argv[1]; // obtained from kBitmap(0) + uint16 x = argv[2].toUint16(); + uint16 y = argv[3].toUint16(); + uint16 fillWidth = argv[4].toUint16(); // width - 1 + uint16 fillHeight = argv[5].toUint16(); // height - 1 uint16 back = argv[6].toUint16(); - warning("kBitmap(5): bitmap ptr %04x:%04x, unk1 %d, unk2 %d, width %d, height %d, back %d", - PRINT_REG(bitmapPtr), unk1, unk2, width, height, back); + + byte *memoryPtr = s->_segMan->getHunkPointer(hunkId); + // Get totalWidth, totalHeight + uint16 totalWidth = READ_LE_UINT16(memoryPtr); + uint16 totalHeight = READ_LE_UINT16(memoryPtr + 2); + uint16 width = MIN<uint16>(totalWidth - x, fillWidth); + uint16 height = MIN<uint16>(totalHeight - y, fillHeight); + byte *bitmap = memoryPtr + BITMAP_HEADER_SIZE; + + for (uint16 curY = 0; curY < height; curY++) { + for (uint16 curX = 0; curX < width; curX++) { + bitmap[(curY + y) * totalWidth + (curX + x)] = back; + } + } + } break; default: @@ -1759,6 +1799,20 @@ reg_t kBitmap(EngineState *s, int argc, reg_t *argv) { return s->r_acc; } +// Used for edit boxes in save/load dialogs. It's a rewritten version of kEditControl, +// but it handles events on its own, using an internal loop, instead of using SCI +// scripts for event management like kEditControl does. Called by script 64914, +// DEdit::hilite(). +reg_t kEditText(EngineState *s, int argc, reg_t *argv) { + reg_t controlObject = argv[0]; + + if (!controlObject.isNull()) { + g_sci->_gfxControls32->kernelTexteditChange(controlObject); + } + + return s->r_acc; +} + #endif } // End of namespace Sci diff --git a/engines/sci/engine/klists.cpp b/engines/sci/engine/klists.cpp index 68469f5c9a..83e59c9c20 100644 --- a/engines/sci/engine/klists.cpp +++ b/engines/sci/engine/klists.cpp @@ -409,7 +409,7 @@ int sort_temp_cmp(const void *p1, const void *p2) { const sort_temp_t *st1 = (const sort_temp_t *)p1; const sort_temp_t *st2 = (const sort_temp_t *)p2; - if (st1->order.segment < st1->order.segment || (st1->order.segment == st1->order.segment && st1->order.offset < st2->order.offset)) + if (st1->order.segment < st2->order.segment || (st1->order.segment == st2->order.segment && st1->order.offset < st2->order.offset)) return -1; if (st1->order.segment > st2->order.segment || (st1->order.segment == st2->order.segment && st1->order.offset > st2->order.offset)) @@ -691,6 +691,16 @@ reg_t kArray(EngineState *s, int argc, reg_t *argv) { } case 2: { // At (return value at an index) SciArray<reg_t> *array = s->_segMan->lookupArray(argv[1]); + if (g_sci->getGameId() == GID_PHANTASMAGORIA2) { + // HACK: Phantasmagoria 2 keeps trying to access past the end of an + // array when it starts. I'm assuming it's trying to see where the + // array ends, or tries to resize it. Adjust the array size + // accordingly, and return NULL for now. + if (array->getSize() == argv[2].toUint16()) { + array->setSize(argv[2].toUint16()); + return NULL_REG; + } + } return array->getValue(argv[2].toUint16()); } case 3: { // Atput (put value at an index) diff --git a/engines/sci/engine/kmovement.cpp b/engines/sci/engine/kmovement.cpp index 14f7db47a0..649a1428a0 100644 --- a/engines/sci/engine/kmovement.cpp +++ b/engines/sci/engine/kmovement.cpp @@ -505,116 +505,6 @@ reg_t kDoAvoider(EngineState *s, int argc, reg_t *argv) { } writeSelectorValue(segMan, avoider, SELECTOR(heading), avoiderHeading); return s->r_acc; - -#if 0 - reg_t client, looper, mover; - int angle; - int dx, dy; - int destx, desty; - - s->r_acc = SIGNAL_REG; - - if (!s->_segMan->isHeapObject(avoider)) { - error("DoAvoider() where avoider %04x:%04x is not an object", PRINT_REG(avoider)); - return NULL_REG; - } - - client = readSelector(segMan, avoider, SELECTOR(client)); - - if (!s->_segMan->isHeapObject(client)) { - error("DoAvoider() where client %04x:%04x is not an object", PRINT_REG(client)); - return NULL_REG; - } - - looper = readSelector(segMan, client, SELECTOR(looper)); - mover = readSelector(segMan, client, SELECTOR(mover)); - - if (!s->_segMan->isHeapObject(mover)) { - if (mover.segment) { - error("DoAvoider() where mover %04x:%04x is not an object", PRINT_REG(mover)); - } - return s->r_acc; - } - - destx = readSelectorValue(segMan, mover, SELECTOR(x)); - desty = readSelectorValue(segMan, mover, SELECTOR(y)); - - debugC(kDebugLevelBresen, "Doing avoider %04x:%04x (dest=%d,%d)", PRINT_REG(avoider), destx, desty); - - invokeSelector(s, mover, SELECTOR(doit), argc, argv); - - mover = readSelector(segMan, client, SELECTOR(mover)); - if (!mover.segment) // Mover has been disposed? - return s->r_acc; // Return gracefully. - - invokeSelector(s, client, SELECTOR(isBlocked), argc, argv); - - dx = destx - readSelectorValue(segMan, client, SELECTOR(x)); - dy = desty - readSelectorValue(segMan, client, SELECTOR(y)); - angle = getAngle(dx, dy); - - debugC(kDebugLevelBresen, "Movement (%d,%d), angle %d is %sblocked", dx, dy, angle, (s->r_acc.offset) ? " " : "not "); - - if (s->r_acc.offset) { // isBlocked() returned non-zero - int rotation = (g_sci->getRNG().getRandomBit() == 1) ? 45 : (360 - 45); // Clockwise/counterclockwise - int oldx = readSelectorValue(segMan, client, SELECTOR(x)); - int oldy = readSelectorValue(segMan, client, SELECTOR(y)); - int xstep = readSelectorValue(segMan, client, SELECTOR(xStep)); - int ystep = readSelectorValue(segMan, client, SELECTOR(yStep)); - int moves; - - debugC(kDebugLevelBresen, " avoider %04x:%04x", PRINT_REG(avoider)); - - for (moves = 0; moves < 8; moves++) { - int move_x = (int)(sin(angle * M_PI / 180.0) * (xstep)); - int move_y = (int)(-cos(angle * M_PI / 180.0) * (ystep)); - - writeSelectorValue(segMan, client, SELECTOR(x), oldx + move_x); - writeSelectorValue(segMan, client, SELECTOR(y), oldy + move_y); - - debugC(kDebugLevelBresen, "Pos (%d,%d): Trying angle %d; delta=(%d,%d)", oldx, oldy, angle, move_x, move_y); - - invokeSelector(s, client, SELECTOR(canBeHere), argc, argv); - - writeSelectorValue(segMan, client, SELECTOR(x), oldx); - writeSelectorValue(segMan, client, SELECTOR(y), oldy); - - if (s->r_acc.offset) { // We can be here - debugC(kDebugLevelBresen, "Success"); - writeSelectorValue(segMan, client, SELECTOR(heading), angle); - - return make_reg(0, angle); - } - - angle += rotation; - - if (angle > 360) - angle -= 360; - } - - error("DoAvoider failed for avoider %04x:%04x", PRINT_REG(avoider)); - } else { - int heading = readSelectorValue(segMan, client, SELECTOR(heading)); - - if (heading == -1) - return s->r_acc; // No change - - writeSelectorValue(segMan, client, SELECTOR(heading), angle); - - s->r_acc = make_reg(0, angle); - - if (looper.segment) { - reg_t params[2] = { make_reg(0, angle), client }; - invokeSelector(s, looper, SELECTOR(doit), argc, argv, 2, params); - return s->r_acc; - } else { - // No looper? Fall back to DirLoop - kDirLoopWorker(client, (uint16)angle, s, argc, argv); - } - } - - return s->r_acc; -#endif } } // End of namespace Sci diff --git a/engines/sci/engine/ksound.cpp b/engines/sci/engine/ksound.cpp index 33bef58e52..c469f775f9 100644 --- a/engines/sci/engine/ksound.cpp +++ b/engines/sci/engine/ksound.cpp @@ -195,6 +195,13 @@ reg_t kDoAudio(EngineState *s, int argc, reg_t *argv) { return make_reg(0, 1); } else { int16 language = argv[1].toSint16(); + + // athrxx: It seems from disasm that the original KQ5 FM-Towns loads a default language (Japanese) audio map at the beginning + // right after loading the video and audio drivers. The -1 language argument in here simply means that the original will stick + // with Japanese. Instead of doing that we switch to the language selected in the launcher. + if (g_sci->getPlatform() == Common::kPlatformFMTowns && language == -1) + language = (g_sci->getLanguage() == Common::JA_JPN) ? K_LANG_JAPANESE : K_LANG_ENGLISH; + debugC(kDebugLevelSound, "kDoAudio: set language to %d", language); if (language != -1) diff --git a/engines/sci/engine/kstring.cpp b/engines/sci/engine/kstring.cpp index 1a9359bb26..5ae18c1367 100644 --- a/engines/sci/engine/kstring.cpp +++ b/engines/sci/engine/kstring.cpp @@ -697,13 +697,15 @@ reg_t kString(EngineState *s, int argc, reg_t *argv) { case 6: { // Cpy const char *string2 = 0; uint32 string2Size = 0; + Common::String string; if (argv[3].segment == s->_segMan->getStringSegmentId()) { - SciString *string = s->_segMan->lookupString(argv[3]); - string2 = string->getRawData(); - string2Size = string->getSize(); + SciString *sstr; + sstr = s->_segMan->lookupString(argv[3]); + string2 = sstr->getRawData(); + string2Size = sstr->getSize(); } else { - Common::String string = s->_segMan->getString(argv[3]); + string = s->_segMan->getString(argv[3]); string2 = string.c_str(); string2Size = string.size() + 1; } diff --git a/engines/sci/engine/kvideo.cpp b/engines/sci/engine/kvideo.cpp index 6d810d516c..c9cf652013 100644 --- a/engines/sci/engine/kvideo.cpp +++ b/engines/sci/engine/kvideo.cpp @@ -21,6 +21,7 @@ */ #include "engines/util.h" +#include "sci/engine/kernel.h" #include "sci/engine/state.h" #include "sci/graphics/helpers.h" #include "sci/graphics/cursor.h" @@ -39,6 +40,7 @@ #include "sci/video/seq_decoder.h" #ifdef ENABLE_SCI32 #include "video/coktel_decoder.h" +#include "sci/video/robot_decoder.h" #endif namespace Sci { @@ -230,6 +232,49 @@ reg_t kShowMovie(EngineState *s, int argc, reg_t *argv) { #ifdef ENABLE_SCI32 +reg_t kRobot(EngineState *s, int argc, reg_t *argv) { + int16 subop = argv[0].toUint16(); + + switch (subop) { + case 0: { // init + int id = argv[1].toUint16(); + reg_t obj = argv[2]; + int16 flag = argv[3].toSint16(); + int16 x = argv[4].toUint16(); + int16 y = argv[5].toUint16(); + warning("kRobot(init), id %d, obj %04x:%04x, flag %d, x=%d, y=%d", id, PRINT_REG(obj), flag, x, y); + g_sci->_robotDecoder->load(id); + g_sci->_robotDecoder->setPos(x, y); + } + break; + case 1: // LSL6 hires (startup) + // TODO + return NULL_REG; // an integer is expected + case 4: { // start - we don't really have a use for this one + //int id = argv[1].toUint16(); + //warning("kRobot(start), id %d", id); + } + break; + case 7: // unknown, called e.g. by Phantasmagoria + warning("kRobot(%d)", subop); + break; + case 8: // sync + if ((uint32)g_sci->_robotDecoder->getCurFrame() != g_sci->_robotDecoder->getFrameCount() - 1) { + writeSelector(s->_segMan, argv[1], SELECTOR(signal), NULL_REG); + } else { + g_sci->_robotDecoder->close(); + // Signal the engine scripts that the video is done + writeSelector(s->_segMan, argv[1], SELECTOR(signal), SIGNAL_REG); + } + break; + default: + warning("kRobot(%d)", subop); + break; + } + + return s->r_acc; +} + reg_t kPlayVMD(EngineState *s, int argc, reg_t *argv) { uint16 operation = argv[0].toUint16(); Video::VideoDecoder *videoDecoder = 0; @@ -331,6 +376,55 @@ reg_t kPlayVMD(EngineState *s, int argc, reg_t *argv) { return s->r_acc; } +reg_t kPlayDuck(EngineState *s, int argc, reg_t *argv) { + uint16 operation = argv[0].toUint16(); + Video::VideoDecoder *videoDecoder = 0; + bool reshowCursor = g_sci->_gfxCursor->isVisible(); + + switch (operation) { + case 1: // Play + // 6 params + s->_videoState.reset(); + s->_videoState.fileName = Common::String::format("%d.duk", argv[1].toUint16()); + + videoDecoder = new Video::AviDecoder(g_system->getMixer()); + + if (!videoDecoder->loadFile(s->_videoState.fileName)) { + warning("Could not open Duck %s", s->_videoState.fileName.c_str()); + break; + } + + if (reshowCursor) + g_sci->_gfxCursor->kernelHide(); + + { + // Duck videos are 16bpp, so we need to change the active pixel format + int oldWidth = g_system->getWidth(); + int oldHeight = g_system->getHeight(); + Common::List<Graphics::PixelFormat> formats; + formats.push_back(videoDecoder->getPixelFormat()); + initGraphics(640, 480, true, formats); + + if (g_system->getScreenFormat().bytesPerPixel != videoDecoder->getPixelFormat().bytesPerPixel) + error("Could not switch screen format for the duck video"); + + playVideo(videoDecoder, s->_videoState); + + // Switch back to 8bpp + initGraphics(oldWidth, oldHeight, oldWidth > 320); + } + + if (reshowCursor) + g_sci->_gfxCursor->kernelShow(); + break; + default: + kStub(s, argc, argv); + break; + } + + return s->r_acc; +} + #endif } // End of namespace Sci diff --git a/engines/sci/engine/object.cpp b/engines/sci/engine/object.cpp index a1854a2723..78e216cdb5 100644 --- a/engines/sci/engine/object.cpp +++ b/engines/sci/engine/object.cpp @@ -202,9 +202,10 @@ bool Object::initBaseObject(SegManager *segMan, reg_t addr, bool doInitSuperClas name = "<invalid name>"; } - warning("Object %04x:%04x (name %s, script %d) varnum doesn't " - "match baseObj's: obj %d, base %d", PRINT_REG(_pos), - name, objScript, originalVarCount, baseObj->getVarCount()); + debugC(kDebugLevelVM, "Object %04x:%04x (name %s, script %d) " + "varnum doesn't match baseObj's: obj %d, base %d", + PRINT_REG(_pos), name, objScript, + originalVarCount, baseObj->getVarCount()); #if 0 // We enumerate the methods selectors which could be hidden here diff --git a/engines/sci/engine/savegame.cpp b/engines/sci/engine/savegame.cpp index c30518ab42..f1c7133d01 100644 --- a/engines/sci/engine/savegame.cpp +++ b/engines/sci/engine/savegame.cpp @@ -203,7 +203,8 @@ void SegManager::saveLoadWithSerializer(Common::Serializer &s) { // Now, load the script itself scr->load(g_sci->getResMan()); - for (ObjMap::iterator it = scr->_objects.begin(); it != scr->_objects.end(); ++it) + ObjMap objects = scr->getObjectMap(); + for (ObjMap::iterator it = objects.begin(); it != objects.end(); ++it) it->_value.syncBaseObject(scr->getBuf(it->_value.getPos().offset)); } @@ -226,9 +227,10 @@ void SegManager::saveLoadWithSerializer(Common::Serializer &s) { continue; Script *scr = (Script *)_heap[i]; - scr->_localsBlock = (scr->_localsSegment == 0) ? NULL : (LocalVariables *)(_heap[scr->_localsSegment]); + scr->syncLocalsBlock(this); - for (ObjMap::iterator it = scr->_objects.begin(); it != scr->_objects.end(); ++it) { + ObjMap objects = scr->getObjectMap(); + for (ObjMap::iterator it = objects.begin(); it != objects.end(); ++it) { reg_t addr = it->_value.getPos(); Object *obj = scr->scriptObjInit(addr, false); @@ -237,7 +239,7 @@ void SegManager::saveLoadWithSerializer(Common::Serializer &s) { // TODO/FIXME: This should not be happening at all. It might indicate a possible issue // with the garbage collector. It happens for example in LSL5 (German, perhaps English too). warning("Failed to locate base object for object at %04X:%04X; skipping", PRINT_REG(addr)); - scr->_objects.erase(addr.toUint16()); + objects.erase(addr.toUint16()); } } } @@ -545,8 +547,6 @@ void DataStack::saveLoadWithSerializer(Common::Serializer &s) { void SciMusic::saveLoadWithSerializer(Common::Serializer &s) { // Sync song lib data. When loading, the actual song lib will be initialized // afterwards in gamestate_restore() - Common::StackLock lock(_mutex); - int songcount = 0; byte masterVolume = soundGetMasterVolume(); byte reverb = _pMidiDrv->getReverb(); @@ -576,9 +576,12 @@ void SciMusic::saveLoadWithSerializer(Common::Serializer &s) { songcount = _playList.size(); s.syncAsUint32LE(songcount); - if (s.isLoading()) { + if (s.isLoading()) clearPlayList(); + Common::StackLock lock(_mutex); + + if (s.isLoading()) { for (int i = 0; i < songcount; i++) { MusicEntry *curSong = new MusicEntry(); curSong->saveLoadWithSerializer(s); diff --git a/engines/sci/engine/script.cpp b/engines/sci/engine/script.cpp index 01e1afe5ea..8b26969f4a 100644 --- a/engines/sci/engine/script.cpp +++ b/engines/sci/engine/script.cpp @@ -492,8 +492,29 @@ SegmentRef Script::dereference(reg_t pointer) { return ret; } +LocalVariables *Script::allocLocalsSegment(SegManager *segMan) { + if (!getLocalsCount()) { // No locals + return NULL; + } else { + LocalVariables *locals; + + if (_localsSegment) { + locals = (LocalVariables *)segMan->getSegment(_localsSegment, SEG_TYPE_LOCALS); + if (!locals || locals->getType() != SEG_TYPE_LOCALS || locals->script_id != getScriptNumber()) + error("Invalid script locals segment while allocating locals"); + } else + locals = (LocalVariables *)segMan->allocSegment(new LocalVariables(), &_localsSegment); + + _localsBlock = locals; + locals->script_id = getScriptNumber(); + locals->_locals.resize(getLocalsCount()); + + return locals; + } +} + void Script::initializeLocals(SegManager *segMan) { - LocalVariables *locals = segMan->allocLocalsSegment(this); + LocalVariables *locals = allocLocalsSegment(segMan); if (locals) { if (getSciVersion() > SCI_VERSION_0_EARLY) { const byte *base = (const byte *)(_buf + getLocalsOffset()); @@ -508,6 +529,10 @@ void Script::initializeLocals(SegManager *segMan) { } } +void Script::syncLocalsBlock(SegManager *segMan) { + _localsBlock = (_localsSegment == 0) ? NULL : (LocalVariables *)(segMan->getSegment(_localsSegment, SEG_TYPE_LOCALS)); +} + void Script::initializeClasses(SegManager *segMan) { const byte *seeker = 0; uint16 mult = 0; diff --git a/engines/sci/engine/script.h b/engines/sci/engine/script.h index ff061e0e36..1ebae3b7a8 100644 --- a/engines/sci/engine/script.h +++ b/engines/sci/engine/script.h @@ -62,23 +62,18 @@ private: const uint16 *_exportTable; /**< Abs. offset of the export table or 0 if not present */ uint16 _numExports; /**< Number of entries in the exports table */ - const byte *_synonyms; /**< Synonyms block or 0 if not present*/ + const byte *_synonyms; /**< Synonyms block or 0 if not present */ uint16 _numSynonyms; /**< Number of entries in the synonyms block */ int _localsOffset; uint16 _localsCount; bool _markedAsDeleted; - -public: - /** - * Table for objects, contains property variables. - * Indexed by the TODO offset. - */ - ObjMap _objects; SegmentId _localsSegment; /**< The local variable segment */ LocalVariables *_localsBlock; + ObjMap _objects; /**< Table for objects, contains property variables */ + public: int getLocalsOffset() const { return _localsOffset; } uint16 getLocalsCount() const { return _localsCount; } @@ -89,6 +84,11 @@ public: const byte *getBuf(uint offset = 0) const { return _buf + offset; } int getScriptNumber() const { return _nr; } + SegmentId getLocalsSegment() const { return _localsSegment; } + reg_t *getLocalsBegin() { return _localsBlock ? _localsBlock->_locals.begin() : NULL; } + void syncLocalsBlock(SegManager *segMan); + ObjMap &getObjectMap() { return _objects; } + const ObjMap &getObjectMap() const { return _objects; } public: Script(); @@ -295,6 +295,8 @@ private: * @param segmentId The script's segment id */ void initializeObjectsSci3(SegManager *segMan, SegmentId segmentId); + + LocalVariables *allocLocalsSegment(SegManager *segMan); }; } // End of namespace Sci diff --git a/engines/sci/engine/scriptdebug.cpp b/engines/sci/engine/scriptdebug.cpp index ad3f4fb788..554a6b6a2c 100644 --- a/engines/sci/engine/scriptdebug.cpp +++ b/engines/sci/engine/scriptdebug.cpp @@ -122,8 +122,8 @@ reg_t disassemble(EngineState *s, reg_t pos, bool printBWTag, bool printBytecode #endif i = 0; - while (g_opcode_formats[opcode][i]) { - switch (g_opcode_formats[opcode][i++]) { + while (g_sci->_opcode_formats[opcode][i]) { + switch (g_sci->_opcode_formats[opcode][i++]) { case Script_Invalid: warning("-Invalid operation-"); break; @@ -296,7 +296,7 @@ bool isJumpOpcode(EngineState *s, reg_t pos, reg_t& jumpTarget) { Script *script_entity = (Script *)mobj; const byte *scr = script_entity->getBuf(); - int scr_size = script_entity->getBufSize(); + int scr_size = script_entity->getScriptSize(); if (pos.offset >= scr_size) return false; @@ -310,7 +310,13 @@ bool isJumpOpcode(EngineState *s, reg_t pos, reg_t& jumpTarget) { case op_bt: case op_bnt: case op_jmp: - jumpTarget = pos + bytecount + opparams[0]; + { + reg_t jmpTarget = pos + bytecount + opparams[0]; + // QFG2 has invalid jumps outside the script buffer in script 260 + if (jmpTarget.offset >= scr_size) + return false; + jumpTarget = jmpTarget; + } return true; default: return false; diff --git a/engines/sci/engine/seg_manager.cpp b/engines/sci/engine/seg_manager.cpp index 1510af8508..04c61f7b7c 100644 --- a/engines/sci/engine/seg_manager.cpp +++ b/engines/sci/engine/seg_manager.cpp @@ -151,8 +151,8 @@ void SegManager::deallocate(SegmentId seg) { if (mobj->getType() == SEG_TYPE_SCRIPT) { Script *scr = (Script *)mobj; _scriptSegMap.erase(scr->getScriptNumber()); - if (scr->_localsSegment) - deallocate(scr->_localsSegment); + if (scr->getLocalsSegment()) + deallocate(scr->getLocalsSegment()); } delete mobj; @@ -270,12 +270,13 @@ reg_t SegManager::findObjectByName(const Common::String &name, int index) { if (mobj->getType() == SEG_TYPE_SCRIPT) { // It's a script, scan all objects in it const Script *scr = (const Script *)mobj; - for (ObjMap::const_iterator it = scr->_objects.begin(); it != scr->_objects.end(); ++it) { + const ObjMap &objects = scr->getObjectMap(); + for (ObjMap::const_iterator it = objects.begin(); it != objects.end(); ++it) { objpos.offset = it->_value.getPos().offset; if (name == getObjectName(objpos)) result.push_back(objpos); } - } else if (mobj->getType() == SEG_TYPE_CLONES) { + } else if (mobj->getType() == SEG_TYPE_CLONES) { // It's clone table, scan all objects in it const CloneTable *ct = (const CloneTable *)mobj; for (uint idx = 0; idx < ct->_table.size(); ++idx) { @@ -341,29 +342,6 @@ SegmentId SegManager::getScriptSegment(int script_nr, ScriptLoadType load) { return segment; } -LocalVariables *SegManager::allocLocalsSegment(Script *scr) { - if (!scr->getLocalsCount()) { // No locals - scr->_localsSegment = 0; - scr->_localsBlock = NULL; - return NULL; - } else { - LocalVariables *locals; - - if (scr->_localsSegment) { - locals = (LocalVariables *)_heap[scr->_localsSegment]; - if (!locals || locals->getType() != SEG_TYPE_LOCALS || locals->script_id != scr->getScriptNumber()) - error("Invalid script locals segment while allocating locals"); - } else - locals = (LocalVariables *)allocSegment(new LocalVariables(), &scr->_localsSegment); - - scr->_localsBlock = locals; - locals->script_id = scr->getScriptNumber(); - locals->_locals.resize(scr->getLocalsCount()); - - return locals; - } -} - DataStack *SegManager::allocateStack(int size, SegmentId *segid) { SegmentObj *mobj = allocSegment(new DataStack(), segid); DataStack *retval = (DataStack *)mobj; diff --git a/engines/sci/engine/seg_manager.h b/engines/sci/engine/seg_manager.h index ab5aeacabf..62e711e686 100644 --- a/engines/sci/engine/seg_manager.h +++ b/engines/sci/engine/seg_manager.h @@ -463,8 +463,10 @@ private: SegmentId _stringSegId; #endif -private: +public: SegmentObj *allocSegment(SegmentObj *mem, SegmentId *segid); + +private: void deallocate(SegmentId seg); void createClassTable(); @@ -477,9 +479,6 @@ private: * 'seg' is a valid segment */ bool check(SegmentId seg); - -public: - LocalVariables *allocLocalsSegment(Script *scr); }; } // End of namespace Sci diff --git a/engines/sci/engine/segment.cpp b/engines/sci/engine/segment.cpp index 3f11d6ff49..73d81baf3a 100644 --- a/engines/sci/engine/segment.cpp +++ b/engines/sci/engine/segment.cpp @@ -143,9 +143,11 @@ SegmentRef LocalVariables::dereference(reg_t pointer) { if (ret.maxSize > 0) { ret.reg = &_locals[pointer.offset / 2]; } else { - if ((g_sci->getEngineState()->currentRoomNumber() == 660 || g_sci->getEngineState()->currentRoomNumber() == 660) + if ((g_sci->getEngineState()->currentRoomNumber() == 160 || + g_sci->getEngineState()->currentRoomNumber() == 220) && g_sci->getGameId() == GID_LAURABOW2) { - // Happens in two places during the intro of LB2CD, both from kMemory(peek): + // WORKAROUND: Happens in two places during the intro of LB2CD, both + // from kMemory(peek): // - room 160: Heap 160 has 83 local variables (0-82), and the game // asks for variables at indices 83 - 90 too. // - room 220: Heap 220 has 114 local variables (0-113), and the diff --git a/engines/sci/engine/selector.cpp b/engines/sci/engine/selector.cpp index c2f857f319..a8b1cf7ec2 100644 --- a/engines/sci/engine/selector.cpp +++ b/engines/sci/engine/selector.cpp @@ -167,6 +167,7 @@ void Kernel::mapSelectors() { #ifdef ENABLE_SCI32 FIND_SELECTOR(data); FIND_SELECTOR(picture); + FIND_SELECTOR(bitmap); FIND_SELECTOR(plane); FIND_SELECTOR(top); FIND_SELECTOR(left); @@ -177,6 +178,7 @@ void Kernel::mapSelectors() { FIND_SELECTOR(dimmed); FIND_SELECTOR(fore); FIND_SELECTOR(back); + FIND_SELECTOR(skip); FIND_SELECTOR(fixPriority); FIND_SELECTOR(mirrored); FIND_SELECTOR(useInsetRect); diff --git a/engines/sci/engine/selector.h b/engines/sci/engine/selector.h index 085dd6e832..4b913a866a 100644 --- a/engines/sci/engine/selector.h +++ b/engines/sci/engine/selector.h @@ -132,6 +132,7 @@ struct SelectorCache { #ifdef ENABLE_SCI32 Selector data; // Used by Array()/String() Selector picture; // Used to hold the picture ID for SCI32 pictures + Selector bitmap; // Used to hold the text bitmap for SCI32 texts Selector plane; Selector top; @@ -143,6 +144,7 @@ struct SelectorCache { Selector fore; Selector back; + Selector skip; Selector dimmed; Selector fixPriority; diff --git a/engines/sci/engine/state.cpp b/engines/sci/engine/state.cpp index 4ea9f72054..28818cddef 100644 --- a/engines/sci/engine/state.cpp +++ b/engines/sci/engine/state.cpp @@ -145,12 +145,12 @@ void EngineState::wait(int16 ticks) { void EngineState::initGlobals() { Script *script_000 = _segMan->getScript(1); - if (!script_000->_localsBlock) + if (script_000->getLocalsCount() == 0) error("Script 0 has no locals block"); - variablesSegment[VAR_GLOBAL] = script_000->_localsSegment; - variablesBase[VAR_GLOBAL] = variables[VAR_GLOBAL] = script_000->_localsBlock->_locals.begin(); - variablesMax[VAR_GLOBAL] = script_000->_localsBlock->_locals.size(); + variablesSegment[VAR_GLOBAL] = script_000->getLocalsSegment(); + variablesBase[VAR_GLOBAL] = variables[VAR_GLOBAL] = script_000->getLocalsBegin(); + variablesMax[VAR_GLOBAL] = script_000->getLocalsCount(); } uint16 EngineState::currentRoomNumber() const { diff --git a/engines/sci/engine/static_selectors.cpp b/engines/sci/engine/static_selectors.cpp index 8f3337743d..74d2851024 100644 --- a/engines/sci/engine/static_selectors.cpp +++ b/engines/sci/engine/static_selectors.cpp @@ -192,9 +192,6 @@ Common::StringArray Kernel::checkStaticSelectorNames() { for (int i = count + countSci1; i < count + countSci1 + countSci11; i++) names[i] = sci11Selectors[i - count - countSci1]; } - - findSpecificSelectors(names); - #ifdef ENABLE_SCI32 } else { // SCI2+ @@ -203,6 +200,8 @@ Common::StringArray Kernel::checkStaticSelectorNames() { #endif } + findSpecificSelectors(names); + for (const SelectorRemap *selectorRemap = sciSelectorRemap; selectorRemap->slot; ++selectorRemap) { if (getSciVersion() >= selectorRemap->minVersion && getSciVersion() <= selectorRemap->maxVersion) { const uint32 slot = selectorRemap->slot; @@ -223,13 +222,16 @@ void Kernel::findSpecificSelectors(Common::StringArray &selectorNames) { // We need to initialize script 0 here, to make sure that it's always // located at segment 1. _segMan->instantiateScript(0); + uint16 sci2Offset = (getSciVersion() >= SCI_VERSION_2) ? 64000 : 0; // The Actor class contains the init, xLast and yLast selectors, which // we reference directly. It's always in script 998, so we need to // explicitly load it here. if ((getSciVersion() >= SCI_VERSION_1_EGA_ONLY)) { - if (_resMan->testResource(ResourceId(kResourceTypeScript, 998))) { - _segMan->instantiateScript(998); + uint16 actorScript = 998; + + if (_resMan->testResource(ResourceId(kResourceTypeScript, actorScript + sci2Offset))) { + _segMan->instantiateScript(actorScript + sci2Offset); const Object *actorClass = _segMan->getObject(_segMan->findObjectByName("Actor")); @@ -237,9 +239,10 @@ void Kernel::findSpecificSelectors(Common::StringArray &selectorNames) { // Find the xLast and yLast selectors, used in kDoBresen const int offset = (getSciVersion() < SCI_VERSION_1_1) ? 3 : 0; + const int offset2 = (getSciVersion() >= SCI_VERSION_2) ? 12 : 0; // xLast and yLast always come between illegalBits and xStep - int illegalBitsSelectorPos = actorClass->locateVarSelector(_segMan, 15 + offset); // illegalBits - int xStepSelectorPos = actorClass->locateVarSelector(_segMan, 51 + offset); // xStep + int illegalBitsSelectorPos = actorClass->locateVarSelector(_segMan, 15 + offset + offset2); // illegalBits + int xStepSelectorPos = actorClass->locateVarSelector(_segMan, 51 + offset + offset2); // xStep if (xStepSelectorPos - illegalBitsSelectorPos != 3) { error("illegalBits and xStep selectors aren't found in " "known locations. illegalBits = %d, xStep = %d", @@ -263,10 +266,10 @@ void Kernel::findSpecificSelectors(Common::StringArray &selectorNames) { // Find selectors from specific classes for (int i = 0; i < ARRAYSIZE(classReferences); i++) { - if (!_resMan->testResource(ResourceId(kResourceTypeScript, classReferences[i].script))) + if (!_resMan->testResource(ResourceId(kResourceTypeScript, classReferences[i].script + sci2Offset))) continue; - _segMan->instantiateScript(classReferences[i].script); + _segMan->instantiateScript(classReferences[i].script + sci2Offset); const Object *targetClass = _segMan->getObject(_segMan->findObjectByName(classReferences[i].className)); int targetSelectorPos = 0; diff --git a/engines/sci/engine/vm.cpp b/engines/sci/engine/vm.cpp index 7c22b48ece..cbe4736ba2 100644 --- a/engines/sci/engine/vm.cpp +++ b/engines/sci/engine/vm.cpp @@ -232,11 +232,10 @@ ExecStack *execute_method(EngineState *s, uint16 script, uint16 pubfunct, StackP if (!temp) { #ifdef ENABLE_SCI32 - // HACK: Temporarily switch to a warning in SCI32 games until we can figure out why Torin has - // an invalid exported function. - if (getSciVersion() >= SCI_VERSION_2) - warning("Request for invalid exported function 0x%x of script %d", pubfunct, script); - else + if (g_sci->getGameId() == GID_TORIN && script == 64036) { + // Script 64036 in Torin's Passage is empty and contains an invalid + // (empty) export + } else #endif error("Request for invalid exported function 0x%x of script %d", pubfunct, script); return NULL; @@ -463,10 +462,10 @@ int readPMachineInstruction(const byte *src, byte &extOpcode, int16 opparams[4]) memset(opparams, 0, 4*sizeof(int16)); - for (int i = 0; g_opcode_formats[opcode][i]; ++i) { + for (int i = 0; g_sci->_opcode_formats[opcode][i]; ++i) { //debugN("Opcode: 0x%x, Opnumber: 0x%x, temp: %d\n", opcode, opcode, temp); assert(i < 3); - switch (g_opcode_formats[opcode][i]) { + switch (g_sci->_opcode_formats[opcode][i]) { case Script_Byte: opparams[i] = src[offset++]; @@ -594,15 +593,9 @@ void run_vm(EngineState *s) { if (!local_script) { error("Could not find local script from segment %x", s->xs->local_segment); } else { - s->variablesSegment[VAR_LOCAL] = local_script->_localsSegment; - if (local_script->_localsBlock) - s->variablesBase[VAR_LOCAL] = s->variables[VAR_LOCAL] = local_script->_localsBlock->_locals.begin(); - else - s->variablesBase[VAR_LOCAL] = s->variables[VAR_LOCAL] = NULL; - if (local_script->_localsBlock) - s->variablesMax[VAR_LOCAL] = local_script->_localsBlock->_locals.size(); - else - s->variablesMax[VAR_LOCAL] = 0; + s->variablesSegment[VAR_LOCAL] = local_script->getLocalsSegment(); + s->variablesBase[VAR_LOCAL] = s->variables[VAR_LOCAL] = local_script->getLocalsBegin(); + s->variablesMax[VAR_LOCAL] = local_script->getLocalsCount(); s->variablesMax[VAR_TEMP] = s->xs->sp - s->xs->fp; s->variablesMax[VAR_PARAM] = s->xs->argc + 1; } @@ -771,16 +764,28 @@ void run_vm(EngineState *s) { // Branch relative if true if (s->r_acc.offset || s->r_acc.segment) s->xs->addr.pc.offset += opparams[0]; + + if (s->xs->addr.pc.offset >= local_script->getScriptSize()) + error("[VM] op_bt: request to jump past the end of script %d (offset %d, script is %d bytes)", + local_script->getScriptNumber(), s->xs->addr.pc.offset, local_script->getScriptSize()); break; case op_bnt: // 0x18 (24) // Branch relative if not true if (!(s->r_acc.offset || s->r_acc.segment)) s->xs->addr.pc.offset += opparams[0]; + + if (s->xs->addr.pc.offset >= local_script->getScriptSize()) + error("[VM] op_bnt: request to jump past the end of script %d (offset %d, script is %d bytes)", + local_script->getScriptNumber(), s->xs->addr.pc.offset, local_script->getScriptSize()); break; case op_jmp: // 0x19 (25) s->xs->addr.pc.offset += opparams[0]; + + if (s->xs->addr.pc.offset >= local_script->getScriptSize()) + error("[VM] op_jmp: request to jump past the end of script %d (offset %d, script is %d bytes)", + local_script->getScriptNumber(), s->xs->addr.pc.offset, local_script->getScriptSize()); break; case op_ldi: // 0x1a (26) diff --git a/engines/sci/engine/vm.h b/engines/sci/engine/vm.h index 36eadfa1c2..334d224baf 100644 --- a/engines/sci/engine/vm.h +++ b/engines/sci/engine/vm.h @@ -139,26 +139,6 @@ enum { GC_INTERVAL = 0x8000 }; -// Opcode formats -enum opcode_format { - Script_Invalid = -1, - Script_None = 0, - Script_Byte, - Script_SByte, - Script_Word, - Script_SWord, - Script_Variable, - Script_SVariable, - Script_SRelative, - Script_Property, - Script_Global, - Script_Local, - Script_Temp, - Script_Param, - Script_Offset, - Script_End -}; - enum sci_opcodes { op_bnot = 0x00, // 000 op_add = 0x01, // 001 @@ -290,8 +270,6 @@ enum sci_opcodes { op_minusspi = 0x7f // 127 }; -extern opcode_format g_opcode_formats[128][4]; - void script_adjust_opcode_formats(); /** diff --git a/engines/sci/engine/vm_types.h b/engines/sci/engine/vm_types.h index dc87cf758a..7b155a4532 100644 --- a/engines/sci/engine/vm_types.h +++ b/engines/sci/engine/vm_types.h @@ -172,6 +172,26 @@ enum { NULL_SELECTOR = -1 }; +// Opcode formats +enum opcode_format { + Script_Invalid = -1, + Script_None = 0, + Script_Byte, + Script_SByte, + Script_Word, + Script_SWord, + Script_Variable, + Script_SVariable, + Script_SRelative, + Script_Property, + Script_Global, + Script_Local, + Script_Temp, + Script_Param, + Script_Offset, + Script_End +}; + } // End of namespace Sci diff --git a/engines/sci/engine/workarounds.cpp b/engines/sci/engine/workarounds.cpp index ac8d5fa262..f68b74e1e0 100644 --- a/engines/sci/engine/workarounds.cpp +++ b/engines/sci/engine/workarounds.cpp @@ -124,6 +124,7 @@ const SciWorkaroundEntry uninitializedReadWorkarounds[] = { { GID_MOTHERGOOSEHIRES,-1,64950, 1, "View", "handleEvent", -1, 0, { WORKAROUND_FAKE, 0 } }, // see above { GID_PEPPER, -1, 894, 0, "Package", "doVerb", -1, 3, { WORKAROUND_FAKE, 0 } }, // using the hand on the book in the inventory - bug #3040012 { GID_PEPPER, 150, 928, 0, "Narrator", "startText", -1, 0, { WORKAROUND_FAKE, 0 } }, // happens during the non-interactive demo of Pepper + { GID_PQ4, -1, 25, 0, "iconToggle", "select", -1, 1, { WORKAROUND_FAKE, 0 } }, // when toggling the icon bar to auto-hide or not { GID_PQSWAT, -1, 64950, 0, "View", "handleEvent", -1, 0, { WORKAROUND_FAKE, 0 } }, // Using the menu in the beginning { GID_QFG1, -1, 210, 0, "Encounter", "init", 0xbd0, 0, { WORKAROUND_FAKE, 0 } }, // hq1: going to the brigands hideout { GID_QFG1, -1, 210, 0, "Encounter", "init", 0xbe4, 0, { WORKAROUND_FAKE, 0 } }, // qfg1: going to the brigands hideout @@ -154,6 +155,9 @@ const SciWorkaroundEntry uninitializedReadWorkarounds[] = { { GID_SHIVERS, -1, 952, 0, "SoundManager", "stop", -1, 2, { WORKAROUND_FAKE, 0 } }, // Just after Sierra logo { GID_SHIVERS, -1, 64950, 0, "Feature", "handleEvent", -1, 0, { WORKAROUND_FAKE, 0 } }, // When clicking on the locked door at the beginning { GID_SHIVERS, -1, 64950, 0, "View", "handleEvent", -1, 0, { WORKAROUND_FAKE, 0 } }, // When clicking on the gargoyle eye at the beginning + { GID_SHIVERS, 20311, 64964, 0, "DPath", "init", -1, 1, { WORKAROUND_FAKE, 0 } }, // Just after door puzzle is solved and the metal balls start to roll + { GID_SHIVERS, 29260, 29260, 0, "spMars", "handleEvent", -1, 4, { WORKAROUND_FAKE, 0 } }, // When clicking mars after seeing fortune to align earth etc... + { GID_SHIVERS, 29260, 29260, 0, "spVenus", "handleEvent", -1, 4, { WORKAROUND_FAKE, 0 } }, // When clicking venus after seeing fortune to align earth etc... { GID_SQ1, 103, 103, 0, "hand", "internalEvent", -1, -1, { WORKAROUND_FAKE, 0 } }, // Spanish (and maybe early versions?) only: when moving cursor over input pad, temps 1 and 2 { GID_SQ1, -1, 703, 0, "", "export 1", -1, 0, { WORKAROUND_FAKE, 0 } }, // sub that's called from several objects while on sarien battle cruiser { GID_SQ1, -1, 703, 0, "firePulsar", "changeState", 0x18a, 0, { WORKAROUND_FAKE, 0 } }, // export 1, but called locally (when shooting at aliens) @@ -383,7 +387,7 @@ const SciWorkaroundEntry kStrLen_workarounds[] = { const SciWorkaroundEntry kUnLoad_workarounds[] = { { GID_ECOQUEST, 380, 61, 0, "gotIt", "changeState", -1, 0, { WORKAROUND_IGNORE, 0 } }, // CD version: after talking to the dolphin the first time, a 3rd parameter is passed by accident { GID_ECOQUEST, 380, 69, 0, "lookAtBlackBoard", "changeState", -1, 0, { WORKAROUND_IGNORE, 0 } }, // German version, when closing the blackboard closeup in the dolphin room, a 3rd parameter is passed by accident - bug #3098353 - { GID_LAURABOW2, -1, 1, 0, "sCartoon", "changeState", -1, 0, { WORKAROUND_IGNORE, 0 } }, // DEMO: during the intro, a 3rd parameter is passed by accident - bug #3034902 + { GID_LAURABOW2, -1, -1, 0, "sCartoon", "changeState", -1, 0, { WORKAROUND_IGNORE, 0 } }, // DEMO: during the intro, a 3rd parameter is passed by accident - bug #3034902 { GID_LSL6, 130, 130, 0, "recruitLarryScr", "changeState", -1, 0, { WORKAROUND_IGNORE, 0 } }, // during intro, a 3rd parameter is passed by accident { GID_LSL6, 740, 740, 0, "showCartoon", "changeState", -1, 0, { WORKAROUND_IGNORE, 0 } }, // during ending, 4 additional parameters are passed by accident { GID_LSL6HIRES, 130, 130, 0, "recruitLarryScr", "changeState", -1, 0, { WORKAROUND_IGNORE, 0 } }, // during intro, a 3rd parameter is passed by accident diff --git a/engines/sci/event.cpp b/engines/sci/event.cpp index c14cfada07..378e88b7df 100644 --- a/engines/sci/event.cpp +++ b/engines/sci/event.cpp @@ -253,14 +253,11 @@ SciEvent EventManager::getScummVMEvent() { if ((modifiers & Common::KBD_ALT) && input.character > 0 && input.character < 27) input.character += 96; // 0x01 -> 'a' - if (getSciVersion() <= SCI_VERSION_1_MIDDLE) { - // TODO: find out if altify is also not needed for sci1late+, couldnt find any game that uses those keys - // Scancodify if appropriate - if (modifiers & Common::KBD_ALT) - input.character = altify(input.character); - else if ((modifiers & Common::KBD_CTRL) && input.character > 0 && input.character < 27) - input.character += 96; // 0x01 -> 'a' - } + // Scancodify if appropriate + if (modifiers & Common::KBD_ALT) + input.character = altify(input.character); + else if ((modifiers & Common::KBD_CTRL) && input.character > 0 && input.character < 27) + input.character += 96; // 0x01 -> 'a' // If no actual key was pressed (e.g. if only a modifier key was pressed), // ignore the event diff --git a/engines/sci/graphics/animate.cpp b/engines/sci/graphics/animate.cpp index 18f8511953..983e697481 100644 --- a/engines/sci/graphics/animate.cpp +++ b/engines/sci/graphics/animate.cpp @@ -32,6 +32,7 @@ #include "sci/engine/selector.h" #include "sci/engine/vm.h" #include "sci/graphics/cache.h" +#include "sci/graphics/compare.h" #include "sci/graphics/cursor.h" #include "sci/graphics/ports.h" #include "sci/graphics/paint16.h" @@ -307,10 +308,7 @@ void GfxAnimate::setNsRect(GfxView *view, AnimateList::iterator it) { // This special handling is not included in the other SCI1.1 interpreters and MUST NOT be // checked in those cases, otherwise we will break games (e.g. EcoQuest 2, room 200) if ((g_sci->getGameId() == GID_HOYLE4) && (it->scaleSignal & kScaleSignalHoyle4SpecialHandling)) { - it->celRect.left = readSelectorValue(_s->_segMan, it->object, SELECTOR(nsLeft)); - it->celRect.top = readSelectorValue(_s->_segMan, it->object, SELECTOR(nsTop)); - it->celRect.right = readSelectorValue(_s->_segMan, it->object, SELECTOR(nsRight)); - it->celRect.bottom = readSelectorValue(_s->_segMan, it->object, SELECTOR(nsBottom)); + it->celRect = g_sci->_gfxCompare->getNSRect(it->object); view->getCelSpecialHoyle4Rect(it->loopNo, it->celNo, it->x, it->y, it->z, it->celRect); shouldSetNsRect = false; } else { @@ -319,10 +317,7 @@ void GfxAnimate::setNsRect(GfxView *view, AnimateList::iterator it) { } if (shouldSetNsRect) { - writeSelectorValue(_s->_segMan, it->object, SELECTOR(nsLeft), it->celRect.left); - writeSelectorValue(_s->_segMan, it->object, SELECTOR(nsTop), it->celRect.top); - writeSelectorValue(_s->_segMan, it->object, SELECTOR(nsRight), it->celRect.right); - writeSelectorValue(_s->_segMan, it->object, SELECTOR(nsBottom), it->celRect.bottom); + g_sci->_gfxCompare->setNSRect(it->object, it->celRect); } } @@ -544,10 +539,7 @@ void GfxAnimate::addToPicDrawCels() { applyGlobalScaling(it, view); } view->getCelScaledRect(it->loopNo, it->celNo, it->x, it->y, it->z, it->scaleX, it->scaleY, it->celRect); - writeSelectorValue(_s->_segMan, curObject, SELECTOR(nsLeft), it->celRect.left); - writeSelectorValue(_s->_segMan, curObject, SELECTOR(nsTop), it->celRect.top); - writeSelectorValue(_s->_segMan, curObject, SELECTOR(nsRight), it->celRect.right); - writeSelectorValue(_s->_segMan, curObject, SELECTOR(nsBottom), it->celRect.bottom); + g_sci->_gfxCompare->setNSRect(curObject, it->celRect); } else { view->getCelRect(it->loopNo, it->celNo, it->x, it->y, it->z, it->celRect); } diff --git a/engines/sci/graphics/cache.cpp b/engines/sci/graphics/cache.cpp index d2bd76ac99..55f8624c49 100644 --- a/engines/sci/graphics/cache.cpp +++ b/engines/sci/graphics/cache.cpp @@ -102,4 +102,8 @@ int16 GfxCache::kernelViewGetCelCount(GuiResourceId viewId, int16 loopNo) { return getView(viewId)->getCelCount(loopNo); } +byte GfxCache::kernelViewGetColorAtCoordinate(GuiResourceId viewId, int16 loopNo, int16 celNo, int16 x, int16 y) { + return getView(viewId)->getColorAtCoordinate(loopNo, celNo, x, y); +} + } // End of namespace Sci diff --git a/engines/sci/graphics/cache.h b/engines/sci/graphics/cache.h index c090cda7d7..2f462fe042 100644 --- a/engines/sci/graphics/cache.h +++ b/engines/sci/graphics/cache.h @@ -49,6 +49,8 @@ public: int16 kernelViewGetLoopCount(GuiResourceId viewId); int16 kernelViewGetCelCount(GuiResourceId viewId, int16 loopNo); + byte kernelViewGetColorAtCoordinate(GuiResourceId viewId, int16 loopNo, int16 celNo, int16 x, int16 y); + private: void purgeFontCache(); void purgeViewCache(); diff --git a/engines/sci/graphics/compare.cpp b/engines/sci/graphics/compare.cpp index 3183ffa2b9..70dff15a86 100644 --- a/engines/sci/graphics/compare.cpp +++ b/engines/sci/graphics/compare.cpp @@ -147,10 +147,7 @@ void GfxCompare::kernelSetNowSeen(reg_t objectReference) { #endif if (lookupSelector(_segMan, objectReference, SELECTOR(nsTop), NULL, NULL) == kSelectorVariable) { - writeSelectorValue(_segMan, objectReference, SELECTOR(nsLeft), celRect.left); - writeSelectorValue(_segMan, objectReference, SELECTOR(nsRight), celRect.right); - writeSelectorValue(_segMan, objectReference, SELECTOR(nsTop), celRect.top); - writeSelectorValue(_segMan, objectReference, SELECTOR(nsBottom), celRect.bottom); + setNSRect(objectReference, celRect); } } @@ -221,10 +218,7 @@ void GfxCompare::kernelBaseSetter(reg_t object) { scaleSignal = 0; if (scaleSignal & kScaleSignalDoScaling) { - celRect.left = readSelectorValue(_segMan, object, SELECTOR(nsLeft)); - celRect.right = readSelectorValue(_segMan, object, SELECTOR(nsRight)); - celRect.top = readSelectorValue(_segMan, object, SELECTOR(nsTop)); - celRect.bottom = readSelectorValue(_segMan, object, SELECTOR(nsBottom)); + celRect = getNSRect(object); } else { if (tmpView->isSci2Hires()) tmpView->adjustToUpscaledCoordinates(y, x); @@ -247,4 +241,29 @@ void GfxCompare::kernelBaseSetter(reg_t object) { } } +Common::Rect GfxCompare::getNSRect(reg_t object, bool fixRect) { + Common::Rect nsRect; + nsRect.top = readSelectorValue(_segMan, object, SELECTOR(nsTop)); + nsRect.left = readSelectorValue(_segMan, object, SELECTOR(nsLeft)); + nsRect.bottom = readSelectorValue(_segMan, object, SELECTOR(nsBottom)); + nsRect.right = readSelectorValue(_segMan, object, SELECTOR(nsRight)); + + if (fixRect) { + // nsRect top/left may be negative, adjust accordingly + if (nsRect.top < 0) + nsRect.top = 0; + if (nsRect.left < 0) + nsRect.left = 0; + } + + return nsRect; +} + +void GfxCompare::setNSRect(reg_t object, Common::Rect nsRect) { + writeSelectorValue(_segMan, object, SELECTOR(nsLeft), nsRect.left); + writeSelectorValue(_segMan, object, SELECTOR(nsTop), nsRect.top); + writeSelectorValue(_segMan, object, SELECTOR(nsRight), nsRect.right); + writeSelectorValue(_segMan, object, SELECTOR(nsBottom), nsRect.bottom); +} + } // End of namespace Sci diff --git a/engines/sci/graphics/compare.h b/engines/sci/graphics/compare.h index bacb6e71e2..91e3b90fdb 100644 --- a/engines/sci/graphics/compare.h +++ b/engines/sci/graphics/compare.h @@ -42,6 +42,8 @@ public: reg_t kernelCanBeHere(reg_t curObject, reg_t listReference); bool kernelIsItSkip(GuiResourceId viewId, int16 loopNo, int16 celNo, Common::Point position); void kernelBaseSetter(reg_t object); + Common::Rect getNSRect(reg_t object, bool fixRect = false); + void setNSRect(reg_t object, Common::Rect nsRect); private: SegManager *_segMan; diff --git a/engines/sci/graphics/controls.cpp b/engines/sci/graphics/controls16.cpp index 8d4712a969..ab54e468d1 100644 --- a/engines/sci/graphics/controls.cpp +++ b/engines/sci/graphics/controls16.cpp @@ -30,31 +30,32 @@ #include "sci/engine/kernel.h" #include "sci/engine/state.h" #include "sci/engine/selector.h" +#include "sci/graphics/compare.h" #include "sci/graphics/ports.h" #include "sci/graphics/paint16.h" #include "sci/graphics/font.h" #include "sci/graphics/screen.h" #include "sci/graphics/text16.h" -#include "sci/graphics/controls.h" +#include "sci/graphics/controls16.h" namespace Sci { -GfxControls::GfxControls(SegManager *segMan, GfxPorts *ports, GfxPaint16 *paint16, GfxText16 *text16, GfxScreen *screen) +GfxControls16::GfxControls16(SegManager *segMan, GfxPorts *ports, GfxPaint16 *paint16, GfxText16 *text16, GfxScreen *screen) : _segMan(segMan), _ports(ports), _paint16(paint16), _text16(text16), _screen(screen) { init(); } -GfxControls::~GfxControls() { +GfxControls16::~GfxControls16() { } -void GfxControls::init() { +void GfxControls16::init() { _texteditCursorVisible = false; } const char controlListUpArrow[2] = { 0x18, 0 }; const char controlListDownArrow[2] = { 0x19, 0 }; -void GfxControls::drawListControl(Common::Rect rect, reg_t obj, int16 maxChars, int16 count, const char **entries, GuiResourceId fontId, int16 upperPos, int16 cursorPos, bool isAlias) { +void GfxControls16::drawListControl(Common::Rect rect, reg_t obj, int16 maxChars, int16 count, const char **entries, GuiResourceId fontId, int16 upperPos, int16 cursorPos, bool isAlias) { Common::Rect workerRect = rect; GuiResourceId oldFontId = _text16->GetFontId(); int16 oldPenColor = _ports->_curPort->penClr; @@ -111,7 +112,7 @@ void GfxControls::drawListControl(Common::Rect rect, reg_t obj, int16 maxChars, _text16->SetFont(oldFontId); } -void GfxControls::texteditCursorDraw(Common::Rect rect, const char *text, uint16 curPos) { +void GfxControls16::texteditCursorDraw(Common::Rect rect, const char *text, uint16 curPos) { int16 textWidth, i; if (!_texteditCursorVisible) { textWidth = 0; @@ -129,7 +130,7 @@ void GfxControls::texteditCursorDraw(Common::Rect rect, const char *text, uint16 } } -void GfxControls::texteditCursorErase() { +void GfxControls16::texteditCursorErase() { if (_texteditCursorVisible) { _paint16->invertRect(_texteditCursorRect); _paint16->bitsShow(_texteditCursorRect); @@ -138,11 +139,11 @@ void GfxControls::texteditCursorErase() { texteditSetBlinkTime(); } -void GfxControls::texteditSetBlinkTime() { +void GfxControls16::texteditSetBlinkTime() { _texteditBlinkTime = g_system->getMillis() + (30 * 1000 / 60); } -void GfxControls::kernelTexteditChange(reg_t controlObject, reg_t eventObject) { +void GfxControls16::kernelTexteditChange(reg_t controlObject, reg_t eventObject) { uint16 cursorPos = readSelectorValue(_segMan, controlObject, SELECTOR(cursor)); uint16 maxChars = readSelectorValue(_segMan, controlObject, SELECTOR(max)); reg_t textReference = readSelector(_segMan, controlObject, SELECTOR(text)); @@ -230,8 +231,8 @@ void GfxControls::kernelTexteditChange(reg_t controlObject, reg_t eventObject) { if (textChanged) { GuiResourceId oldFontId = _text16->GetFontId(); GuiResourceId fontId = readSelectorValue(_segMan, controlObject, SELECTOR(font)); - rect = Common::Rect(readSelectorValue(_segMan, controlObject, SELECTOR(nsLeft)), readSelectorValue(_segMan, controlObject, SELECTOR(nsTop)), - readSelectorValue(_segMan, controlObject, SELECTOR(nsRight)), readSelectorValue(_segMan, controlObject, SELECTOR(nsBottom))); + rect = g_sci->_gfxCompare->getNSRect(controlObject); + _text16->SetFont(fontId); if (textAddChar) { @@ -276,13 +277,13 @@ void GfxControls::kernelTexteditChange(reg_t controlObject, reg_t eventObject) { writeSelectorValue(_segMan, controlObject, SELECTOR(cursor), cursorPos); } -int GfxControls::getPicNotValid() { +int GfxControls16::getPicNotValid() { if (getSciVersion() >= SCI_VERSION_1_1) return _screen->_picNotValidSci11; return _screen->_picNotValid; } -void GfxControls::kernelDrawButton(Common::Rect rect, reg_t obj, const char *text, int16 fontId, int16 style, bool hilite) { +void GfxControls16::kernelDrawButton(Common::Rect rect, reg_t obj, const char *text, int16 fontId, int16 style, bool hilite) { int16 sci0EarlyPen = 0, sci0EarlyBack = 0; if (!hilite) { if (getSciVersion() == SCI_VERSION_0_EARLY) { @@ -320,7 +321,7 @@ void GfxControls::kernelDrawButton(Common::Rect rect, reg_t obj, const char *tex } } -void GfxControls::kernelDrawText(Common::Rect rect, reg_t obj, const char *text, int16 fontId, TextAlignment alignment, int16 style, bool hilite) { +void GfxControls16::kernelDrawText(Common::Rect rect, reg_t obj, const char *text, int16 fontId, TextAlignment alignment, int16 style, bool hilite) { if (!hilite) { rect.grow(1); _paint16->eraseRect(rect); @@ -337,7 +338,7 @@ void GfxControls::kernelDrawText(Common::Rect rect, reg_t obj, const char *text, } } -void GfxControls::kernelDrawTextEdit(Common::Rect rect, reg_t obj, const char *text, int16 fontId, int16 mode, int16 style, int16 cursorPos, int16 maxChars, bool hilite) { +void GfxControls16::kernelDrawTextEdit(Common::Rect rect, reg_t obj, const char *text, int16 fontId, int16 mode, int16 style, int16 cursorPos, int16 maxChars, bool hilite) { Common::Rect textRect = rect; uint16 oldFontId = _text16->GetFontId(); @@ -358,7 +359,7 @@ void GfxControls::kernelDrawTextEdit(Common::Rect rect, reg_t obj, const char *t _paint16->bitsShow(rect); } -void GfxControls::kernelDrawIcon(Common::Rect rect, reg_t obj, GuiResourceId viewId, int16 loopNo, int16 celNo, int16 priority, int16 style, bool hilite) { +void GfxControls16::kernelDrawIcon(Common::Rect rect, reg_t obj, GuiResourceId viewId, int16 loopNo, int16 celNo, int16 priority, int16 style, bool hilite) { if (!hilite) { _paint16->drawCelAndShow(viewId, loopNo, celNo, rect.left, rect.top, priority, 0); if (style & 0x20) { @@ -372,7 +373,7 @@ void GfxControls::kernelDrawIcon(Common::Rect rect, reg_t obj, GuiResourceId vie } } -void GfxControls::kernelDrawList(Common::Rect rect, reg_t obj, int16 maxChars, int16 count, const char **entries, GuiResourceId fontId, int16 style, int16 upperPos, int16 cursorPos, bool isAlias, bool hilite) { +void GfxControls16::kernelDrawList(Common::Rect rect, reg_t obj, int16 maxChars, int16 count, const char **entries, GuiResourceId fontId, int16 style, int16 upperPos, int16 cursorPos, bool isAlias, bool hilite) { if (!hilite) { drawListControl(rect, obj, maxChars, count, entries, fontId, upperPos, cursorPos, isAlias); rect.grow(1); diff --git a/engines/sci/graphics/controls.h b/engines/sci/graphics/controls16.h index 17e7c39318..90bd7beacb 100644 --- a/engines/sci/graphics/controls.h +++ b/engines/sci/graphics/controls16.h @@ -20,8 +20,8 @@ * */ -#ifndef SCI_GRAPHICS_CONTROLS_H -#define SCI_GRAPHICS_CONTROLS_H +#ifndef SCI_GRAPHICS_CONTROLS16_H +#define SCI_GRAPHICS_CONTROLS16_H namespace Sci { @@ -50,10 +50,10 @@ class GfxScreen; /** * Controls class, handles drawing of controls in SCI16 (SCI0-SCI1.1) games */ -class GfxControls { +class GfxControls16 { public: - GfxControls(SegManager *segMan, GfxPorts *ports, GfxPaint16 *paint16, GfxText16 *text16, GfxScreen *screen); - ~GfxControls(); + GfxControls16(SegManager *segMan, GfxPorts *ports, GfxPaint16 *paint16, GfxText16 *text16, GfxScreen *screen); + ~GfxControls16(); void kernelDrawButton(Common::Rect rect, reg_t obj, const char *text, int16 fontId, int16 style, bool hilite); void kernelDrawText(Common::Rect rect, reg_t obj, const char *text, int16 fontId, int16 alignment, int16 style, bool hilite); diff --git a/engines/sci/graphics/controls32.cpp b/engines/sci/graphics/controls32.cpp new file mode 100644 index 0000000000..ad1d9e8623 --- /dev/null +++ b/engines/sci/graphics/controls32.cpp @@ -0,0 +1,204 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "common/system.h" + +#include "sci/sci.h" +#include "sci/event.h" +#include "sci/engine/kernel.h" +#include "sci/engine/seg_manager.h" +#include "sci/graphics/cache.h" +#include "sci/graphics/compare.h" +#include "sci/graphics/controls32.h" +#include "sci/graphics/font.h" +#include "sci/graphics/screen.h" +#include "sci/graphics/text32.h" + +namespace Sci { + +GfxControls32::GfxControls32(SegManager *segMan, GfxCache *cache, GfxScreen *screen, GfxText32 *text) + : _segMan(segMan), _cache(cache), _screen(screen), _text(text) { +} + +GfxControls32::~GfxControls32() { +} + +void GfxControls32::kernelTexteditChange(reg_t controlObject) { + SciEvent curEvent; + uint16 maxChars = 40; //readSelectorValue(_segMan, controlObject, SELECTOR(max)); // TODO + reg_t textReference = readSelector(_segMan, controlObject, SELECTOR(text)); + GfxFont *font = _cache->getFont(readSelectorValue(_segMan, controlObject, SELECTOR(font))); + Common::String text; + uint16 textSize; + bool textChanged = false; + bool textAddChar = false; + Common::Rect rect; + + if (textReference.isNull()) + error("kEditControl called on object that doesnt have a text reference"); + text = _segMan->getString(textReference); + + // TODO: Finish this + warning("kEditText ('%s')", text.c_str()); + return; + + uint16 cursorPos = 0; + //uint16 oldCursorPos = cursorPos; + bool captureEvents = true; + EventManager* eventMan = g_sci->getEventManager(); + + while (captureEvents) { + curEvent = g_sci->getEventManager()->getSciEvent(SCI_EVENT_KEYBOARD | SCI_EVENT_PEEK); + + if (curEvent.type == SCI_EVENT_NONE) { + eventMan->getSciEvent(SCI_EVENT_KEYBOARD); // consume the event + } else { + textSize = text.size(); + + switch (curEvent.type) { + case SCI_EVENT_MOUSE_PRESS: + // TODO: Implement mouse support for cursor change + break; + case SCI_EVENT_KEYBOARD: + switch (curEvent.data) { + case SCI_KEY_BACKSPACE: + if (cursorPos > 0) { + cursorPos--; text.deleteChar(cursorPos); + textChanged = true; + } + eventMan->getSciEvent(SCI_EVENT_KEYBOARD); // consume the event + break; + case SCI_KEY_DELETE: + if (cursorPos < textSize) { + text.deleteChar(cursorPos); + textChanged = true; + } + eventMan->getSciEvent(SCI_EVENT_KEYBOARD); // consume the event + break; + case SCI_KEY_HOME: // HOME + cursorPos = 0; textChanged = true; + eventMan->getSciEvent(SCI_EVENT_KEYBOARD); // consume the event + break; + case SCI_KEY_END: // END + cursorPos = textSize; textChanged = true; + eventMan->getSciEvent(SCI_EVENT_KEYBOARD); // consume the event + break; + case SCI_KEY_LEFT: // LEFT + if (cursorPos > 0) { + cursorPos--; textChanged = true; + } + eventMan->getSciEvent(SCI_EVENT_KEYBOARD); // consume the event + break; + case SCI_KEY_RIGHT: // RIGHT + if (cursorPos + 1 <= textSize) { + cursorPos++; textChanged = true; + } + eventMan->getSciEvent(SCI_EVENT_KEYBOARD); // consume the event + break; + case 3: // returned in SCI1 late and newer when Control - C is pressed + if (curEvent.modifiers & SCI_KEYMOD_CTRL) { + // Control-C erases the whole line + cursorPos = 0; text.clear(); + textChanged = true; + } + eventMan->getSciEvent(SCI_EVENT_KEYBOARD); // consume the event + break; + case SCI_KEY_UP: + case SCI_KEY_DOWN: + case SCI_KEY_ENTER: + case SCI_KEY_ESC: + case SCI_KEY_TAB: + case SCI_KEY_SHIFT_TAB: + captureEvents = false; + break; + default: + if ((curEvent.modifiers & SCI_KEYMOD_CTRL) && curEvent.data == 99) { + // Control-C in earlier SCI games (SCI0 - SCI1 middle) + // Control-C erases the whole line + cursorPos = 0; text.clear(); + textChanged = true; + } else if (curEvent.data > 31 && curEvent.data < 256 && textSize < maxChars) { + // insert pressed character + textAddChar = true; + textChanged = true; + } + eventMan->getSciEvent(SCI_EVENT_KEYBOARD); // consume the event + break; + } + break; + } + } + + if (textChanged) { + rect = g_sci->_gfxCompare->getNSRect(controlObject); + + if (textAddChar) { + const char *textPtr = text.c_str(); + + // We check if we are really able to add the new char + uint16 textWidth = 0; + while (*textPtr) + textWidth += font->getCharWidth((byte)*textPtr++); + textWidth += font->getCharWidth(curEvent.data); + + // Does it fit? + if (textWidth >= rect.width()) { + return; + } + + text.insertChar(curEvent.data, cursorPos++); + + // Note: the following checkAltInput call might make the text + // too wide to fit, but SSCI fails to check that too. + } + + reg_t hunkId = readSelector(_segMan, controlObject, SELECTOR(bitmap)); + Common::Rect nsRect = g_sci->_gfxCompare->getNSRect(controlObject); + //texteditCursorErase(); // TODO: Cursor + + // Write back string + _segMan->strcpy(textReference, text.c_str()); + // Modify the buffer and show it + _text->createTextBitmap(controlObject, 0, 0, hunkId); + + _text->drawTextBitmap(0, 0, nsRect, controlObject); + //texteditCursorDraw(rect, text.c_str(), cursorPos); // TODO: Cursor + g_system->updateScreen(); + } else { + // TODO: Cursor + /* + if (g_system->getMillis() >= _texteditBlinkTime) { + _paint16->invertRect(_texteditCursorRect); + _paint16->bitsShow(_texteditCursorRect); + _texteditCursorVisible = !_texteditCursorVisible; + texteditSetBlinkTime(); + } + */ + } + + textAddChar = false; + textChanged = false; + g_sci->sleep(10); + } // while +} + +} // End of namespace Sci diff --git a/engines/sci/graphics/controls32.h b/engines/sci/graphics/controls32.h new file mode 100644 index 0000000000..68dca59462 --- /dev/null +++ b/engines/sci/graphics/controls32.h @@ -0,0 +1,51 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef SCI_GRAPHICS_CONTROLS32_H +#define SCI_GRAPHICS_CONTROLS32_H + +namespace Sci { + +class GfxCache; +class GfxScreen; +class GfxText32; + +/** + * Controls class, handles drawing of controls in SCI32 (SCI2, SCI2.1, SCI3) games + */ +class GfxControls32 { +public: + GfxControls32(SegManager *segMan, GfxCache *cache, GfxScreen *screen, GfxText32 *text); + ~GfxControls32(); + + void kernelTexteditChange(reg_t controlObject); + +private: + SegManager *_segMan; + GfxCache *_cache; + GfxScreen *_screen; + GfxText32 *_text; +}; + +} // End of namespace Sci + +#endif diff --git a/engines/sci/graphics/coordadjuster.cpp b/engines/sci/graphics/coordadjuster.cpp index 2952d4da7b..1446888cf4 100644 --- a/engines/sci/graphics/coordadjuster.cpp +++ b/engines/sci/graphics/coordadjuster.cpp @@ -86,8 +86,8 @@ Common::Rect GfxCoordAdjuster16::pictureGetDisplayArea() { #ifdef ENABLE_SCI32 GfxCoordAdjuster32::GfxCoordAdjuster32(SegManager *segMan) : _segMan(segMan) { - scriptsRunningWidth = 0; - scriptsRunningHeight = 0; + _scriptsRunningWidth = 0; + _scriptsRunningHeight = 0; } GfxCoordAdjuster32::~GfxCoordAdjuster32() { @@ -109,18 +109,18 @@ void GfxCoordAdjuster32::kernelLocalToGlobal(int16 &x, int16 &y, reg_t planeObje } void GfxCoordAdjuster32::setScriptsResolution(uint16 width, uint16 height) { - scriptsRunningWidth = width; - scriptsRunningHeight = height; + _scriptsRunningWidth = width; + _scriptsRunningHeight = height; } void GfxCoordAdjuster32::fromDisplayToScript(int16 &y, int16 &x) { - y = ((y * scriptsRunningHeight) / g_sci->_gfxScreen->getHeight()); - x = ((x * scriptsRunningWidth) / g_sci->_gfxScreen->getWidth()); + y = ((y * _scriptsRunningHeight) / g_sci->_gfxScreen->getHeight()); + x = ((x * _scriptsRunningWidth) / g_sci->_gfxScreen->getWidth()); } void GfxCoordAdjuster32::fromScriptToDisplay(int16 &y, int16 &x) { - y = ((y * g_sci->_gfxScreen->getHeight()) / scriptsRunningHeight); - x = ((x * g_sci->_gfxScreen->getWidth()) / scriptsRunningWidth); + y = ((y * g_sci->_gfxScreen->getHeight()) / _scriptsRunningHeight); + x = ((x * g_sci->_gfxScreen->getWidth()) / _scriptsRunningWidth); } void GfxCoordAdjuster32::pictureSetDisplayArea(Common::Rect displayArea) { diff --git a/engines/sci/graphics/coordadjuster.h b/engines/sci/graphics/coordadjuster.h index 23cf79d209..63f608be6b 100644 --- a/engines/sci/graphics/coordadjuster.h +++ b/engines/sci/graphics/coordadjuster.h @@ -96,8 +96,8 @@ private: Common::Rect _pictureDisplayArea; - uint16 scriptsRunningWidth; - uint16 scriptsRunningHeight; + uint16 _scriptsRunningWidth; + uint16 _scriptsRunningHeight; }; #endif diff --git a/engines/sci/graphics/cursor.cpp b/engines/sci/graphics/cursor.cpp index 57c65aa6e0..50da48aaf3 100644 --- a/engines/sci/graphics/cursor.cpp +++ b/engines/sci/graphics/cursor.cpp @@ -179,6 +179,18 @@ void GfxCursor::kernelSetView(GuiResourceId viewNum, int loopNum, int celNum, Co if (_useOriginalKQ6WinCursors) viewNum += 2000; // Windows cursors + if (g_sci->getGameId() == GID_PHANTASMAGORIA2) { + // HACK: Ignore cursor views for Phantasmagoria 2. They've got + // differences from other SCI32 views, thus we skip them for + // now, otherwise our view decoding code will crash. + // The view code will crash with *any* view in P2, but this hack + // allows the game to start and show the menu. + // TODO: Remove once the view code is updated to handle + // Phantasmagoria 2 views. + warning("TODO: Cursor views for Phantasmagoria 2"); + return; + } + if (!_cachedCursors.contains(viewNum)) _cachedCursors[viewNum] = new GfxView(_resMan, _screen, _palette, viewNum); diff --git a/engines/sci/graphics/frameout.cpp b/engines/sci/graphics/frameout.cpp index 6bd310f1a0..7bb4162020 100644 --- a/engines/sci/graphics/frameout.cpp +++ b/engines/sci/graphics/frameout.cpp @@ -37,6 +37,7 @@ #include "sci/engine/vm.h" #include "sci/graphics/cache.h" #include "sci/graphics/coordadjuster.h" +#include "sci/graphics/compare.h" #include "sci/graphics/font.h" #include "sci/graphics/view.h" #include "sci/graphics/screen.h" @@ -55,8 +56,8 @@ GfxFrameout::GfxFrameout(SegManager *segMan, ResourceManager *resMan, GfxCoordAd : _segMan(segMan), _resMan(resMan), _cache(cache), _screen(screen), _palette(palette), _paint32(paint32) { _coordAdjuster = (GfxCoordAdjuster32 *)coordAdjuster; - scriptsRunningWidth = 320; - scriptsRunningHeight = 200; + _scriptsRunningWidth = 320; + _scriptsRunningHeight = 200; } GfxFrameout::~GfxFrameout() { @@ -79,17 +80,18 @@ void GfxFrameout::kernelAddPlane(reg_t object) { // The above can be 0 in SCI3 (e.g. Phantasmagoria 2) if (tmpRunningWidth > 0 && tmpRunningHeight > 0) { - scriptsRunningWidth = tmpRunningWidth; - scriptsRunningHeight = tmpRunningHeight; + _scriptsRunningWidth = tmpRunningWidth; + _scriptsRunningHeight = tmpRunningHeight; } - _coordAdjuster->setScriptsResolution(scriptsRunningWidth, scriptsRunningHeight); + _coordAdjuster->setScriptsResolution(_scriptsRunningWidth, _scriptsRunningHeight); } newPlane.object = object; newPlane.priority = readSelectorValue(_segMan, object, SELECTOR(priority)); newPlane.lastPriority = 0xFFFF; // hidden newPlane.planeOffsetX = 0; + newPlane.planeOffsetY = 0; newPlane.pictureId = 0xFFFF; newPlane.planePictureMirrored = false; newPlane.planeBack = 0; @@ -116,14 +118,14 @@ void GfxFrameout::kernelUpdatePlane(reg_t object) { } it->planeRect.top = readSelectorValue(_segMan, object, SELECTOR(top)); it->planeRect.left = readSelectorValue(_segMan, object, SELECTOR(left)); - it->planeRect.bottom = readSelectorValue(_segMan, object, SELECTOR(bottom)) + 1; - it->planeRect.right = readSelectorValue(_segMan, object, SELECTOR(right)) + 1; + it->planeRect.bottom = readSelectorValue(_segMan, object, SELECTOR(bottom)); + it->planeRect.right = readSelectorValue(_segMan, object, SELECTOR(right)); Common::Rect screenRect(_screen->getWidth(), _screen->getHeight()); - it->planeRect.top = (it->planeRect.top * screenRect.height()) / scriptsRunningHeight; - it->planeRect.left = (it->planeRect.left * screenRect.width()) / scriptsRunningWidth; - it->planeRect.bottom = (it->planeRect.bottom * screenRect.height()) / scriptsRunningHeight; - it->planeRect.right = (it->planeRect.right * screenRect.width()) / scriptsRunningWidth; + it->planeRect.top = (it->planeRect.top * screenRect.height()) / _scriptsRunningHeight; + it->planeRect.left = (it->planeRect.left * screenRect.width()) / _scriptsRunningWidth; + it->planeRect.bottom = (it->planeRect.bottom * screenRect.height()) / _scriptsRunningHeight; + it->planeRect.right = (it->planeRect.right * screenRect.width()) / _scriptsRunningWidth; // We get negative left in kq7 in scrolling rooms if (it->planeRect.left < 0) { @@ -132,9 +134,14 @@ void GfxFrameout::kernelUpdatePlane(reg_t object) { } else { it->planeOffsetX = 0; } - - if (it->planeRect.top < 0) + + if (it->planeRect.top < 0) { + it->planeOffsetY = -it->planeRect.top; it->planeRect.top = 0; + } else { + it->planeOffsetY = 0; + } + // We get bad plane-bottom in sq6 if (it->planeRect.right > _screen->getWidth()) it->planeRect.right = _screen->getWidth(); @@ -170,10 +177,6 @@ void GfxFrameout::kernelUpdatePlane(reg_t object) { error("kUpdatePlane called on plane that wasn't added before"); } -void GfxFrameout::kernelRepaintPlane(reg_t object) { - // TODO -} - void GfxFrameout::kernelDeletePlane(reg_t object) { deletePlanePictures(object); for (PlaneList::iterator it = _planes.begin(); it != _planes.end(); it++) { @@ -182,15 +185,18 @@ void GfxFrameout::kernelDeletePlane(reg_t object) { Common::Rect planeRect; planeRect.top = readSelectorValue(_segMan, object, SELECTOR(top)); planeRect.left = readSelectorValue(_segMan, object, SELECTOR(left)); - planeRect.bottom = readSelectorValue(_segMan, object, SELECTOR(bottom)) + 1; - planeRect.right = readSelectorValue(_segMan, object, SELECTOR(right)) + 1; + planeRect.bottom = readSelectorValue(_segMan, object, SELECTOR(bottom)); + planeRect.right = readSelectorValue(_segMan, object, SELECTOR(right)); Common::Rect screenRect(_screen->getWidth(), _screen->getHeight()); - planeRect.top = (planeRect.top * screenRect.height()) / scriptsRunningHeight; - planeRect.left = (planeRect.left * screenRect.width()) / scriptsRunningWidth; - planeRect.bottom = (planeRect.bottom * screenRect.height()) / scriptsRunningHeight; - planeRect.right = (planeRect.right * screenRect.width()) / scriptsRunningWidth; + planeRect.top = (planeRect.top * screenRect.height()) / _scriptsRunningHeight; + planeRect.left = (planeRect.left * screenRect.width()) / _scriptsRunningWidth; + planeRect.bottom = (planeRect.bottom * screenRect.height()) / _scriptsRunningHeight; + planeRect.right = (planeRect.right * screenRect.width()) / _scriptsRunningWidth; planeRect.clip(screenRect); // we need to do this, at least in gk1 on cemetary we get bottom right -> 201, 321 + // FIXME: The code above incorrectly added 1 pixel to the plane's + // bottom and right, so probably the plane clipping code is no + // longer necessary // Blackout removed plane rect _paint32->fillRect(planeRect, 0); return; @@ -239,36 +245,45 @@ void GfxFrameout::kernelUpdateScreenItem(reg_t object) { if (!_segMan->isObject(object)) return; - for (FrameoutList::iterator listIterator = _screenItems.begin(); listIterator != _screenItems.end(); listIterator++) { - FrameoutEntry *itemEntry = *listIterator; - - if (itemEntry->object == object) { - itemEntry->viewId = readSelectorValue(_segMan, object, SELECTOR(view)); - itemEntry->loopNo = readSelectorValue(_segMan, object, SELECTOR(loop)); - itemEntry->celNo = readSelectorValue(_segMan, object, SELECTOR(cel)); - itemEntry->x = readSelectorValue(_segMan, object, SELECTOR(x)); - itemEntry->y = readSelectorValue(_segMan, object, SELECTOR(y)); - itemEntry->z = readSelectorValue(_segMan, object, SELECTOR(z)); - itemEntry->priority = readSelectorValue(_segMan, object, SELECTOR(priority)); - if (readSelectorValue(_segMan, object, SELECTOR(fixPriority)) == 0) - itemEntry->priority = itemEntry->y; - - itemEntry->signal = readSelectorValue(_segMan, object, SELECTOR(signal)); - itemEntry->scaleX = readSelectorValue(_segMan, object, SELECTOR(scaleX)); - itemEntry->scaleY = readSelectorValue(_segMan, object, SELECTOR(scaleY)); - return; - } + FrameoutEntry *itemEntry = findScreenItem(object); + if (!itemEntry) { + warning("kernelUpdateScreenItem: invalid object %04x:%04x", PRINT_REG(object)); + return; } + + itemEntry->viewId = readSelectorValue(_segMan, object, SELECTOR(view)); + itemEntry->loopNo = readSelectorValue(_segMan, object, SELECTOR(loop)); + itemEntry->celNo = readSelectorValue(_segMan, object, SELECTOR(cel)); + itemEntry->x = readSelectorValue(_segMan, object, SELECTOR(x)); + itemEntry->y = readSelectorValue(_segMan, object, SELECTOR(y)); + itemEntry->z = readSelectorValue(_segMan, object, SELECTOR(z)); + itemEntry->priority = readSelectorValue(_segMan, object, SELECTOR(priority)); + if (readSelectorValue(_segMan, object, SELECTOR(fixPriority)) == 0) + itemEntry->priority = itemEntry->y; + + itemEntry->signal = readSelectorValue(_segMan, object, SELECTOR(signal)); + itemEntry->scaleX = readSelectorValue(_segMan, object, SELECTOR(scaleX)); + itemEntry->scaleY = readSelectorValue(_segMan, object, SELECTOR(scaleY)); } void GfxFrameout::kernelDeleteScreenItem(reg_t object) { + FrameoutEntry *itemEntry = findScreenItem(object); + if (!itemEntry) { + warning("kernelDeleteScreenItem: invalid object %04x:%04x", PRINT_REG(object)); + return; + } + + _screenItems.remove(itemEntry); +} + +FrameoutEntry *GfxFrameout::findScreenItem(reg_t object) { for (FrameoutList::iterator listIterator = _screenItems.begin(); listIterator != _screenItems.end(); listIterator++) { FrameoutEntry *itemEntry = *listIterator; - if (itemEntry->object == object) { - _screenItems.remove(itemEntry); - return; - } + if (itemEntry->object == object) + return itemEntry; } + + return NULL; } int16 GfxFrameout::kernelGetHighPlanePri() { @@ -317,37 +332,149 @@ void GfxFrameout::sortPlanes() { Common::sort(_planes.begin(), _planes.end(), planeSortHelper); } -void GfxFrameout::kernelFrameout() { - if (g_sci->_robotDecoder->isVideoLoaded()) { - bool skipVideo = false; - RobotDecoder *videoDecoder = g_sci->_robotDecoder; - uint16 x = videoDecoder->getPos().x; - uint16 y = videoDecoder->getPos().y; +int16 GfxFrameout::upscaleHorizontalCoordinate(int16 coordinate) { + return ((coordinate * _screen->getWidth()) / _scriptsRunningWidth); +} + +int16 GfxFrameout::upscaleVerticalCoordinate(int16 coordinate) { + return ((coordinate * _screen->getHeight()) / _scriptsRunningHeight); +} - if (videoDecoder->hasDirtyPalette()) - videoDecoder->setSystemPalette(); +Common::Rect GfxFrameout::upscaleRect(Common::Rect &rect) { + rect.top = (rect.top * _scriptsRunningHeight) / _screen->getHeight(); + rect.left = (rect.left * _scriptsRunningWidth) / _screen->getWidth(); + rect.bottom = (rect.bottom * _scriptsRunningHeight) / _screen->getHeight(); + rect.right = (rect.right * _scriptsRunningWidth) / _screen->getWidth(); - while (!g_engine->shouldQuit() && !videoDecoder->endOfVideo() && !skipVideo) { - if (videoDecoder->needsUpdate()) { - const Graphics::Surface *frame = videoDecoder->decodeNextFrame(); - if (frame) { - g_system->copyRectToScreen((byte *)frame->pixels, frame->pitch, x, y, frame->w, frame->h); + return rect; +} - if (videoDecoder->hasDirtyPalette()) - videoDecoder->setSystemPalette(); +void GfxFrameout::showVideo() { + bool skipVideo = false; + RobotDecoder *videoDecoder = g_sci->_robotDecoder; + uint16 x = videoDecoder->getPos().x; + uint16 y = videoDecoder->getPos().y; - g_system->updateScreen(); - } + if (videoDecoder->hasDirtyPalette()) + videoDecoder->setSystemPalette(); + + while (!g_engine->shouldQuit() && !videoDecoder->endOfVideo() && !skipVideo) { + if (videoDecoder->needsUpdate()) { + const Graphics::Surface *frame = videoDecoder->decodeNextFrame(); + if (frame) { + g_system->copyRectToScreen((byte *)frame->pixels, frame->pitch, x, y, frame->w, frame->h); + + if (videoDecoder->hasDirtyPalette()) + videoDecoder->setSystemPalette(); + + g_system->updateScreen(); } + } + + Common::Event event; + while (g_system->getEventManager()->pollEvent(event)) { + if ((event.type == Common::EVENT_KEYDOWN && event.kbd.keycode == Common::KEYCODE_ESCAPE) || event.type == Common::EVENT_LBUTTONUP) + skipVideo = true; + } - Common::Event event; - while (g_system->getEventManager()->pollEvent(event)) { - if ((event.type == Common::EVENT_KEYDOWN && event.kbd.keycode == Common::KEYCODE_ESCAPE) || event.type == Common::EVENT_LBUTTONUP) - skipVideo = true; + g_system->delayMillis(10); + } +} + +void GfxFrameout::createPlaneItemList(reg_t planeObject, FrameoutList &itemList) { + // Copy screen items of the current frame to the list of items to be drawn + for (FrameoutList::iterator listIterator = _screenItems.begin(); listIterator != _screenItems.end(); listIterator++) { + reg_t itemPlane = readSelector(_segMan, (*listIterator)->object, SELECTOR(plane)); + if (planeObject == itemPlane) { + kernelUpdateScreenItem((*listIterator)->object); // TODO: Why is this necessary? + itemList.push_back(*listIterator); + } + } + + for (PlanePictureList::iterator pictureIt = _planePictures.begin(); pictureIt != _planePictures.end(); pictureIt++) { + if (pictureIt->object == planeObject) { + GfxPicture *planePicture = pictureIt->picture; + // Allocate memory for picture cels + pictureIt->pictureCels = new FrameoutEntry[planePicture->getSci32celCount()]; + + // Add following cels to the itemlist + FrameoutEntry *picEntry = pictureIt->pictureCels; + int planePictureCels = planePicture->getSci32celCount(); + for (int pictureCelNr = 0; pictureCelNr < planePictureCels; pictureCelNr++) { + picEntry->celNo = pictureCelNr; + picEntry->object = NULL_REG; + picEntry->picture = planePicture; + picEntry->y = planePicture->getSci32celY(pictureCelNr); + picEntry->x = planePicture->getSci32celX(pictureCelNr); + picEntry->picStartX = pictureIt->startX; + picEntry->picStartY = pictureIt->startY; + + picEntry->priority = planePicture->getSci32celPriority(pictureCelNr); + + itemList.push_back(picEntry); + picEntry++; } + } + } + + // Now sort our itemlist + Common::sort(itemList.begin(), itemList.end(), sortHelper); +} - g_system->delayMillis(10); +bool GfxFrameout::isPictureOutOfView(FrameoutEntry *itemEntry, Common::Rect planeRect, int16 planeOffsetX, int16 planeOffsetY) { + // Out of view horizontally (sanity checks) + int16 pictureCelStartX = itemEntry->picStartX + itemEntry->x; + int16 pictureCelEndX = pictureCelStartX + itemEntry->picture->getSci32celWidth(itemEntry->celNo); + int16 planeStartX = planeOffsetX; + int16 planeEndX = planeStartX + planeRect.width(); + if (pictureCelEndX < planeStartX) + return true; + if (pictureCelStartX > planeEndX) + return true; + + // Out of view vertically (sanity checks) + int16 pictureCelStartY = itemEntry->picStartY + itemEntry->y; + int16 pictureCelEndY = pictureCelStartY + itemEntry->picture->getSci32celHeight(itemEntry->celNo); + int16 planeStartY = planeOffsetY; + int16 planeEndY = planeStartY + planeRect.height(); + if (pictureCelEndY < planeStartY) + return true; + if (pictureCelStartY > planeEndY) + return true; + + return false; +} + +void GfxFrameout::drawPicture(FrameoutEntry *itemEntry, int16 planeOffsetX, int16 planeOffsetY, bool planePictureMirrored) { + int16 pictureOffsetX = planeOffsetX; + int16 pictureX = itemEntry->x; + if ((planeOffsetX) || (itemEntry->picStartX)) { + if (planeOffsetX <= itemEntry->picStartX) { + pictureX += itemEntry->picStartX - planeOffsetX; + pictureOffsetX = 0; + } else { + pictureOffsetX = planeOffsetX - itemEntry->picStartX; + } + } + + int16 pictureOffsetY = planeOffsetY; + int16 pictureY = itemEntry->y; + if ((planeOffsetY) || (itemEntry->picStartY)) { + if (planeOffsetY <= itemEntry->picStartY) { + pictureY += itemEntry->picStartY - planeOffsetY; + pictureOffsetY = 0; + } else { + pictureOffsetY = planeOffsetY - itemEntry->picStartY; } + } + + itemEntry->picture->drawSci32Vga(itemEntry->celNo, pictureX, itemEntry->y, pictureOffsetX, pictureOffsetY, planePictureMirrored); + // warning("picture cel %d %d", itemEntry->celNo, itemEntry->priority); +} + +void GfxFrameout::kernelFrameout() { + if (g_sci->_robotDecoder->isVideoLoaded()) { + showVideo(); return; } @@ -368,7 +495,10 @@ void GfxFrameout::kernelFrameout() { continue; } - if (it->planeBack) + // There is a race condition lurking in SQ6, which causes the game to hang in the intro, when teleporting to Polysorbate LX. + // Since I first wrote the patch, the race has stopped occurring for me though. + // I'll leave this for investigation later, when someone can reproduce. + if (it->pictureId == 0xffff) _paint32->fillRect(it->planeRect, it->planeBack); GuiResourceId planeMainPictureId = it->pictureId; @@ -378,43 +508,7 @@ void GfxFrameout::kernelFrameout() { FrameoutList itemList; - // Copy screen items of the current frame to the list of items to be drawn - for (FrameoutList::iterator listIterator = _screenItems.begin(); listIterator != _screenItems.end(); listIterator++) { - reg_t itemPlane = readSelector(_segMan, (*listIterator)->object, SELECTOR(plane)); - if (planeObject == itemPlane) { - kernelUpdateScreenItem((*listIterator)->object); // TODO: Why is this necessary? - itemList.push_back(*listIterator); - } - } - - for (PlanePictureList::iterator pictureIt = _planePictures.begin(); pictureIt != _planePictures.end(); pictureIt++) { - if (pictureIt->object == planeObject) { - GfxPicture *planePicture = pictureIt->picture; - // Allocate memory for picture cels - pictureIt->pictureCels = new FrameoutEntry[planePicture->getSci32celCount()]; - - // Add following cels to the itemlist - FrameoutEntry *picEntry = pictureIt->pictureCels; - int planePictureCels = planePicture->getSci32celCount(); - for (int pictureCelNr = 0; pictureCelNr < planePictureCels; pictureCelNr++) { - picEntry->celNo = pictureCelNr; - picEntry->object = NULL_REG; - picEntry->picture = planePicture; - picEntry->y = planePicture->getSci32celY(pictureCelNr); - picEntry->x = planePicture->getSci32celX(pictureCelNr); - picEntry->picStartX = pictureIt->startX; - picEntry->picStartY = pictureIt->startY; - - picEntry->priority = planePicture->getSci32celPriority(pictureCelNr); - - itemList.push_back(picEntry); - picEntry++; - } - } - } - - // Now sort our itemlist - Common::sort(itemList.begin(), itemList.end(), sortHelper); + createPlaneItemList(planeObject, itemList); // warning("Plane %s", _segMan->getObjectName(planeObject)); @@ -423,100 +517,76 @@ void GfxFrameout::kernelFrameout() { if (itemEntry->object.isNull()) { // Picture cel data - itemEntry->y = ((itemEntry->y * _screen->getHeight()) / scriptsRunningHeight); - itemEntry->x = ((itemEntry->x * _screen->getWidth()) / scriptsRunningWidth); - itemEntry->picStartX = ((itemEntry->picStartX * _screen->getWidth()) / scriptsRunningWidth); - itemEntry->picStartY = ((itemEntry->picStartY * _screen->getHeight()) / scriptsRunningHeight); - - // Out of view horizontally (sanity checks) - int16 pictureCelStartX = itemEntry->picStartX + itemEntry->x; - int16 pictureCelEndX = pictureCelStartX + itemEntry->picture->getSci32celWidth(itemEntry->celNo); - int16 planeStartX = it->planeOffsetX; - int16 planeEndX = planeStartX + it->planeRect.width(); - if (pictureCelEndX < planeStartX) - continue; - if (pictureCelStartX > planeEndX) - continue; - - // Out of view vertically (sanity checks) - // TODO - - int16 pictureOffsetX = it->planeOffsetX; - int16 pictureX = itemEntry->x; - if ((it->planeOffsetX) || (itemEntry->picStartX)) { - if (it->planeOffsetX <= itemEntry->picStartX) { - pictureX += itemEntry->picStartX - it->planeOffsetX; - pictureOffsetX = 0; - } else { - pictureOffsetX = it->planeOffsetX - itemEntry->picStartX; - } - } - - // TODO: pictureOffsetY - itemEntry->picture->drawSci32Vga(itemEntry->celNo, pictureX, itemEntry->y, pictureOffsetX, it->planePictureMirrored); -// warning("picture cel %d %d", itemEntry->celNo, itemEntry->priority); - - } else if (itemEntry->viewId != 0xFFFF) { - GfxView *view = _cache->getView(itemEntry->viewId); - -// warning("view %s %04x:%04x", _segMan->getObjectName(itemEntry->object), PRINT_REG(itemEntry->object)); + itemEntry->x = upscaleHorizontalCoordinate(itemEntry->x); + itemEntry->y = upscaleVerticalCoordinate(itemEntry->y); + itemEntry->picStartX = upscaleHorizontalCoordinate(itemEntry->picStartX); + itemEntry->picStartY = upscaleVerticalCoordinate(itemEntry->picStartY); - - if (view->isSci2Hires()) { + if (!isPictureOutOfView(itemEntry, it->planeRect, it->planeOffsetX, it->planeOffsetY)) + drawPicture(itemEntry, it->planeOffsetX, it->planeOffsetY, it->planePictureMirrored); + } else { + GfxView *view = (itemEntry->viewId != 0xFFFF) ? _cache->getView(itemEntry->viewId) : NULL; + + if (view && view->isSci2Hires()) { int16 dummyX = 0; view->adjustToUpscaledCoordinates(itemEntry->y, itemEntry->x); view->adjustToUpscaledCoordinates(itemEntry->z, dummyX); } else if (getSciVersion() == SCI_VERSION_2_1) { - itemEntry->y = (itemEntry->y * _screen->getHeight()) / scriptsRunningHeight; - itemEntry->x = (itemEntry->x * _screen->getWidth()) / scriptsRunningWidth; - itemEntry->z = (itemEntry->z * _screen->getHeight()) / scriptsRunningHeight; + itemEntry->x = upscaleHorizontalCoordinate(itemEntry->x); + itemEntry->y = upscaleVerticalCoordinate(itemEntry->y); + itemEntry->z = upscaleVerticalCoordinate(itemEntry->z); } // Adjust according to current scroll position itemEntry->x -= it->planeOffsetX; + itemEntry->y -= it->planeOffsetY; uint16 useInsetRect = readSelectorValue(_segMan, itemEntry->object, SELECTOR(useInsetRect)); if (useInsetRect) { itemEntry->celRect.top = readSelectorValue(_segMan, itemEntry->object, SELECTOR(inTop)); itemEntry->celRect.left = readSelectorValue(_segMan, itemEntry->object, SELECTOR(inLeft)); - itemEntry->celRect.bottom = readSelectorValue(_segMan, itemEntry->object, SELECTOR(inBottom)) + 1; - itemEntry->celRect.right = readSelectorValue(_segMan, itemEntry->object, SELECTOR(inRight)) + 1; - if (view->isSci2Hires()) { + itemEntry->celRect.bottom = readSelectorValue(_segMan, itemEntry->object, SELECTOR(inBottom)); + itemEntry->celRect.right = readSelectorValue(_segMan, itemEntry->object, SELECTOR(inRight)); + if (view && view->isSci2Hires()) { view->adjustToUpscaledCoordinates(itemEntry->celRect.top, itemEntry->celRect.left); view->adjustToUpscaledCoordinates(itemEntry->celRect.bottom, itemEntry->celRect.right); } itemEntry->celRect.translate(itemEntry->x, itemEntry->y); // TODO: maybe we should clip the cels rect with this, i'm not sure // the only currently known usage is game menu of gk1 - } else { - if ((itemEntry->scaleX == 128) && (itemEntry->scaleY == 128)) - view->getCelRect(itemEntry->loopNo, itemEntry->celNo, itemEntry->x, itemEntry->y, itemEntry->z, itemEntry->celRect); - else - view->getCelScaledRect(itemEntry->loopNo, itemEntry->celNo, itemEntry->x, itemEntry->y, itemEntry->z, itemEntry->scaleX, itemEntry->scaleY, itemEntry->celRect); + } else if (view) { + if ((itemEntry->scaleX == 128) && (itemEntry->scaleY == 128)) + view->getCelRect(itemEntry->loopNo, itemEntry->celNo, + itemEntry->x, itemEntry->y, itemEntry->z, itemEntry->celRect); + else + view->getCelScaledRect(itemEntry->loopNo, itemEntry->celNo, + itemEntry->x, itemEntry->y, itemEntry->z, itemEntry->scaleX, + itemEntry->scaleY, itemEntry->celRect); Common::Rect nsRect = itemEntry->celRect; // Translate back to actual coordinate within scrollable plane - nsRect.translate(it->planeOffsetX, 0); + nsRect.translate(it->planeOffsetX, it->planeOffsetY); - if (view->isSci2Hires()) { + if (view && view->isSci2Hires()) { view->adjustBackUpscaledCoordinates(nsRect.top, nsRect.left); view->adjustBackUpscaledCoordinates(nsRect.bottom, nsRect.right); } else if (getSciVersion() == SCI_VERSION_2_1) { - nsRect.top = (nsRect.top * scriptsRunningHeight) / _screen->getHeight(); - nsRect.left = (nsRect.left * scriptsRunningWidth) / _screen->getWidth(); - nsRect.bottom = (nsRect.bottom * scriptsRunningHeight) / _screen->getHeight(); - nsRect.right = (nsRect.right * scriptsRunningWidth) / _screen->getWidth(); + nsRect = upscaleRect(nsRect); } - writeSelectorValue(_segMan, itemEntry->object, SELECTOR(nsLeft), nsRect.left); - writeSelectorValue(_segMan, itemEntry->object, SELECTOR(nsTop), nsRect.top); - writeSelectorValue(_segMan, itemEntry->object, SELECTOR(nsRight), nsRect.right); - writeSelectorValue(_segMan, itemEntry->object, SELECTOR(nsBottom), nsRect.bottom); + if (g_sci->getGameId() == GID_PHANTASMAGORIA2) { + // HACK: Some (?) objects in Phantasmagoria 2 have no NS rect. Skip them for now. + // TODO: Remove once we figure out how Phantasmagoria 2 draws objects on screen. + if (lookupSelector(_segMan, itemEntry->object, SELECTOR(nsLeft), NULL, NULL) != kSelectorVariable) + continue; + } + + g_sci->_gfxCompare->setNSRect(itemEntry->object, nsRect); } int16 screenHeight = _screen->getHeight(); int16 screenWidth = _screen->getWidth(); - if (view->isSci2Hires()) { + if (view && view->isSci2Hires()) { screenHeight = _screen->getDisplayHeight(); screenWidth = _screen->getDisplayWidth(); } @@ -529,7 +599,8 @@ void GfxFrameout::kernelFrameout() { Common::Rect clipRect, translatedClipRect; clipRect = itemEntry->celRect; - if (view->isSci2Hires()) { + + if (view && view->isSci2Hires()) { clipRect.clip(it->upscaledPlaneClipRect); translatedClipRect = clipRect; translatedClipRect.translate(it->upscaledPlaneRect.left, it->upscaledPlaneRect.top); @@ -539,33 +610,20 @@ void GfxFrameout::kernelFrameout() { translatedClipRect.translate(it->planeRect.left, it->planeRect.top); } - if (!clipRect.isEmpty()) { - if ((itemEntry->scaleX == 128) && (itemEntry->scaleY == 128)) - view->draw(itemEntry->celRect, clipRect, translatedClipRect, itemEntry->loopNo, itemEntry->celNo, 255, 0, view->isSci2Hires()); - else - view->drawScaled(itemEntry->celRect, clipRect, translatedClipRect, itemEntry->loopNo, itemEntry->celNo, 255, itemEntry->scaleX, itemEntry->scaleY); - } - } else { - // Most likely a text entry - if (lookupSelector(_segMan, itemEntry->object, SELECTOR(text), NULL, NULL) == kSelectorVariable) { - TextEntry *textEntry = g_sci->_gfxText32->getTextEntry(itemEntry->object); - uint16 startX = ((textEntry->x * _screen->getWidth()) / scriptsRunningWidth) + it->planeRect.left; - uint16 startY = ((textEntry->y * _screen->getHeight()) / scriptsRunningHeight) + it->planeRect.top; - // HACK. The plane sometimes doesn't contain the correct width. This - // hack breaks the dialog options when speaking with Grace, but it's - // the best we got up to now. This happens because of the unimplemented - // kTextWidth function in SCI32. - // TODO: Remove this once kTextWidth has been implemented. - uint16 w = it->planeRect.width() >= 20 ? it->planeRect.width() : _screen->getWidth() - 10; - - // Upscale the coordinates/width if the fonts are already upscaled - if (_screen->fontIsUpscaled()) { - startX = startX * _screen->getDisplayWidth() / _screen->getWidth(); - startY = startY * _screen->getDisplayHeight() / _screen->getHeight(); - w = w * _screen->getDisplayWidth() / _screen->getWidth(); + if (view) { + if (!clipRect.isEmpty()) { + if ((itemEntry->scaleX == 128) && (itemEntry->scaleY == 128)) + view->draw(itemEntry->celRect, clipRect, translatedClipRect, + itemEntry->loopNo, itemEntry->celNo, 255, 0, view->isSci2Hires()); + else + view->drawScaled(itemEntry->celRect, clipRect, translatedClipRect, + itemEntry->loopNo, itemEntry->celNo, 255, itemEntry->scaleX, itemEntry->scaleY); } + } - g_sci->_gfxText32->drawTextBitmap(itemEntry->object, startX, startY, w); + // Draw text, if it exists + if (lookupSelector(_segMan, itemEntry->object, SELECTOR(text), NULL, NULL) == kSelectorVariable) { + g_sci->_gfxText32->drawTextBitmap(itemEntry->x, itemEntry->y, it->planeRect, itemEntry->object); } } } diff --git a/engines/sci/graphics/frameout.h b/engines/sci/graphics/frameout.h index d2c8086f5f..a4a0a853e4 100644 --- a/engines/sci/graphics/frameout.h +++ b/engines/sci/graphics/frameout.h @@ -32,6 +32,7 @@ struct PlaneEntry { uint16 priority; uint16 lastPriority; int16 planeOffsetX; + int16 planeOffsetY; GuiResourceId pictureId; Common::Rect planeRect; Common::Rect planeClipRect; @@ -89,11 +90,11 @@ public: void kernelAddPlane(reg_t object); void kernelUpdatePlane(reg_t object); - void kernelRepaintPlane(reg_t object); void kernelDeletePlane(reg_t object); void kernelAddScreenItem(reg_t object); void kernelUpdateScreenItem(reg_t object); void kernelDeleteScreenItem(reg_t object); + FrameoutEntry *findScreenItem(reg_t object); int16 kernelGetHighPlanePri(); void kernelAddPicAt(reg_t planeObj, GuiResourceId pictureId, int16 pictureX, int16 pictureY); void kernelFrameout(); @@ -103,6 +104,14 @@ public: void clear(); private: + void showVideo(); + void createPlaneItemList(reg_t planeObject, FrameoutList &itemList); + bool isPictureOutOfView(FrameoutEntry *itemEntry, Common::Rect planeRect, int16 planeOffsetX, int16 planeOffsetY); + void drawPicture(FrameoutEntry *itemEntry, int16 planeOffsetX, int16 planeOffsetY, bool planePictureMirrored); + int16 upscaleHorizontalCoordinate(int16 coordinate); + int16 upscaleVerticalCoordinate(int16 coordinate); + Common::Rect upscaleRect(Common::Rect &rect); + SegManager *_segMan; ResourceManager *_resMan; GfxCoordAdjuster32 *_coordAdjuster; @@ -117,8 +126,8 @@ private: void sortPlanes(); - uint16 scriptsRunningWidth; - uint16 scriptsRunningHeight; + uint16 _scriptsRunningWidth; + uint16 _scriptsRunningHeight; }; } // End of namespace Sci diff --git a/engines/sci/graphics/paint.h b/engines/sci/graphics/paint.h index efeaa38875..27f7e428b6 100644 --- a/engines/sci/graphics/paint.h +++ b/engines/sci/graphics/paint.h @@ -23,8 +23,6 @@ #ifndef SCI_GRAPHICS_PAINT_H #define SCI_GRAPHICS_PAINT_H -#include "common/hashmap.h" - namespace Sci { class GfxPaint { diff --git a/engines/sci/graphics/paint16.cpp b/engines/sci/graphics/paint16.cpp index 75fef0a3ec..23177dfc7b 100644 --- a/engines/sci/graphics/paint16.cpp +++ b/engines/sci/graphics/paint16.cpp @@ -467,9 +467,9 @@ void GfxPaint16::kernelGraphRedrawBox(Common::Rect rect) { #define SCI_DISPLAY_WIDTH 106 #define SCI_DISPLAY_SAVEUNDER 107 #define SCI_DISPLAY_RESTOREUNDER 108 -#define SCI_DISPLAY_DUMMY1 114 // used in longbow demo/qfg1 ega demo, not supported in sierra sci - no parameters -#define SCI_DISPLAY_DUMMY2 115 // used in longbow demo, not supported in sierra sci - has 1 parameter -#define SCI_DISPLAY_DUMMY3 117 // used in qfg1 ega demo, not supported in sierra sci - no parameters +#define SCI_DISPLAY_DUMMY1 114 +#define SCI_DISPLAY_DUMMY2 115 +#define SCI_DISPLAY_DUMMY3 117 #define SCI_DISPLAY_DONTSHOWBITS 121 reg_t GfxPaint16::kernelDisplay(const char *text, int argc, reg_t *argv) { @@ -539,26 +539,29 @@ reg_t GfxPaint16::kernelDisplay(const char *text, int argc, reg_t *argv) { bRedraw = 0; break; - // 2 Dummy functions, longbow-demo is using those several times but sierra sci doesn't support them at all - // The Quest for Glory 1 EGA demo also calls kDisplay(114) and kDisplay(117) - case SCI_DISPLAY_DUMMY1: - case SCI_DISPLAY_DUMMY2: - case SCI_DISPLAY_DUMMY3: - if (!g_sci->isDemo() || (g_sci->getGameId() != GID_LONGBOW && g_sci->getGameId() != GID_QFG1)) + // The following three dummy calls are not supported by the Sierra SCI + // interpreter, but are erroneously called in some game scripts. + case SCI_DISPLAY_DUMMY1: // Longbow demo (all rooms) and QFG1 EGA demo (room 11) + case SCI_DISPLAY_DUMMY2: // Longbow demo (all rooms) + case SCI_DISPLAY_DUMMY3: // QFG1 EGA demo (room 11) and PQ2 (room 23) + if (!(g_sci->getGameId() == GID_LONGBOW && g_sci->isDemo()) && + !(g_sci->getGameId() == GID_QFG1 && g_sci->isDemo()) && + !(g_sci->getGameId() == GID_PQ2)) error("Unknown kDisplay argument %d", displayArg.offset); + if (displayArg.offset == SCI_DISPLAY_DUMMY2) { - if (argc) { - argc--; argv++; - } else { + if (!argc) error("No parameter left for kDisplay(115)"); - } + argc--; argv++; } break; default: SciTrackOriginReply originReply; SciWorkaroundSolution solution = trackOriginAndFindWorkaround(0, kDisplay_workarounds, &originReply); if (solution.type == WORKAROUND_NONE) - error("Unknown kDisplay argument (%04x:%04x) from method %s::%s (script %d, localCall %x)", PRINT_REG(displayArg), originReply.objectName.c_str(), originReply.methodName.c_str(), originReply.scriptNr, originReply.localCallOffset); + error("Unknown kDisplay argument (%04x:%04x) from method %s::%s (script %d, localCall %x)", + PRINT_REG(displayArg), originReply.objectName.c_str(), originReply.methodName.c_str(), + originReply.scriptNr, originReply.localCallOffset); assert(solution.type == WORKAROUND_IGNORE); break; } diff --git a/engines/sci/graphics/paint16.h b/engines/sci/graphics/paint16.h index 31916599ba..46df203200 100644 --- a/engines/sci/graphics/paint16.h +++ b/engines/sci/graphics/paint16.h @@ -25,8 +25,6 @@ #include "sci/graphics/paint.h" -#include "common/hashmap.h" - namespace Sci { class GfxPorts; diff --git a/engines/sci/graphics/paint32.h b/engines/sci/graphics/paint32.h index dd4246c507..66b31de282 100644 --- a/engines/sci/graphics/paint32.h +++ b/engines/sci/graphics/paint32.h @@ -25,8 +25,6 @@ #include "sci/graphics/paint.h" -#include "common/hashmap.h" - namespace Sci { class GfxPorts; diff --git a/engines/sci/graphics/palette.cpp b/engines/sci/graphics/palette.cpp index 5f703b90e3..47d1647c6c 100644 --- a/engines/sci/graphics/palette.cpp +++ b/engines/sci/graphics/palette.cpp @@ -37,7 +37,7 @@ namespace Sci { -GfxPalette::GfxPalette(ResourceManager *resMan, GfxScreen *screen, bool useMerging) +GfxPalette::GfxPalette(ResourceManager *resMan, GfxScreen *screen) : _resMan(resMan), _screen(screen) { int16 color; @@ -65,7 +65,14 @@ GfxPalette::GfxPalette(ResourceManager *resMan, GfxScreen *screen, bool useMergi // the real merging done in earlier games. If we use the copying over, we // will get issues because some views have marked all colors as being used // and those will overwrite the current palette in that case - _useMerging = useMerging; + if (getSciVersion() < SCI_VERSION_1_1) + _useMerging = true; + else if (getSciVersion() == SCI_VERSION_1_1) + // there are some games that use inbetween SCI1.1 interpreter, so we have + // to detect if the current game is merging or copying + _useMerging = _resMan->detectPaletteMergingSci11(); + else // SCI32 + _useMerging = false; palVaryInit(); @@ -327,7 +334,9 @@ bool GfxPalette::insert(Palette *newPalette, Palette *destPalette) { for (int i = 1; i < 255; i++) { if (newPalette->colors[i].used) { - if ((newPalette->colors[i].r != destPalette->colors[i].r) || (newPalette->colors[i].g != destPalette->colors[i].g) || (newPalette->colors[i].b != destPalette->colors[i].b)) { + if ((newPalette->colors[i].r != destPalette->colors[i].r) || + (newPalette->colors[i].g != destPalette->colors[i].g) || + (newPalette->colors[i].b != destPalette->colors[i].b)) { destPalette->colors[i].r = newPalette->colors[i].r; destPalette->colors[i].g = newPalette->colors[i].g; destPalette->colors[i].b = newPalette->colors[i].b; @@ -354,7 +363,9 @@ bool GfxPalette::merge(Palette *newPalette, bool force, bool forceRealMerge) { // forced palette merging or dest color is not used yet if (force || (!_sysPalette.colors[i].used)) { _sysPalette.colors[i].used = newPalette->colors[i].used; - if ((newPalette->colors[i].r != _sysPalette.colors[i].r) || (newPalette->colors[i].g != _sysPalette.colors[i].g) || (newPalette->colors[i].b != _sysPalette.colors[i].b)) { + if ((newPalette->colors[i].r != _sysPalette.colors[i].r) || + (newPalette->colors[i].g != _sysPalette.colors[i].g) || + (newPalette->colors[i].b != _sysPalette.colors[i].b)) { _sysPalette.colors[i].r = newPalette->colors[i].r; _sysPalette.colors[i].g = newPalette->colors[i].g; _sysPalette.colors[i].b = newPalette->colors[i].b; @@ -367,7 +378,9 @@ bool GfxPalette::merge(Palette *newPalette, bool force, bool forceRealMerge) { // is the same color already at the same position? -> match it directly w/o lookup // this fixes games like lsl1demo/sq5 where the same rgb color exists multiple times and where we would // otherwise match the wrong one (which would result into the pixels affected (or not) by palette changes) - if ((_sysPalette.colors[i].r == newPalette->colors[i].r) && (_sysPalette.colors[i].g == newPalette->colors[i].g) && (_sysPalette.colors[i].b == newPalette->colors[i].b)) { + if ((_sysPalette.colors[i].r == newPalette->colors[i].r) && + (_sysPalette.colors[i].g == newPalette->colors[i].g) && + (_sysPalette.colors[i].b == newPalette->colors[i].b)) { newPalette->mapping[i] = i; continue; } @@ -696,6 +709,13 @@ bool GfxPalette::palVaryLoadTargetPalette(GuiResourceId resourceId) { } void GfxPalette::palVaryInstallTimer() { + // Remove any possible leftover palVary timer callbacks. + // This happens for example in QFG1VGA, when sleeping at Erana's place + // (bug #3439240) - the nighttime to daytime effect clashes with the + // scene transition effect, as we load scene images too quickly for + // the SCI scripts in that case (also refer to kernelPalVaryInit). + palVaryRemoveTimer(); + int16 ticks = _palVaryTicks > 0 ? _palVaryTicks : 1; // Call signal increase every [ticks] g_sci->getTimerManager()->installTimerProc(&palVaryCallback, 1000000 / 60 * ticks, this, "sciPalette"); @@ -953,7 +973,7 @@ void GfxPalette::loadMacIconBarPalette() { } bool GfxPalette::colorIsFromMacClut(byte index) { - return index != 0 && _macClut && (_macClut[index * 3] != 0 || _macClut[index * 3 + 1] != 0 || _macClut[index * 3 + 1] != 0); + return index != 0 && _macClut && (_macClut[index * 3] != 0 || _macClut[index * 3 + 1] != 0 || _macClut[index * 3 + 2] != 0); } #ifdef ENABLE_SCI32 diff --git a/engines/sci/graphics/palette.h b/engines/sci/graphics/palette.h index 243420cc47..a9ea1c32de 100644 --- a/engines/sci/graphics/palette.h +++ b/engines/sci/graphics/palette.h @@ -36,7 +36,7 @@ class GfxScreen; */ class GfxPalette : public Common::Serializable { public: - GfxPalette(ResourceManager *resMan, GfxScreen *screen, bool useMerging); + GfxPalette(ResourceManager *resMan, GfxScreen *screen); ~GfxPalette(); bool isMerging(); diff --git a/engines/sci/graphics/picture.cpp b/engines/sci/graphics/picture.cpp index dad2b77036..bb326b1d2f 100644 --- a/engines/sci/graphics/picture.cpp +++ b/engines/sci/graphics/picture.cpp @@ -77,7 +77,7 @@ void GfxPicture::draw(int16 animationNr, bool mirroredFlag, bool addToFlag, int1 #ifdef ENABLE_SCI32 case 0x0e: // SCI32 VGA picture _resourceType = SCI_PICTURE_TYPE_SCI32; - //drawSci32Vga(); + drawSci32Vga(0, 0, 0, 0, 0, false); break; #endif default: @@ -132,7 +132,7 @@ void GfxPicture::drawSci11Vga() { _palette->createFromData(inbuffer + palette_data_ptr, size - palette_data_ptr, &palette); _palette->set(&palette, true); - drawCelData(inbuffer, size, cel_headerPos, cel_RlePos, cel_LiteralPos, 0, 0, 0); + drawCelData(inbuffer, size, cel_headerPos, cel_RlePos, cel_LiteralPos, 0, 0, 0, 0); } // process vector data @@ -148,18 +148,18 @@ int16 GfxPicture::getSci32celCount() { return inbuffer[2]; } -int16 GfxPicture::getSci32celY(int16 celNo) { +int16 GfxPicture::getSci32celX(int16 celNo) { byte *inbuffer = _resource->data; int header_size = READ_SCI11ENDIAN_UINT16(inbuffer); int cel_headerPos = header_size + 42 * celNo; - return READ_SCI11ENDIAN_UINT16(inbuffer + cel_headerPos + 40); + return READ_SCI11ENDIAN_UINT16(inbuffer + cel_headerPos + 38); } -int16 GfxPicture::getSci32celX(int16 celNo) { +int16 GfxPicture::getSci32celY(int16 celNo) { byte *inbuffer = _resource->data; int header_size = READ_SCI11ENDIAN_UINT16(inbuffer); int cel_headerPos = header_size + 42 * celNo; - return READ_SCI11ENDIAN_UINT16(inbuffer + cel_headerPos + 38); + return READ_SCI11ENDIAN_UINT16(inbuffer + cel_headerPos + 40); } int16 GfxPicture::getSci32celWidth(int16 celNo) { @@ -169,6 +169,14 @@ int16 GfxPicture::getSci32celWidth(int16 celNo) { return READ_SCI11ENDIAN_UINT16(inbuffer + cel_headerPos + 0); } +int16 GfxPicture::getSci32celHeight(int16 celNo) { + byte *inbuffer = _resource->data; + int header_size = READ_SCI11ENDIAN_UINT16(inbuffer); + int cel_headerPos = header_size + 42 * celNo; + return READ_SCI11ENDIAN_UINT16(inbuffer + cel_headerPos + 2); +} + + int16 GfxPicture::getSci32celPriority(int16 celNo) { byte *inbuffer = _resource->data; int header_size = READ_SCI11ENDIAN_UINT16(inbuffer); @@ -176,7 +184,7 @@ int16 GfxPicture::getSci32celPriority(int16 celNo) { return READ_SCI11ENDIAN_UINT16(inbuffer + cel_headerPos + 36); } -void GfxPicture::drawSci32Vga(int16 celNo, int16 drawX, int16 drawY, int16 pictureX, bool mirrored) { +void GfxPicture::drawSci32Vga(int16 celNo, int16 drawX, int16 drawY, int16 pictureX, int16 pictureY, bool mirrored) { byte *inbuffer = _resource->data; int size = _resource->size; int header_size = READ_SCI11ENDIAN_UINT16(inbuffer); @@ -216,14 +224,14 @@ void GfxPicture::drawSci32Vga(int16 celNo, int16 drawX, int16 drawY, int16 pictu cel_RlePos = READ_SCI11ENDIAN_UINT32(inbuffer + cel_headerPos + 24); cel_LiteralPos = READ_SCI11ENDIAN_UINT32(inbuffer + cel_headerPos + 28); - drawCelData(inbuffer, size, cel_headerPos, cel_RlePos, cel_LiteralPos, drawX, drawY, pictureX); + drawCelData(inbuffer, size, cel_headerPos, cel_RlePos, cel_LiteralPos, drawX, drawY, pictureX, pictureY); cel_headerPos += 42; } #endif extern void unpackCelData(byte *inBuffer, byte *celBitmap, byte clearColor, int pixelCount, int rlePos, int literalPos, ViewType viewType, uint16 width, bool isMacSci11ViewData); -void GfxPicture::drawCelData(byte *inbuffer, int size, int headerPos, int rlePos, int literalPos, int16 drawX, int16 drawY, int16 pictureX) { +void GfxPicture::drawCelData(byte *inbuffer, int size, int headerPos, int rlePos, int literalPos, int16 drawX, int16 drawY, int16 pictureX, int16 pictureY) { byte *celBitmap = NULL; byte *ptr = NULL; byte *headerPtr = inbuffer + headerPos; @@ -300,10 +308,11 @@ void GfxPicture::drawCelData(byte *inbuffer, int size, int headerPos, int rlePos Common::Rect displayArea = _coordAdjuster->pictureGetDisplayArea(); + // Horizontal clipping uint16 skipCelBitmapPixels = 0; int16 displayWidth = width; if (pictureX) { - // scroll position for picture active, we need to adjust drawX accordingly + // horizontal scroll position for picture active, we need to adjust drawX accordingly drawX -= pictureX; if (drawX < 0) { skipCelBitmapPixels = -drawX; @@ -312,7 +321,21 @@ void GfxPicture::drawCelData(byte *inbuffer, int size, int headerPos, int rlePos } } - if (displayWidth > 0) { + // Vertical clipping + uint16 skipCelBitmapLines = 0; + int16 displayHeight = height; + if (pictureY) { + // vertical scroll position for picture active, we need to adjust drawY accordingly + // TODO: Finish this + /*drawY -= pictureY; + if (drawY < 0) { + skipCelBitmapLines = -drawY; + displayHeight -= skipCelBitmapLines; + drawY = 0; + }*/ + } + + if (displayWidth > 0 && displayHeight > 0) { y = displayArea.top + drawY; lastY = MIN<int16>(height + y, displayArea.bottom); leftX = displayArea.left + drawX; @@ -334,6 +357,7 @@ void GfxPicture::drawCelData(byte *inbuffer, int size, int headerPos, int rlePos ptr = celBitmap; ptr += skipCelBitmapPixels; + ptr += skipCelBitmapLines * width; if (!_mirroredFlag) { // Draw bitmap to screen x = leftX; @@ -714,7 +738,7 @@ void GfxPicture::drawVectorData(byte *data, int dataSize) { vectorGetAbsCoordsNoMirror(data, curPos, x, y); size = READ_LE_UINT16(data + curPos); curPos += 2; _priority = pic_priority; // set global priority so the cel gets drawn using current priority as well - drawCelData(data, _resource->size, curPos, curPos + 8, 0, x, y, 0); + drawCelData(data, _resource->size, curPos, curPos + 8, 0, x, y, 0, 0); curPos += size; break; case PIC_OPX_EGA_SET_PRIORITY_TABLE: @@ -757,7 +781,7 @@ void GfxPicture::drawVectorData(byte *data, int dataSize) { vectorGetAbsCoordsNoMirror(data, curPos, x, y); size = READ_LE_UINT16(data + curPos); curPos += 2; _priority = pic_priority; // set global priority so the cel gets drawn using current priority as well - drawCelData(data, _resource->size, curPos, curPos + 8, 0, x, y, 0); + drawCelData(data, _resource->size, curPos, curPos + 8, 0, x, y, 0, 0); curPos += size; break; case PIC_OPX_VGA_PRIORITY_TABLE_EQDIST: diff --git a/engines/sci/graphics/picture.h b/engines/sci/graphics/picture.h index 78623d5e09..4f075a6226 100644 --- a/engines/sci/graphics/picture.h +++ b/engines/sci/graphics/picture.h @@ -56,15 +56,16 @@ public: int16 getSci32celY(int16 celNo); int16 getSci32celX(int16 celNo); int16 getSci32celWidth(int16 celNo); + int16 getSci32celHeight(int16 celNo); int16 getSci32celPriority(int16 celNo); - void drawSci32Vga(int16 celNo, int16 callerX, int16 callerY, int16 pictureX, bool mirrored); + void drawSci32Vga(int16 celNo, int16 callerX, int16 callerY, int16 pictureX, int16 pictureY, bool mirrored); #endif private: void initData(GuiResourceId resourceId); void reset(); void drawSci11Vga(); - void drawCelData(byte *inbuffer, int size, int headerPos, int rlePos, int literalPos, int16 drawX, int16 drawY, int16 pictureX); + void drawCelData(byte *inbuffer, int size, int headerPos, int rlePos, int literalPos, int16 drawX, int16 drawY, int16 pictureX, int16 pictureY); void drawVectorData(byte *data, int size); bool vectorIsNonOpcode(byte pixel); void vectorGetAbsCoords(byte *data, int &curPos, int16 &x, int16 &y); diff --git a/engines/sci/graphics/text32.cpp b/engines/sci/graphics/text32.cpp index 21372f1502..fd6637f313 100644 --- a/engines/sci/graphics/text32.cpp +++ b/engines/sci/graphics/text32.cpp @@ -32,169 +32,185 @@ #include "sci/engine/selector.h" #include "sci/engine/state.h" #include "sci/graphics/cache.h" +#include "sci/graphics/compare.h" #include "sci/graphics/font.h" #include "sci/graphics/screen.h" #include "sci/graphics/text32.h" namespace Sci { +#define BITMAP_HEADER_SIZE 46 + +#define SCI_TEXT32_ALIGNMENT_RIGHT -1 +#define SCI_TEXT32_ALIGNMENT_CENTER 1 +#define SCI_TEXT32_ALIGNMENT_LEFT 0 + GfxText32::GfxText32(SegManager *segMan, GfxCache *fonts, GfxScreen *screen) : _segMan(segMan), _cache(fonts), _screen(screen) { } GfxText32::~GfxText32() { - purgeCache(); } -void GfxText32::purgeCache() { - for (TextCache::iterator cacheIterator = _textCache.begin(); cacheIterator != _textCache.end(); cacheIterator++) { - delete[] cacheIterator->_value->surface; - delete cacheIterator->_value; - cacheIterator->_value = 0; - } - - _textCache.clear(); -} +reg_t GfxText32::createTextBitmap(reg_t textObject, uint16 maxWidth, uint16 maxHeight, reg_t prevHunk) { + reg_t stringObject = readSelector(_segMan, textObject, SELECTOR(text)); -void GfxText32::createTextBitmap(reg_t textObject) { - if (_textCache.size() >= MAX_CACHED_TEXTS) - purgeCache(); + // The object in the text selector of the item can be either a raw string + // or a Str object. In the latter case, we need to access the object's data + // selector to get the raw string. + if (_segMan->isHeapObject(stringObject)) + stringObject = readSelector(_segMan, stringObject, SELECTOR(data)); - uint32 textId = (textObject.segment << 16) | textObject.offset; + Common::String text = _segMan->getString(stringObject); + // HACK: The character offsets of the up and down arrow buttons are off by one + // in GK1, for some unknown reason. Fix them here. + if (text.size() == 1 && (text[0] == 29 || text[0] == 30)) { + text.setChar(text[0] + 1, 0); + } + GuiResourceId fontId = readSelectorValue(_segMan, textObject, SELECTOR(font)); + GfxFont *font = _cache->getFont(fontId); + bool dimmed = readSelectorValue(_segMan, textObject, SELECTOR(dimmed)); + int16 alignment = readSelectorValue(_segMan, textObject, SELECTOR(mode)); + uint16 foreColor = readSelectorValue(_segMan, textObject, SELECTOR(fore)); + uint16 backColor = readSelectorValue(_segMan, textObject, SELECTOR(back)); + + Common::Rect nsRect = g_sci->_gfxCompare->getNSRect(textObject); + uint16 width = nsRect.width() + 1; + uint16 height = nsRect.height() + 1; + + // Limit rectangle dimensions, if requested + if (maxWidth > 0) + width = maxWidth; + if (maxHeight > 0) + height = maxHeight; + + // Upscale the coordinates/width if the fonts are already upscaled + if (_screen->fontIsUpscaled()) { + width = width * _screen->getDisplayWidth() / _screen->getWidth(); + height = height * _screen->getDisplayHeight() / _screen->getHeight(); + } - if (_textCache.contains(textId)) { - // Delete the old entry - TextEntry *oldEntry = _textCache[textId]; - delete[] oldEntry->surface; - delete oldEntry; - _textCache.erase(textId); + int entrySize = width * height + BITMAP_HEADER_SIZE; + reg_t memoryId = NULL_REG; + if (prevHunk.isNull()) { + memoryId = _segMan->allocateHunkEntry("TextBitmap()", entrySize); + writeSelector(_segMan, textObject, SELECTOR(bitmap), memoryId); + } else { + memoryId = prevHunk; } + byte *memoryPtr = _segMan->getHunkPointer(memoryId); - _textCache[textId] = createTextEntry(textObject); -} + if (prevHunk.isNull()) + memset(memoryPtr, 0, BITMAP_HEADER_SIZE); -// TODO: Finish this! -void GfxText32::drawTextBitmap(reg_t textObject, uint16 textX, uint16 textY, uint16 w) { - uint32 textId = (textObject.segment << 16) | textObject.offset; + byte *bitmap = memoryPtr + BITMAP_HEADER_SIZE; + memset(bitmap, backColor, width * height); - if (!_textCache.contains(textId)) - createTextBitmap(textObject); + // Save totalWidth, totalHeight + WRITE_LE_UINT16(memoryPtr, width); + WRITE_LE_UINT16(memoryPtr + 2, height); - TextEntry *entry = _textCache[textId]; + int16 charCount = 0; + uint16 curX = 0, curY = 0; + const char *txt = text.c_str(); + int16 textWidth, textHeight, totalHeight = 0, offsetX = 0, offsetY = 0; + uint16 start = 0; - // This draws text the "SCI0-SCI11" way. In SCI2, text is prerendered in kCreateTextBitmap - // TODO: rewrite this the "SCI2" way (i.e. implement the text buffer to draw inside kCreateTextBitmap) - GfxFont *font = _cache->getFont(readSelectorValue(_segMan, textObject, SELECTOR(font))); - bool dimmed = readSelectorValue(_segMan,textObject, SELECTOR(dimmed)); - uint16 foreColor = readSelectorValue(_segMan, textObject, SELECTOR(fore)); + // Calculate total text height + while (*txt) { + charCount = GetLongest(txt, width, font); + if (charCount == 0) + break; - const char *txt = entry->text.c_str(); - int16 charCount; + Width(txt, 0, (int16)strlen(txt), fontId, textWidth, textHeight, true); + + totalHeight += textHeight; + txt += charCount; + while (*txt == ' ') + txt++; // skip over breaking spaces + } + + txt = text.c_str(); + // Draw text in buffer while (*txt) { - charCount = GetLongest(txt, w, font); + charCount = GetLongest(txt, width, font); if (charCount == 0) break; + Width(txt, start, charCount, fontId, textWidth, textHeight, true); - uint16 curX = textX; + switch (alignment) { + case SCI_TEXT32_ALIGNMENT_RIGHT: + offsetX = width - textWidth; + break; + case SCI_TEXT32_ALIGNMENT_CENTER: + // Center text both horizontally and vertically + offsetX = (width - textWidth) / 2; + offsetY = (height - totalHeight) / 2; + break; + case SCI_TEXT32_ALIGNMENT_LEFT: + offsetX = 0; + break; + + default: + warning("Invalid alignment %d used in TextBox()", alignment); + } for (int i = 0; i < charCount; i++) { unsigned char curChar = txt[i]; - font->draw(curChar, textY, curX, foreColor, dimmed); + font->drawToBuffer(curChar, curY + offsetY, curX + offsetX, foreColor, dimmed, bitmap, width, height); curX += font->getCharWidth(curChar); } - textY += font->getHeight(); + curX = 0; + curY += font->getHeight(); txt += charCount; while (*txt == ' ') txt++; // skip over breaking spaces } - // TODO: The "SCI2" way of font drawing. Currently buggy - /* - for (int x = textX; x < entry->width; x++) { - for (int y = textY; y < entry->height; y++) { - byte pixel = entry->surface[y * entry->width + x]; - if (pixel) - _screen->putPixel(x, y, 1, pixel, 0, 0); - } - } - */ + return memoryId; } -TextEntry *GfxText32::getTextEntry(reg_t textObject) { - uint32 textId = (textObject.segment << 16) | textObject.offset; - - if (!_textCache.contains(textId)) - createTextBitmap(textObject); - - return _textCache[textId]; +void GfxText32::disposeTextBitmap(reg_t hunkId) { + _segMan->freeHunkEntry(hunkId); } -// TODO: Finish this! Currently buggy. -TextEntry *GfxText32::createTextEntry(reg_t textObject) { - reg_t stringObject = readSelector(_segMan, textObject, SELECTOR(text)); +void GfxText32::drawTextBitmap(uint16 x, uint16 y, Common::Rect planeRect, reg_t textObject) { + reg_t hunkId = readSelector(_segMan, textObject, SELECTOR(bitmap)); + // Sanity check: Check if the hunk is set. If not, either the game scripts + // didn't set it, or an old saved game has been loaded, where it wasn't set. + if (hunkId.isNull()) + return; - // The object in the text selector of the item can be either a raw string - // or a Str object. In the latter case, we need to access the object's data - // selector to get the raw string. - if (_segMan->isHeapObject(stringObject)) - stringObject = readSelector(_segMan, stringObject, SELECTOR(data)); + byte *memoryPtr = _segMan->getHunkPointer(hunkId); - const char *text = _segMan->getString(stringObject).c_str(); - GfxFont *font = _cache->getFont(readSelectorValue(_segMan, textObject, SELECTOR(font))); - bool dimmed = readSelectorValue(_segMan, textObject, SELECTOR(dimmed)); - uint16 foreColor = readSelectorValue(_segMan, textObject, SELECTOR(fore)); - uint16 x = readSelectorValue(_segMan, textObject, SELECTOR(x)); - uint16 y = readSelectorValue(_segMan, textObject, SELECTOR(y)); - - // Now get the bounding box from the associated plane - reg_t planeObject = readSelector(_segMan, textObject, SELECTOR(plane)); - Common::Rect planeRect; - if (!planeObject.isNull()) { - planeRect.top = readSelectorValue(_segMan, planeObject, SELECTOR(top)); - planeRect.left = readSelectorValue(_segMan, planeObject, SELECTOR(left)); - planeRect.bottom = readSelectorValue(_segMan, planeObject, SELECTOR(bottom)) + 1; - planeRect.right = readSelectorValue(_segMan, planeObject, SELECTOR(right)) + 1; - } else { - planeRect.top = 0; - planeRect.left = 0; - planeRect.bottom = _screen->getHeight(); - planeRect.right = _screen->getWidth(); - } + if (!memoryPtr) + error("Attempt to draw an invalid text bitmap"); - TextEntry *newEntry = new TextEntry(); - newEntry->object = stringObject; - newEntry->x = x; - newEntry->y = y; - newEntry->width = planeRect.width(); - newEntry->height = planeRect.height(); - newEntry->surface = new byte[newEntry->width * newEntry->height]; - memset(newEntry->surface, 0, newEntry->width * newEntry->height); - newEntry->text = _segMan->getString(stringObject); - - int16 maxTextWidth, charCount; - uint16 curX = 0, curY = 0; + byte *surface = memoryPtr + BITMAP_HEADER_SIZE; - maxTextWidth = 0; - while (*text) { - charCount = GetLongest(text, planeRect.width(), font); - if (charCount == 0) - break; + int curByte = 0; + uint16 skipColor = readSelectorValue(_segMan, textObject, SELECTOR(skip)); + uint16 textX = planeRect.left + x; + uint16 textY = planeRect.top + y; + // Get totalWidth, totalHeight + uint16 width = READ_LE_UINT16(memoryPtr); + uint16 height = READ_LE_UINT16(memoryPtr + 2); - for (int i = 0; i < charCount; i++) { - unsigned char curChar = text[i]; - font->drawToBuffer(curChar, curY, curX, foreColor, dimmed, newEntry->surface, newEntry->width, newEntry->height); - curX += font->getCharWidth(curChar); - } - - curY += font->getHeight(); - text += charCount; - while (*text == ' ') - text++; // skip over breaking spaces + // Upscale the coordinates/width if the fonts are already upscaled + if (_screen->fontIsUpscaled()) { + textX = textX * _screen->getDisplayWidth() / _screen->getWidth(); + textY = textY * _screen->getDisplayHeight() / _screen->getHeight(); } - return newEntry; + for (int curY = 0; curY < height; curY++) { + for (int curX = 0; curX < width; curX++) { + byte pixel = surface[curByte++]; + if (pixel != skipColor) + _screen->putFontPixel(textY, curX + textX, curY, pixel); + } + } } int16 GfxText32::GetLongest(const char *text, int16 maxWidth, GfxFont *font) { @@ -235,4 +251,77 @@ int16 GfxText32::GetLongest(const char *text, int16 maxWidth, GfxFont *font) { return maxChars; } +void GfxText32::kernelTextSize(const char *text, int16 font, int16 maxWidth, int16 *textWidth, int16 *textHeight) { + Common::Rect rect(0, 0, 0, 0); + Size(rect, text, font, maxWidth); + *textWidth = rect.width(); + *textHeight = rect.height(); +} + +void GfxText32::StringWidth(const char *str, GuiResourceId fontId, int16 &textWidth, int16 &textHeight) { + Width(str, 0, (int16)strlen(str), fontId, textWidth, textHeight, true); +} + +void GfxText32::Width(const char *text, int16 from, int16 len, GuiResourceId fontId, int16 &textWidth, int16 &textHeight, bool restoreFont) { + uint16 curChar; + textWidth = 0; textHeight = 0; + + GfxFont *font = _cache->getFont(fontId); + + if (font) { + text += from; + while (len--) { + curChar = (*(const byte *)text++); + switch (curChar) { + case 0x0A: + case 0x0D: + case 0x9781: // this one is used by SQ4/japanese as line break as well + textHeight = MAX<int16> (textHeight, font->getHeight()); + break; + case 0x7C: + warning("Code processing isn't implemented in SCI32"); + break; + default: + textHeight = MAX<int16> (textHeight, font->getHeight()); + textWidth += font->getCharWidth(curChar); + break; + } + } + } +} + +int16 GfxText32::Size(Common::Rect &rect, const char *text, GuiResourceId fontId, int16 maxWidth) { + int16 charCount; + int16 maxTextWidth = 0, textWidth; + int16 totalHeight = 0, textHeight; + + rect.top = rect.left = 0; + GfxFont *font = _cache->getFont(fontId); + + if (maxWidth < 0) { // force output as single line + StringWidth(text, fontId, textWidth, textHeight); + rect.bottom = textHeight; + rect.right = textWidth; + } else { + // rect.right=found widest line with RTextWidth and GetLongest + // rect.bottom=num. lines * GetPointSize + rect.right = (maxWidth ? maxWidth : 192); + const char *curPos = text; + while (*curPos) { + charCount = GetLongest(curPos, rect.right, font); + if (charCount == 0) + break; + Width(curPos, 0, charCount, fontId, textWidth, textHeight, false); + maxTextWidth = MAX(textWidth, maxTextWidth); + totalHeight += textHeight; + curPos += charCount; + while (*curPos == ' ') + curPos++; // skip over breaking spaces + } + rect.bottom = totalHeight; + rect.right = maxWidth ? maxWidth : MIN(rect.right, maxTextWidth); + } + return rect.right; +} + } // End of namespace Sci diff --git a/engines/sci/graphics/text32.h b/engines/sci/graphics/text32.h index 39fe710a86..3a411ce663 100644 --- a/engines/sci/graphics/text32.h +++ b/engines/sci/graphics/text32.h @@ -26,24 +26,8 @@ #ifndef SCI_GRAPHICS_TEXT32_H #define SCI_GRAPHICS_TEXT32_H -#include "common/hashmap.h" - namespace Sci { -struct TextEntry { - reg_t object; - uint16 x; - uint16 y; - uint16 width; - uint16 height; - byte *surface; - Common::String text; -}; - -// TODO: Move to Cache, perhaps? -#define MAX_CACHED_TEXTS 20 -typedef Common::HashMap<uint32, TextEntry *> TextCache; - /** * Text32 class, handles text calculation and displaying of text for SCI2, SCI21 and SCI3 games */ @@ -51,18 +35,20 @@ class GfxText32 { public: GfxText32(SegManager *segMan, GfxCache *fonts, GfxScreen *screen); ~GfxText32(); - void createTextBitmap(reg_t textObject); - void drawTextBitmap(reg_t textObject, uint16 textX, uint16 textY, uint16 w); + reg_t createTextBitmap(reg_t textObject, uint16 maxWidth = 0, uint16 maxHeight = 0, reg_t prevHunk = NULL_REG); + void disposeTextBitmap(reg_t hunkId); + void drawTextBitmap(uint16 x, uint16 y, Common::Rect planeRect, reg_t textObject); int16 GetLongest(const char *text, int16 maxWidth, GfxFont *font); - TextEntry *getTextEntry(reg_t textObject); + + void kernelTextSize(const char *text, int16 font, int16 maxWidth, int16 *textWidth, int16 *textHeight); private: - TextEntry *createTextEntry(reg_t textObject); - void purgeCache(); + int16 Size(Common::Rect &rect, const char *text, GuiResourceId fontId, int16 maxWidth); + void Width(const char *text, int16 from, int16 len, GuiResourceId orgFontId, int16 &textWidth, int16 &textHeight, bool restoreFont); + void StringWidth(const char *str, GuiResourceId orgFontId, int16 &textWidth, int16 &textHeight); SegManager *_segMan; GfxCache *_cache; - TextCache _textCache; GfxScreen *_screen; }; diff --git a/engines/sci/graphics/view.cpp b/engines/sci/graphics/view.cpp index a0d5b51a2b..a77bcccc52 100644 --- a/engines/sci/graphics/view.cpp +++ b/engines/sci/graphics/view.cpp @@ -172,6 +172,20 @@ void GfxView::initData(GuiResourceId resourceId) { cel->displaceX = (signed char)celData[4]; cel->displaceY = celData[5]; cel->clearKey = celData[6]; + + // HACK: Fix Ego's odd displacement in the QFG3 demo, scene 740. + // For some reason, ego jumps above the rope, so we fix his rope + // hanging view by displacing it down by 40 pixels. Fixes bug + // #3035693. + // FIXME: Remove this once we figure out why Ego jumps so high. + // Likely culprits include kInitBresen, kDoBresen and kCantBeHere. + // The scripts have the y offset that hero reaches (11) hardcoded, + // so it might be collision detection. However, since this requires + // extensive work to fix properly for very little gain, this hack + // here will suffice until the actual issue is found. + if (g_sci->getGameId() == GID_QFG3 && g_sci->isDemo() && resourceId == 39) + cel->displaceY = 98; + if (isEGA) { cel->offsetEGA = celOffset + 7; cel->offsetRLE = 0; @@ -418,10 +432,11 @@ void unpackCelData(byte *inBuffer, byte *celBitmap, byte clearColor, int pixelCo // Skip the next YYYYY pixels (i.e. transparency) if (literalPos && isMacSci11ViewData) { - // KQ6/Freddy Pharkas use byte lengths, all others use uint16 + // KQ6/Freddy Pharkas/Slater use byte lengths, all others use uint16 // The SCI devs must have realized that a max of 255 pixels wide // was not very good for 320 or 640 width games. - bool hasByteLengths = (g_sci->getGameId() == GID_KQ6 || g_sci->getGameId() == GID_FREDDYPHARKAS); + bool hasByteLengths = (g_sci->getGameId() == GID_KQ6 || g_sci->getGameId() == GID_FREDDYPHARKAS + || g_sci->getGameId() == GID_SLATER); // compression for SCI1.1+ Mac while (pixelNr < pixelCount) { @@ -837,4 +852,13 @@ void GfxView::adjustBackUpscaledCoordinates(int16 &y, int16 &x) { _screen->adjustBackUpscaledCoordinates(y, x, _sci2ScaleRes); } +byte GfxView::getColorAtCoordinate(int16 loopNo, int16 celNo, int16 x, int16 y) { + const CelInfo *celInfo = getCelInfo(loopNo, celNo); + const byte *bitmap = getBitmap(loopNo, celNo); + const int16 celWidth = celInfo->width; + + bitmap += (celWidth * y); + return bitmap[x]; +} + } // End of namespace Sci diff --git a/engines/sci/graphics/view.h b/engines/sci/graphics/view.h index 19ef2e62f8..d3473f1024 100644 --- a/engines/sci/graphics/view.h +++ b/engines/sci/graphics/view.h @@ -85,6 +85,8 @@ public: void adjustToUpscaledCoordinates(int16 &y, int16 &x); void adjustBackUpscaledCoordinates(int16 &y, int16 &x); + byte getColorAtCoordinate(int16 loopNo, int16 celNo, int16 x, int16 y); + private: void initData(GuiResourceId resourceId); void unpackCel(int16 loopNo, int16 celNo, byte *outPtr, uint32 pixelCount); diff --git a/engines/sci/module.mk b/engines/sci/module.mk index c129ae5439..90a0f33f06 100644 --- a/engines/sci/module.mk +++ b/engines/sci/module.mk @@ -43,7 +43,7 @@ MODULE_OBJS := \ graphics/animate.o \ graphics/cache.o \ graphics/compare.o \ - graphics/controls.o \ + graphics/controls16.o \ graphics/coordadjuster.o \ graphics/cursor.o \ graphics/font.o \ @@ -71,6 +71,7 @@ MODULE_OBJS := \ sound/drivers/amigamac.o \ sound/drivers/cms.o \ sound/drivers/fb01.o \ + sound/drivers/fmtowns.o \ sound/drivers/midi.o \ sound/drivers/pcjr.o \ video/seq_decoder.o @@ -78,6 +79,7 @@ MODULE_OBJS := \ ifdef ENABLE_SCI32 MODULE_OBJS += \ + graphics/controls32.o \ graphics/frameout.o \ graphics/paint32.o \ graphics/text32.o \ diff --git a/engines/sci/resource.cpp b/engines/sci/resource.cpp index bdd7d6692b..9171e5e5d9 100644 --- a/engines/sci/resource.cpp +++ b/engines/sci/resource.cpp @@ -169,8 +169,11 @@ ResourceType ResourceManager::convertResType(byte type) { if (type < ARRAYSIZE(s_resTypeMapSci21)) { // LSL6 hires doesn't have the chunk resource type, to match // the resource types of the lowres version, thus we use the - // older resource types here - if (g_sci && g_sci->getGameId() == GID_LSL6HIRES) + // older resource types here. + // PQ4 CD and QFG4 CD are SCI2.1, but use the resource types of the + // corresponding SCI2 floppy disk versions. + if (g_sci && (g_sci->getGameId() == GID_LSL6HIRES || + g_sci->getGameId() == GID_QFG4 || g_sci->getGameId() == GID_PQ4)) return s_resTypeMapSci0[type]; else return s_resTypeMapSci21[type]; @@ -2181,15 +2184,16 @@ void ResourceManager::detectSciVersion() { } if (_volVersion == kResVersionSci11Mac) { - // SCI32 doesn't have the resource.cfg file, so we can figure out - // which of the games are SCI1.1. Note that there are no Mac SCI2 games. - // Yes, that means that GK1 Mac is SCI2.1 and not SCI2. + Resource *res = testResource(ResourceId(kResourceTypeScript, 64920)); + // Distinguish between SCI1.1 and SCI32 games here. SCI32 games will + // always include script 64920 (the Array class). Note that there are + // no Mac SCI2 games. Yes, that means that GK1 Mac is SCI2.1 and not SCI2. // TODO: Decide between SCI2.1 and SCI3 - if (Common::File::exists("resource.cfg")) - s_sciVersion = SCI_VERSION_1_1; - else + if (res) s_sciVersion = SCI_VERSION_2_1; + else + s_sciVersion = SCI_VERSION_1_1; return; } @@ -2354,7 +2358,7 @@ bool ResourceManager::detectFontExtended() { } // detects, if SCI1.1 game uses palette merging or copying - this is supposed to only get used on SCI1.1 games -bool ResourceManager::detectForPaletteMergingForSci11() { +bool ResourceManager::detectPaletteMergingSci11() { // Load palette 999 (default palette) Resource *res = findResource(ResourceId(kResourceTypePalette, 999), false); diff --git a/engines/sci/resource.h b/engines/sci/resource.h index f450f1b397..47602de017 100644 --- a/engines/sci/resource.h +++ b/engines/sci/resource.h @@ -354,7 +354,7 @@ public: // Detects, if standard font of current game includes extended characters (>0x80) bool detectFontExtended(); // Detects, if SCI1.1 game uses palette merging - bool detectForPaletteMergingForSci11(); + bool detectPaletteMergingSci11(); // Detects, if SCI0EARLY game also has SCI0EARLY sound resources bool detectEarlySound(); diff --git a/engines/sci/resource_audio.cpp b/engines/sci/resource_audio.cpp index f3a3c8dd5b..a3cf1b0c84 100644 --- a/engines/sci/resource_audio.cpp +++ b/engines/sci/resource_audio.cpp @@ -915,18 +915,23 @@ bool ResourceManager::addAudioSources() { void ResourceManager::changeAudioDirectory(Common::String path) { // Remove all of the audio map resource sources, as well as the audio resource sources - for (Common::List<ResourceSource *>::iterator it = _sources.begin(); it != _sources.end(); ++it) { + for (Common::List<ResourceSource *>::iterator it = _sources.begin(); it != _sources.end();) { ResourceSource *source = *it; ResSourceType sourceType = source->getSourceType(); // Remove the resource source, if it's an audio map or an audio file if (sourceType == kSourceIntMap || sourceType == kSourceAudioVolume) { // Don't remove 65535.map (the SFX map) or resource.sfx - if (source->_volumeNumber == 65535 || source->getLocationName() == "RESOURCE.SFX") + if (source->_volumeNumber == 65535 || source->getLocationName() == "RESOURCE.SFX") { + ++it; continue; + } + // erase() will move the iterator to the next element it = _sources.erase(it); delete source; + } else { + ++it; } } diff --git a/engines/sci/sci.cpp b/engines/sci/sci.cpp index 6c1b6e4dd6..00731fc1cf 100644 --- a/engines/sci/sci.cpp +++ b/engines/sci/sci.cpp @@ -46,7 +46,8 @@ #include "sci/graphics/animate.h" #include "sci/graphics/cache.h" #include "sci/graphics/compare.h" -#include "sci/graphics/controls.h" +#include "sci/graphics/controls16.h" +#include "sci/graphics/controls32.h" #include "sci/graphics/coordadjuster.h" #include "sci/graphics/cursor.h" #include "sci/graphics/maciconbar.h" @@ -90,6 +91,7 @@ SciEngine::SciEngine(OSystem *syst, const ADGameDescription *desc, SciGameId gam _vocabularyLanguage = 1; // we load english vocabulary on startup _eventMan = 0; _console = 0; + _opcode_formats = 0; // Set up the engine specific debug levels DebugMan.addDebugChannel(kDebugLevelError, "Error", "Script error debugging"); @@ -113,6 +115,7 @@ SciEngine::SciEngine(OSystem *syst, const ADGameDescription *desc, SciGameId gam DebugMan.addDebugChannel(kDebugLevelGC, "GC", "Garbage Collector debugging"); DebugMan.addDebugChannel(kDebugLevelResMan, "ResMan", "Resource manager debugging"); DebugMan.addDebugChannel(kDebugLevelOnStartup, "OnStartup", "Enter debugger at start of game"); + DebugMan.addDebugChannel(kDebugLevelDebugMode, "DebugMode", "Enable game debug mode at start of game"); const Common::FSNode gameDataDir(ConfMan.get("path")); @@ -147,12 +150,13 @@ SciEngine::~SciEngine() { DebugMan.clearAllDebugChannels(); #ifdef ENABLE_SCI32 + delete _gfxControls32; delete _gfxText32; delete _robotDecoder; delete _gfxFrameout; #endif delete _gfxMenu; - delete _gfxControls; + delete _gfxControls16; delete _gfxText16; delete _gfxAnimate; delete _gfxPaint; @@ -176,6 +180,9 @@ SciEngine::~SciEngine() { delete _eventMan; delete _gamestate->_segMan; delete _gamestate; + + delete[] _opcode_formats; + delete _resMan; // should be deleted last g_sci = 0; } @@ -588,7 +595,7 @@ void SciEngine::initGraphics() { _gfxAnimate = 0; _gfxCache = 0; _gfxCompare = 0; - _gfxControls = 0; + _gfxControls16 = 0; _gfxCoordAdjuster = 0; _gfxCursor = 0; _gfxMacIconBar = 0; @@ -600,6 +607,7 @@ void SciEngine::initGraphics() { _gfxText16 = 0; _gfxTransitions = 0; #ifdef ENABLE_SCI32 + _gfxControls32 = 0; _gfxText32 = 0; _robotDecoder = 0; _gfxFrameout = 0; @@ -609,16 +617,7 @@ void SciEngine::initGraphics() { if (hasMacIconBar()) _gfxMacIconBar = new GfxMacIconBar(); - bool paletteMerging = true; - if (getSciVersion() >= SCI_VERSION_1_1) { - // there are some games that use inbetween SCI1.1 interpreter, so we have to detect if it's merging or copying - if (getSciVersion() == SCI_VERSION_1_1) - paletteMerging = _resMan->detectForPaletteMergingForSci11(); - else - paletteMerging = false; - } - - _gfxPalette = new GfxPalette(_resMan, _gfxScreen, paletteMerging); + _gfxPalette = new GfxPalette(_resMan, _gfxScreen); _gfxCache = new GfxCache(_resMan, _gfxScreen, _gfxPalette); _gfxCursor = new GfxCursor(_resMan, _gfxPalette, _gfxScreen); @@ -631,6 +630,7 @@ void SciEngine::initGraphics() { _gfxPaint32 = new GfxPaint32(_resMan, _gamestate->_segMan, _kernel, _gfxCoordAdjuster, _gfxCache, _gfxScreen, _gfxPalette); _gfxPaint = _gfxPaint32; _gfxText32 = new GfxText32(_gamestate->_segMan, _gfxCache, _gfxScreen); + _gfxControls32 = new GfxControls32(_gamestate->_segMan, _gfxCache, _gfxScreen, _gfxText32); _robotDecoder = new RobotDecoder(g_system->getMixer(), getPlatform() == Common::kPlatformMacintosh); _gfxFrameout = new GfxFrameout(_gamestate->_segMan, _resMan, _gfxCoordAdjuster, _gfxCache, _gfxScreen, _gfxPalette, _gfxPaint32); } else { @@ -645,7 +645,7 @@ void SciEngine::initGraphics() { _gfxPaint = _gfxPaint16; _gfxAnimate = new GfxAnimate(_gamestate, _gfxCache, _gfxPorts, _gfxPaint16, _gfxScreen, _gfxPalette, _gfxCursor, _gfxTransitions); _gfxText16 = new GfxText16(_resMan, _gfxCache, _gfxPorts, _gfxPaint16, _gfxScreen); - _gfxControls = new GfxControls(_gamestate->_segMan, _gfxPorts, _gfxPaint16, _gfxText16, _gfxScreen); + _gfxControls16 = new GfxControls16(_gamestate->_segMan, _gfxPorts, _gfxPaint16, _gfxText16, _gfxScreen); _gfxMenu = new GfxMenu(_eventMan, _gamestate->_segMan, _gfxPorts, _gfxPaint16, _gfxText16, _gfxScreen, _gfxCursor); _gfxMenu->reset(); diff --git a/engines/sci/sci.h b/engines/sci/sci.h index 81bbdc51de..9f18219cb7 100644 --- a/engines/sci/sci.h +++ b/engines/sci/sci.h @@ -59,7 +59,8 @@ class SegManager; class GfxAnimate; class GfxCache; class GfxCompare; -class GfxControls; +class GfxControls16; +class GfxControls32; class GfxCoordAdjuster; class GfxCursor; class GfxMacIconBar; @@ -101,7 +102,8 @@ enum kDebugLevels { kDebugLevelScripts = 1 << 17, kDebugLevelGC = 1 << 18, kDebugLevelResMan = 1 << 19, - kDebugLevelOnStartup = 1 << 20 + kDebugLevelOnStartup = 1 << 20, + kDebugLevelDebugMode = 1 << 21 }; enum SciGameId { @@ -303,7 +305,8 @@ public: GfxAnimate *_gfxAnimate; // Animate for 16-bit gfx GfxCache *_gfxCache; GfxCompare *_gfxCompare; - GfxControls *_gfxControls; // Controls for 16-bit gfx + GfxControls16 *_gfxControls16; // Controls for 16-bit gfx + GfxControls32 *_gfxControls32; // Controls for 32-bit gfx GfxCoordAdjuster *_gfxCoordAdjuster; GfxCursor *_gfxCursor; GfxMenu *_gfxMenu; // Menu for 16-bit gfx @@ -327,6 +330,8 @@ public: SoundCommandParser *_soundCmd; GameFeatures *_features; + opcode_format (*_opcode_formats)[4]; + DebugState _debugState; Common::MacResManager *getMacExecutable() { return &_macExecutable; } diff --git a/engines/sci/sound/drivers/adlib.cpp b/engines/sci/sound/drivers/adlib.cpp index add3d8851f..db9317e071 100644 --- a/engines/sci/sound/drivers/adlib.cpp +++ b/engines/sci/sound/drivers/adlib.cpp @@ -613,8 +613,6 @@ void MidiDriver_AdLib::setNote(int voice, int note, bool key) { _voices[voice].note = note; - delta = 0; - n = note % 12; if (bend < 8192) diff --git a/engines/sci/sound/drivers/amigamac.cpp b/engines/sci/sound/drivers/amigamac.cpp index 3c750401b9..41697d4a07 100644 --- a/engines/sci/sound/drivers/amigamac.cpp +++ b/engines/sci/sound/drivers/amigamac.cpp @@ -130,7 +130,7 @@ private: }; bool _isSci1; - bool _isSci1Early; // KQ1 Amiga, patch 5 + bool _isSci1Early; // KQ1/MUMG Amiga, patch 5 bool _playSwitch; int _masterVolume; int _frequency; @@ -586,12 +586,12 @@ int MidiDriver_AmigaMac::open() { } else { ResourceManager *resMan = g_sci->getResMan(); - Resource *resource = resMan->findResource(ResourceId(kResourceTypePatch, 7), false); // Mac + Resource *resource = resMan->findResource(ResourceId(kResourceTypePatch, 7), false); // Mac if (!resource) - resource = resMan->findResource(ResourceId(kResourceTypePatch, 9), false); // Amiga + resource = resMan->findResource(ResourceId(kResourceTypePatch, 9), false); // Amiga if (!resource) { - resource = resMan->findResource(ResourceId(kResourceTypePatch, 5), false); // KQ1 Amiga + resource = resMan->findResource(ResourceId(kResourceTypePatch, 5), false); // KQ1/MUMG Amiga if (resource) _isSci1Early = true; } @@ -892,7 +892,7 @@ bool MidiDriver_AmigaMac::loadInstrumentsSCI1(Common::SeekableReadStream &file) _bank.size = 128; if (_isSci1Early) - file.skip(4); // TODO: What is this offset for? + file.readUint32BE(); // Skip size of bank Common::Array<uint32> instrumentOffsets; instrumentOffsets.resize(_bank.size); @@ -911,12 +911,6 @@ bool MidiDriver_AmigaMac::loadInstrumentsSCI1(Common::SeekableReadStream &file) // Read in the instrument name file.read(_bank.instruments[i].name, 10); // last two bytes are always 0 - // TODO: Finish off support of SCI1 early patches (patch.005 - KQ1 Amiga) - if (_isSci1Early) { - warning("Music patch 5 isn't supported yet - ignoring instrument %d", i); - continue; - } - for (uint32 j = 0; ; j++) { InstrumentSample *sample = new InstrumentSample; memset(sample, 0, sizeof(InstrumentSample)); @@ -943,16 +937,30 @@ bool MidiDriver_AmigaMac::loadInstrumentsSCI1(Common::SeekableReadStream &file) int16 loop = file.readSint16BE(); uint32 nextSamplePos = file.pos(); - file.seek(samplePtr); + file.seek(samplePtr + (_isSci1Early ? 4 : 0)); file.read(sample->name, 8); - sample->isUnsigned = file.readUint16BE() == 0; - uint16 phase1Offset = file.readUint16BE(); - uint16 phase1End = file.readUint16BE(); - uint16 phase2Offset = file.readUint16BE(); - uint16 phase2End = file.readUint16BE(); - sample->baseNote = file.readUint16BE(); - uint32 periodTableOffset = file.readUint32BE(); + uint16 phase1Offset, phase1End; + uint16 phase2Offset, phase2End; + + if (_isSci1Early) { + sample->isUnsigned = false; + file.readUint32BE(); // skip total sample size + phase2Offset = file.readUint16BE(); + phase2End = file.readUint16BE(); + sample->baseNote = file.readUint16BE(); + phase1Offset = file.readUint16BE(); + phase1End = file.readUint16BE(); + } else { + sample->isUnsigned = file.readUint16BE() == 0; + phase1Offset = file.readUint16BE(); + phase1End = file.readUint16BE(); + phase2Offset = file.readUint16BE(); + phase2End = file.readUint16BE(); + sample->baseNote = file.readUint16BE(); + } + + uint32 periodTableOffset = _isSci1Early ? 0 : file.readUint32BE(); uint32 sampleDataPos = file.pos(); sample->size = phase1End - phase1Offset + 1; @@ -974,8 +982,13 @@ bool MidiDriver_AmigaMac::loadInstrumentsSCI1(Common::SeekableReadStream &file) _bank.instruments[i].push_back(sample); - file.seek(periodTableOffset + 0xe0); - sample->baseFreq = file.readUint16BE(); + if (_isSci1Early) { + // There's no frequency specified by the sample and is hardcoded like in SCI0 + sample->baseFreq = 11000; + } else { + file.seek(periodTableOffset + 0xe0); + sample->baseFreq = file.readUint16BE(); + } file.seek(nextSamplePos); } diff --git a/engines/sci/sound/drivers/fmtowns.cpp b/engines/sci/sound/drivers/fmtowns.cpp new file mode 100644 index 0000000000..6d8bb2e525 --- /dev/null +++ b/engines/sci/sound/drivers/fmtowns.cpp @@ -0,0 +1,652 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "sci/sci.h" + +#include "common/file.h" +#include "common/system.h" +#include "common/textconsole.h" + +#include "audio/softsynth/fmtowns_pc98/towns_audio.h" + +#include "sci/resource.h" +#include "sci/sound/drivers/mididriver.h" + +namespace Sci { + +class MidiDriver_FMTowns; + +class TownsChannel { +public: + TownsChannel(MidiDriver_FMTowns *driver, uint8 id); + ~TownsChannel() {} + + void noteOff(); + void noteOn(uint8 note, uint8 velo); + void pitchBend(int16 val); + void updateVolume(); + void updateDuration(); + + uint8 _assign; + uint8 _note; + uint8 _sustain; + uint16 _duration; + +private: + uint8 _id; + uint8 _velo; + uint8 _program; + + MidiDriver_FMTowns *_drv; +}; + +class TownsMidiPart { +friend class MidiDriver_FMTowns; +public: + TownsMidiPart(MidiDriver_FMTowns *driver, uint8 id); + ~TownsMidiPart() {} + + void noteOff(uint8 note); + void noteOn(uint8 note, uint8 velo); + void controlChangeVolume(uint8 vol); + void controlChangeSustain(uint8 sus); + void controlChangePolyphony(uint8 numChan); + void controlChangeAllNotesOff(); + void programChange(uint8 prg); + void pitchBend(int16 val); + + void addChannels(int num); + void dropChannels(int num); + + uint8 currentProgram() const; + +private: + int allocateChannel(); + + uint8 _id; + uint8 _program; + uint8 _volume; + uint8 _sustain; + uint8 _chanMissing; + int16 _pitchBend; + uint8 _outChan; + + MidiDriver_FMTowns *_drv; +}; + +class MidiDriver_FMTowns : public MidiDriver, public TownsAudioInterfacePluginDriver { +friend class TownsChannel; +friend class TownsMidiPart; +public: + MidiDriver_FMTowns(Audio::Mixer *mixer, SciVersion version); + ~MidiDriver_FMTowns(); + + int open(); + void loadInstruments(const uint8 *data); + bool isOpen() const { return _isOpen; } + void close(); + + void send(uint32 b); + + uint32 property(int prop, uint32 param); + void setTimerCallback(void *timer_param, Common::TimerManager::TimerProc timer_proc); + + void setSoundOn(bool toggle); + + uint32 getBaseTempo(); + MidiChannel *allocateChannel() { return 0; } + MidiChannel *getPercussionChannel() { return 0; } + + uint8 currentProgram(); + + void timerCallback(int timerId); + +private: + int getChannelVolume(uint8 midiPart); + void addMissingChannels(); + + void updateParser(); + void updateChannels(); + + Common::TimerManager::TimerProc _timerProc; + void *_timerProcPara; + + TownsMidiPart **_parts; + TownsChannel **_out; + + uint8 _masterVolume; + + bool _soundOn; + + bool _isOpen; + bool _ready; + + const uint16 _baseTempo; + SciVersion _version; + + TownsAudioInterface *_intf; +}; + +class MidiPlayer_FMTowns : public MidiPlayer { +public: + MidiPlayer_FMTowns(SciVersion version); + ~MidiPlayer_FMTowns(); + + int open(ResourceManager *resMan); + + bool hasRhythmChannel() const; + byte getPlayId() const; + int getPolyphony() const; + void playSwitch(bool play); + +private: + MidiDriver_FMTowns *_townsDriver; +}; + +TownsChannel::TownsChannel(MidiDriver_FMTowns *driver, uint8 id) : _drv(driver), _id(id), _assign(0xff), _note(0xff), _velo(0), _sustain(0), _duration(0), _program(0xff) { +} + +void TownsChannel::noteOn(uint8 note, uint8 velo) { + _duration = 0; + + if (_drv->_version != SCI_VERSION_1_EARLY) { + if (_program != _drv->_parts[_assign]->currentProgram() && _drv->_soundOn) { + _program = _drv->_parts[_assign]->currentProgram(); + _drv->_intf->callback(4, _id, _program); + } + } + + _note = note; + _velo = velo; + _drv->_intf->callback(1, _id, _note, _velo); +} + +void TownsChannel::noteOff() { + if (_sustain) + return; + + _drv->_intf->callback(2, _id); + _note = 0xff; + _duration = 0; +} + +void TownsChannel::pitchBend(int16 val) { + _drv->_intf->callback(7, _id, val); +} + +void TownsChannel::updateVolume() { + if (_assign > 15 && _drv->_version != SCI_VERSION_1_EARLY) + return; + _drv->_intf->callback(8, _id, _drv->getChannelVolume((_drv->_version == SCI_VERSION_1_EARLY) ? 0 : _assign)); +} + +void TownsChannel::updateDuration() { + if (_note != 0xff) + _duration++; +} + +TownsMidiPart::TownsMidiPart(MidiDriver_FMTowns *driver, uint8 id) : _drv(driver), _id(id), _program(0), _volume(0x3f), _sustain(0), _chanMissing(0), _pitchBend(0x2000), _outChan(0) { +} + +void TownsMidiPart::noteOff(uint8 note) { + for (int i = 0; i < 6; i++) { + if ((_drv->_out[i]->_assign != _id && _drv->_version != SCI_VERSION_1_EARLY) || _drv->_out[i]->_note != note) + continue; + if (_sustain) + _drv->_out[i]->_sustain = 1; + else + _drv->_out[i]->noteOff(); + return; + } +} + +void TownsMidiPart::noteOn(uint8 note, uint8 velo) { + if (note < 12 || note > 107) + return; + + if (velo == 0) { + noteOff(note); + return; + } + + if (_drv->_version != SCI_VERSION_1_EARLY) + velo >>= 1; + + for (int i = 0; i < 6; i++) { + if ((_drv->_out[i]->_assign != _id && _drv->_version != SCI_VERSION_1_EARLY) || _drv->_out[i]->_note != note) + continue; + _drv->_out[i]->_sustain = 0; + _drv->_out[i]->noteOff(); + _drv->_out[i]->noteOn(note, velo); + return; + } + + int chan = allocateChannel(); + if (chan != -1) + _drv->_out[chan]->noteOn(note, velo); +} + +void TownsMidiPart::controlChangeVolume(uint8 vol) { + if (_drv->_version == SCI_VERSION_1_EARLY) + return; + + _volume = vol >> 1; + for (int i = 0; i < 6; i++) { + if (_drv->_out[i]->_assign == _id) + _drv->_out[i]->updateVolume(); + } +} + +void TownsMidiPart::controlChangeSustain(uint8 sus) { + if (_drv->_version == SCI_VERSION_1_EARLY) + return; + + _sustain = sus; + if (_sustain) + return; + + for (int i = 0; i < 6; i++) { + if (_drv->_out[i]->_assign == _id && _drv->_out[i]->_sustain) { + _drv->_out[i]->_sustain = 0; + _drv->_out[i]->noteOff(); + } + } +} + +void TownsMidiPart::controlChangePolyphony(uint8 numChan) { + if (_drv->_version == SCI_VERSION_1_EARLY) + return; + + uint8 numAssigned = 0; + for (int i = 0; i < 6; i++) { + if (_drv->_out[i]->_assign == _id) + numAssigned++; + } + + numAssigned += _chanMissing; + if (numAssigned < numChan) { + addChannels(numChan - numAssigned); + } else if (numAssigned > numChan) { + dropChannels(numAssigned - numChan); + _drv->addMissingChannels(); + } +} + +void TownsMidiPart::controlChangeAllNotesOff() { + for (int i = 0; i < 6; i++) { + if ((_drv->_out[i]->_assign == _id || _drv->_version == SCI_VERSION_1_EARLY) && _drv->_out[i]->_note != 0xff) + _drv->_out[i]->noteOff(); + } +} + +void TownsMidiPart::programChange(uint8 prg) { + _program = prg; +} + +void TownsMidiPart::pitchBend(int16 val) { + _pitchBend = val; + val -= 0x2000; + for (int i = 0; i < 6; i++) { + // Strangely, the early version driver applies the setting to channel 0 only. + if (_drv->_out[i]->_assign == _id || (_drv->_version == SCI_VERSION_1_EARLY && i == 0)) + _drv->_out[i]->pitchBend(val); + } +} + +void TownsMidiPart::addChannels(int num) { + for (int i = 0; i < 6; i++) { + if (_drv->_out[i]->_assign != 0xff) + continue; + + _drv->_out[i]->_assign = _id; + _drv->_out[i]->updateVolume(); + + if (_drv->_out[i]->_note != 0xff) + _drv->_out[i]->noteOff(); + + if (!--num) + break; + } + + _chanMissing += num; + programChange(_program); +} + +void TownsMidiPart::dropChannels(int num) { + if (_chanMissing == num) { + _chanMissing = 0; + return; + } else if (_chanMissing > num) { + _chanMissing -= num; + return; + } + + num -= _chanMissing; + _chanMissing = 0; + + for (int i = 0; i < 6; i++) { + if (_drv->_out[i]->_assign != _id || _drv->_out[i]->_note != 0xff) + continue; + _drv->_out[i]->_assign = 0xff; + if (!--num) + return; + } + + for (int i = 0; i < 6; i++) { + if (_drv->_out[i]->_assign != _id) + continue; + _drv->_out[i]->_sustain = 0; + _drv->_out[i]->noteOff(); + _drv->_out[i]->_assign = 0xff; + if (!--num) + return; + } +} + +uint8 TownsMidiPart::currentProgram() const { + return _program; +} + +int TownsMidiPart::allocateChannel() { + int chan = _outChan; + int ovrChan = 0; + int ld = 0; + bool found = false; + + for (bool loop = true; loop; ) { + if (++chan == 6) + chan = 0; + + if (chan == _outChan) + loop = false; + + if (_id == _drv->_out[chan]->_assign || _drv->_version == SCI_VERSION_1_EARLY) { + if (_drv->_out[chan]->_note == 0xff) { + found = true; + break; + } + + if (_drv->_out[chan]->_duration >= ld) { + ld = _drv->_out[chan]->_duration; + ovrChan = chan; + } + } + } + + if (!found) { + if (!ld) + return -1; + chan = ovrChan; + _drv->_out[chan]->_sustain = 0; + _drv->_out[chan]->noteOff(); + } + + _outChan = chan; + return chan; +} + +MidiDriver_FMTowns::MidiDriver_FMTowns(Audio::Mixer *mixer, SciVersion version) : _version(version), _timerProc(0), _timerProcPara(0), _baseTempo(10080), _ready(false), _isOpen(false), _masterVolume(0x0f), _soundOn(true) { + _intf = new TownsAudioInterface(mixer, this, true); + _out = new TownsChannel*[6]; + for (int i = 0; i < 6; i++) + _out[i] = new TownsChannel(this, i); + _parts = new TownsMidiPart*[16]; + for (int i = 0; i < 16; i++) + _parts[i] = new TownsMidiPart(this, i); +} + +MidiDriver_FMTowns::~MidiDriver_FMTowns() { + delete _intf; + + if (_parts) { + for (int i = 0; i < 16; i++) { + delete _parts[i]; + _parts[i] = 0; + } + delete[] _parts; + _parts = 0; + } + + if (_out) { + for (int i = 0; i < 6; i++) { + delete _out[i]; + _out[i] = 0; + } + delete[] _out; + _out = 0; + } +} + +int MidiDriver_FMTowns::open() { + if (_isOpen) + return MERR_ALREADY_OPEN; + + if (!_ready) { + if (!_intf->init()) + return MERR_CANNOT_CONNECT; + + _intf->callback(0); + + _intf->callback(21, 255, 1); + _intf->callback(21, 0, 1); + _intf->callback(22, 255, 221); + + _intf->callback(33, 8); + _intf->setSoundEffectChanMask(~0x3f); + + _ready = true; + } + + _isOpen = true; + + return 0; +} + +void MidiDriver_FMTowns::loadInstruments(const uint8 *data) { + if (data) { + data += 6; + for (int i = 0; i < 128; i++) { + _intf->callback(5, 0, i, data); + data += 48; + } + } + _intf->callback(70, 3); + property(MIDI_PROP_MASTER_VOLUME, _masterVolume); +} + +void MidiDriver_FMTowns::close() { + _isOpen = false; +} + +void MidiDriver_FMTowns::send(uint32 b) { + if (!_isOpen) + return; + + byte para2 = (b >> 16) & 0xFF; + byte para1 = (b >> 8) & 0xFF; + byte cmd = b & 0xF0; + + TownsMidiPart *chan = _parts[b & 0x0F]; + + switch (cmd) { + case 0x80: + chan->noteOff(para1); + break; + case 0x90: + chan->noteOn(para1, para2); + break; + case 0xb0: + switch (para1) { + case 7: + chan->controlChangeVolume(para2); + break; + case 64: + chan->controlChangeSustain(para2); + break; + case SCI_MIDI_SET_POLYPHONY: + chan->controlChangePolyphony(para2); + break; + case SCI_MIDI_CHANNEL_NOTES_OFF: + chan->controlChangeAllNotesOff(); + break; + default: + break; + } + break; + case 0xc0: + chan->programChange(para1); + break; + case 0xe0: + chan->pitchBend(para1 | (para2 << 7)); + break; + default: + break; + } +} + +uint32 MidiDriver_FMTowns::property(int prop, uint32 param) { + switch(prop) { + case MIDI_PROP_MASTER_VOLUME: + if (param != 0xffff) { + _masterVolume = param; + for (int i = 0; i < 6; i++) + _out[i]->updateVolume(); + } + return _masterVolume; + default: + break; + } + return 0; +} + +void MidiDriver_FMTowns::setTimerCallback(void *timer_param, Common::TimerManager::TimerProc timer_proc) { + _timerProc = timer_proc; + _timerProcPara = timer_param; +} + +void MidiDriver_FMTowns::setSoundOn(bool toggle) { + _soundOn = toggle; +} + +uint32 MidiDriver_FMTowns::getBaseTempo() { + return _baseTempo; +} + +void MidiDriver_FMTowns::timerCallback(int timerId) { + if (!_isOpen) + return; + + switch (timerId) { + case 1: + updateParser(); + updateChannels(); + break; + default: + break; + } +} + +int MidiDriver_FMTowns::getChannelVolume(uint8 midiPart) { + static const uint8 volumeTable[] = { 0x00, 0x0D, 0x1B, 0x28, 0x36, 0x43, 0x51, 0x5F, 0x63, 0x67, 0x6B, 0x6F, 0x73, 0x77, 0x7B, 0x7F }; + int tableIndex = (_version == SCI_VERSION_1_EARLY) ? _masterVolume : (_parts[midiPart]->_volume * (_masterVolume + 1)) >> 6; + assert(tableIndex < 16); + return volumeTable[tableIndex]; +} + +void MidiDriver_FMTowns::addMissingChannels() { + uint8 avlChan = 0; + for (int i = 0; i < 6; i++) { + if (_out[i]->_assign == 0xff) + avlChan++; + } + + if (!avlChan) + return; + + for (int i = 0; i < 16; i++) { + if (!_parts[i]->_chanMissing) + continue; + + if (_parts[i]->_chanMissing < avlChan) { + avlChan -= _parts[i]->_chanMissing; + uint8 m = _parts[i]->_chanMissing; + _parts[i]->_chanMissing = 0; + _parts[i]->addChannels(m); + } else { + _parts[i]->_chanMissing -= avlChan; + _parts[i]->addChannels(avlChan); + return; + } + } +} + +void MidiDriver_FMTowns::updateParser() { + if (_timerProc) + _timerProc(_timerProcPara); +} + +void MidiDriver_FMTowns::updateChannels() { + for (int i = 0; i < 6; i++) + _out[i]->updateDuration(); +} + +MidiPlayer_FMTowns::MidiPlayer_FMTowns(SciVersion version) : MidiPlayer(version) { + _driver = _townsDriver = new MidiDriver_FMTowns(g_system->getMixer(), version); +} + +MidiPlayer_FMTowns::~MidiPlayer_FMTowns() { + delete _driver; +} + +int MidiPlayer_FMTowns::open(ResourceManager *resMan) { + int result = MidiDriver::MERR_DEVICE_NOT_AVAILABLE; + if (_townsDriver) { + result = _townsDriver->open(); + if (!result && _version == SCI_VERSION_1_LATE) + _townsDriver->loadInstruments((resMan->findResource(ResourceId(kResourceTypePatch, 8), true))->data); + } + return result; +} + +bool MidiPlayer_FMTowns::hasRhythmChannel() const { + return false; +} + +byte MidiPlayer_FMTowns::getPlayId() const { + return (_version == SCI_VERSION_1_EARLY) ? 0x00 : 0x16; +} + +int MidiPlayer_FMTowns::getPolyphony() const { + return (_version == SCI_VERSION_1_EARLY) ? 1 : 6; +} + +void MidiPlayer_FMTowns::playSwitch(bool play) { + if (_townsDriver) + _townsDriver->setSoundOn(play); +} + +MidiPlayer *MidiPlayer_FMTowns_create(SciVersion _soundVersion) { + return new MidiPlayer_FMTowns(_soundVersion); +} + +} // End of namespace Sci + diff --git a/engines/sci/sound/drivers/mididriver.h b/engines/sci/sound/drivers/mididriver.h index ec66984bd4..8938eef62f 100644 --- a/engines/sci/sound/drivers/mididriver.h +++ b/engines/sci/sound/drivers/mididriver.h @@ -130,6 +130,7 @@ extern MidiPlayer *MidiPlayer_PCSpeaker_create(SciVersion version); extern MidiPlayer *MidiPlayer_CMS_create(SciVersion version); extern MidiPlayer *MidiPlayer_Midi_create(SciVersion version); extern MidiPlayer *MidiPlayer_Fb01_create(SciVersion version); +extern MidiPlayer *MidiPlayer_FMTowns_create(SciVersion version); } // End of namespace Sci diff --git a/engines/sci/sound/midiparser_sci.cpp b/engines/sci/sound/midiparser_sci.cpp index ad7ba7ca36..422948f975 100644 --- a/engines/sci/sound/midiparser_sci.cpp +++ b/engines/sci/sound/midiparser_sci.cpp @@ -355,17 +355,14 @@ void MidiParser_SCI::sendInitCommands() { } } - // Send a velocity off signal to all channels - for (int i = 0; i < 15; ++i) { - if (_channelUsed[i]) - sendToDriver(0xB0 | i, 0x4E, 0); // Reset velocity - } - - // Center the pitch wheels and hold pedal in preparation for the next piece of music + // Reset all the parameters of the channels used by this song for (int i = 0; i < 16; ++i) { if (_channelUsed[i]) { - sendToDriver(0xE0 | i, 0, 0x40); // Reset pitch wheel - sendToDriver(0xB0 | i, 0x40, 0); // Reset hold pedal + sendToDriver(0xB0 | i, 0x07, 127); // Reset volume to maximum + sendToDriver(0xB0 | i, 0x0A, 64); // Reset panning to center + sendToDriver(0xB0 | i, 0x40, 0); // Reset hold pedal to none + sendToDriver(0xB0 | i, 0x4E, 0); // Reset velocity to none + sendToDriver(0xE0 | i, 0, 64); // Reset pitch wheel to center } } } diff --git a/engines/sci/sound/music.cpp b/engines/sci/sound/music.cpp index 9610b6f847..4ffa8d7590 100644 --- a/engines/sci/sound/music.cpp +++ b/engines/sci/sound/music.cpp @@ -44,8 +44,10 @@ SciMusic::SciMusic(SciVersion soundVersion) // operations _playList.reserve(10); - for (int i = 0; i < 16; i++) + for (int i = 0; i < 16; i++) { _usedChannel[i] = 0; + _channelRemap[i] = -1; + } _queuedCommands.reserve(1000); } @@ -76,6 +78,13 @@ void SciMusic::init() { if (getSciVersion() >= SCI_VERSION_1_EGA_ONLY && getSciVersion() <= SCI_VERSION_1_1) deviceFlags |= MDT_CMS; + if (g_sci->getPlatform() == Common::kPlatformFMTowns) { + if (getSciVersion() > SCI_VERSION_1_EARLY) + deviceFlags = MDT_TOWNS; + else + deviceFlags |= MDT_TOWNS; + } + uint32 dev = MidiDriver::detectDevice(deviceFlags); _musicType = MidiDriver::getMusicType(dev); @@ -96,6 +105,9 @@ void SciMusic::init() { case MT_CMS: _pMidiDrv = MidiPlayer_CMS_create(_soundVersion); break; + case MT_TOWNS: + _pMidiDrv = MidiPlayer_FMTowns_create(_soundVersion); + break; default: if (ConfMan.getBool("native_fb01")) _pMidiDrv = MidiPlayer_Fb01_create(_soundVersion); @@ -349,6 +361,7 @@ int16 SciMusic::tryToOwnChannel(MusicEntry *caller, int16 bestChannel) { if (!_usedChannel[bestChannel]) { // currently unused, so give it to caller directly _usedChannel[bestChannel] = caller; + _channelRemap[bestChannel] = bestChannel; return bestChannel; } // otherwise look for unused channel @@ -357,6 +370,7 @@ int16 SciMusic::tryToOwnChannel(MusicEntry *caller, int16 bestChannel) { continue; if (!_usedChannel[channelNr]) { _usedChannel[channelNr] = caller; + _channelRemap[bestChannel] = channelNr; return channelNr; } } @@ -369,8 +383,24 @@ int16 SciMusic::tryToOwnChannel(MusicEntry *caller, int16 bestChannel) { void SciMusic::freeChannels(MusicEntry *caller) { // Remove used channels for (int i = 0; i < 15; i++) { - if (_usedChannel[i] == caller) + if (_usedChannel[i] == caller) { + if (_channelRemap[i] != -1) { + // athrxx: The original handles this differently. It seems to be checking for (and effecting) necessary + // remaps / resets etc. more or less all the time. There are several more tables to keep track of everything. + // I don't know whether all of that is needed and to which SCI versions it applies, though. + // At least it is necessary to release the allocated channels inside the driver. Otherwise these channels + // won't be available any more (e.g. after half of the KQ5 FM-Towns intro there will be no more music + // since the driver can't pick up any more channels). The channels also have to be reset to + // default values, since the original does the same (although in a different manny) and the music will be wrong + // otherwise (at least KQ5 FM-Towns). + + sendMidiCommand(0x4000e0 | _channelRemap[i]); // Reset pitch wheel + sendMidiCommand(0x0040b0 | _channelRemap[i]); // Release pedal + sendMidiCommand(0x004bb0 | _channelRemap[i]); // Release assigned driver channels + } _usedChannel[i] = 0; + _channelRemap[i] = -1; + } } // Also tell midiparser, that he lost ownership caller->pMidiParser->lostChannels(); @@ -446,9 +476,9 @@ void SciMusic::soundPlay(MusicEntry *pSnd) { // volume of the sound channels that the faded song occupies.. // Fixes bug #3266480 and partially fixes bug #3041738. for (uint i = 0; i < playListCount; i++) { - // Is another MIDI song being faded? If yes, stop it + // Is another MIDI song being faded down? If yes, stop it // immediately instead - if (_playList[i]->fadeStep && _playList[i]->pMidiParser) { + if (_playList[i]->fadeStep < 0 && _playList[i]->pMidiParser) { _playList[i]->status = kSoundStopped; if (_soundVersion <= SCI_VERSION_0_LATE) _playList[i]->isQueued = false; diff --git a/engines/sci/sound/music.h b/engines/sci/sound/music.h index 8577ed7313..fa6f538a7e 100644 --- a/engines/sci/sound/music.h +++ b/engines/sci/sound/music.h @@ -219,6 +219,7 @@ private: bool _soundOn; byte _masterVolume; MusicEntry *_usedChannel[16]; + int8 _channelRemap[16]; int8 _globalReverb; MidiCommandQueue _queuedCommands; diff --git a/engines/sci/sound/soundcmd.cpp b/engines/sci/sound/soundcmd.cpp index a91b103214..274c532779 100644 --- a/engines/sci/sound/soundcmd.cpp +++ b/engines/sci/sound/soundcmd.cpp @@ -37,7 +37,15 @@ SoundCommandParser::SoundCommandParser(ResourceManager *resMan, SegManager *segM _music = new SciMusic(_soundVersion); _music->init(); + // Check if the user wants synthesized or digital sound effects in SCI1.1 + // or later games _bMultiMidi = ConfMan.getBool("multi_midi"); + // In SCI2 and later games, this check should always be true - there was + // always only one version of each sound effect or digital music track + // (e.g. the menu music in GK1 - there is a sound effect with the same + // resource number, but it's totally unrelated to the menu music). + if (getSciVersion() >= SCI_VERSION_2) + _bMultiMidi = true; } SoundCommandParser::~SoundCommandParser() { @@ -75,13 +83,16 @@ void SoundCommandParser::initSoundResource(MusicEntry *newSound) { // effects. If the resource exists, play it using map 65535 (sound // effects map) bool checkAudioResource = getSciVersion() >= SCI_VERSION_1_1; - if (g_sci->getGameId() == GID_HOYLE4) - checkAudioResource = false; // hoyle 4 has garbled audio resources in place of the sound resources - // if we play those, we will only make the user deaf and break speakers. Sierra SCI doesn't play anything - // on soundblaster. FIXME: check, why this is + // Hoyle 4 has garbled audio resources in place of the sound resources. + // The demo of GK1 has no alternate sound effects. + if ((g_sci->getGameId() == GID_HOYLE4) || + (g_sci->getGameId() == GID_GK1 && g_sci->isDemo())) + checkAudioResource = false; if (checkAudioResource && _resMan->testResource(ResourceId(kResourceTypeAudio, newSound->resourceId))) { - // Found a relevant audio resource, create an audio stream + // Found a relevant audio resource, create an audio stream if there is + // no associated sound resource, or if both resources exist and the + // user wants the digital version. if (_bMultiMidi || !newSound->soundRes) { int sampleLen; newSound->pStreamAud = _audio->getAudioStream(newSound->resourceId, 65535, &sampleLen); @@ -123,8 +134,6 @@ void SoundCommandParser::processInitSound(reg_t obj) { writeSelectorValue(_segMan, obj, SELECTOR(state), kSoundInitialized); else writeSelector(_segMan, obj, SELECTOR(nodePtr), obj); - - writeSelector(_segMan, obj, SELECTOR(handle), obj); } } @@ -138,9 +147,9 @@ void SoundCommandParser::processPlaySound(reg_t obj) { MusicEntry *musicSlot = _music->getSlot(obj); if (!musicSlot) { warning("kDoSound(play): Slot not found (%04x:%04x), initializing it manually", PRINT_REG(obj)); - // The sound hasn't been initialized for some reason, so initialize it here. - // Happens in KQ6, room 460, when giving the creature to the bookwork (the - // bookworm's child). Fixes bug #3413301. + // The sound hasn't been initialized for some reason, so initialize it + // here. Happens in KQ6, room 460, when giving the creature (child) to + // the bookworm. Fixes bugs #3413301 and #3421098. processInitSound(obj); musicSlot = _music->getSlot(obj); if (!musicSlot) |