[Scummvm-cvs-logs] SF.net SVN: scummvm:[50211] scummvm/trunk/engines/sci/engine
m_kiewitz at users.sourceforge.net
m_kiewitz at users.sourceforge.net
Thu Jun 24 13:54:33 CEST 2010
Revision: 50211
http://scummvm.svn.sourceforge.net/scummvm/?rev=50211&view=rev
Author: m_kiewitz
Date: 2010-06-24 11:54:33 +0000 (Thu, 24 Jun 2010)
Log Message:
-----------
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
Modified Paths:
--------------
scummvm/trunk/engines/sci/engine/kgraphics.cpp
scummvm/trunk/engines/sci/engine/vm.cpp
Modified: scummvm/trunk/engines/sci/engine/kgraphics.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/kgraphics.cpp 2010-06-24 11:52:08 UTC (rev 50210)
+++ scummvm/trunk/engines/sci/engine/kgraphics.cpp 2010-06-24 11:54:33 UTC (rev 50211)
@@ -351,7 +351,7 @@
}
textWidth = dest[3].toUint16(); textHeight = dest[2].toUint16();
-
+
#ifdef ENABLE_SCI32
if (!g_sci->_gfxText16) {
// TODO: Implement this
@@ -1041,6 +1041,7 @@
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 @@
if ((viewId == 995) && (priority == 0))
priority = 15;
}
+#endif
g_sci->_gfxPaint16->kernelDrawCel(viewId, loopNo, celNo, x, y, priority, paletteNo, hiresMode, upscaledHiresHandle);
Modified: scummvm/trunk/engines/sci/engine/vm.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/vm.cpp 2010-06-24 11:52:08 UTC (rev 50210)
+++ scummvm/trunk/engines/sci/engine/vm.cpp 2010-06-24 11:54:33 UTC (rev 50211)
@@ -184,9 +184,28 @@
}
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 @@
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,15 +1153,22 @@
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;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
More information about the Scummvm-git-logs
mailing list