diff options
-rw-r--r-- | engines/sci/console.cpp | 10 | ||||
-rw-r--r-- | engines/sci/engine/vm.cpp | 20 |
2 files changed, 17 insertions, 13 deletions
diff --git a/engines/sci/console.cpp b/engines/sci/console.cpp index c515d45a1a..7896a55dac 100644 --- a/engines/sci/console.cpp +++ b/engines/sci/console.cpp @@ -2771,16 +2771,6 @@ void Console::printKernelCallsFound(int kernelFuncNum, bool showFoundScripts) { uint16 curJmpOffset = offset + (uint16)opparams[0]; if (curJmpOffset > maxJmpOffset) maxJmpOffset = curJmpOffset; - // FIXME: There seems to be a bug in the way we handle the SCI2 debug opcode - // (i.e. 0x7e/0x3f), which is probably why the bugs below occur - if (maxJmpOffset >= script->getBufSize()) { - warning("Called from script %d, object %s, method %s(%d) with %d parameters", - itr->getNumber(), objName, - _engine->getKernel()->getSelectorName(obj->getFuncSelector(i)).c_str(), i, 0); - warning("Script %d has a jump to an invalid offset (%d, script size is %d) - adjusting", - script->getScriptNumber(), maxJmpOffset, script->getBufSize()); - maxJmpOffset = script->getBufSize() - 1; - } } // Check for end of function/script diff --git a/engines/sci/engine/vm.cpp b/engines/sci/engine/vm.cpp index df2ba9cbac..244e3b0b6a 100644 --- a/engines/sci/engine/vm.cpp +++ b/engines/sci/engine/vm.cpp @@ -903,6 +903,22 @@ int readPMachineInstruction(const byte *src, byte &extOpcode, int16 opparams[4]) } } + // Special handling of the op_line opcode + if (opcode == op_pushSelf) { + // Compensate for a bug in non-Sierra compilers, which seem to generate + // pushSelf instructions with the low bit set. This makes the following + // heuristic fail and leads to endless loops and crashes. Our + // interpretation of this seems correct, as other SCI tools, like for + // example SCI Viewer, have issues with these scripts (e.g. script 999 + // in Circus Quest). Fixes bug #3038686. + if (!(extOpcode & 1) || g_sci->getGameId() == GID_FANMADE) { + // op_pushSelf: no adjustment necessary + } else { + // Debug opcode op_file, skip null-terminated string (file name) + while (src[offset++]) {} + } + } + return offset; } @@ -1825,9 +1841,7 @@ void run_vm(EngineState *s) { if (!(extOpcode & 1) || g_sci->getGameId() == GID_FANMADE) { PUSH32(s->xs->objp); } else { - // Debug opcode op_file, skip null-terminated string (file name) - const byte *code_buf = scr->getBuf(); - while (code_buf[s->xs->addr.pc.offset++]) ; + // Debug opcode op_file } break; |