[Scummvm-git-logs] scummvm master -> 27195a1b0aa9ed600618b0ab437b3cbac622c8f4

sluicebox 22204938+sluicebox at users.noreply.github.com
Tue Oct 19 13:46:47 UTC 2021


This automated email contains information about 3 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
388f3a02ef SCI32: Create kScummVMSleep for script patches
ff11be91c3 SCI32; Improve KQ7 cursor script patch
27195a1b0a SCI32: Fix GK2 "bad" cursor not appearing


Commit: 388f3a02ef93a83e85cef28237c6d93eb0b3a04c
    https://github.com/scummvm/scummvm/commit/388f3a02ef93a83e85cef28237c6d93eb0b3a04c
Author: sluicebox (22204938+sluicebox at users.noreply.github.com)
Date: 2021-10-19T08:40:33-05:00

Commit Message:
SCI32: Create kScummVMSleep for script patches

We have several SCI32 script patches that replace kGetTime spin loops
with calls to kWait for the intended delay. This prevents blocking
the main thread and allows ScummVM to be responsive and update the
screen. But kWait isn't a simple sleep, it's a throttling function,
and the duration that it sleeps (if any) is determined by the time
since it was last called. kWait was only in SCI16 interpreters so it
had to be restored to SCI32 and this required a further workaround
for Phant2 compatibility.

Now we have a dedicated custom kernel function, kScummVMSleep, which
does a simple sleep so that SCI32 script patch delays are consistent
and the Phant2 workaround isn't needed. This approach is similar to
kScummVMSaveLoad.

Changed paths:
    engines/sci/engine/guest_additions.cpp
    engines/sci/engine/kernel.cpp
    engines/sci/engine/kernel.h
    engines/sci/engine/kernel_tables.h
    engines/sci/engine/kgraphics.cpp
    engines/sci/engine/script_patches.cpp


diff --git a/engines/sci/engine/guest_additions.cpp b/engines/sci/engine/guest_additions.cpp
index 49ba1a9187..2c4e67d7d0 100644
--- a/engines/sci/engine/guest_additions.cpp
+++ b/engines/sci/engine/guest_additions.cpp
@@ -292,15 +292,6 @@ bool GuestAdditions::kWaitHook() const {
 		return false;
 	}
 
-	// kWait cannot be used in Phant2 for delayed restore because it is
-	// called during the fade-in of music in the intro room, before graphics
-	// are fully initialized, which causes "Click to continue" text to be
-	// brokenly drawn over the game and then crashes the engine on the next
-	// room transition
-	if (g_sci->getGameId() == GID_PHANTASMAGORIA2) {
-		return false;
-	}
-
 	return g_sci->_guestAdditions->restoreFromLauncher();
 }
 
diff --git a/engines/sci/engine/kernel.cpp b/engines/sci/engine/kernel.cpp
index b199a9946a..f4d12c0a9f 100644
--- a/engines/sci/engine/kernel.cpp
+++ b/engines/sci/engine/kernel.cpp
@@ -865,9 +865,8 @@ void Kernel::loadKernelNames(GameFeatures *features) {
 			_kernelNames[id] = "Dummy";
 		}
 
-		// Used by Hoyle5 script patches to remove CPU spinning on kGetTime
-		// (this repurposes the existing SCI16 kWait call that was removed in SCI32)
-		_kernelNames[kScummVMWaitId] = "Wait";
+		// Used by SCI32 script patches to remove CPU spinning on kGetTime
+		_kernelNames[kScummVMSleepId] = "ScummVMSleep";
 
 		// Used by GuestAdditions to support integrated save/load dialogue
 		_kernelNames[kScummVMSaveLoadId] = "ScummVMSaveLoad";
diff --git a/engines/sci/engine/kernel.h b/engines/sci/engine/kernel.h
index d64b719a85..5462c4be48 100644
--- a/engines/sci/engine/kernel.h
+++ b/engines/sci/engine/kernel.h
@@ -105,10 +105,13 @@ struct SciWorkaroundEntry;	// from workarounds.h
 
 // ---- Kernel signatures -----------------------------------------------------
 
+#ifdef ENABLE_SCI32
+// Kernel functions that have been added for ScummVM script patches to call
 enum {
-	kScummVMWaitId     = 0xe0,
-	kScummVMSaveLoadId = 0xe1
+	kScummVMSleepId    = 0xe0, // sleeps for a delay while remaining responsive
+	kScummVMSaveLoadId = 0xe1  // launches ScummVM's save/load dialog
 };
+#endif
 
 // internal kernel signature data
 enum {
@@ -496,7 +499,6 @@ reg_t kGetSaveFiles32(EngineState *s, int argc, reg_t *argv);
 reg_t kCheckSaveGame32(EngineState *s, int argc, reg_t *argv);
 reg_t kMakeSaveCatName(EngineState *s, int argc, reg_t *argv);
 reg_t kMakeSaveFileName(EngineState *s, int argc, reg_t *argv);
-reg_t kScummVMSaveLoad(EngineState *s, int argc, reg_t *argv);
 
 reg_t kSetHotRectangles(EngineState *s, int argc, reg_t *argv);
 reg_t kIsHiRes(EngineState *s, int argc, reg_t *argv);
@@ -668,6 +670,10 @@ reg_t kPlayDuckClose(EngineState *s, int argc, reg_t *argv);
 reg_t kPlayDuckSetVolume(EngineState *s, int argc, reg_t *argv);
 reg_t kWebConnect(EngineState *s, int argc, reg_t *argv);
 reg_t kWinExec(EngineState *s, int argc, reg_t *argv);
+
+// SCI32 custom ScummVM kernel functions
+reg_t kScummVMSleep(EngineState *s, int argc, reg_t *argv);
+reg_t kScummVMSaveLoad(EngineState *s, int argc, reg_t *argv);
 #endif
 
 reg_t kDoSoundInit(EngineState *s, int argc, reg_t *argv);
diff --git a/engines/sci/engine/kernel_tables.h b/engines/sci/engine/kernel_tables.h
index 8079ad11d3..9808179fec 100644
--- a/engines/sci/engine/kernel_tables.h
+++ b/engines/sci/engine/kernel_tables.h
@@ -833,6 +833,9 @@ static SciKernelMapEntry s_kernelMap[] = {
 #endif
 	{ MAP_CALL(Show),              SIG_EVERYWHERE,           "i",                     NULL,            NULL },
 	{ MAP_CALL(SinDiv),            SIG_EVERYWHERE,           "ii",                    NULL,            NULL },
+#ifdef ENABLE_SCI32
+	{ MAP_CALL(ScummVMSleep),      SIG_SCI32, SIGFOR_ALL,    "i",                     NULL,            NULL },
+#endif
 	{ MAP_CALL(Sort),              SIG_EVERYWHERE,           "ooo",                   NULL,            NULL },
 	{ MAP_CALL(Sqrt),              SIG_EVERYWHERE,           "i",                     NULL,            NULL },
 	{ MAP_CALL(StrAt),             SIG_EVERYWHERE,           "ri(i)",                 NULL,            kStrAt_workarounds },
@@ -855,7 +858,7 @@ static SciKernelMapEntry s_kernelMap[] = {
 	{ MAP_CALL(UnLoad),            SIG_EVERYWHERE,           "i[ir!]",                NULL,            kUnLoad_workarounds },
 	// ^ We allow invalid references here (e.g. bug #6600), since they will be invalidated anyway by the call itself
 	{ MAP_CALL(ValidPath),         SIG_EVERYWHERE,           "r",                     NULL,            NULL },
-	{ MAP_CALL(Wait),              SIG_EVERYWHERE,           "i",                     NULL,            NULL },
+	{ MAP_CALL(Wait),              SIG_SCI16, SIGFOR_ALL,    "i",                     NULL,            NULL },
 
 	// Unimplemented SCI0-SCI1.1 unused functions, always mapped to kDummy
 	{ MAP_DUMMY(InspectObj),      SIG_EVERYWHERE,           "(.*)",                  NULL,            NULL },
@@ -1445,7 +1448,7 @@ static const char *const sci21_default_knames[] = {
 	/*0x4c*/ "ScrollWindow",	// Dummy in SCI3
 	/*0x4d*/ "Dummy",
 	/*0x4e*/ "Dummy",
-	/*0x4f*/ "Dummy",           // Replaced with kWait for Hoyle5 in ScummVM
+	/*0x4f*/ "Dummy",
 	/*0x50*/ "GetEvent",
 	/*0x51*/ "GlobalToLocal",
 	/*0x52*/ "LocalToGlobal",
diff --git a/engines/sci/engine/kgraphics.cpp b/engines/sci/engine/kgraphics.cpp
index 2ed31016c6..e954afbc16 100644
--- a/engines/sci/engine/kgraphics.cpp
+++ b/engines/sci/engine/kgraphics.cpp
@@ -394,6 +394,9 @@ reg_t kTextSize(EngineState *s, int argc, reg_t *argv) {
 	return s->r_acc;
 }
 
+// kWait is a throttling function that sleeps up to the requested
+// number of ticks, or possibly not at all. The sleep duration
+// is based on the time since kWait was last called.
 reg_t kWait(EngineState *s, int argc, reg_t *argv) {
 	uint16 ticks = argv[0].toUint16();
 
@@ -407,6 +410,19 @@ reg_t kWait(EngineState *s, int argc, reg_t *argv) {
 	return make_reg(0, delta);
 }
 
+#ifdef ENABLE_SCI32
+// kScummVMSleep is our own custom kernel function that sleeps for
+// the number of ticks requested. We use this in SCI32 script patches
+// to replace spin loops so that the application remains responsive
+// and doesn't just block the thread without updating the screen or
+// processing input events.
+reg_t kScummVMSleep(EngineState *s, int argc, reg_t *argv) {
+	uint16 ticks = argv[0].toUint16();
+	s->sleep(ticks);
+	return s->r_acc;
+}
+#endif
+
 reg_t kCoordPri(EngineState *s, int argc, reg_t *argv) {
 	int16 y = argv[0].toSint16();
 
diff --git a/engines/sci/engine/script_patches.cpp b/engines/sci/engine/script_patches.cpp
index 2fa89a5d32..7408a26997 100644
--- a/engines/sci/engine/script_patches.cpp
+++ b/engines/sci/engine/script_patches.cpp
@@ -2181,10 +2181,9 @@ static const SciScriptPatcherEntry hoyle4Signatures[] = {
 
 // 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 for Hoyle5, and the spin subroutines are patched here to call
-// that function instead.
-// Applies to at least: English Demo
+// unresponsive, we replace this with a call to kScummVMSleep for the requested
+// number of ticks.
+// Applies to at least: English Demo, English PC, English Mac
 static const uint16 hoyle5SignatureSpinLoop[] = {
 	SIG_MAGICDWORD,
 	0x76,                         // push0
@@ -2199,7 +2198,7 @@ static const uint16 hoyle5SignatureSpinLoop[] = {
 static const uint16 hoyle5PatchSpinLoop[] = {
 	0x78,                                     // push1
 	0x8f, 0x01,                               // lsp param[1]
-	0x43, kScummVMWaitId, PATCH_UINT16(0x02), // callk Wait, $2
+	0x43, kScummVMSleepId, PATCH_UINT16(0x02),// callk ScummVMSleep, $2
 	0x48,                                     // ret
 	PATCH_END
 };
@@ -6579,7 +6578,7 @@ static const uint16 kq7BenchmarkPatch[] = {
 // maxes out the CPU for no reason, and keeps the engine from polling for
 // events (which may make the window appear nonresponsive to the OS).
 //
-// We replace the loop with a call to kWait().
+// We replace the loop with a call to kScummVMSleep.
 //
 // Applies to at least: KQ7 English 2.00b
 // Responsible method: KQ7CD::pragmaFail in script 0
@@ -6596,7 +6595,7 @@ static const uint16 kq7PragmaFailSpinSignature[] = {
 static const uint16 kq7PragmaFailSpinPatch[] = {
 	0x78,                                     // push1
 	0x39, 0x12,                               // pushi 18 (~300ms)
-	0x43, kScummVMWaitId, PATCH_UINT16(0x02), // callk Wait, 2
+	0x43, kScummVMSleepId, PATCH_UINT16(0x02),// callk ScummVMSleep, 2
 	0x33, 0x16,                               // jmp [to setCursor]
 	PATCH_END
 };
@@ -10287,7 +10286,7 @@ static const SciScriptPatcherEntry phantasmagoriaSignatures[] = {
 
 // The game uses a spin loop when navigating to and from Curtis's computer in
 // the office, and when entering passwords, which causes the mouse to appear
-// unresponsive. Replace the spin loop with a call to ScummVM kWait.
+// unresponsive. Replace the spin loop with a call to kScummVMSleep.
 // Applies to at least: US English
 // Responsible method: Script 3000 localproc 2ee4, script 63019 localproc 4f04
 static const uint16 phant2WaitParam1Signature[] = {
@@ -10302,7 +10301,7 @@ static const uint16 phant2WaitParam1Signature[] = {
 static const uint16 phant2WaitParam1Patch[] = {
 	0x78,                                     // push1
 	0x8f, 0x01,                               // lsp param[1]
-	0x43, kScummVMWaitId, PATCH_UINT16(0x02), // callk Wait, 2
+	0x43, kScummVMSleepId, PATCH_UINT16(0x02),// callk ScummVMSleep, 2
 	0x48,                                     // ret
 	PATCH_END
 };
@@ -10330,7 +10329,7 @@ static const uint16 phant2SlowIFadePatch[] = {
 
 // The game uses a spin loop during music transitions which causes the mouse to
 // appear unresponsive during scene changes. Replace the spin loop with a call
-// to ScummVM kWait.
+// to kScummVMSleep.
 // Applies to at least: US English
 // Responsible method: P2SongPlyr::wait4Fade
 static const uint16 phant2Wait4FadeSignature[] = {
@@ -10345,7 +10344,7 @@ static const uint16 phant2Wait4FadeSignature[] = {
 static const uint16 phant2Wait4FadePatch[] = {
 	0x78,                                     // push1
 	0x8d, 0x00,                               // lst temp[0]
-	0x43, kScummVMWaitId, PATCH_UINT16(0x02), // callk Wait, 2
+	0x43, kScummVMSleepId, PATCH_UINT16(0x02),// callk ScummVMSleep, 2
 	0x48,                                     // ret
 	PATCH_END
 };
@@ -10417,13 +10416,13 @@ static const uint16 phant2RatboyPatch[] = {
 	0x78,                                     // push1
 	0x35, 0x1e,                               // ldi $1e
 	0x36,                                     // push
-	0x43, kScummVMWaitId, PATCH_UINT16(0x02), // callk Wait, $2
+	0x43, kScummVMSleepId, PATCH_UINT16(0x02),// callk ScummVMSleep, $2
 	0x33, 0x14,                               // jmp [to next outer loop]
 	PATCH_END
 };
 
 // The game uses a spin loop during the floating head easter egg, which causes
-//  the mouse to appear unresponsive. Replace the inner loop with kWait.
+//  the mouse to appear unresponsive. Replace the inner loop with kScummVMSleep.
 //
 // Applies to at least: US English
 // Responsible method: bigScript:changeState
@@ -10441,7 +10440,7 @@ static const uint16 phant2FloatingHeadSignature[] = {
 static const uint16 phant2FloatingHeadPatch[] = {
 	0x78,                                     // push1
 	0x39, 0x3c,                               // pushi 3c [ 1 second ]
-	0x43, kScummVMWaitId, PATCH_UINT16(0x02), // callk Wait, 2
+	0x43, kScummVMSleepId, PATCH_UINT16(0x02),// callk ScummVMSleep, 2
 	0x33, 0x04,                               // jmp 04
 	PATCH_END
 };
@@ -10557,7 +10556,7 @@ static const uint16 phant2SlowScrollSignature[] = {
 static const uint16 phant2SlowScrollPatch[] = {
 	0x78,                                     // push1
 	0x39, 0x03,                               // pushi 3
-	0x43, kScummVMWaitId, PATCH_UINT16(0x02), // callk Wait, 2
+	0x43, kScummVMSleepId, PATCH_UINT16(0x02),// callk ScummVMSleep, 2
 	0x33, 0x13,                               // jmp [end of loop]
 	PATCH_END
 };


Commit: ff11be91c3c8809e417dc40e3e6c1940494b570e
    https://github.com/scummvm/scummvm/commit/ff11be91c3c8809e417dc40e3e6c1940494b570e
Author: sluicebox (22204938+sluicebox at users.noreply.github.com)
Date: 2021-10-19T08:40:33-05:00

Commit Message:
SCI32; Improve KQ7 cursor script patch

Removes a jump to an unverified offset

Changed paths:
    engines/sci/engine/script_patches.cpp


diff --git a/engines/sci/engine/script_patches.cpp b/engines/sci/engine/script_patches.cpp
index 7408a26997..fffd31a30b 100644
--- a/engines/sci/engine/script_patches.cpp
+++ b/engines/sci/engine/script_patches.cpp
@@ -6596,7 +6596,7 @@ static const uint16 kq7PragmaFailSpinPatch[] = {
 	0x78,                                     // push1
 	0x39, 0x12,                               // pushi 18 (~300ms)
 	0x43, kScummVMSleepId, PATCH_UINT16(0x02),// callk ScummVMSleep, 2
-	0x33, 0x16,                               // jmp [to setCursor]
+	0x35, 0x00,                               // ldi 0 [ exit loop ]
 	PATCH_END
 };
 


Commit: 27195a1b0aa9ed600618b0ab437b3cbac622c8f4
    https://github.com/scummvm/scummvm/commit/27195a1b0aa9ed600618b0ab437b3cbac622c8f4
Author: sluicebox (22204938+sluicebox at users.noreply.github.com)
Date: 2021-10-19T08:43:45-05:00

Commit Message:
SCI32: Fix GK2 "bad" cursor not appearing

Changed paths:
    engines/sci/engine/script_patches.cpp


diff --git a/engines/sci/engine/script_patches.cpp b/engines/sci/engine/script_patches.cpp
index fffd31a30b..21d0501745 100644
--- a/engines/sci/engine/script_patches.cpp
+++ b/engines/sci/engine/script_patches.cpp
@@ -3975,6 +3975,33 @@ static const SciScriptPatcherEntry gk1Signatures[] = {
 #pragma mark -
 #pragma mark Gabriel Knight 2
 
+// GK2 uses a kGetTime spin loop to delay for half a second while displaying
+//  the "bad" cursor when clicking an item on something it can't be used on.
+//  This leaves ScummVM unresponsive without displaying the cursor.
+//
+// We fix this by replacing the spin loop with a call to kScummVMSleep.
+//
+// Applies to: All versions
+// Responsible method: GKHotCursor:flashBad
+static const uint16 gk2FlashBadCursorSignature[] = {
+	0x8d, SIG_MAGICDWORD, 0x00,     // lst 00
+	0x76,                           // push0
+	0x43, 0x79, SIG_UINT16(0x0000), // callk GetTime 00
+	0x1e,                           // gt?
+	0x31, 0x02,                     // bnt 02 [ exit loop ]
+	0x33, 0xf4,                     // jmp f4 [ continue loop ]
+	SIG_END
+};
+
+static const uint16 gk2FlashBadCursorPatch[] = {
+	0x78,                           // push1
+	0x39, 0x1e,                     // pushi 1e [ half a second ]
+	0x43, kScummVMSleepId,          // callk ScummVMSleep 02
+	      PATCH_UINT16(0x0002),
+	0x32, PATCH_UINT16(0x0002),     // jmp 0002 [ exit loop ]
+	PATCH_END
+};
+
 // GK2's inventory scrolls smoothly when the mouse is held down in the original
 //  due to an inner loop in ScrollButton:track, but this causes slow scrolling
 //  in our interpreter since we throttle kFrameOut. The script's inner loop is
@@ -4422,6 +4449,7 @@ static const SciScriptPatcherEntry gk2Signatures[] = {
 	{  true,  8617, "fix wagner painting message",                         2, gk2WagnerPaintingMessageSignature, gk2WagnerPaintingMessagePatch },
 	{  true, 64928, "Narrator lockup fix",                                 1, sciNarratorLockupSignature,        sciNarratorLockupPatch },
 	{  true, 64928, "Narrator lockup fix",                                 1, sciNarratorLockupLineSignature,    sciNarratorLockupLinePatch },
+	{  true, 64962, "flash bad cursor spin loop",                          1, gk2FlashBadCursorSignature,        gk2FlashBadCursorPatch },
 	{  true, 64990, "increase number of save games (1/2)",                 1, sci2NumSavesSignature1,            sci2NumSavesPatch1 },
 	{  true, 64990, "increase number of save games (2/2)",                 1, sci2NumSavesSignature2,            sci2NumSavesPatch2 },
 	{  true, 64990, "disable change directory button",                     1, sci2ChangeDirSignature,            sci2ChangeDirPatch },




More information about the Scummvm-git-logs mailing list