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

m_kiewitz at users.sourceforge.net m_kiewitz at users.sourceforge.net
Fri Jul 23 16:32:25 CEST 2010


Revision: 51209
          http://scummvm.svn.sourceforge.net/scummvm/?rev=51209&view=rev
Author:   m_kiewitz
Date:     2010-07-23 14:32:24 +0000 (Fri, 23 Jul 2010)

Log Message:
-----------
SCI: adding table for kDisplay workarounds

and removing hardcoded checks, adding another workaround for kGraph(drawLine) in island of dr. brain (also gene explanation chart)
Moving trackOriginAndFindWorkaround() into workarounds.cpp

Modified Paths:
--------------
    scummvm/trunk/engines/sci/engine/vm.cpp
    scummvm/trunk/engines/sci/engine/workarounds.cpp
    scummvm/trunk/engines/sci/engine/workarounds.h
    scummvm/trunk/engines/sci/graphics/paint16.cpp

Modified: scummvm/trunk/engines/sci/engine/vm.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/vm.cpp	2010-07-23 13:57:45 UTC (rev 51208)
+++ scummvm/trunk/engines/sci/engine/vm.cpp	2010-07-23 14:32:24 UTC (rev 51209)
@@ -183,88 +183,6 @@
 	return true;
 }
 
-struct SciTrackOriginReply {
-	int scriptNr;
-	Common::String objectName;
-	Common::String methodName;
-	int localCallOffset;
-};
-
-static SciWorkaroundSolution trackOriginAndFindWorkaround(int index, const SciWorkaroundEntry *workaroundList, SciTrackOriginReply *trackOrigin) {
-	EngineState *state = g_sci->getEngineState();
-	ExecStack *lastCall = state->xs;
-	Script *local_script = state->_segMan->getScriptIfLoaded(lastCall->local_segment);
-	int curScriptNr = local_script->getScriptNumber();
-
-	if (lastCall->debugLocalCallOffset != -1) {
-		// if lastcall was actually a local call search back for a real call
-		Common::List<ExecStack>::iterator callIterator = state->_executionStack.end();
-		while (callIterator != state->_executionStack.begin()) {
-			callIterator--;
-			ExecStack loopCall = *callIterator;
-			if ((loopCall.debugSelector != -1) || (loopCall.debugExportId != -1)) {
-				lastCall->debugSelector = loopCall.debugSelector;
-				lastCall->debugExportId = loopCall.debugExportId;
-				break;
-			}
-		}
-	}
-
-	Common::String curObjectName = state->_segMan->getObjectName(lastCall->sendp);
-	Common::String curMethodName;
-	const SciGameId gameId = g_sci->getGameId();
-	const int curRoomNumber = state->currentRoomNumber();
-
-	if (lastCall->type == EXEC_STACK_TYPE_CALL) {
-		if (lastCall->debugSelector != -1) {
-			curMethodName = g_sci->getKernel()->getSelectorName(lastCall->debugSelector);
-		} else if (lastCall->debugExportId != -1) {
-			curObjectName = "";
-			curMethodName = curMethodName.printf("export %d", lastCall->debugExportId);
-		}
-	}
-
-	if (workaroundList) {
-		// Search if there is a workaround for this one
-		const SciWorkaroundEntry *workaround;
-		int16 inheritanceLevel = 0;
-		Common::String searchObjectName = curObjectName;
-		reg_t searchObject = lastCall->sendp;
-		do {
-			workaround = workaroundList;
-			while (workaround->objectName) {
-				if (workaround->gameId == gameId && workaround->scriptNr == curScriptNr
-						&& ((workaround->roomNr == -1) || (workaround->roomNr == curRoomNumber))
-						&& ((workaround->inheritanceLevel == -1) || (workaround->inheritanceLevel == inheritanceLevel))
-						&& (workaround->objectName == searchObjectName)
-						&& workaround->methodName == curMethodName && workaround->localCallOffset == lastCall->debugLocalCallOffset
-						&& ((workaround->index == -1) || (workaround->index == index))) {
-					// Workaround found
-					return workaround->newValue;
-				}
-				workaround++;
-			}
-
-			// Go back to the parent
-			inheritanceLevel++;
-			searchObject = state->_segMan->getObject(searchObject)->getSuperClassSelector();
-			if (!searchObject.isNull())
-				searchObjectName = state->_segMan->getObjectName(searchObject);
-		} while (!searchObject.isNull()); // no parent left?
-	}
-
-	// give caller origin data
-	trackOrigin->objectName = curObjectName;
-	trackOrigin->methodName = curMethodName;
-	trackOrigin->scriptNr = curScriptNr;
-	trackOrigin->localCallOffset = lastCall->debugLocalCallOffset;
-
-	SciWorkaroundSolution noneFound;
-	noneFound.type = WORKAROUND_NONE;
-	noneFound.value = 0;
-	return noneFound;
-}
-
 static bool validate_unsignedInteger(reg_t reg, uint16 &integer) {
 	if (reg.segment)
 		return false;

Modified: scummvm/trunk/engines/sci/engine/workarounds.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/workarounds.cpp	2010-07-23 13:57:45 UTC (rev 51208)
+++ scummvm/trunk/engines/sci/engine/workarounds.cpp	2010-07-23 14:32:24 UTC (rev 51209)
@@ -23,6 +23,9 @@
  *
  */
 
+#include "sci/engine/kernel.h"
+#include "sci/engine/state.h"
+#include "sci/engine/vm.h"
 #include "sci/engine/workarounds.h"
 
 #define SCI_WORKAROUNDENTRY_TERMINATOR { (SciGameId)0, -1, -1, 0, NULL, NULL, -1, 0, { WORKAROUND_NONE, 0 } }
@@ -101,6 +104,13 @@
 };
 
 //    gameID,           room,script,lvl,          object-name, method-name,    call,index,                workaround
+const SciWorkaroundEntry kDisplay_workarounds[] = {
+    { GID_ISLANDBRAIN,   300,   300,  0,           "geneDude", "show",           -1,    0, { WORKAROUND_IGNORE,    0 } }, // when looking at the gene explanation chart - a parameter is an object
+    { GID_SQ4,           391,   391,  0,          "doCatalog", "mode",         0x84,    0, { WORKAROUND_IGNORE,    0 } }, // clicking on catalog in roboter sale - a parameter is an object
+    SCI_WORKAROUNDENTRY_TERMINATOR
+};
+
+//    gameID,           room,script,lvl,          object-name, method-name,    call,index,                workaround
 const SciWorkaroundEntry kDisposeScript_workarounds[] = {
     { GID_QFG1,           64,    64,  0,               "rm64", "dispose",        -1,    0, { WORKAROUND_IGNORE,    0 } }, // when leaving graveyard, parameter 0 is an object
     SCI_WORKAROUNDENTRY_TERMINATOR
@@ -115,7 +125,8 @@
 
 //    gameID,           room,script,lvl,          object-name, method-name,    call,index,                workaround
 const SciWorkaroundEntry kGraphDrawLine_workarounds[] = {
-    { GID_SQ1,            43,    43,  0,        "someoneDied", "changeState",    -1,    0, { WORKAROUND_STILLCALL, 0 } }, // happens when ordering beer, gets called with 1 extra parameter
+    { GID_ISLANDBRAIN,   300,   300,  0,         "dudeViewer", "show",           -1,    0, { WORKAROUND_STILLCALL, 0 } }, // when looking at the gene explanation chart, gets called with 1 extra parameter
+    { GID_SQ1,            43,    43,  0,        "someoneDied", "changeState",    -1,    0, { WORKAROUND_STILLCALL, 0 } }, // when ordering beer, gets called with 1 extra parameter
     SCI_WORKAROUNDENTRY_TERMINATOR
 };
 
@@ -172,4 +183,79 @@
     SCI_WORKAROUNDENTRY_TERMINATOR
 };
 
+SciWorkaroundSolution trackOriginAndFindWorkaround(int index, const SciWorkaroundEntry *workaroundList, SciTrackOriginReply *trackOrigin) {
+	EngineState *state = g_sci->getEngineState();
+	ExecStack *lastCall = state->xs;
+	Script *local_script = state->_segMan->getScriptIfLoaded(lastCall->local_segment);
+	int curScriptNr = local_script->getScriptNumber();
+
+	if (lastCall->debugLocalCallOffset != -1) {
+		// if lastcall was actually a local call search back for a real call
+		Common::List<ExecStack>::iterator callIterator = state->_executionStack.end();
+		while (callIterator != state->_executionStack.begin()) {
+			callIterator--;
+			ExecStack loopCall = *callIterator;
+			if ((loopCall.debugSelector != -1) || (loopCall.debugExportId != -1)) {
+				lastCall->debugSelector = loopCall.debugSelector;
+				lastCall->debugExportId = loopCall.debugExportId;
+				break;
+			}
+		}
+	}
+
+	Common::String curObjectName = state->_segMan->getObjectName(lastCall->sendp);
+	Common::String curMethodName;
+	const SciGameId gameId = g_sci->getGameId();
+	const int curRoomNumber = state->currentRoomNumber();
+
+	if (lastCall->type == EXEC_STACK_TYPE_CALL) {
+		if (lastCall->debugSelector != -1) {
+			curMethodName = g_sci->getKernel()->getSelectorName(lastCall->debugSelector);
+		} else if (lastCall->debugExportId != -1) {
+			curObjectName = "";
+			curMethodName = curMethodName.printf("export %d", lastCall->debugExportId);
+		}
+	}
+
+	if (workaroundList) {
+		// Search if there is a workaround for this one
+		const SciWorkaroundEntry *workaround;
+		int16 inheritanceLevel = 0;
+		Common::String searchObjectName = curObjectName;
+		reg_t searchObject = lastCall->sendp;
+		do {
+			workaround = workaroundList;
+			while (workaround->objectName) {
+				if (workaround->gameId == gameId && workaround->scriptNr == curScriptNr
+						&& ((workaround->roomNr == -1) || (workaround->roomNr == curRoomNumber))
+						&& ((workaround->inheritanceLevel == -1) || (workaround->inheritanceLevel == inheritanceLevel))
+						&& (workaround->objectName == searchObjectName)
+						&& workaround->methodName == curMethodName && workaround->localCallOffset == lastCall->debugLocalCallOffset
+						&& ((workaround->index == -1) || (workaround->index == index))) {
+					// Workaround found
+					return workaround->newValue;
+				}
+				workaround++;
+			}
+
+			// Go back to the parent
+			inheritanceLevel++;
+			searchObject = state->_segMan->getObject(searchObject)->getSuperClassSelector();
+			if (!searchObject.isNull())
+				searchObjectName = state->_segMan->getObjectName(searchObject);
+		} while (!searchObject.isNull()); // no parent left?
+	}
+
+	// give caller origin data
+	trackOrigin->objectName = curObjectName;
+	trackOrigin->methodName = curMethodName;
+	trackOrigin->scriptNr = curScriptNr;
+	trackOrigin->localCallOffset = lastCall->debugLocalCallOffset;
+
+	SciWorkaroundSolution noneFound;
+	noneFound.type = WORKAROUND_NONE;
+	noneFound.value = 0;
+	return noneFound;
+}
+
 } // End of namespace Sci

Modified: scummvm/trunk/engines/sci/engine/workarounds.h
===================================================================
--- scummvm/trunk/engines/sci/engine/workarounds.h	2010-07-23 13:57:45 UTC (rev 51208)
+++ scummvm/trunk/engines/sci/engine/workarounds.h	2010-07-23 14:32:24 UTC (rev 51209)
@@ -38,6 +38,13 @@
 	WORKAROUND_FAKE       // fake kernel call / replace temp value / fake opcode
 };
 
+struct SciTrackOriginReply {
+	int scriptNr;
+	Common::String objectName;
+	Common::String methodName;
+	int localCallOffset;
+};
+
 struct SciWorkaroundSolution {
 	SciWorkaroundType type;
 	uint16 value;
@@ -65,6 +72,7 @@
 extern const SciWorkaroundEntry opcodeDptoaWorkarounds[];
 extern const SciWorkaroundEntry uninitializedReadWorkarounds[];
 extern const SciWorkaroundEntry kAbs_workarounds[];
+extern const SciWorkaroundEntry kDisplay_workarounds[];
 extern const SciWorkaroundEntry kDisposeScript_workarounds[];
 extern const SciWorkaroundEntry kDoSoundFade_workarounds[];
 extern const SciWorkaroundEntry kGraphDrawLine_workarounds[];
@@ -76,6 +84,8 @@
 extern const SciWorkaroundEntry kUnLoad_workarounds[];
 extern const SciWorkaroundEntry kStrCpy_workarounds[];
 
+extern SciWorkaroundSolution trackOriginAndFindWorkaround(int index, const SciWorkaroundEntry *workaroundList, SciTrackOriginReply *trackOrigin);
+
 } // End of namespace Sci
 
 #endif // SCI_ENGINE_WORKAROUNDS_H

Modified: scummvm/trunk/engines/sci/graphics/paint16.cpp
===================================================================
--- scummvm/trunk/engines/sci/graphics/paint16.cpp	2010-07-23 13:57:45 UTC (rev 51208)
+++ scummvm/trunk/engines/sci/graphics/paint16.cpp	2010-07-23 14:32:24 UTC (rev 51209)
@@ -32,6 +32,7 @@
 #include "sci/engine/features.h"
 #include "sci/engine/state.h"
 #include "sci/engine/selector.h"
+#include "sci/engine/workarounds.h"
 #include "sci/graphics/cache.h"
 #include "sci/graphics/coordadjuster.h"
 #include "sci/graphics/ports.h"
@@ -544,11 +545,11 @@
 			}
 			break;
 		default:
-			if ((g_sci->getGameId() == GID_ISLANDBRAIN) && (g_sci->getEngineState()->currentRoomNumber() == 300))
-				break; // WORKAROUND: we are called there with an forwarded 0 as additional parameter (script bug)
-			if ((g_sci->getGameId() == GID_SQ4) && (g_sci->getEngineState()->currentRoomNumber() == 391))
-				break; // WORKAROUND: we get a pointer as parameter, skip it (sub 84h)
-			error("Unknown kDisplay argument %X", displayArg);
+			SciTrackOriginReply originReply;
+			SciWorkaroundSolution solution = trackOriginAndFindWorkaround(0, kDisplay_workarounds, &originReply);
+			if (solution.type == WORKAROUND_NONE)
+				error("Unknown kDisplay argument (%04x:%04x) from method %s::%s (script %d, localCall %x)", PRINT_REG(argv[0]), originReply.objectName.c_str(), originReply.methodName.c_str(), originReply.scriptNr, originReply.localCallOffset);
+			assert(solution.type == WORKAROUND_IGNORE);
 			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