[Scummvm-cvs-logs] SF.net SVN: scummvm:[50214] scummvm/trunk/engines/sci/engine

m_kiewitz at users.sourceforge.net m_kiewitz at users.sourceforge.net
Thu Jun 24 15:17:45 CEST 2010


Revision: 50214
          http://scummvm.svn.sourceforge.net/scummvm/?rev=50214&view=rev
Author:   m_kiewitz
Date:     2010-06-24 13:17:45 +0000 (Thu, 24 Jun 2010)

Log Message:
-----------
SCI: created a workaround table for uninitialized reads, removing old commented out workarounds for pharkas and laura bow 2

Modified Paths:
--------------
    scummvm/trunk/engines/sci/engine/kgraphics.cpp
    scummvm/trunk/engines/sci/engine/vm.cpp
    scummvm/trunk/engines/sci/engine/vm.h

Modified: scummvm/trunk/engines/sci/engine/kgraphics.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/kgraphics.cpp	2010-06-24 12:32:41 UTC (rev 50213)
+++ scummvm/trunk/engines/sci/engine/kgraphics.cpp	2010-06-24 13:17:45 UTC (rev 50214)
@@ -639,7 +639,6 @@
 	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 @@
 	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;

Modified: scummvm/trunk/engines/sci/engine/vm.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/vm.cpp	2010-06-24 12:32:41 UTC (rev 50213)
+++ scummvm/trunk/engines/sci/engine/vm.cpp	2010-06-24 13:17:45 UTC (rev 50214)
@@ -183,16 +183,21 @@
 	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 @@
 				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);
+			warning("uninitialized read for temp %d from method %s::%s (script %d)", index, curObjectName, curMethodName, curScriptNr);
 
-			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];
+			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

Modified: scummvm/trunk/engines/sci/engine/vm.h
===================================================================
--- scummvm/trunk/engines/sci/engine/vm.h	2010-06-24 12:32:41 UTC (rev 50213)
+++ scummvm/trunk/engines/sci/engine/vm.h	2010-06-24 13:17:45 UTC (rev 50214)
@@ -109,6 +109,15 @@
 	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,


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