aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorMartin Kiewitz2010-06-24 11:54:33 +0000
committerMartin Kiewitz2010-06-24 11:54:33 +0000
commitf93ca1e4242da27079e6ce4cd4d4e8d569984ec4 (patch)
tree81faa804e5ca1d5de337a197373991b6809c6497 /engines
parent0722d96a3e249a7efe853d77b1432100912499d1 (diff)
downloadscummvm-rg350-f93ca1e4242da27079e6ce4cd4d4e8d569984ec4.tar.gz
scummvm-rg350-f93ca1e4242da27079e6ce4cd4d4e8d569984ec4.tar.bz2
scummvm-rg350-f93ca1e4242da27079e6ce4cd4d4e8d569984ec4.zip
SCI: implement detection for uninitialized temp variable reads and implement direct fixes for them, i couldnt figure out a valid replacement for island, pharkas and laurabow2 work that way. this should also get changed to a replacement table
svn-id: r50211
Diffstat (limited to 'engines')
-rw-r--r--engines/sci/engine/kgraphics.cpp4
-rw-r--r--engines/sci/engine/vm.cpp49
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;