aboutsummaryrefslogtreecommitdiff
path: root/engines/sci/sci.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/sci/sci.cpp')
-rw-r--r--engines/sci/sci.cpp94
1 files changed, 66 insertions, 28 deletions
diff --git a/engines/sci/sci.cpp b/engines/sci/sci.cpp
index c1aadc3622..668ad053cc 100644
--- a/engines/sci/sci.cpp
+++ b/engines/sci/sci.cpp
@@ -8,12 +8,12 @@
* 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.
@@ -38,6 +38,7 @@
#include "sci/engine/state.h"
#include "sci/engine/kernel.h"
#include "sci/engine/script.h" // for script_adjust_opcode_formats
+#include "sci/engine/script_patches.h"
#include "sci/engine/selector.h" // for SELECTOR
#include "sci/sound/audio.h"
@@ -112,6 +113,8 @@ SciEngine::SciEngine(OSystem *syst, const ADGameDescription *desc, SciGameId gam
DebugMan.addDebugChannel(kDebugLevelDclInflate, "DCL", "DCL inflate debugging");
DebugMan.addDebugChannel(kDebugLevelVM, "VM", "VM debugging");
DebugMan.addDebugChannel(kDebugLevelScripts, "Scripts", "Notifies when scripts are unloaded");
+ DebugMan.addDebugChannel(kDebugLevelScriptPatcher, "ScriptPatcher", "Notifies when scripts are patched");
+ DebugMan.addDebugChannel(kDebugLevelWorkarounds, "Workarounds", "Notifies when workarounds are triggered");
DebugMan.addDebugChannel(kDebugLevelGC, "GC", "Garbage Collector debugging");
DebugMan.addDebugChannel(kDebugLevelResMan, "ResMan", "Resource manager debugging");
DebugMan.addDebugChannel(kDebugLevelOnStartup, "OnStartup", "Enter debugger at start of game");
@@ -135,7 +138,7 @@ SciEngine::SciEngine(OSystem *syst, const ADGameDescription *desc, SciGameId gam
SearchMan.addSubDirectoryMatching(gameDataDir, "duk"); // Duck movie files in Phantasmagoria 2
SearchMan.addSubDirectoryMatching(gameDataDir, "Robot Folder"); // Mac robot files
SearchMan.addSubDirectoryMatching(gameDataDir, "Sound Folder"); // Mac audio files
- SearchMan.addSubDirectoryMatching(gameDataDir, "Voices Folder"); // Mac audio36 files
+ SearchMan.addSubDirectoryMatching(gameDataDir, "Voices Folder", 0, 2, true); // Mac audio36 files (recursive for Torin)
SearchMan.addSubDirectoryMatching(gameDataDir, "Voices"); // Mac audio36 files
SearchMan.addSubDirectoryMatching(gameDataDir, "VMD Folder"); // Mac VMD files
@@ -183,6 +186,7 @@ SciEngine::~SciEngine() {
delete[] _opcode_formats;
+ delete _scriptPatcher;
delete _resMan; // should be deleted last
g_sci = 0;
}
@@ -217,13 +221,15 @@ Common::Error SciEngine::run() {
_resMan->addNewGMPatch(_gameId);
_gameObjectAddress = _resMan->findGameObject();
- SegManager *segMan = new SegManager(_resMan);
+ _scriptPatcher = new ScriptPatcher();
+ SegManager *segMan = new SegManager(_resMan, _scriptPatcher);
// Initialize the game screen
_gfxScreen = new GfxScreen(_resMan);
_gfxScreen->enableUndithering(ConfMan.getBool("disable_dithering"));
_kernel = new Kernel(_resMan, segMan);
+ _kernel->init();
_features = new GameFeatures(segMan, _kernel);
// Only SCI0, SCI01 and SCI1 EGA games used a parser
@@ -276,20 +282,13 @@ Common::Error SciEngine::run() {
// Check whether loading a savestate was requested
int directSaveSlotLoading = ConfMan.getInt("save_slot");
if (directSaveSlotLoading >= 0) {
- // call GameObject::play (like normally)
- initStackBaseWithSelector(SELECTOR(play));
- // We set this, so that the game automatically quit right after init
- _gamestate->variables[VAR_GLOBAL][4] = TRUE_REG;
-
- _gamestate->_executionStackPosChanged = false;
- run_vm(_gamestate);
+ _gamestate->_delayedRestoreGame = true;
+ _gamestate->_delayedRestoreGameId = directSaveSlotLoading;
- // As soon as we get control again, actually restore the game
- reg_t restoreArgv[2] = { NULL_REG, make_reg(0, directSaveSlotLoading) }; // special call (argv[0] is NULL)
- kRestoreGame(_gamestate, 2, restoreArgv);
-
- // this indirectly calls GameObject::init, which will setup menu, text font/color codes etc.
- // without this games would be pretty badly broken
+ // Jones only initializes its menus when restarting/restoring, thus set
+ // the gameIsRestarting flag here before initializing. Fixes bug #6536.
+ if (g_sci->getGameId() == GID_JONES)
+ _gamestate->gameIsRestarting = GAMEISRESTARTING_RESTORE;
}
// Show any special warnings for buggy scripts with severe game bugs,
@@ -501,6 +500,7 @@ void SciEngine::patchGameSaveRestore() {
case GID_HOYLE1: // gets confused, although the game doesnt support saving/restoring at all
case GID_HOYLE2: // gets confused, see hoyle1
case GID_JONES: // gets confused, when we patch us in, the game is only able to save to 1 slot, so hooking is not required
+ case GID_MOTHERGOOSE: // mother goose EGA saves/restores directly and has no save/restore dialogs
case GID_MOTHERGOOSE256: // mother goose saves/restores directly and has no save/restore dialogs
case GID_PHANTASMAGORIA: // has custom save/load code
case GID_SHIVERS: // has custom save/load code
@@ -571,7 +571,7 @@ bool SciEngine::initGame() {
// Script 0 should always be at segment 1
if (script0Segment != 1) {
- debug(2, "Failed to instantiate script.000");
+ debug(2, "Failed to instantiate script 0");
return false;
}
@@ -881,8 +881,18 @@ void SciEngine::syncSoundSettings() {
}
}
+// used by Script Patcher. Used to find out, if Laura Bow 2/King's Quest 6 need patching for Speech+Subtitles - or not
+bool SciEngine::speechAndSubtitlesEnabled() {
+ bool subtitlesOn = ConfMan.getBool("subtitles");
+ bool speechOn = !ConfMan.getBool("speech_mute");
+
+ if (isCD() && subtitlesOn && speechOn)
+ return true;
+ return false;
+}
+
void SciEngine::syncIngameAudioOptions() {
- // Now, sync the in-game speech/subtitles settings for SCI1.1 CD games
+ // Sync the in-game speech/subtitles settings for SCI1.1 CD games
if (isCD() && getSciVersion() == SCI_VERSION_1_1) {
bool subtitlesOn = ConfMan.getBool("subtitles");
bool speechOn = !ConfMan.getBool("speech_mute");
@@ -893,16 +903,16 @@ void SciEngine::syncIngameAudioOptions() {
_gamestate->variables[VAR_GLOBAL][90] = make_reg(0, 2); // speech
} else if (subtitlesOn && speechOn) {
// Is it a game that supports simultaneous speech and subtitles?
- if (getGameId() == GID_SQ4
- || getGameId() == GID_FREDDYPHARKAS
- || getGameId() == GID_ECOQUEST
- || getGameId() == GID_LSL6
- // TODO: The following need script patches for simultaneous speech and subtitles
- //|| getGameId() == GID_KQ6
- //|| getGameId() == GID_LAURABOW2
- ) {
+ switch (_gameId) {
+ case GID_SQ4:
+ case GID_FREDDYPHARKAS:
+ case GID_ECOQUEST:
+ case GID_LSL6:
+ case GID_LAURABOW2:
+ case GID_KQ6:
_gamestate->variables[VAR_GLOBAL][90] = make_reg(0, 3); // speech + subtitles
- } else {
+ break;
+ default:
// Game does not support speech and subtitles, set it to speech
_gamestate->variables[VAR_GLOBAL][90] = make_reg(0, 2); // speech
}
@@ -910,6 +920,34 @@ void SciEngine::syncIngameAudioOptions() {
}
}
+void SciEngine::updateScummVMAudioOptions() {
+ // Update ScummVM's speech/subtitles settings for SCI1.1 CD games,
+ // depending on the in-game settings
+ if (isCD() && getSciVersion() == SCI_VERSION_1_1) {
+ uint16 ingameSetting = _gamestate->variables[VAR_GLOBAL][90].getOffset();
+
+ switch (ingameSetting) {
+ case 1:
+ // subtitles
+ ConfMan.setBool("subtitles", true);
+ ConfMan.setBool("speech_mute", true);
+ break;
+ case 2:
+ // speech
+ ConfMan.setBool("subtitles", false);
+ ConfMan.setBool("speech_mute", false);
+ break;
+ case 3:
+ // speech + subtitles
+ ConfMan.setBool("subtitles", true);
+ ConfMan.setBool("speech_mute", false);
+ break;
+ default:
+ break;
+ }
+ }
+}
+
void SciEngine::loadMacExecutable() {
if (getPlatform() != Common::kPlatformMacintosh || getSciVersion() < SCI_VERSION_1_EARLY || getSciVersion() > SCI_VERSION_1_1)
return;