aboutsummaryrefslogtreecommitdiff
path: root/engines/sci/engine/kernel.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/sci/engine/kernel.cpp')
-rw-r--r--engines/sci/engine/kernel.cpp67
1 files changed, 61 insertions, 6 deletions
diff --git a/engines/sci/engine/kernel.cpp b/engines/sci/engine/kernel.cpp
index 2fb1452fa2..0fd21671a0 100644
--- a/engines/sci/engine/kernel.cpp
+++ b/engines/sci/engine/kernel.cpp
@@ -199,6 +199,41 @@ static const char *s_defaultKernelNames[] = {
/*0x88*/ "Dummy" // DbugStr
};
+reg_t kStub(EngineState *s, int argc, reg_t *argv) {
+ Kernel *kernel = g_sci->getKernel();
+ int kernelCallNr = -1;
+
+ Common::List<ExecStack>::iterator callIterator = s->_executionStack.end();
+ if (callIterator != s->_executionStack.begin()) {
+ callIterator--;
+ ExecStack lastCall = *callIterator;
+ kernelCallNr = lastCall.debugSelector;
+ }
+
+ Common::String warningMsg = "Dummy function k" + kernel->getKernelName(kernelCallNr) +
+ Common::String::printf("[%x]", kernelCallNr) +
+ " invoked. 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());
+ return s->r_acc;
+}
+
+reg_t kStubNull(EngineState *s, int argc, reg_t *argv) {
+ kStub(s, argc, argv);
+ return NULL_REG;
+}
+
+reg_t kDummy(EngineState *s, int argc, reg_t *argv) {
+ kStub(s, argc, argv);
+ error("Kernel function was called, which was considered to be unused - see log for details");
+}
+
// [io] -> either integer or object
// (io) -> optionally integer AND an object
// (i) -> optional integer
@@ -308,6 +343,26 @@ static const SciKernelMapSubEntry kDoSound_subops[] = {
SCI_SUBOPENTRY_TERMINATOR
};
+static const SciKernelMapSubEntry kGraph_subops[] = {
+ { SIG_SCI32, 1, MAP_CALL(StubNull), "", NULL }, // called by gk1 sci32 right at the start
+ { SIG_SCIALL, 2, MAP_CALL(GraphGetColorCount), "", NULL },
+ // 3 - set palette via resource
+ { SIG_SCIALL, 4, MAP_CALL(GraphDrawLine), "iiiii(i)(i)", NULL },
+ // 5 - nop
+ // 6 - draw pattern
+ { SIG_SCIALL, 7, MAP_CALL(GraphSaveBox), "iiiii", NULL },
+ { SIG_SCIALL, 8, MAP_CALL(GraphRestoreBox), "[r0!]", NULL },
+ // ^ this may get called with invalid references, we check them within restoreBits() and sierra sci behaves the same
+ { SIG_SCIALL, 9, MAP_CALL(GraphFillBoxBackground), "iiii", NULL },
+ { SIG_SCIALL, 10, MAP_CALL(GraphFillBoxForeground), "iiii", NULL },
+ { SIG_SCIALL, 11, MAP_CALL(GraphFillBoxAny), "iiiiii(i)(i)", NULL },
+ { SIG_SCIALL, 12, MAP_CALL(GraphUpdateBox), "iiii(i)(r)", NULL },
+ { SIG_SCIALL, 13, MAP_CALL(GraphRedrawBox), "iiii", NULL },
+ { SIG_SCIALL, 14, MAP_CALL(GraphAdjustPriority), "ii", NULL },
+ { SIG_SCI11, 15, MAP_CALL(GraphSaveUpscaledHiresBox), "iiii", NULL }, // kq6 hires
+ SCI_SUBOPENTRY_TERMINATOR
+};
+
static const SciKernelMapSubEntry kPalVary_subops[] = {
{ SIG_SCIALL, 0, MAP_CALL(PalVaryInit), "ii(i)(i)", NULL },
{ SIG_SCIALL, 1, MAP_CALL(PalVaryReverse), "(i)(i)(i)", NULL },
@@ -372,6 +427,7 @@ static SciKernelMapEntry s_kernelMap[] = {
{ MAP_CALL(DeviceInfo), SIG_EVERYWHERE, "i(r)(r)(i)", NULL, NULL }, // subop
{ MAP_CALL(Display), SIG_EVERYWHERE, "[ir]([ir!]*)", NULL, NULL },
// ^ we allow invalid references here, because kDisplay gets called with those in e.g. pq3 during intro
+ // restoreBits() checks and skips invalid handles, so that's fine. Sierra SCI behaved the same
{ MAP_CALL(DirLoop), SIG_EVERYWHERE, "oi", NULL, NULL },
{ MAP_CALL(DisposeClone), SIG_EVERYWHERE, "o", NULL, NULL },
{ MAP_CALL(DisposeList), SIG_EVERYWHERE, "l", NULL, NULL },
@@ -417,9 +473,7 @@ static SciKernelMapEntry s_kernelMap[] = {
{ MAP_CALL(GetTime), SIG_EVERYWHERE, "(i)", NULL, NULL },
{ MAP_CALL(GlobalToLocal), SIG_SCI32, SIGFOR_ALL, "oo", NULL, NULL },
{ MAP_CALL(GlobalToLocal), SIG_EVERYWHERE, "o", NULL, NULL },
- { MAP_CALL(Graph), SIG_EVERYWHERE, "i([!.]*)", NULL, NULL }, // subop
- // ^^ we allow invalid references here, because kGraph(restoreBox) gets called with old non-existant handles often
- // this should get limited to this call only as soon as subop signatures are available
+ { MAP_CALL(Graph), SIG_EVERYWHERE, "i([!.]*)", kGraph_subops, NULL },
{ MAP_CALL(HaveMouse), SIG_EVERYWHERE, "", NULL, NULL },
{ MAP_CALL(HiliteControl), SIG_EVERYWHERE, "o", NULL, NULL },
{ MAP_CALL(InitBresen), SIG_EVERYWHERE, "o(i)", NULL, NULL },
@@ -1032,7 +1086,6 @@ void Kernel::mapFunctions() {
_kernelFuncs[id].function = NULL;
_kernelFuncs[id].signature = NULL;
_kernelFuncs[id].name = NULL;
- _kernelFuncs[id].isDummy = true;
_kernelFuncs[id].workarounds = NULL;
_kernelFuncs[id].subFunctions = NULL;
_kernelFuncs[id].subFunctionCount = 0;
@@ -1044,8 +1097,10 @@ void Kernel::mapFunctions() {
}
// Don't map dummy functions - they will never be called
- if (kernelName == "Dummy")
+ if (kernelName == "Dummy") {
+ _kernelFuncs[id].function = kDummy;
continue;
+ }
// If the name is known, look it up in s_kernelMap. This table
// maps kernel func names to actual function (pointers).
@@ -1068,7 +1123,6 @@ void Kernel::mapFunctions() {
_kernelFuncs[id].name = kernelMap->name;
_kernelFuncs[id].signature = parseKernelSignature(kernelMap->name, kernelMap->signature);
_kernelFuncs[id].workarounds = kernelMap->workarounds;
- _kernelFuncs[id].isDummy = false;
if (kernelMap->subFunctions) {
// Get version for subfunction identification
SciVersion mySubVersion = (SciVersion)kernelMap->function(NULL, 0, NULL).offset;
@@ -1129,6 +1183,7 @@ void Kernel::mapFunctions() {
error("k%s[%x]: not found for this version/platform", kernelName.c_str(), id);
// No match but a name was given -> stub
warning("k%s[%x]: unmapped", kernelName.c_str(), id);
+ _kernelFuncs[id].function = kStub;
}
} // for all functions requesting to be mapped