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.cpp136
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() {