diff options
-rw-r--r-- | engines/sci/engine/vm.cpp | 15 | ||||
-rw-r--r-- | engines/sci/engine/workarounds.cpp | 6 | ||||
-rw-r--r-- | engines/sci/engine/workarounds.h | 1 |
3 files changed, 14 insertions, 8 deletions
diff --git a/engines/sci/engine/vm.cpp b/engines/sci/engine/vm.cpp index 7bcc5b43a3..6eff5c3ff7 100644 --- a/engines/sci/engine/vm.cpp +++ b/engines/sci/engine/vm.cpp @@ -136,12 +136,7 @@ static int validate_arithmetic(reg_t reg) { if (reg.segment) { // The results of this are likely unpredictable... It most likely means that a kernel function is returning something wrong. // If such an error occurs, we usually need to find the last kernel function called and check its return value. - if (g_sci->getGameId() == GID_QFG2 && g_sci->getEngineState()->currentRoomNumber() == 200) { - // WORKAROUND: This happens in QFG2, room 200, when talking to the astrologer (bug #3039879) - script bug. - // Returning 0 in this case. - } else { - error("[VM] Attempt to read arithmetic value from non-zero segment [%04x]. Address: %04x:%04x", reg.segment, PRINT_REG(reg)); - } + error("[VM] Attempt to read arithmetic value from non-zero segment [%04x]. Address: %04x:%04x", reg.segment, PRINT_REG(reg)); return 0; } @@ -1820,13 +1815,17 @@ void run_vm(EngineState *s) { case op_lsgi: // 0x4c (76) case op_lsli: // 0x4d (77) case op_lsti: // 0x4e (78) - case op_lspi: // 0x4f (79) + case op_lspi: { // 0x4f (79) // Load global, local, temp or param variable into the stack, // using the accumulator as an additional index var_type = opcode & 0x3; // Gets the variable type: g, l, t or p - var_number = opparams[0] + signed_validate_arithmetic(s->r_acc); + int16 value; + if (!validate_signedInteger(s->r_acc, value)) + value = arithmetic_lookForWorkaround(opcode, opcodeLsiWorkarounds, s->r_acc, NULL_REG).offset; + var_number = opparams[0] + value; PUSH32(READ_VAR(var_type, var_number)); break; + } case op_sag: // 0x50 (80) case op_sal: // 0x51 (81) diff --git a/engines/sci/engine/workarounds.cpp b/engines/sci/engine/workarounds.cpp index 25022ec03e..dd7edde968 100644 --- a/engines/sci/engine/workarounds.cpp +++ b/engines/sci/engine/workarounds.cpp @@ -53,6 +53,12 @@ const SciWorkaroundEntry opcodeGeWorkarounds[] = { }; // gameID, room,script,lvl, object-name, method-name, call,index, workaround +const SciWorkaroundEntry opcodeLsiWorkarounds[] = { + { GID_QFG2, 200, 200, 0, "astro", "messages", -1, 0, { WORKAROUND_FAKE, 0 } }, // when getting asked for your name by the astrologer bug #3039879 + SCI_WORKAROUNDENTRY_TERMINATOR +}; + +// gameID, room,script,lvl, object-name, method-name, call,index, workaround const SciWorkaroundEntry opcodeMulWorkarounds[] = { { GID_FANMADE, 516, 983, 0, "Wander", "setTarget", -1, 0, { WORKAROUND_FAKE, 0 } }, // The Legend of the Lost Jewel Demo (fan made): called with object as second parameter when attacked by insects - bug #3038913 SCI_WORKAROUNDENTRY_TERMINATOR diff --git a/engines/sci/engine/workarounds.h b/engines/sci/engine/workarounds.h index 8a3edb6246..eb13849bdd 100644 --- a/engines/sci/engine/workarounds.h +++ b/engines/sci/engine/workarounds.h @@ -71,6 +71,7 @@ struct SciWorkaroundEntry { extern const SciWorkaroundEntry opcodeDivWorkarounds[]; extern const SciWorkaroundEntry opcodeDptoaWorkarounds[]; extern const SciWorkaroundEntry opcodeGeWorkarounds[]; +extern const SciWorkaroundEntry opcodeLsiWorkarounds[]; extern const SciWorkaroundEntry opcodeMulWorkarounds[]; extern const SciWorkaroundEntry opcodeOrWorkarounds[]; extern const SciWorkaroundEntry uninitializedReadWorkarounds[]; |