aboutsummaryrefslogtreecommitdiff
path: root/engines/sci/engine/vm.cpp
diff options
context:
space:
mode:
authorMartin Kiewitz2010-07-09 12:06:41 +0000
committerMartin Kiewitz2010-07-09 12:06:41 +0000
commitba776fb2934c7124e969d54e559c5136f5a2fc73 (patch)
tree1df751f02bbf8c55ad9f87931a2aae5b44650fca /engines/sci/engine/vm.cpp
parent9117eec6a72c9dc4abb72ca45ecebbfb7ee04bfc (diff)
downloadscummvm-rg350-ba776fb2934c7124e969d54e559c5136f5a2fc73.tar.gz
scummvm-rg350-ba776fb2934c7124e969d54e559c5136f5a2fc73.tar.bz2
scummvm-rg350-ba776fb2934c7124e969d54e559c5136f5a2fc73.zip
SCI: implemented subsignatures for kDoSound
svn-id: r50755
Diffstat (limited to 'engines/sci/engine/vm.cpp')
-rw-r--r--engines/sci/engine/vm.cpp28
1 files changed, 23 insertions, 5 deletions
diff --git a/engines/sci/engine/vm.cpp b/engines/sci/engine/vm.cpp
index 6973694ea9..a0f38c634c 100644
--- a/engines/sci/engine/vm.cpp
+++ b/engines/sci/engine/vm.cpp
@@ -787,16 +787,17 @@ static void callKernelFunc(EngineState *s, int kernelFuncNr, int argc) {
error("Invalid kernel function 0x%x requested", kernelFuncNr);
const KernelFunction &kernelCall = kernel->_kernelFuncs[kernelFuncNr];
+ reg_t *argv = s->xs->sp + 1;
if (kernelCall.signature
- && !kernel->signatureMatch(kernelCall.signature, argc, s->xs->sp + 1)) {
+ && !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) {
- kernel->signatureDebug(kernelCall.signature, argc, s->xs->sp + 1);
+ kernel->signatureDebug(kernelCall.signature, argc, argv);
error("[VM] k%s (%x) signature mismatch via method %s::%s (script %d, localCall %x)", kernel->getKernelName(kernelFuncNr).c_str(), kernelFuncNr, 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.
@@ -804,8 +805,6 @@ static void callKernelFunc(EngineState *s, int kernelFuncNr, int argc) {
return;
}
- reg_t *argv = s->xs->sp + 1;
-
if (!kernelCall.isDummy) {
// Add stack frame to indicate we're executing a callk.
// This is useful in debugger backtraces if this
@@ -817,7 +816,26 @@ static void callKernelFunc(EngineState *s, int kernelFuncNr, int argc) {
xstack->type = EXEC_STACK_TYPE_KERNEL;
// Call kernel function
- s->r_acc = kernelCall.function(s, argc, argv);
+ if (!kernelCall.subFunctionCount) {
+ s->r_acc = kernelCall.function(s, argc, argv);
+ } else {
+ // Sub-functions available, check signature and call that one directly
+ if (argc < 1)
+ error("[VM] k%s: no subfunction-id parameter given");
+ const uint16 subId = argv[0].toUint16();
+ // Skip over subfunction-id
+ argc--;
+ argv++;
+ if (subId >= kernelCall.subFunctionCount)
+ error("[VM] k%s: subfunction-id %d requested, but not available", kernelCall.origName, subId);
+ 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);
+ }
+ s->r_acc = kernelSubCall.function(s, argc, argv);
+ }
#if 0
// Used for debugging