[Scummvm-git-logs] scummvm master -> 6d2c4222b313818350f79fda7864cf2bf28d4f26

sluicebox noreply at scummvm.org
Sun Oct 9 15:23:49 UTC 2022


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

Summary:
6d2c4222b3 SCI32: Fix LIGHTHOUSE stuttering sounds


Commit: 6d2c4222b313818350f79fda7864cf2bf28d4f26
    https://github.com/scummvm/scummvm/commit/6d2c4222b313818350f79fda7864cf2bf28d4f26
Author: sluicebox (22204938+sluicebox at users.noreply.github.com)
Date: 2022-10-09T11:23:05-04:00

Commit Message:
SCI32: Fix LIGHTHOUSE stuttering sounds

Works around script bugs in the original game that often accidentally
worked because of the time it took the original interpreter to load and
begin playing a sound.

Fixes bugs #10224, #10231, #10232, #10237, #10238

Changed paths:
    engines/sci/sound/soundcmd.cpp
    engines/sci/sound/soundcmd.h


diff --git a/engines/sci/sound/soundcmd.cpp b/engines/sci/sound/soundcmd.cpp
index 2e7f4f23807..96d112d40c7 100644
--- a/engines/sci/sound/soundcmd.cpp
+++ b/engines/sci/sound/soundcmd.cpp
@@ -189,6 +189,12 @@ reg_t SoundCommandParser::kDoSoundPlay(EngineState *s, int argc, reg_t *argv) {
 
 void SoundCommandParser::processPlaySound(reg_t obj, bool playBed, bool restoring) {
 	MusicEntry *musicSlot = _music->getSlot(obj);
+
+	if (!restoring && isUninterruptableSoundPlaying(obj)) {
+		debugC(kDebugLevelSound, "kDoSound(play): sound %d already playing", musicSlot->resourceId);
+		return;
+	}
+
 	if (!musicSlot) {
 		warning("kDoSound(play): Slot not found (%04x:%04x), initializing it manually", PRINT_REG(obj));
 		// The sound hasn't been initialized for some reason, so initialize it
@@ -953,4 +959,51 @@ MusicType SoundCommandParser::getMusicType() const {
 	return _music->soundGetMusicType();
 }
 
+bool SoundCommandParser::isUninterruptableSoundPlaying(reg_t obj) {
+#ifdef ENABLE_SCI32
+	// WORKAROUND
+	// Lighthouse has a buggy script pattern in several places that causes
+	// stuttering audio. The scripts poll game state on each game cycle and
+	// play a sound when a condition is met. Usually that's when a robot or
+	// view is on a particular frame. But since these conditions stay true for
+	// multiple cycles, each subsequent iteration plays the song again and
+	// restarts it, creating a stuttering effect. In the original, this usually
+	// worked because of the time it took the interpreter to load and begin
+	// playing a sound, but it could still occur on subsequent plays.
+	// Sierra included the necessary checks in some scripts to prevent this bug,
+	// but not all of them. Unfortunately there are too many functions to patch.
+	// Each is different and would require finding a way to add new code, so
+	// instead we detect the known sounds and ignore requests to play them if
+	// their Sound object is already playing.
+	const uint16 lighthouseSoundIds[] = {
+		// script 270
+		802, 838,      // powerLever:doit
+		813,           // trainBot:doit   (bug #10231)
+		828,           // elevLever:doit  (bug #10238)
+		911, 912,      // railProp:doit   (bug #10232)
+		913, 914, 915, // switchProp:doit (bug #10237)
+		2037,          // steam:doit
+		// script 470
+		443,                 // birdMan:doit (bug #10224)
+		44001, 44005, 44006, // birdManSmash:doit
+		// script 700
+		45905, 45906, // closeHatch:doit
+		// script 870
+		851, 852, 879, 880, 881, 882, 883 // ValveProp:doit
+	};
+	if (g_sci->getGameId() == GID_LIGHTHOUSE) {
+		const reg_t handle = readSelector(_segMan, obj, SELECTOR(handle));
+		if (handle != NULL_REG) { // handle can be an object or -1 when playing
+			const uint16 soundId = readSelectorValue(_segMan, obj, SELECTOR(number));
+			for (int i = 0; i < ARRAYSIZE(lighthouseSoundIds); ++i) {
+				if (lighthouseSoundIds[i] == soundId) {
+					return true;
+				}
+			}
+		}
+	}
+#endif
+	return false;
+}
+
 } // End of namespace Sci
diff --git a/engines/sci/sound/soundcmd.h b/engines/sci/sound/soundcmd.h
index 1c0b6771cc9..d27e625716f 100644
--- a/engines/sci/sound/soundcmd.h
+++ b/engines/sci/sound/soundcmd.h
@@ -117,6 +117,13 @@ private:
 	void processDisposeSound(reg_t obj);
 	void processUpdateCues(reg_t obj);
 	int getSoundResourceId(reg_t obj);
+	
+	/**
+	 * Returns true if the sound is already playing and shouldn't be interrupted.
+	 * This is a workaround for known buggy scripts that accidentally rely on
+	 * the time it took Sierra's interpreter to load a sound and begin playing.
+	 */
+	bool isUninterruptableSoundPlaying(reg_t obj);
 };
 
 } // End of namespace Sci




More information about the Scummvm-git-logs mailing list