diff options
author | Martin Kiewitz | 2010-07-09 12:06:41 +0000 |
---|---|---|
committer | Martin Kiewitz | 2010-07-09 12:06:41 +0000 |
commit | ba776fb2934c7124e969d54e559c5136f5a2fc73 (patch) | |
tree | 1df751f02bbf8c55ad9f87931a2aae5b44650fca /engines/sci/engine/vm.cpp | |
parent | 9117eec6a72c9dc4abb72ca45ecebbfb7ee04bfc (diff) | |
download | scummvm-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.cpp | 28 |
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 |