aboutsummaryrefslogtreecommitdiff
path: root/engines/sci
diff options
context:
space:
mode:
Diffstat (limited to 'engines/sci')
-rw-r--r--engines/sci/engine/kernel.cpp5
-rw-r--r--engines/sci/engine/kernel_tables.h2
-rw-r--r--engines/sci/engine/script_patches.cpp40
3 files changed, 46 insertions, 1 deletions
diff --git a/engines/sci/engine/kernel.cpp b/engines/sci/engine/kernel.cpp
index 1845ecaac5..c7732c6b15 100644
--- a/engines/sci/engine/kernel.cpp
+++ b/engines/sci/engine/kernel.cpp
@@ -905,6 +905,11 @@ void Kernel::loadKernelNames(GameFeatures *features) {
} else {
// Normal SCI2.1 kernel table
_kernelNames = Common::StringArray(sci21_default_knames, kKernelEntriesSci21);
+
+ // Used by script patcher to remove CPU spinning on kGetTime
+ if (g_sci->getGameId() == GID_HOYLE5) {
+ _kernelNames[0x4f] = "Wait";
+ }
}
break;
diff --git a/engines/sci/engine/kernel_tables.h b/engines/sci/engine/kernel_tables.h
index ac4987e603..741f46e02c 100644
--- a/engines/sci/engine/kernel_tables.h
+++ b/engines/sci/engine/kernel_tables.h
@@ -1408,7 +1408,7 @@ static const char *const sci21_default_knames[] = {
/*0x4c*/ "ScrollWindow", // Dummy in SCI3
/*0x4d*/ "Dummy",
/*0x4e*/ "Dummy",
- /*0x4f*/ "Dummy",
+ /*0x4f*/ "Dummy", // Replaced with kWait for Hoyle5 in ScummVM
/*0x50*/ "GetEvent",
/*0x51*/ "GlobalToLocal",
/*0x52*/ "LocalToGlobal",
diff --git a/engines/sci/engine/script_patches.cpp b/engines/sci/engine/script_patches.cpp
index b2d66d0170..968d72747a 100644
--- a/engines/sci/engine/script_patches.cpp
+++ b/engines/sci/engine/script_patches.cpp
@@ -699,6 +699,43 @@ static const SciScriptPatcherEntry freddypharkasSignatures[] = {
#ifdef ENABLE_SCI32
#pragma mark -
+#pragma mark Hoyle 5
+
+// Several scripts in Hoyle5 contain a subroutine which spins on kGetTime until
+// a certain number of ticks elapse. Since this wastes CPU and makes ScummVM
+// unresponsive, the kWait kernel function (which was removed in SCI2) is
+// reintroduced at 0x4f in kernel.cpp only for Hoyle5, and the spin subroutines
+// are patched here to call that function instead.
+// Applies to at least: English Demo
+static const uint16 hoyle5SignatureSpinLoop[] = {
+ SIG_MAGICDWORD,
+ 0x76, // push0
+ 0x43, 0x79, SIG_UINT16(0x00), // callk GetTime, $0
+ 0x36, // push
+ 0x87, 0x01, // lap param[1]
+ 0x02, // add
+ 0xa5, 0x00, // sat temp[0]
+ SIG_END
+};
+
+static const uint16 hoyle5PatchSpinLoop[] = {
+ 0x78, // push1
+ 0x8f, 0x01, // lsp param[1]
+ 0x43, 0x4f, PATCH_UINT16(0x02), // callk Wait, $2
+ 0x48, // ret
+ PATCH_END
+};
+
+// script, description, signature patch
+static const SciScriptPatcherEntry hoyle5Signatures[] = {
+ { true, 3, "remove kGetTime spin", 1, hoyle5SignatureSpinLoop, hoyle5PatchSpinLoop },
+ { true, 23, "remove kGetTime spin", 1, hoyle5SignatureSpinLoop, hoyle5PatchSpinLoop },
+ { true, 500, "remove kGetTime spin", 1, hoyle5SignatureSpinLoop, hoyle5PatchSpinLoop },
+ { true, 64937, "remove kGetTime spin", 1, hoyle5SignatureSpinLoop, hoyle5PatchSpinLoop },
+ SCI_SIGNATUREENTRY_TERMINATOR
+};
+
+#pragma mark -
#pragma mark Gabriel Knight 1
// ===========================================================================
@@ -5170,6 +5207,9 @@ void ScriptPatcher::processScript(uint16 scriptNr, byte *scriptData, const uint3
signatureTable = freddypharkasSignatures;
break;
#ifdef ENABLE_SCI32
+ case GID_HOYLE5:
+ signatureTable = hoyle5Signatures;
+ break;
case GID_GK1:
signatureTable = gk1Signatures;
break;