aboutsummaryrefslogtreecommitdiff
path: root/engines/gob
diff options
context:
space:
mode:
authorArnaud Boutonné2010-08-24 06:25:08 +0000
committerArnaud Boutonné2010-08-24 06:25:08 +0000
commita484a99e9f27753ef1aaebb3b54159316410aed2 (patch)
treeaa6960a343de5deef948ab301a0b74696fa42b2a /engines/gob
parente93eaa0d95381573bfa5986216a18a871ae02412 (diff)
downloadscummvm-rg350-a484a99e9f27753ef1aaebb3b54159316410aed2.tar.gz
scummvm-rg350-a484a99e9f27753ef1aaebb3b54159316410aed2.tar.bz2
scummvm-rg350-a484a99e9f27753ef1aaebb3b54159316410aed2.zip
GOB: Avoid a crash in the protection screen of Fascination (PC).
When failing the protection check, the script of the PC version was writing on purpose everywhere in the memory to hang the computer. This resulted in a crash in Scummvm, fixed by this workaround. (Tested on the 256 Col version french and german) svn-id: r52316
Diffstat (limited to 'engines/gob')
-rw-r--r--engines/gob/inter.h1
-rw-r--r--engines/gob/inter_fascin.cpp39
2 files changed, 40 insertions, 0 deletions
diff --git a/engines/gob/inter.h b/engines/gob/inter.h
index b819c5e46a..ca97483054 100644
--- a/engines/gob/inter.h
+++ b/engines/gob/inter.h
@@ -432,6 +432,7 @@ protected:
void oFascin_playProtracker(OpGobParams &params);
+ bool oFascin_repeatUntil(OpFuncParams &params);
bool oFascin_assign(OpFuncParams &params);
bool oFascin_copySprite(OpFuncParams &params);
bool oFascin_keyFunc(OpFuncParams &params);
diff --git a/engines/gob/inter_fascin.cpp b/engines/gob/inter_fascin.cpp
index 185cce5e19..d2b97eea43 100644
--- a/engines/gob/inter_fascin.cpp
+++ b/engines/gob/inter_fascin.cpp
@@ -88,6 +88,7 @@ void Inter_Fascination::setupOpcodesDraw() {
void Inter_Fascination::setupOpcodesFunc() {
Inter_v2::setupOpcodesFunc();
+ OPCODEFUNC(0x06, oFascin_repeatUntil);
OPCODEFUNC(0x09, oFascin_assign);
OPCODEFUNC(0x32, oFascin_copySprite);
}
@@ -113,6 +114,43 @@ void Inter_Fascination::setupOpcodesGob() {
OPCODEGOB(1002, o2_stopProtracker);
}
+bool Inter_Fascination::oFascin_repeatUntil(OpFuncParams &params) {
+ int16 size;
+ bool flag;
+
+ _nestLevel[0]++;
+
+ uint32 blockPos = _vm->_game->_script->pos();
+
+ do {
+ _vm->_game->_script->seek(blockPos);
+ size = _vm->_game->_script->peekUint16(2) + 2;
+
+ funcBlock(1);
+
+ _vm->_game->_script->seek(blockPos + size + 1);
+
+ flag = _vm->_game->_script->evalBoolResult();
+
+ // WORKAROUND: The script of the PC version of Fascination, when the protection check
+ // fails, writes on purpose everywhere in the memory in order to hang the computer.
+ // This results in a crash in Scummvm. This workaround avoids that crash.
+ if (_vm->getPlatform() == Common::kPlatformPC) {
+ if ((!scumm_stricmp(_vm->_game->_curTotFile, "INTRO1.TOT") && (blockPos == 3533)) ||
+ (!scumm_stricmp(_vm->_game->_curTotFile, "INTRO2.TOT") && (blockPos == 3519)))
+ _terminate = 1;
+ }
+ } while (!flag && !_break && !_terminate && !_vm->shouldQuit());
+
+ _nestLevel[0]--;
+
+ if (*_breakFromLevel > -1) {
+ _break = false;
+ *_breakFromLevel = -1;
+ }
+ return false;
+}
+
bool Inter_Fascination::oFascin_assign(OpFuncParams &params) {
byte destType = _vm->_game->_script->peekByte();
int16 dest = _vm->_game->_script->readVarIndex();
@@ -322,4 +360,5 @@ void Inter_Fascination::oFascin_setWinFlags() {
void Inter_Fascination::oFascin_playProtracker(OpGobParams &params) {
_vm->_sound->protrackerPlay("mod.extasy");
}
+
} // End of namespace Gob