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.cpp83
1 files changed, 54 insertions, 29 deletions
diff --git a/engines/sci/engine/kernel.cpp b/engines/sci/engine/kernel.cpp
index 2b16bb3d99..d764a88a0a 100644
--- a/engines/sci/engine/kernel.cpp
+++ b/engines/sci/engine/kernel.cpp
@@ -35,6 +35,9 @@ namespace Sci {
Kernel::Kernel(ResourceManager *resMan, SegManager *segMan)
: _resMan(resMan), _segMan(segMan), _invalid("<invalid>") {
+#ifdef ENABLE_SCI32
+ _kernelFunc_StringId = 0;
+#endif
}
Kernel::~Kernel() {
@@ -81,13 +84,19 @@ uint Kernel::getKernelNamesSize() const {
}
const Common::String &Kernel::getKernelName(uint number) const {
- // FIXME: The following check is a temporary workaround for an issue
- // leading to crashes when using the debugger's backtrace command.
- if (number >= _kernelNames.size())
- return _invalid;
+ assert(number < _kernelFuncs.size());
return _kernelNames[number];
}
+Common::String Kernel::getKernelName(uint number, uint subFunction) const {
+ assert(number < _kernelFuncs.size());
+ const KernelFunction &kernelCall = _kernelFuncs[number];
+
+ assert(subFunction < kernelCall.subFunctionCount);
+ return kernelCall.subFunctions[subFunction].name;
+}
+
+
int Kernel::findKernelFuncPos(Common::String kernelFuncName) {
for (uint32 i = 0; i < _kernelNames.size(); i++)
if (_kernelNames[i] == kernelFuncName)
@@ -118,7 +127,7 @@ void Kernel::loadSelectorNames() {
// Starting with KQ7, Mac versions have a BE name table. GK1 Mac and earlier (and all
// other platforms) always use LE.
- bool isBE = (g_sci->getPlatform() == Common::kPlatformMacintosh && getSciVersion() >= SCI_VERSION_2_1
+ bool isBE = (g_sci->getPlatform() == Common::kPlatformMacintosh && getSciVersion() >= SCI_VERSION_2_1_EARLY
&& g_sci->getGameId() != GID_GK1);
if (!r) { // No such resource?
@@ -399,6 +408,7 @@ uint16 Kernel::findRegType(reg_t reg) {
#ifdef ENABLE_SCI32
case SEG_TYPE_ARRAY:
case SEG_TYPE_STRING:
+ case SEG_TYPE_BITMAP:
#endif
result |= SIG_TYPE_REFERENCE;
break;
@@ -432,57 +442,66 @@ static const SignatureDebugType signatureDebugTypeList[] = {
{ 0, NULL }
};
-static void kernelSignatureDebugType(const uint16 type) {
+static void kernelSignatureDebugType(Common::String &signatureDetailsStr, const uint16 type) {
bool firstPrint = true;
const SignatureDebugType *list = signatureDebugTypeList;
while (list->typeCheck) {
if (type & list->typeCheck) {
if (!firstPrint)
- debugN(", ");
- debugN("%s", list->text);
+// debugN(", ");
+ signatureDetailsStr += ", ";
+// debugN("%s", list->text);
+// signatureDetailsStr += signatureDetailsStr.format("%s", list->text);
+ signatureDetailsStr += list->text;
firstPrint = false;
}
list++;
}
}
-// Shows kernel call signature and current arguments for debugging purposes
-void Kernel::signatureDebug(const uint16 *sig, int argc, const reg_t *argv) {
+// Create string, that holds the details of a kernel call signature and current arguments
+// For debugging purposes
+void Kernel::signatureDebug(Common::String &signatureDetailsStr, const uint16 *sig, int argc, const reg_t *argv) {
int argnr = 0;
+
+ // add ERROR: to debug output
+ debugN("ERROR:");
+
while (*sig || argc) {
- debugN("parameter %d: ", argnr++);
+ // add leading spaces for additional parameters
+ signatureDetailsStr += signatureDetailsStr.format("parameter %d: ", argnr++);
if (argc) {
reg_t parameter = *argv;
- debugN("%04x:%04x (", PRINT_REG(parameter));
+ signatureDetailsStr += signatureDetailsStr.format("%04x:%04x (", PRINT_REG(parameter));
int regType = findRegType(parameter);
if (regType)
- kernelSignatureDebugType(regType);
+ kernelSignatureDebugType(signatureDetailsStr, regType);
else
- debugN("unknown type of %04x:%04x", PRINT_REG(parameter));
- debugN(")");
+ signatureDetailsStr += signatureDetailsStr.format("unknown type of %04x:%04x", PRINT_REG(parameter));
+ signatureDetailsStr += ")";
argv++;
argc--;
} else {
- debugN("not passed");
+ signatureDetailsStr += "not passed";
}
if (*sig) {
const uint16 signature = *sig;
if ((signature & SIG_MAYBE_ANY) == SIG_MAYBE_ANY) {
- debugN(", may be any");
+ signatureDetailsStr += ", may be any";
} else {
- debugN(", should be ");
- kernelSignatureDebugType(signature);
+ signatureDetailsStr += ", should be ";
+ kernelSignatureDebugType(signatureDetailsStr, signature);
}
if (signature & SIG_IS_OPTIONAL)
- debugN(" (optional)");
+ signatureDetailsStr += " (optional)";
if (signature & SIG_NEEDS_MORE)
- debugN(" (needs more)");
+ signatureDetailsStr += " (needs more)";
if (signature & SIG_MORE_MAY_FOLLOW)
- debugN(" (more may follow)");
+ signatureDetailsStr += " (more may follow)";
sig++;
}
- debugN("\n");
+ signatureDetailsStr += "\n";
}
}
@@ -594,6 +613,10 @@ void Kernel::mapFunctions() {
}
#ifdef ENABLE_SCI32
+ if (kernelName == "String") {
+ _kernelFunc_StringId = id;
+ }
+
// HACK: Phantasmagoria Mac uses a modified kDoSound (which *nothing*
// else seems to use)!
if (g_sci->getPlatform() == Common::kPlatformMacintosh && g_sci->getGameId() == GID_PHANTASMAGORIA && kernelName == "DoSound") {
@@ -833,11 +856,11 @@ void Kernel::loadKernelNames(GameFeatures *features) {
// In the Windows version of KQ6 CD, the empty kSetSynonyms
// function has been replaced with kPortrait. In KQ6 Mac,
// kPlayBack has been replaced by kShowMovie.
- if (g_sci->getPlatform() == Common::kPlatformWindows)
+ if ((g_sci->getPlatform() == Common::kPlatformWindows) || (g_sci->forceHiresGraphics()))
_kernelNames[0x26] = "Portrait";
else if (g_sci->getPlatform() == Common::kPlatformMacintosh)
_kernelNames[0x84] = "ShowMovie";
- } else if (g_sci->getGameId() == GID_QFG4 && g_sci->isDemo()) {
+ } else if (g_sci->getGameId() == GID_QFG4DEMO) {
_kernelNames[0x7b] = "RemapColors"; // QFG4 Demo has this SCI2 function instead of StrSplit
}
@@ -854,15 +877,17 @@ void Kernel::loadKernelNames(GameFeatures *features) {
_kernelNames = Common::StringArray(sci2_default_knames, kKernelEntriesSci2);
break;
- case SCI_VERSION_2_1:
+ case SCI_VERSION_2_1_EARLY:
+ case SCI_VERSION_2_1_MIDDLE:
+ case SCI_VERSION_2_1_LATE:
if (features->detectSci21KernelType() == SCI_VERSION_2) {
// Some early SCI2.1 games use a modified SCI2 kernel table instead of
// the SCI2.1 kernel table. We detect which version to use based on
// how kDoSound is called from Sound::play().
// Known games that use this:
// GK2 demo
- // KQ7 1.4
- // PQ4 SWAT demo
+ // KQ7 1.4/1.51
+ // PQ:SWAT demo
// LSL6
// PQ4CD
// QFG4CD
@@ -873,7 +898,7 @@ void Kernel::loadKernelNames(GameFeatures *features) {
_kernelNames = Common::StringArray(sci2_default_knames, kKernelEntriesGk2Demo);
// OnMe is IsOnMe here, but they should be compatible
- _kernelNames[0x23] = "Robot"; // Graph in SCI2
+ _kernelNames[0x23] = g_sci->getGameId() == GID_LSL6HIRES ? "Empty" : "Robot"; // Graph in SCI2
_kernelNames[0x2e] = "Priority"; // DisposeTextBitmap in SCI2
} else {
// Normal SCI2.1 kernel table