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.cpp377
1 files changed, 256 insertions, 121 deletions
diff --git a/engines/sci/sci.cpp b/engines/sci/sci.cpp
index 6d36fabde9..d725e36a5a 100644
--- a/engines/sci/sci.cpp
+++ b/engines/sci/sci.cpp
@@ -43,12 +43,12 @@
#include "sci/sound/audio.h"
#include "sci/sound/music.h"
+#include "sci/sound/sync.h"
#include "sci/sound/soundcmd.h"
#include "sci/graphics/animate.h"
#include "sci/graphics/cache.h"
#include "sci/graphics/compare.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"
@@ -58,24 +58,27 @@
#include "sci/graphics/picture.h"
#include "sci/graphics/ports.h"
#include "sci/graphics/palette.h"
+#include "sci/graphics/remap.h"
#include "sci/graphics/screen.h"
#include "sci/graphics/text16.h"
#include "sci/graphics/transitions.h"
#ifdef ENABLE_SCI32
+#include "sci/graphics/controls32.h"
+#include "sci/graphics/cursor32.h"
+#include "sci/graphics/frameout.h"
#include "sci/graphics/palette32.h"
+#include "sci/graphics/remap32.h"
#include "sci/graphics/text32.h"
-#include "sci/graphics/frameout.h"
-#include "sci/video/robot_decoder.h"
+#include "sci/graphics/transitions32.h"
+#include "sci/graphics/video32.h"
+#include "sci/sound/audio32.h"
#endif
namespace Sci {
SciEngine *g_sci = 0;
-
-class GfxDriver;
-
SciEngine::SciEngine(OSystem *syst, const ADGameDescription *desc, SciGameId gameId)
: Engine(syst), _gameDescription(desc), _gameId(gameId), _rng("sci") {
@@ -85,6 +88,12 @@ SciEngine::SciEngine(OSystem *syst, const ADGameDescription *desc, SciGameId gam
_gfxMacIconBar = 0;
_audio = 0;
+ _sync = nullptr;
+#ifdef ENABLE_SCI32
+ _audio32 = nullptr;
+ _video32 = nullptr;
+ _gfxCursor32 = nullptr;
+#endif
_features = 0;
_resMan = 0;
_gamestate = 0;
@@ -118,6 +127,8 @@ SciEngine::SciEngine(OSystem *syst, const ADGameDescription *desc, SciGameId gam
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(kDebugLevelVideo, "Video", "Video (SEQ, VMD, RBT) debugging");
+ DebugMan.addDebugChannel(kDebugLevelGame, "Game", "Debug calls from game scripts");
DebugMan.addDebugChannel(kDebugLevelGC, "GC", "Garbage Collector debugging");
DebugMan.addDebugChannel(kDebugLevelResMan, "ResMan", "Resource manager debugging");
DebugMan.addDebugChannel(kDebugLevelOnStartup, "OnStartup", "Enter debugger at start of game");
@@ -156,29 +167,37 @@ SciEngine::~SciEngine() {
DebugMan.clearAllDebugChannels();
#ifdef ENABLE_SCI32
- // _gfxPalette32 is the same as _gfxPalette16
- // and will be destroyed when _gfxPalette16 is
- // destroyed
delete _gfxControls32;
+ delete _gfxPaint32;
delete _gfxText32;
- delete _robotDecoder;
+ // GfxFrameout and GfxPalette32 must be deleted after Video32 since
+ // destruction of screen items in the Video32 destructor relies on these
+ // components
+ delete _video32;
+ delete _gfxCursor32;
+ delete _gfxPalette32;
+ delete _gfxTransitions32;
delete _gfxFrameout;
+ delete _gfxRemap32;
+ delete _audio32;
#endif
delete _gfxMenu;
delete _gfxControls16;
delete _gfxText16;
delete _gfxAnimate;
- delete _gfxPaint;
+ delete _gfxPaint16;
delete _gfxTransitions;
delete _gfxCompare;
delete _gfxCoordAdjuster;
delete _gfxPorts;
delete _gfxCache;
delete _gfxPalette16;
+ delete _gfxRemap16;
delete _gfxCursor;
delete _gfxScreen;
delete _audio;
+ delete _sync;
delete _soundCmd;
delete _kernel;
delete _vocabulary;
@@ -224,41 +243,31 @@ Common::Error SciEngine::run() {
_scriptPatcher = new ScriptPatcher();
SegManager *segMan = new SegManager(_resMan, _scriptPatcher);
- // Read user option for hires graphics
+ // Read user option for forcing hires graphics
// Only show/selectable for:
// - King's Quest 6 CD
// - King's Quest 6 CD demo
// - Gabriel Knight 1 CD
// - Police Quest 4 CD
// TODO: Check, if Gabriel Knight 1 floppy supports high resolution
- // TODO: Check, if Gabriel Knight 1 on Mac supports high resolution
- switch (getPlatform()) {
- case Common::kPlatformDOS:
- case Common::kPlatformWindows:
- // Only DOS+Windows
- switch (_gameId) {
- case GID_KQ6:
- if (isCD())
- _forceHiresGraphics = ConfMan.getBool("enable_high_resolution_graphics");
- break;
- case GID_GK1:
- if ((isCD()) && (!isDemo()))
- _forceHiresGraphics = ConfMan.getBool("enable_high_resolution_graphics");
- break;
- case GID_PQ4:
- if (isCD())
- _forceHiresGraphics = ConfMan.getBool("enable_high_resolution_graphics");
- break;
- default:
- break;
- }
- default:
- break;
- };
+ //
+ // Gabriel Knight 1 on Mac is hi-res only, so it should NOT get this option.
+ // Confirmed by [md5] and originally by clone2727.
+ if (Common::checkGameGUIOption(GAMEOPTION_HIGH_RESOLUTION_GRAPHICS, ConfMan.get("guioptions"))) {
+ // GAMEOPTION_HIGH_RESOLUTION_GRAPHICS is available for the currently detected game,
+ // so read the user option now.
+ // We need to do this, because the option's default is "true", but we don't want "true"
+ // for any game that does not have this option.
+ _forceHiresGraphics = ConfMan.getBool("enable_high_resolution_graphics");
+ }
- // Initialize the game screen
- _gfxScreen = new GfxScreen(_resMan);
- _gfxScreen->enableUndithering(ConfMan.getBool("disable_dithering"));
+ if (getSciVersion() < SCI_VERSION_2) {
+ // Initialize the game screen
+ _gfxScreen = new GfxScreen(_resMan);
+ _gfxScreen->enableUndithering(ConfMan.getBool("disable_dithering"));
+ } else {
+ _gfxScreen = nullptr;
+ }
_kernel = new Kernel(_resMan, segMan);
_kernel->init();
@@ -269,9 +278,21 @@ Common::Error SciEngine::run() {
// Also, XMAS1990 apparently had a parser too. Refer to http://forums.scummvm.org/viewtopic.php?t=9135
if (getGameId() == GID_CHRISTMAS1990)
_vocabulary = new Vocabulary(_resMan, false);
- _audio = new AudioPlayer(_resMan);
+
_gamestate = new EngineState(segMan);
_eventMan = new EventManager(_resMan->detectFontExtended());
+#ifdef ENABLE_SCI32
+ if (getSciVersion() >= SCI_VERSION_2_1_EARLY) {
+ _audio32 = new Audio32(_resMan);
+ } else
+#endif
+ _audio = new AudioPlayer(_resMan);
+#ifdef ENABLE_SCI32
+ if (getSciVersion() >= SCI_VERSION_2) {
+ _video32 = new Video32(segMan, _eventMan);
+ }
+#endif
+ _sync = new Sync(_resMan, segMan);
// Create debugger console. It requires GFX and _gamestate to be initialized
_console = new Console(this);
@@ -296,10 +317,6 @@ Common::Error SciEngine::run() {
// Must be called after game_init(), as they use _features
_kernel->loadKernelNames(_features);
- _soundCmd = new SoundCommandParser(_resMan, segMan, _kernel, _audio, _features->detectDoSoundType());
-
- syncSoundSettings();
- syncIngameAudioOptions();
// Load our Mac executable here for icon bar palettes and high-res fonts
loadMacExecutable();
@@ -307,6 +324,15 @@ Common::Error SciEngine::run() {
// Initialize all graphics related subsystems
initGraphics();
+ // Sound must be initialized after graphics because SysEx transfers at the
+ // start of the game must pump the event loop to avoid making the OS think
+ // that ScummVM is hanged, and pumping the event loop requires GfxCursor to
+ // be initialized
+ _soundCmd = new SoundCommandParser(_resMan, segMan, _kernel, _audio, _features->detectDoSoundType());
+
+ syncSoundSettings();
+ syncIngameAudioOptions();
+
// Patch in our save/restore code, so that dialogs are replaced
patchGameSaveRestore();
setLauncherLanguage();
@@ -316,6 +342,7 @@ Common::Error SciEngine::run() {
if (directSaveSlotLoading >= 0) {
_gamestate->_delayedRestoreGame = true;
_gamestate->_delayedRestoreGameId = directSaveSlotLoading;
+ _gamestate->_delayedRestoreFromLauncher = true;
// Jones only initializes its menus when restarting/restoring, thus set
// the gameIsRestarting flag here before initializing. Fixes bug #6536.
@@ -343,6 +370,17 @@ Common::Error SciEngine::run() {
}
}
+ if (getGameId() == GID_KQ7 && ConfMan.getBool("subtitles")) {
+ showScummVMDialog("Subtitles are enabled, but subtitling in King's"
+ " Quest 7 was unfinished and disabled in the release"
+ " version of the game. ScummVM allows the subtitles"
+ " to be re-enabled, but because they were removed from"
+ " the original game, they do not always render"
+ " properly or reflect the actual game speech."
+ " This is not a ScummVM bug -- it is a problem with"
+ " the game's assets.");
+ }
+
// Show a warning if the user has selected a General MIDI device, no GM patch exists
// (i.e. patch 4) and the game is one of the known 8 SCI1 games that Sierra has provided
// after market patches for in their "General MIDI Utility".
@@ -462,62 +500,89 @@ static byte patchGameRestoreSave[] = {
0x48, // ret
};
+#ifdef ENABLE_SCI32
// SCI2 version: Same as above, but the second parameter to callk is a word
-static byte patchGameRestoreSaveSci2[] = {
- 0x39, 0x03, // pushi 03
- 0x76, // push0
- 0x38, 0xff, 0xff, // pushi -1
- 0x76, // push0
- 0x43, 0xff, 0x06, 0x00, // callk kRestoreGame/kSaveGame (will get changed afterwards)
- 0x48, // ret
+// and third parameter is a string reference
+static byte patchGameRestoreSci2[] = {
+ 0x39, 0x03, // pushi 03
+ 0x76, // push0 (game name)
+ 0x38, 0xff, 0xff, // pushi -1 (save number)
+ 0x89, 0x1b, // lsg global[27] (game version)
+ 0x43, 0xff, 0x06, 0x00, // callk kRestoreGame (0xFF will be overwritten by patcher)
+ 0x48, // ret
};
-// SCI21 version: Same as above, but the second parameter to callk is a word
-static byte patchGameRestoreSaveSci21[] = {
- 0x39, 0x04, // pushi 04
- 0x76, // push0 // 0: save, 1: restore (will get changed afterwards)
- 0x76, // push0
- 0x38, 0xff, 0xff, // pushi -1
- 0x76, // push0
- 0x43, 0xff, 0x08, 0x00, // callk kSave (will get changed afterwards)
- 0x48, // ret
+static byte patchGameSaveSci2[] = {
+ 0x39, 0x04, // pushi 04
+ 0x76, // push0 (game name)
+ 0x38, 0xff, 0xff, // pushi -1 (save number)
+ 0x76, // push0 (save description)
+ 0x89, 0x1b, // lsg global[27] (game version)
+ 0x43, 0xff, 0x08, 0x00, // callk kSaveGame (0xFF will be overwritten by patcher)
+ 0x48, // ret
};
+// SCI2.1mid version: Same as above, but with an extra subop parameter
+static byte patchGameRestoreSci21[] = {
+ 0x39, 0x04, // pushi 04
+ 0x78, // push1 (subop)
+ 0x76, // push0 (game name)
+ 0x38, 0xff, 0xff, // pushi -1 (save number)
+ 0x89, 0x1b, // lsg global[27] (game version)
+ 0x43, 0xff, 0x08, 0x00, // callk kSave (0xFF will be overwritten by patcher)
+ 0x48, // ret
+};
+
+static byte patchGameSaveSci21[] = {
+ 0x39, 0x05, // pushi 05
+ 0x76, // push0 (subop)
+ 0x76, // push0 (game name)
+ 0x38, 0xff, 0xff, // pushi -1 (save number)
+ 0x76, // push0 (save description)
+ 0x89, 0x1b, // lsg global[27] (game version)
+ 0x43, 0xff, 0x0a, 0x00, // callk kSave (0xFF will be overwritten by patcher)
+ 0x48, // ret
+};
+#endif
+
static void patchGameSaveRestoreCode(SegManager *segMan, reg_t methodAddress, byte id) {
Script *script = segMan->getScript(methodAddress.getSegment());
byte *patchPtr = const_cast<byte *>(script->getBuf(methodAddress.getOffset()));
- if (getSciVersion() <= SCI_VERSION_1_1) {
- memcpy(patchPtr, patchGameRestoreSave, sizeof(patchGameRestoreSave));
- } else { // SCI2+
- memcpy(patchPtr, patchGameRestoreSaveSci2, sizeof(patchGameRestoreSaveSci2));
-
- if (g_sci->isBE()) {
- // LE -> BE
- patchPtr[9] = 0x00;
- patchPtr[10] = 0x06;
- }
- }
-
+ memcpy(patchPtr, patchGameRestoreSave, sizeof(patchGameRestoreSave));
patchPtr[8] = id;
}
-static void patchGameSaveRestoreCodeSci21(SegManager *segMan, reg_t methodAddress, byte id, bool doRestore) {
+#ifdef ENABLE_SCI32
+static void patchGameSaveRestoreCodeSci2(SegManager *segMan, reg_t methodAddress, byte id, bool doRestore) {
Script *script = segMan->getScript(methodAddress.getSegment());
byte *patchPtr = const_cast<byte *>(script->getBuf(methodAddress.getOffset()));
- memcpy(patchPtr, patchGameRestoreSaveSci21, sizeof(patchGameRestoreSaveSci21));
+ int kcallOffset;
- if (doRestore)
- patchPtr[2] = 0x78; // push1
+ if (getSciVersion() < SCI_VERSION_2_1_MIDDLE) {
+ if (doRestore) {
+ memcpy(patchPtr, patchGameRestoreSci2, sizeof(patchGameRestoreSci2));
+ kcallOffset = 9;
+ } else {
+ memcpy(patchPtr, patchGameSaveSci2, sizeof(patchGameSaveSci2));
+ kcallOffset = 10;
+ }
+ } else {
+ if (doRestore) {
+ memcpy(patchPtr, patchGameRestoreSci21, sizeof(patchGameRestoreSci21));
+ kcallOffset = 10;
+ } else {
+ memcpy(patchPtr, patchGameSaveSci21, sizeof(patchGameSaveSci21));
+ kcallOffset = 11;
+ }
+ }
+ patchPtr[kcallOffset] = id;
if (g_sci->isBE()) {
- // LE -> BE
- patchPtr[10] = 0x00;
- patchPtr[11] = 0x08;
+ SWAP(patchPtr[kcallOffset + 1], patchPtr[kcallOffset + 2]);
}
-
- patchPtr[9] = id;
}
+#endif
void SciEngine::patchGameSaveRestore() {
SegManager *segMan = _gamestate->_segMan;
@@ -532,9 +597,12 @@ void SciEngine::patchGameSaveRestore() {
case GID_HOYLE1: // gets confused, although the game doesn't 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_KQ7: // has custom save/load code
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_MOTHERGOOSEHIRES: // has custom save/load code
case GID_PHANTASMAGORIA: // has custom save/load code
+ case GID_PQSWAT: // has custom save/load code
case GID_SHIVERS: // has custom save/load code
return;
default:
@@ -561,17 +629,21 @@ void SciEngine::patchGameSaveRestore() {
uint16 selectorId = gameSuperObject->getFuncSelector(methodNr);
Common::String methodName = _kernel->getSelectorName(selectorId);
if (methodName == "restore") {
- if (kernelIdSave != kernelIdRestore)
+#ifdef ENABLE_SCI32
+ if (getSciVersion() >= SCI_VERSION_2) {
+ patchGameSaveRestoreCodeSci2(segMan, gameSuperObject->getFunction(methodNr), kernelIdRestore, true);
+ } else
+#endif
patchGameSaveRestoreCode(segMan, gameSuperObject->getFunction(methodNr), kernelIdRestore);
- else
- patchGameSaveRestoreCodeSci21(segMan, gameSuperObject->getFunction(methodNr), kernelIdRestore, true);
}
else if (methodName == "save") {
if (_gameId != GID_FAIRYTALES) { // Fairy Tales saves automatically without a dialog
- if (kernelIdSave != kernelIdRestore)
+#ifdef ENABLE_SCI32
+ if (getSciVersion() >= SCI_VERSION_2) {
+ patchGameSaveRestoreCodeSci2(segMan, gameSuperObject->getFunction(methodNr), kernelIdSave, false);
+ } else
+#endif
patchGameSaveRestoreCode(segMan, gameSuperObject->getFunction(methodNr), kernelIdSave);
- else
- patchGameSaveRestoreCodeSci21(segMan, gameSuperObject->getFunction(methodNr), kernelIdSave, false);
}
}
}
@@ -595,10 +667,12 @@ void SciEngine::patchGameSaveRestore() {
Common::String methodName = _kernel->getSelectorName(selectorId);
if (methodName == "save") {
if (_gameId != GID_FAIRYTALES) { // Fairy Tales saves automatically without a dialog
- if (kernelIdSave != kernelIdRestore)
+#ifdef ENABLE_SCI32
+ if (getSciVersion() >= SCI_VERSION_2) {
+ patchGameSaveRestoreCodeSci2(segMan, gameSuperObject->getFunction(methodNr), kernelIdSave, false);
+ } else
+#endif
patchGameSaveRestoreCode(segMan, patchObjectSave->getFunction(methodNr), kernelIdSave);
- else
- patchGameSaveRestoreCodeSci21(segMan, patchObjectSave->getFunction(methodNr), kernelIdSave, false);
}
break;
}
@@ -662,19 +736,21 @@ void SciEngine::initGraphics() {
_gfxCursor = 0;
_gfxMacIconBar = 0;
_gfxMenu = 0;
- _gfxPaint = 0;
_gfxPaint16 = 0;
_gfxPalette16 = 0;
+ _gfxRemap16 = 0;
_gfxPorts = 0;
_gfxText16 = 0;
_gfxTransitions = 0;
#ifdef ENABLE_SCI32
_gfxControls32 = 0;
_gfxText32 = 0;
- _robotDecoder = 0;
_gfxFrameout = 0;
_gfxPaint32 = 0;
_gfxPalette32 = 0;
+ _gfxRemap32 = 0;
+ _gfxTransitions32 = 0;
+ _gfxCursor32 = 0;
#endif
if (hasMacIconBar())
@@ -682,41 +758,41 @@ void SciEngine::initGraphics() {
#ifdef ENABLE_SCI32
if (getSciVersion() >= SCI_VERSION_2) {
- _gfxPalette32 = new GfxPalette32(_resMan, _gfxScreen);
- _gfxPalette16 = _gfxPalette32;
+ _gfxPalette32 = new GfxPalette32(_resMan);
+ _gfxRemap32 = new GfxRemap32();
} else {
#endif
_gfxPalette16 = new GfxPalette(_resMan, _gfxScreen);
+ if (getGameId() == GID_QFG4DEMO)
+ _gfxRemap16 = new GfxRemap(_gfxPalette16);
#ifdef ENABLE_SCI32
}
#endif
_gfxCache = new GfxCache(_resMan, _gfxScreen, _gfxPalette16);
- _gfxCursor = new GfxCursor(_resMan, _gfxPalette16, _gfxScreen);
#ifdef ENABLE_SCI32
if (getSciVersion() >= SCI_VERSION_2) {
// SCI32 graphic objects creation
- _gfxCoordAdjuster = new GfxCoordAdjuster32(_gamestate->_segMan);
- _gfxCursor->init(_gfxCoordAdjuster, _eventMan);
- _gfxCompare = new GfxCompare(_gamestate->_segMan, _gfxCache, _gfxScreen, _gfxCoordAdjuster);
- _gfxPaint32 = new GfxPaint32(_resMan, _gfxCoordAdjuster, _gfxScreen, _gfxPalette32);
- _gfxPaint = _gfxPaint32;
- _robotDecoder = new RobotDecoder(getPlatform() == Common::kPlatformMacintosh);
- _gfxFrameout = new GfxFrameout(_gamestate->_segMan, _resMan, _gfxCoordAdjuster, _gfxCache, _gfxScreen, _gfxPalette32, _gfxPaint32);
- _gfxText32 = new GfxText32(_gamestate->_segMan, _gfxCache, _gfxScreen);
+ _gfxCursor32 = new GfxCursor32();
+ _gfxCompare = new GfxCompare(_gamestate->_segMan, _gfxCache, nullptr, _gfxCoordAdjuster);
+ _gfxPaint32 = new GfxPaint32(_gamestate->_segMan);
+ _gfxTransitions32 = new GfxTransitions32(_gamestate->_segMan);
+ _gfxFrameout = new GfxFrameout(_gamestate->_segMan, _gfxPalette32, _gfxTransitions32, _gfxCursor32);
+ _gfxCursor32->init(_gfxFrameout->getCurrentBuffer());
+ _gfxText32 = new GfxText32(_gamestate->_segMan, _gfxCache);
_gfxControls32 = new GfxControls32(_gamestate->_segMan, _gfxCache, _gfxText32);
_gfxFrameout->run();
} else {
#endif
// SCI0-SCI1.1 graphic objects creation
+ _gfxCursor = new GfxCursor(_resMan, _gfxPalette16, _gfxScreen);
_gfxPorts = new GfxPorts(_gamestate->_segMan, _gfxScreen);
_gfxCoordAdjuster = new GfxCoordAdjuster16(_gfxPorts);
_gfxCursor->init(_gfxCoordAdjuster, _eventMan);
_gfxCompare = new GfxCompare(_gamestate->_segMan, _gfxCache, _gfxScreen, _gfxCoordAdjuster);
_gfxTransitions = new GfxTransitions(_gfxScreen, _gfxPalette16);
_gfxPaint16 = new GfxPaint16(_resMan, _gamestate->_segMan, _gfxCache, _gfxPorts, _gfxCoordAdjuster, _gfxScreen, _gfxPalette16, _gfxTransitions, _audio);
- _gfxPaint = _gfxPaint16;
_gfxAnimate = new GfxAnimate(_gamestate, _scriptPatcher, _gfxCache, _gfxPorts, _gfxPaint16, _gfxScreen, _gfxPalette16, _gfxCursor, _gfxTransitions);
_gfxText16 = new GfxText16(_gfxCache, _gfxPorts, _gfxPaint16, _gfxScreen);
_gfxControls16 = new GfxControls16(_gamestate->_segMan, _gfxPorts, _gfxPaint16, _gfxText16, _gfxScreen);
@@ -731,8 +807,10 @@ void SciEngine::initGraphics() {
}
#endif
- // Set default (EGA, amiga or resource 999) palette
- _gfxPalette16->setDefault();
+ if (getSciVersion() < SCI_VERSION_2) {
+ // Set default (EGA, amiga or resource 999) palette
+ _gfxPalette16->setDefault();
+ }
}
void SciEngine::initStackBaseWithSelector(Selector selector) {
@@ -798,7 +876,10 @@ void SciEngine::runGame() {
void SciEngine::exitGame() {
if (_gamestate->abortScriptProcessing != kAbortLoadGame) {
_gamestate->_executionStack.clear();
- _audio->stopAllAudio();
+ if (_audio) {
+ _audio->stopAllAudio();
+ }
+ _sync->stop();
_soundCmd->clearPlayList();
}
@@ -833,7 +914,7 @@ Console *SciEngine::getSciDebugger() {
}
const char *SciEngine::getGameIdStr() const {
- return _gameDescription->gameid;
+ return _gameDescription->gameId;
}
Common::Language SciEngine::getLanguage() const {
@@ -884,14 +965,23 @@ Common::String SciEngine::getFilePrefix() const {
}
Common::String SciEngine::wrapFilename(const Common::String &name) const {
- return getFilePrefix() + "-" + name;
+ Common::String prefix = getFilePrefix() + "-";
+ if (name.hasPrefix(prefix.c_str()))
+ return name;
+ else
+ return prefix + name;
}
Common::String SciEngine::unwrapFilename(const Common::String &name) const {
Common::String prefix = getFilePrefix() + "-";
if (name.hasPrefix(prefix.c_str()))
return Common::String(name.c_str() + prefix.size());
- return name;
+ else
+ return name;
+}
+
+const char *SciEngine::getGameObjectName() {
+ return _gamestate->_segMan->getObjectName(_gameObjectAddress);
}
int SciEngine::inQfGImportRoom() const {
@@ -907,6 +997,25 @@ int SciEngine::inQfGImportRoom() const {
return 0;
}
+void SciEngine::sleep(uint32 msecs) {
+ uint32 time;
+ const uint32 wakeUpTime = g_system->getMillis() + msecs;
+
+ for (;;) {
+ // let backend process events and update the screen
+ _eventMan->getSciEvent(SCI_EVENT_PEEK);
+ time = g_system->getMillis();
+ if (time + 10 < wakeUpTime) {
+ g_system->delayMillis(10);
+ } else {
+ if (time < wakeUpTime)
+ g_system->delayMillis(wakeUpTime - time);
+ break;
+ }
+
+ }
+}
+
void SciEngine::setLauncherLanguage() {
if (_gameDescription->flags & ADGF_ADDENGLISH) {
// If game is multilingual
@@ -992,17 +1101,19 @@ void SciEngine::syncIngameAudioOptions() {
case GID_SQ6: // SCI2.1
case GID_TORIN: // SCI2.1
case GID_QFG4: // SCI2.1
+ case GID_PQ4: // SCI2
+ case GID_PHANTASMAGORIA: // SCI2.1
+ case GID_MOTHERGOOSEHIRES: // SCI2.1
useGlobal90 = true;
break;
case GID_LSL6: // SCI2.1
// TODO: Uses gameFlags array
break;
+ // Shivers does not use global 90
+ // Police Quest: SWAT does not use global 90
+ //
// TODO: Unknown at the moment:
- // Shivers - seems not to use global 90
- // Police Quest: SWAT - unable to check
- // Police Quest 4 - unable to check
- // Mixed Up Mother Goose - unable to check
- // Phantasmagoria - seems to use global 90, unable to check for subtitles atm
+ // LSL7, Lighthouse, RAMA, Phantasmagoria 2
default:
return;
}
@@ -1015,11 +1126,30 @@ void SciEngine::syncIngameAudioOptions() {
bool subtitlesOn = ConfMan.getBool("subtitles");
bool speechOn = !ConfMan.getBool("speech_mute");
+#ifdef ENABLE_SCI32
+ if (getSciVersion() >= SCI_VERSION_2) {
+ GlobalVar index;
+ uint16 textSpeed;
+
+ switch (g_sci->getGameId()) {
+ case GID_LSL6HIRES:
+ index = kGlobalVarLSL6HiresTextSpeed;
+ textSpeed = 14 - ConfMan.getInt("talkspeed") * 14 / 255 + 1;
+ break;
+ default:
+ index = kGlobalVarTextSpeed;
+ textSpeed = 8 - ConfMan.getInt("talkspeed") * 8 / 255;
+ }
+
+ _gamestate->variables[VAR_GLOBAL][index] = make_reg(0, textSpeed);
+ }
+#endif
+
if (useGlobal90) {
if (subtitlesOn && !speechOn) {
- _gamestate->variables[VAR_GLOBAL][90] = make_reg(0, 1); // subtitles
+ _gamestate->variables[VAR_GLOBAL][kGlobalVarMessageType] = make_reg(0, 1); // subtitles
} else if (!subtitlesOn && speechOn) {
- _gamestate->variables[VAR_GLOBAL][90] = make_reg(0, 2); // speech
+ _gamestate->variables[VAR_GLOBAL][kGlobalVarMessageType] = make_reg(0, 2); // speech
} else if (subtitlesOn && speechOn) {
// Is it a game that supports simultaneous speech and subtitles?
switch (_gameId) {
@@ -1036,12 +1166,15 @@ void SciEngine::syncIngameAudioOptions() {
case GID_SQ6: // SCI2.1, SQ6 seems to always use subtitles anyway
case GID_TORIN: // SCI2.1
case GID_QFG4: // SCI2.1
+ case GID_PQ4: // SCI2
+ // Phantasmagoria does not support simultaneous speech + subtitles
+ // Mixed Up Mother Goose Deluxe does not support simultaneous speech + subtitles
#endif // ENABLE_SCI32
- _gamestate->variables[VAR_GLOBAL][90] = make_reg(0, 3); // speech + subtitles
+ _gamestate->variables[VAR_GLOBAL][kGlobalVarMessageType] = make_reg(0, 3); // speech + subtitles
break;
default:
// Game does not support speech and subtitles, set it to speech
- _gamestate->variables[VAR_GLOBAL][90] = make_reg(0, 2); // speech
+ _gamestate->variables[VAR_GLOBAL][kGlobalVarMessageType] = make_reg(0, 2); // speech
}
}
}
@@ -1051,8 +1184,10 @@ 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();
+ if ((isCD() && getSciVersion() == SCI_VERSION_1_1) ||
+ getSciVersion() >= SCI_VERSION_2) {
+
+ uint16 ingameSetting = _gamestate->variables[VAR_GLOBAL][kGlobalVarMessageType].getOffset();
switch (ingameSetting) {
case 1: