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

fingolfin at users.sourceforge.net fingolfin at users.sourceforge.net
Sun Feb 7 18:57:52 CET 2010


Revision: 47979
          http://scummvm.svn.sourceforge.net/scummvm/?rev=47979&view=rev
Author:   fingolfin
Date:     2010-02-07 17:57:51 +0000 (Sun, 07 Feb 2010)

Log Message:
-----------
SCI: Move bulk of op_callk code to new func callKernelFunc()

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-02-07 17:57:25 UTC (rev 47978)
+++ scummvm/trunk/engines/sci/engine/vm.cpp	2010-02-07 17:57:51 UTC (rev 47979)
@@ -549,13 +549,76 @@
 		break;
 
 	default:
-		// Changed this to warning, because iceman does this during dancing with girl
+		// FIXME: Changed this to warning, because iceman does this during dancing with girl.
+		// Investigate why that is so and either fix the underlying issue or implement a more
+		// specialized workaround!
 		warning("[VM] Error: Attempt to add %d to pointer %04x:%04x, type %d: Pointer arithmetics of this type unsupported", offset, PRINT_REG(base), mobj->getType());
 		return NULL_REG;
 
 	}
 }
 
+static void callKernelFunc(EngineState *s, int kernelFuncNum, int argc) {
+
+	if (kernelFuncNum >= (int)s->_kernel->_kernelFuncs.size())
+		error("Invalid kernel function 0x%x requested", kernelFuncNum);
+
+	const KernelFuncWithSignature &kernelFunc = s->_kernel->_kernelFuncs[kernelFuncNum];
+
+	if (kernelFunc.signature
+			&& !kernel_matches_signature(s->_segMan, kernelFunc.signature, argc, scriptState.xs->sp + 1)) {
+		error("[VM] Invalid arguments to kernel call %x", kernelFuncNum);
+	}
+
+	reg_t *argv = scriptState.xs->sp + 1;
+
+	if (!kernelFunc.isDummy) {
+		// Add stack frame to indicate we're executing a callk.
+		// This is useful in debugger backtraces if this
+		// kernel function calls a script itself.
+		ExecStack *xstack;
+		xstack = add_exec_stack_entry(s->_executionStack, NULL_REG, NULL, NULL_REG, argc, argv - 1, 0, NULL_REG,
+				  s->_executionStack.size()-1, SCI_XS_CALLEE_LOCALS);
+		xstack->selector = kernelFuncNum;
+		xstack->type = EXEC_STACK_TYPE_KERNEL;
+
+		//warning("callk %s", kernelFunc.orig_name.c_str());
+
+		// TODO: SCI2/SCI2.1+ equivalent, once saving/loading works in SCI2/SCI2.1+
+		if (g_loadFromLauncher >= 0 && kernelFuncNum == 0x8) {
+			// A game is being loaded from the launcher, and kDisplay is called, all initialization has taken
+			// place (i.e. menus have been constructed etc). Therefore, inject a kRestoreGame call
+			// here, instead of the requested function.
+			int saveSlot = g_loadFromLauncher;
+			g_loadFromLauncher = -1;	// invalidate slot, so that we don't load again
+
+			if (saveSlot < 0)
+				error("Requested to load invalid save slot");	// should never happen, really
+
+			reg_t restoreArgv[2] = { NULL_REG, make_reg(0, saveSlot) };	// special call (argv[0] is NULL)
+			kRestoreGame(s, 2, restoreArgv);
+		} else {
+			// Call kernel function
+			s->r_acc = kernelFunc.fun(s, argc, argv);
+		}
+
+		// Remove callk stack frame again
+		s->_executionStack.pop_back();
+	} else {
+		Common::String warningMsg = "Dummy function " + kernelFunc.orig_name +
+									Common::String::printf("[0x%x]", kernelFuncNum) +
+									" invoked - ignoring. Params: " +
+									Common::String::printf("%d", argc) + " (";
+
+		for (int i = 0; i < argc; i++) {
+			warningMsg +=  Common::String::printf("%04x:%04x", PRINT_REG(argv[i]));
+			warningMsg += (i == argc - 1 ? ")" : ", ");
+		}
+
+		warning("%s", warningMsg.c_str());
+	}
+}
+
 static void gc_countdown(EngineState *s) {
 	if (s->gc_countdown-- <= 0) {
 		// Only run garbage collection when execution stack base
@@ -1078,77 +1141,21 @@
 				s->restAdjust = 0; // We just used up the scriptState.restAdjust, remember?
 			}
 
-			if (opparams[0] >= (int)s->_kernel->_kernelFuncs.size()) {
-				error("Invalid kernel function 0x%x requested", opparams[0]);
-			} else {
-				const KernelFuncWithSignature &kfun = s->_kernel->_kernelFuncs[opparams[0]];
-				int argc = validate_arithmetic(scriptState.xs->sp[0]);
+			int argc = validate_arithmetic(scriptState.xs->sp[0]);
 
-				if (!oldScriptHeader)
-					argc += scriptState.restAdjust;
+			if (!oldScriptHeader)
+				argc += scriptState.restAdjust;
 
-				if (kfun.signature
-						&& !kernel_matches_signature(s->_segMan, kfun.signature, argc, scriptState.xs->sp + 1)) {
-					error("[VM] Invalid arguments to kernel call %x", opparams[0]);
-				} else {
-					reg_t *argv = scriptState.xs->sp + 1;
+			callKernelFunc(s, opparams[0], argc);
 
-					if (!kfun.isDummy) {
-						// Add stack frame to indicate we're executing a callk.
-						// This is useful in debugger backtraces if this
-						// kernel function calls a script itself.
-						ExecStack *xstack;
-						xstack = add_exec_stack_entry(s->_executionStack, NULL_REG, NULL, NULL_REG, argc, argv - 1, 0, NULL_REG,
-	                              s->_executionStack.size()-1, SCI_XS_CALLEE_LOCALS);
-						xstack->selector = opparams[0];
-						xstack->type = EXEC_STACK_TYPE_KERNEL;
+			if (!oldScriptHeader)
+				scriptState.restAdjust = s->restAdjust;
 
-						//warning("callk %s", kfun.orig_name.c_str());
+			// Calculate xs again: The kernel function might
+			// have spawned a new VM
 
-						// TODO: SCI2/SCI2.1+ equivalent, once saving/loading works in SCI2/SCI2.1+
-						if (g_loadFromLauncher >= 0 && opparams[0] == 0x8) {
-							// A game is being loaded from the launcher, and kDisplay is called, all initialization has taken
-							// place (i.e. menus have been constructed etc). Therefore, inject a kRestoreGame call
-							// here, instead of the requested function.
-							int saveSlot = g_loadFromLauncher;
-							g_loadFromLauncher = -1;	// invalidate slot, so that we don't load again
-
-							if (saveSlot < 0)
-								error("Requested to load invalid save slot");	// should never happen, really
-
-							reg_t restoreArgv[2] = { NULL_REG, make_reg(0, saveSlot) };	// special call (argv[0] is NULL)
-							kRestoreGame(s, 2, restoreArgv);
-						} else {
-							// Call kernel function
-							s->r_acc = kfun.fun(s, argc, argv);
-						}
-
-						// Remove callk stack frame again
-						s->_executionStack.pop_back();
-					} else {
-						Common::String warningMsg = "Dummy function " + kfun.orig_name +
-													Common::String::printf("[0x%x]", opparams[0]) +
-													" invoked - ignoring. Params: " +
-													Common::String::printf("%d", argc) + " (";
-
-						for (int i = 0; i < argc; i++) {
-							warningMsg +=  Common::String::printf("%04x:%04x", PRINT_REG(argv[i]));
-							warningMsg += (i == argc - 1 ? ")" : ", ");
-						}
-
-						warning("%s", warningMsg.c_str());
-					}
-				}
-
-				// Calculate xs again: The kernel function might
-				// have spawned a new VM
-
-				xs_new = &(s->_executionStack.back());
-				s->_executionStackPosChanged = true;
-
-				if (!oldScriptHeader)
-					scriptState.restAdjust = s->restAdjust;
-			}
+			xs_new = &(s->_executionStack.back());
+			s->_executionStackPosChanged = true;
 			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