diff options
author | Martin Kiewitz | 2010-06-24 13:17:45 +0000 |
---|---|---|
committer | Martin Kiewitz | 2010-06-24 13:17:45 +0000 |
commit | e45ffc68a32a13e81e7d12d3f43750f91e71cf91 (patch) | |
tree | 0f3c1469f45b2dfeaad4be5098b5e3ea02f606c8 /engines | |
parent | 898c9165d9a7f110b674a8bee82d30090a6010bc (diff) | |
download | scummvm-rg350-e45ffc68a32a13e81e7d12d3f43750f91e71cf91.tar.gz scummvm-rg350-e45ffc68a32a13e81e7d12d3f43750f91e71cf91.tar.bz2 scummvm-rg350-e45ffc68a32a13e81e7d12d3f43750f91e71cf91.zip |
SCI: created a workaround table for uninitialized reads, removing old commented out workarounds for pharkas and laura bow 2
svn-id: r50214
Diffstat (limited to 'engines')
-rw-r--r-- | engines/sci/engine/kgraphics.cpp | 21 | ||||
-rw-r--r-- | engines/sci/engine/vm.cpp | 51 | ||||
-rw-r--r-- | engines/sci/engine/vm.h | 9 |
3 files changed, 42 insertions, 39 deletions
diff --git a/engines/sci/engine/kgraphics.cpp b/engines/sci/engine/kgraphics.cpp index 3d1bca320b..974e034ddb 100644 --- a/engines/sci/engine/kgraphics.cpp +++ b/engines/sci/engine/kgraphics.cpp @@ -639,7 +639,6 @@ reg_t kPalette(EngineState *s, int argc, reg_t *argv) { return s->r_acc; } -// This here is needed to make Pharkas work reg_t kPalVary(EngineState *s, int argc, reg_t *argv) { uint16 operation = argv[0].toUint16(); @@ -1041,26 +1040,6 @@ 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 - // is not set. in Sierra sci this happens to be 8250h. In our sci temporary variables are initialized thus we would - // get 0 here resulting in broken menus. - if ((viewId == 995) && (loopNo == 0) && (celNo == 0) && (priority == 0)) // game menu - priority = 15; - if ((viewId == 992) && (loopNo == 0) && (celNo == 0) && (priority == 0)) // quit game - priority = 15; - } - - if (g_sci->getGameId() == "laurabow2") { - // WORKAROUND - // see the one above - if ((viewId == 995) && (priority == 0)) - priority = 15; - } -#endif - g_sci->_gfxPaint16->kernelDrawCel(viewId, loopNo, celNo, x, y, priority, paletteNo, hiresMode, upscaledHiresHandle); return s->r_acc; diff --git a/engines/sci/engine/vm.cpp b/engines/sci/engine/vm.cpp index 4204131ad3..0e0b8308dc 100644 --- a/engines/sci/engine/vm.cpp +++ b/engines/sci/engine/vm.cpp @@ -183,16 +183,21 @@ static bool validate_variable(reg_t *r, reg_t *stack_base, int type, int max, in return true; } +static const UninitializedReadWorkaround uninitializedReadWorkarounds[] = { + { "laurabow2", 24, "gcWin", "open", 5, 0xf }, // is used as priority for game menu + { "freddypharkas", 24, "gcWin", "open", 5, 0xf }, // is used as priority for game menu + { "islandbrain", 140, "piece", "init", 3, 0 }, // currently unknown, new value is not right + { "", -1, "", "", 0, 0 } +}; + 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 (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 EngineState *engine = g_sci->getEngineState(); Script *local_script = engine->_segMan->getScriptIfLoaded(engine->xs->local_segment); - int currentScriptNr = local_script->_nr; + int curScriptNr = local_script->_nr; Common::List<ExecStack>::iterator callIterator = engine->_executionStack.begin(); ExecStack call = *callIterator; @@ -201,24 +206,34 @@ static reg_t validate_read_var(reg_t *r, reg_t *stack_base, int type, int max, i callIterator++; } - const char *objName = engine->_segMan->getObjectName(call.sendp); - const char *selectorName = ""; + const char *curObjectName = engine->_segMan->getObjectName(call.sendp); + const char *curMethodName = ""; if (call.type == EXEC_STACK_TYPE_CALL) { - selectorName = g_sci->getKernel()->getSelectorName(call.selector).c_str(); + curMethodName = g_sci->getKernel()->getSelectorName(call.selector).c_str(); } - warning("uninitialized read for temp %d from method %s::%s (script %d)", index, objName, selectorName, currentScriptNr); - - Common::String gameId = g_sci->getGameId(); - if ((gameId == "laurabow2") && (currentScriptNr == 24) && (index == 5)) - return make_reg(0, 0xf); // priority replacement for menu - gcWin::open - if ((gameId == "freddypharkas") && (currentScriptNr == 24) && (index == 5)) - return make_reg(0, 0xf); // priority replacement for menu - gcWin::open - if ((gameId == "islandbrain") && (currentScriptNr == 140) && (index == 3)) { - // piece::init - //r[index] = make_reg(0, 255); - //return r[index]; + warning("uninitialized read for temp %d from method %s::%s (script %d)", index, curObjectName, curMethodName, curScriptNr); + + const char *gameId = g_sci->getGameId().c_str(); + + // Search if this is a known uninitialized read + const UninitializedReadWorkaround *workaround = uninitializedReadWorkarounds; + while (workaround->gameId) { + if (strcmp(workaround->gameId, gameId) == 0) { + if (workaround->scriptNr == curScriptNr) { + if (strcmp(workaround->objectName, curObjectName) == 0) { + if (strcmp(workaround->methodName, curMethodName) == 0) { + if (workaround->index == index) { + // Workaround found + r[index] = make_reg(0, workaround->newValue); + return r[index]; + } + } + } + } + } + workaround++; } - error("uninitialized read!"); + error("unknown uninitialized read!"); } return r[index]; } else diff --git a/engines/sci/engine/vm.h b/engines/sci/engine/vm.h index 88898cdbba..006bed4126 100644 --- a/engines/sci/engine/vm.h +++ b/engines/sci/engine/vm.h @@ -109,6 +109,15 @@ struct ExecStack { reg_t* getVarPointer(SegManager *segMan) const; }; +struct UninitializedReadWorkaround { + const char *gameId; + int scriptNr; + const char *objectName; + const char *methodName; + int index; + uint16 newValue; +}; + enum { VAR_GLOBAL = 0, VAR_LOCAL = 1, |