diff options
-rw-r--r-- | engines/sci/engine/kgraphics.cpp | 4 | ||||
-rw-r--r-- | engines/sci/engine/vm.cpp | 49 |
2 files changed, 39 insertions, 14 deletions
diff --git a/engines/sci/engine/kgraphics.cpp b/engines/sci/engine/kgraphics.cpp index eaef049951..3d1bca320b 100644 --- a/engines/sci/engine/kgraphics.cpp +++ b/engines/sci/engine/kgraphics.cpp @@ -351,7 +351,7 @@ reg_t kTextSize(EngineState *s, int argc, reg_t *argv) { } textWidth = dest[3].toUint16(); textHeight = dest[2].toUint16(); - + #ifdef ENABLE_SCI32 if (!g_sci->_gfxText16) { // TODO: Implement this @@ -1041,6 +1041,7 @@ reg_t kDrawCel(EngineState *s, int argc, reg_t *argv) { bool hiresMode = (argc > 7) ? true : false; reg_t upscaledHiresHandle = (argc > 7) ? argv[7] : NULL_REG; +#if 0 if (g_sci->getGameId() == "freddypharkas") { // WORKAROUND // Script 24 contains code that draws the game menu on screen. It uses a temp variable for setting priority that @@ -1058,6 +1059,7 @@ reg_t kDrawCel(EngineState *s, int argc, reg_t *argv) { if ((viewId == 995) && (priority == 0)) priority = 15; } +#endif g_sci->_gfxPaint16->kernelDrawCel(viewId, loopNo, celNo, x, y, priority, paletteNo, hiresMode, upscaledHiresHandle); diff --git a/engines/sci/engine/vm.cpp b/engines/sci/engine/vm.cpp index 53cba93f98..fdd2032ce3 100644 --- a/engines/sci/engine/vm.cpp +++ b/engines/sci/engine/vm.cpp @@ -184,9 +184,28 @@ static bool validate_variable(reg_t *r, reg_t *stack_base, int type, int max, in } static reg_t validate_read_var(reg_t *r, reg_t *stack_base, int type, int max, int index, int line, reg_t default_value) { - if (validate_variable(r, stack_base, type, max, index, line)) + if (validate_variable(r, stack_base, type, max, index, line)) { + if (type == VAR_TEMP && r[index].segment == 0xffff) { + // Uninitialized read on a temp + // We need to find correct replacements for each situation manually + // FIXME: this should use a table which contains workarounds for gameId, scriptnumber and temp index and + // a replacement value + Script *local_script = g_sci->getEngineState()->_segMan->getScriptIfLoaded(g_sci->getEngineState()->xs->local_segment); + int currentScriptNr = local_script->_nr; + warning("uninitialized read for temp %d, script %d", index, currentScriptNr); + Common::String gameId = g_sci->getGameId(); + if ((gameId == "laurabow2") && (currentScriptNr == 24) && (index == 5)) + return make_reg(0, 0xf); // priority replacement for menu + if ((gameId == "freddypharkas") && (currentScriptNr == 24) && (index == 5)) + return make_reg(0, 0xf); // priority replacement for menu + if ((gameId == "islandbrain") && (currentScriptNr == 140) && (index == 3)) { + r[index] = make_reg(0, 255); + return r[index]; + } + error("uninitialized read!"); + } return r[index]; - else + } else return default_value; } @@ -763,9 +782,6 @@ void run_vm(EngineState *s, bool restoring) { int old_executionStackBase = s->executionStackBase; // Used to detect the stack bottom, for "physical" returns const byte *code_buf = NULL; // (Avoid spurious warning) - // Used for a workaround in op_link below, in order to avoid string matching (which can - // be slow if used in the game script interpreter) - bool isIslandOfDrBrain = (g_sci->getGameId() == "islandbrain"); if (!local_script) { error("run_vm(): program counter gone astray (local_script pointer is null)"); @@ -1137,14 +1153,21 @@ void run_vm(EngineState *s, bool restoring) { break; case op_link: // 0x1f (31) - if (local_script->_nr == 140 && isIslandOfDrBrain) { - // WORKAROUND for The Island of Dr. Brain, room 140. - // Script 140 runs in an endless loop if we set its - // variables to 0 here. - } else { - for (int i = 0; i < opparams[0]; i++) - s->xs->sp[i] = NULL_REG; - } + // We shouldn't initialize temp variables at all + // We put special segment 0xFFFF in there, so that uninitialized reads can get detected + for (int i = 0; i < opparams[0]; i++) + s->xs->sp[i] = make_reg(0xffff, 0xffff); +// for (int i = 0; i < opparams[0]; i++) +// s->xs->sp[i] = make_reg(0, 'ss'); + + //if (local_script->_nr == 140 && isIslandOfDrBrain) { + // // WORKAROUND for The Island of Dr. Brain, room 140. + // // Script 140 runs in an endless loop if we set its + // // variables to 0 here. + //} else { + // for (int i = 0; i < opparams[0]; i++) + // s->xs->sp[i] = NULL_REG; + //} s->xs->sp += opparams[0]; break; |