diff options
Diffstat (limited to 'engines/sci/sci.cpp')
-rw-r--r-- | engines/sci/sci.cpp | 136 |
1 files changed, 112 insertions, 24 deletions
diff --git a/engines/sci/sci.cpp b/engines/sci/sci.cpp index 3fe398f426..43422b4ede 100644 --- a/engines/sci/sci.cpp +++ b/engines/sci/sci.cpp @@ -39,6 +39,7 @@ #include "sci/engine/features.h" #include "sci/engine/message.h" +#include "sci/engine/object.h" #include "sci/engine/state.h" #include "sci/engine/kernel.h" #include "sci/engine/script.h" // for script_adjust_opcode_formats @@ -128,9 +129,10 @@ SciEngine::SciEngine(OSystem *syst, const ADGameDescription *desc, SciGameId gam SearchMan.addSubDirectoryMatching(gameDataDir, "seq"); // SEQ movie files for DOS versions SearchMan.addSubDirectoryMatching(gameDataDir, "robot"); // robot movie files SearchMan.addSubDirectoryMatching(gameDataDir, "robots"); // robot movie files - SearchMan.addSubDirectoryMatching(gameDataDir, "movie"); // vmd movie files - SearchMan.addSubDirectoryMatching(gameDataDir, "movies"); // vmd movie files - SearchMan.addSubDirectoryMatching(gameDataDir, "vmd"); // vmd movie files + SearchMan.addSubDirectoryMatching(gameDataDir, "movie"); // VMD movie files + SearchMan.addSubDirectoryMatching(gameDataDir, "movies"); // VMD movie files + SearchMan.addSubDirectoryMatching(gameDataDir, "vmd"); // VMD movie files + SearchMan.addSubDirectoryMatching(gameDataDir, "duk"); // Duck movie files in Phantasmagoria 2 // Add the patches directory, except for KQ6CD; The patches folder in some versions of KQ6CD // is for the demo of Phantasmagoria, included in the disk @@ -180,9 +182,9 @@ Common::Error SciEngine::run() { g_eventRec.registerRandomSource(_rng, "sci"); // Assign default values to the config manager, in case settings are missing - ConfMan.registerDefault("sci_undither", "true"); ConfMan.registerDefault("sci_originalsaveload", "false"); ConfMan.registerDefault("native_fb01", "false"); + ConfMan.registerDefault("windows_cursors", "false"); // Windows cursors for KQ6 Windows _resMan = new ResourceManager(); assert(_resMan); @@ -210,7 +212,7 @@ Common::Error SciEngine::run() { // Initialize the game screen _gfxScreen = new GfxScreen(_resMan); - _gfxScreen->debugUnditherSetState(ConfMan.getBool("sci_undither")); + _gfxScreen->debugUnditherSetState(ConfMan.getBool("disable_dithering")); // Create debugger console. It requires GFX to be initialized _console = new Console(this); @@ -303,10 +305,10 @@ Common::Error SciEngine::run() { if (buggyScript && (buggyScript->size == 12354 || buggyScript->size == 12362)) { showScummVMDialog("A known buggy game script has been detected, which could " - "prevent you from progressing later on in the game, during " - "the sequence with the Green Man's riddles. Please, apply " - "the latest patch for this game by Sierra to avoid possible " - "problems"); + "prevent you from progressing later on in the game, during " + "the sequence with the Green Man's riddles. Please, apply " + "the latest patch for this game by Sierra to avoid possible " + "problems"); } } @@ -325,16 +327,16 @@ Common::Error SciEngine::run() { case GID_SQ4: case GID_FAIRYTALES: showScummVMDialog("You have selected General MIDI as a sound device. Sierra " - "has provided after-market support for General MIDI for this " - "game in their \"General MIDI Utility\". Please, apply this " - "patch in order to enjoy MIDI music with this game. Once you " - "have obtained it, you can unpack all of the included *.PAT " - "files in your ScummVM extras folder and ScummVM will add the " - "appropriate patch automatically. Alternatively, you can follow " - "the instructions in the READ.ME file included in the patch and " - "rename the associated *.PAT file to 4.PAT and place it in the " - "game folder. Without this patch, General MIDI music for this " - "game will sound badly distorted."); + "has provided after-market support for General MIDI for this " + "game in their \"General MIDI Utility\". Please, apply this " + "patch in order to enjoy MIDI music with this game. Once you " + "have obtained it, you can unpack all of the included *.PAT " + "files in your ScummVM extras folder and ScummVM will add the " + "appropriate patch automatically. Alternatively, you can follow " + "the instructions in the READ.ME file included in the patch and " + "rename the associated *.PAT file to 4.PAT and place it in the " + "game folder. Without this patch, General MIDI music for this " + "game will sound badly distorted."); break; default: break; @@ -342,6 +344,13 @@ Common::Error SciEngine::run() { } } + if (gameHasFanMadePatch()) { + showScummVMDialog("Your game is patched with a fan made script patch. Such patches have " + "been reported to cause issues, as they modify game scripts extensively. " + "The issues that these patches fix do not occur in ScummVM, so you are " + "advised to remove this patch from your game folder in order to avoid " + "having unexpected errors and/or issues later on."); + } runGame(); @@ -350,6 +359,69 @@ Common::Error SciEngine::run() { return Common::kNoError; } +bool SciEngine::gameHasFanMadePatch() { + struct FanMadePatchInfo { + SciGameId gameID; + uint16 targetScript; + uint16 targetSize; + uint16 patchedByteOffset; + byte patchedByte; + }; + + const FanMadePatchInfo patchInfo[] = { + // game script size offset byte + // ** NRS Patches ************************** + { GID_HOYLE3, 994, 2580, 656, 0x78 }, + { GID_KQ1, 85, 5156, 631, 0x02 }, + { GID_LAURABOW2, 994, 4382, 0, 0x00 }, + { GID_LONGBOW, 994, 4950, 1455, 0x78 }, // English + { GID_LONGBOW, 994, 5020, 1469, 0x78 }, // German + { GID_LSL1, 803, 592, 342, 0x01 }, + { GID_LSL3, 380, 6148, 195, 0x35 }, + { GID_LSL5, 994, 4810, 1342, 0x78 }, // English + { GID_LSL5, 994, 4942, 1392, 0x76 }, // German + { GID_PQ1, 994, 4332, 1473, 0x78 }, + { GID_PQ2, 200, 10614, 0, 0x00 }, + { GID_PQ3, 994, 4686, 1291, 0x78 }, // English + { GID_PQ3, 994, 4734, 1283, 0x78 }, // German + { GID_QFG1VGA, 994, 4388, 0, 0x00 }, + { GID_QFG3, 994, 4714, 0, 0x00 }, + // TODO: Disabled, as it fixes a whole lot of bugs which can't be tested till SCI2.1 support is finished + //{ GID_QFG4, 710, 11477, 0, 0x00 }, + { GID_SQ1, 994, 4740, 0, 0x00 }, + { GID_SQ5, 994, 4142, 1496, 0x78 }, // English/German/French + // TODO: Disabled, till we can test the Italian version + //{ GID_SQ5, 994, 4148, 0, 0x00 }, // Italian - patched file is the same size as the original + // TODO: The bugs in SQ6 can't be tested till SCI2.1 support is finished + //{ GID_SQ6, 380, 16308, 15042, 0x0C }, // English + //{ GID_SQ6, 380, 11652, 0, 0x00 }, // German - patched file is the same size as the original + // ** End marker *************************** + { GID_FANMADE, 0, 0, 0, 0x00 } + }; + + int curEntry = 0; + + while (true) { + if (patchInfo[curEntry].targetSize == 0) + break; + + if (patchInfo[curEntry].gameID == getGameId()) { + Resource *targetScript = _resMan->findResource(ResourceId(kResourceTypeScript, patchInfo[curEntry].targetScript), 0); + + if (targetScript && targetScript->size + 2 == patchInfo[curEntry].targetSize) { + if (patchInfo[curEntry].patchedByteOffset == 0) + return true; + else if (targetScript->data[patchInfo[curEntry].patchedByteOffset - 2] == patchInfo[curEntry].patchedByte) + return true; + } + } + + curEntry++; + } + + return false; +} + static byte patchGameRestoreSave[] = { 0x39, 0x03, // pushi 03 0x76, // push0 @@ -363,6 +435,8 @@ void SciEngine::patchGameSaveRestore(SegManager *segMan) { const Object *gameObject = segMan->getObject(_gameObjectAddress); const uint16 gameMethodCount = gameObject->getMethodCount(); const Object *gameSuperObject = segMan->getObject(_gameSuperClassAddress); + if (!gameSuperObject) + gameSuperObject = gameObject; // happens in KQ5CD, when loading saved games before r54510 const uint16 gameSuperMethodCount = gameSuperObject->getMethodCount(); reg_t methodAddress; const uint16 kernelCount = _kernel->getKernelNamesSize(); @@ -484,7 +558,7 @@ bool SciEngine::initGame() { _vocabulary->reset(); } - _gamestate->gameStartTime = _gamestate->lastWaitTime = _gamestate->_screenUpdateTime = g_system->getMillis(); + _gamestate->lastWaitTime = _gamestate->_screenUpdateTime = g_system->getMillis(); // Load game language into printLang property of game object setSciLanguage(); @@ -514,7 +588,7 @@ void SciEngine::initGraphics() { _gfxPaint32 = 0; #endif - if (_resMan->isSci11Mac() && getSciVersion() == SCI_VERSION_1_1) + if (hasMacIconBar()) _gfxMacIconBar = new GfxMacIconBar(); bool paletteMerging = true; @@ -580,6 +654,8 @@ void SciEngine::initStackBaseWithSelector(Selector selector) { } void SciEngine::runGame() { + setTotalPlayTime(0); + initStackBaseWithSelector(SELECTOR(play)); // Call the play selector // Attach the debug console on game startup, if requested @@ -633,8 +709,10 @@ void SciEngine::exitGame() { GUI::Debugger *SciEngine::getDebugger() { if (_gamestate) { ExecStack *xs = &(_gamestate->_executionStack.back()); - xs->addr.pc.offset = _debugState.old_pc_offset; - xs->sp = _debugState.old_sp; + if (xs) { + xs->addr.pc.offset = _debugState.old_pc_offset; + xs->sp = _debugState.old_sp; + } } _debugState.runningStep = 0; // Stop multiple execution @@ -664,8 +742,16 @@ bool SciEngine::isDemo() const { return _gameDescription->flags & ADGF_DEMO; } +bool SciEngine::isCD() const { + return _gameDescription->flags & ADGF_CD; +} + +bool SciEngine::hasMacIconBar() const { + return _resMan->isSci11Mac() && getSciVersion() == SCI_VERSION_1_1 && getGameId() != GID_HOYLE4; +} + Common::String SciEngine::getSavegameName(int nr) const { - return _targetName + Common::String::printf(".%03d", nr); + return _targetName + Common::String::format(".%03d", nr); } Common::String SciEngine::getSavegamePattern() const { @@ -702,6 +788,8 @@ int SciEngine::inQfGImportRoom() const { void SciEngine::pauseEngineIntern(bool pause) { _mixer->pauseAll(pause); + if (_soundCmd) + _soundCmd->pauseAll(pause); } void SciEngine::syncSoundSettings() { |