SCI: Moved the handling of the op_line debug opcode inside readPMachineInstruction()

The handling has been moved inside readPMachineInstruction(), instead of run_vm(), as a
lot of parts of the code depend on this function handling all opcodes correctly (e.g. the
script dissassembler, the features class, find_callk etc)

svn-id: r55154
This commit is contained in:
Filippos Karapetis 2011-01-07 20:24:49 +00:00
parent 59d00fca17
commit 2b87eebdb0
2 changed files with 17 additions and 13 deletions

View File

@ -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

View File

@ -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;