diff options
author | Colin Snover | 2017-01-10 12:33:21 -0600 |
---|---|---|
committer | Colin Snover | 2017-01-16 12:16:12 -0600 |
commit | 0744dc4109acd6ca433d3da492b9a1f02bd38a81 (patch) | |
tree | be6672e5a2ebbf5ec920d463ceca7369ebe9cc09 /engines/sci | |
parent | 60867811ccc6d0b7d0e5dbb4ad92883a9a59657c (diff) | |
download | scummvm-rg350-0744dc4109acd6ca433d3da492b9a1f02bd38a81.tar.gz scummvm-rg350-0744dc4109acd6ca433d3da492b9a1f02bd38a81.tar.bz2 scummvm-rg350-0744dc4109acd6ca433d3da492b9a1f02bd38a81.zip |
SCI32: Fix spinloop in Hoyle5
Hoyle5 will spin on kGetTime between 15 and 300 ticks in multiple
game scripts in order to delay execution (for example, after
choosing opponents and clicking "okay"). This causes ScummVM to
be unresponsive and wastes CPU time.
This commit patches the spin subroutines to instead call a kernel
function (kWait) that waits without a spin loop. This kernel
function was removed in SCI2, and has been added back in ScummVM
specifically for Hoyle5, so this patch will not work with the
original interpreter.
Diffstat (limited to 'engines/sci')
-rw-r--r-- | engines/sci/engine/kernel.cpp | 5 | ||||
-rw-r--r-- | engines/sci/engine/kernel_tables.h | 2 | ||||
-rw-r--r-- | engines/sci/engine/script_patches.cpp | 40 |
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; |