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

m_kiewitz at users.sourceforge.net m_kiewitz at users.sourceforge.net
Fri Jul 9 23:33:12 CEST 2010


Revision: 50770
          http://scummvm.svn.sourceforge.net/scummvm/?rev=50770&view=rev
Author:   m_kiewitz
Date:     2010-07-09 21:33:12 +0000 (Fri, 09 Jul 2010)

Log Message:
-----------
SCI: adding workaround support for kernel subcalls, cleanup

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

Modified: scummvm/trunk/engines/sci/engine/vm.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/vm.cpp	2010-07-09 21:10:14 UTC (rev 50769)
+++ scummvm/trunk/engines/sci/engine/vm.cpp	2010-07-09 21:33:12 UTC (rev 50770)
@@ -270,7 +270,7 @@
 	int localCallOffset;
 };
 
-static reg_t trackOriginAndFindWorkaround(int index, const SciWorkaroundEntry *workaroundList, bool &workaroundFound, SciTrackOriginReply *trackOrigin) {
+static reg_t 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);
@@ -315,7 +315,6 @@
 				if (workaround->gameId == gameId && workaround->scriptNr == curScriptNr && (workaround->inheritanceLevel == inheritanceLevel) && (workaround->objectName == searchObjectName)
 						&& workaround->methodName == curMethodName && workaround->localCallOffset == lastCall->debugLocalCallOffset && workaround->index == index) {
 					// Workaround found
-					workaroundFound = true;
 					return workaround->newValue;
 				}
 				workaround++;
@@ -334,8 +333,6 @@
 	trackOrigin->methodName = curMethodName;
 	trackOrigin->scriptNr = curScriptNr;
 	trackOrigin->localCallOffset = lastCall->debugLocalCallOffset;
-
-	workaroundFound = false;
 	return make_reg(0xFFFF, 0xFFFF);
 }
 
@@ -369,10 +366,9 @@
 		if (type == VAR_TEMP && r[index].segment == 0xffff) {
 			// Uninitialized read on a temp
 			//  We need to find correct replacements for each situation manually
-			bool workaroundFound;
 			SciTrackOriginReply originReply;
-			r[index] = trackOriginAndFindWorkaround(index, uninitializedReadWorkarounds, workaroundFound, &originReply);
-			if (!workaroundFound)
+			r[index] = trackOriginAndFindWorkaround(index, uninitializedReadWorkarounds, &originReply);
+			if ((r[index].segment == 0xFFFF) && (r[index].offset == 0xFFFF))
 				error("Uninitialized read for temp %d from method %s::%s (script %d, localCall %x)", index, originReply.objectName.c_str(), originReply.methodName.c_str(), originReply.scriptNr, originReply.localCallOffset);
 		}
 		return r[index];
@@ -780,25 +776,24 @@
 	}
 }
 
-static void callKernelFunc(EngineState *s, int kernelFuncNr, int argc) {
+static void callKernelFunc(EngineState *s, int kernelCallNr, int argc) {
 	Kernel *kernel = g_sci->getKernel();
 
-	if (kernelFuncNr >= (int)kernel->_kernelFuncs.size())
-		error("Invalid kernel function 0x%x requested", kernelFuncNr);
+	if (kernelCallNr >= (int)kernel->_kernelFuncs.size())
+		error("Invalid kernel function 0x%x requested", kernelCallNr);
 
-	const KernelFunction &kernelCall = kernel->_kernelFuncs[kernelFuncNr];
+	const KernelFunction &kernelCall = kernel->_kernelFuncs[kernelCallNr];
 	reg_t *argv = s->xs->sp + 1;
 
 	if (kernelCall.signature
 			&& !kernel->signatureMatch(kernelCall.signature, argc, argv)) {
 		// signature mismatch, check if a workaround is available
-		bool workaroundFound;
 		SciTrackOriginReply originReply;
 		reg_t workaround;
-		workaround = trackOriginAndFindWorkaround(0, kernelCall.workarounds, workaroundFound, &originReply);
-		if (!workaroundFound) {
+		workaround = trackOriginAndFindWorkaround(0, kernelCall.workarounds, &originReply);
+		if ((workaround.segment == 0xFFFF) && (workaround.offset == 0xFFFF)) {
 			kernel->signatureDebug(kernelCall.signature, argc, argv);
-			error("[VM] k%s (%x) signature mismatch via method %s::%s (script %d, localCall %x)", kernelCall.name, kernelFuncNr, originReply.objectName.c_str(), originReply.methodName.c_str(), originReply.scriptNr, originReply.localCallOffset);
+			error("[VM] k%s[%x]: signature mismatch via method %s::%s (script %d, localCall %x)", kernelCall.name, kernelCallNr, originReply.objectName.c_str(), originReply.methodName.c_str(), originReply.scriptNr, originReply.localCallOffset);
 		}
 		// FIXME: implement some real workaround type logic - ignore call, still do call etc.
 		if (workaround.segment)
@@ -812,7 +807,7 @@
 		ExecStack *xstack;
 		xstack = add_exec_stack_entry(s->_executionStack, NULL_REG, NULL, NULL_REG, argc, argv - 1, 0, -1, -1, NULL_REG,
 				  s->_executionStack.size()-1, SCI_XS_CALLEE_LOCALS);
-		xstack->debugSelector = kernelFuncNr;
+		xstack->debugSelector = kernelCallNr;
 		xstack->type = EXEC_STACK_TYPE_KERNEL;
 
 		// Call kernel function
@@ -821,7 +816,7 @@
 		} else {
 			// Sub-functions available, check signature and call that one directly
 			if (argc < 1)
-				error("[VM] k%s: no subfunction-id parameter given");
+				error("[VM] k%s[%x]: no subfunction-id parameter given", kernelCall.name, kernelCallNr);
 			const uint16 subId = argv[0].toUint16();
 			// Skip over subfunction-id
 			argc--;
@@ -831,8 +826,16 @@
 			const KernelSubFunction &kernelSubCall = kernelCall.subFunctions[subId];
 			if (!kernel->signatureMatch(kernelSubCall.signature, argc, argv)) {
 				// Signature mismatch
-				kernel->signatureDebug(kernelSubCall.signature, argc, argv);
-				error("[VM] k%s: subfunction signature mismatch", kernelSubCall.name);
+				SciTrackOriginReply originReply;
+				reg_t workaround;
+				workaround = trackOriginAndFindWorkaround(0, kernelSubCall.workarounds, &originReply);
+				if ((workaround.segment == 0xFFFF) && (workaround.offset == 0xFFFF)) {
+					kernel->signatureDebug(kernelSubCall.signature, argc, argv);
+					error("[VM] k%s (%x) signature mismatch via method %s::%s (script %d, localCall %x)", kernelSubCall.name, kernelCallNr, originReply.objectName.c_str(), originReply.methodName.c_str(), originReply.scriptNr, originReply.localCallOffset);
+				}
+				// FIXME: implement some real workaround type logic - ignore call, still do call etc.
+				if (workaround.segment)
+					return;
 			}
 			s->r_acc = kernelSubCall.function(s, argc, argv);
 		}
@@ -857,8 +860,8 @@
 		if (s->_executionStack.begin() != s->_executionStack.end())
 			s->_executionStack.pop_back();
 	} else {
-		Common::String warningMsg = "Dummy function " + kernel->getKernelName(kernelFuncNr) +
-									Common::String::printf("[0x%x]", kernelFuncNr) +
+		Common::String warningMsg = "Dummy function " + kernel->getKernelName(kernelCallNr) +
+									Common::String::printf("[0x%x]", kernelCallNr) +
 									" invoked - ignoring. Params: " +
 									Common::String::printf("%d", argc) + " (";
 
@@ -871,8 +874,8 @@
 
 		// Make sure that the game doesn't call a function that is considered unused. If
 		// that happens, error out.
-		if (kernel->getKernelName(kernelFuncNr) == "Dummy")
-			error("Kernel function %d was called, which was considered to be unused", kernelFuncNr);
+		if (kernel->getKernelName(kernelCallNr) == "Dummy")
+			error("Kernel function %d was called, which was considered to be unused", kernelCallNr);
 	}
 }
 


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