[Scummvm-git-logs] scummvm master -> 90f8cb2613c2f6a895ce0853f568d9c55b641575

sluicebox noreply at scummvm.org
Thu Jun 13 20:31:20 UTC 2024


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

Summary:
0a497c5af4 SCI: Set kShowMovie subop 0 return value
de9710be94 SCI32: Remove completed TODO
98fefbdfda SCI: Remove unused function declaration
90f8cb2613 SCI: Implement SCI1.1 AudioLoc behavior


Commit: 0a497c5af406accc61017187b80b1b483a2fb0ca
    https://github.com/scummvm/scummvm/commit/0a497c5af406accc61017187b80b1b483a2fb0ca
Author: sluicebox (22204938+sluicebox at users.noreply.github.com)
Date: 2024-06-13T14:30:29-06:00

Commit Message:
SCI: Set kShowMovie subop 0 return value

This doesn't alter game behavior, but the KQ6 Windows movies were
only working by accident due to a stale value in the accumulator.

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


diff --git a/engines/sci/engine/kvideo.cpp b/engines/sci/engine/kvideo.cpp
index 234e3fe69bc..74372731931 100644
--- a/engines/sci/engine/kvideo.cpp
+++ b/engines/sci/engine/kvideo.cpp
@@ -114,6 +114,8 @@ void playVideo(Video::VideoDecoder &videoDecoder) {
 }
 
 reg_t kShowMovie(EngineState *s, int argc, reg_t *argv) {
+	reg_t retval = s->r_acc;
+
 	// Hide the cursor if it's showing and then show it again if it was
 	// previously visible.
 	bool reshowCursor = g_sci->_gfxCursor->isVisible();
@@ -168,9 +170,10 @@ reg_t kShowMovie(EngineState *s, int argc, reg_t *argv) {
 			}
 		}
 	} else {
-		// Windows AVI
-		// TODO: This appears to be some sort of subop. case 0 contains the string
-		// for the video, so we'll just play it from there for now.
+		// Windows AVI: Only used by KQ6 CD for the Sierra logo and intro cartoon.
+		// The first parameter is a subop. Some of the subops set the accumulator.
+		// The interpreter implements subops 0-6. KQ6 only calls 0, 1, 2, 3, 6.
+		// Subop 0 plays the AVI; it is the only one that needs to be implemented.
 
 		switch (argv[0].toUint16()) {
 		case 0: {
@@ -180,10 +183,11 @@ reg_t kShowMovie(EngineState *s, int argc, reg_t *argv) {
 				warning("Failed to open movie file %s", filename.c_str());
 				videoDecoder.reset();
 			}
+			retval = TRUE_REG;
 			break;
 		}
 		default:
-			warning("Unhandled SCI kShowMovie subop %d", argv[0].toUint16());
+			debug(kDebugLevelVideo, "Unhandled kShowMovie subop %d", argv[0].toUint16());
 		}
 	}
 
@@ -205,7 +209,7 @@ reg_t kShowMovie(EngineState *s, int argc, reg_t *argv) {
 	if (reshowCursor)
 		g_sci->_gfxCursor->kernelShow();
 
-	return s->r_acc;
+	return retval;
 }
 
 #ifdef ENABLE_SCI32


Commit: de9710be94e32da98bdd223c4277286307984692
    https://github.com/scummvm/scummvm/commit/de9710be94e32da98bdd223c4277286307984692
Author: sluicebox (22204938+sluicebox at users.noreply.github.com)
Date: 2024-06-13T14:30:30-06:00

Commit Message:
SCI32: Remove completed TODO

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


diff --git a/engines/sci/engine/features.cpp b/engines/sci/engine/features.cpp
index 846a205d307..8eeae5cde1f 100644
--- a/engines/sci/engine/features.cpp
+++ b/engines/sci/engine/features.cpp
@@ -566,7 +566,6 @@ bool GameFeatures::supportsSpeechWithSubtitles() const {
 	case GID_LAURABOW2:
 	case GID_KQ6:
 #ifdef ENABLE_SCI32
-	// TODO: SCI3
 	case GID_GK1:
 	case GID_KQ7:
 	case GID_LSL6HIRES:
@@ -612,7 +611,6 @@ MessageTypeSyncStrategy GameFeatures::getMessageTypeSyncStrategy() const {
 
 #ifdef ENABLE_SCI32
 	switch (g_sci->getGameId()) {
-	// TODO: SCI3
 	case GID_GK1:
 	case GID_PQ4:
 	case GID_QFG4:


Commit: 98fefbdfda4c6de759c9a47e20a64943e00a9d54
    https://github.com/scummvm/scummvm/commit/98fefbdfda4c6de759c9a47e20a64943e00a9d54
Author: sluicebox (22204938+sluicebox at users.noreply.github.com)
Date: 2024-06-13T14:30:30-06:00

Commit Message:
SCI: Remove unused function declaration

Changed paths:
    engines/sci/engine/vm.h


diff --git a/engines/sci/engine/vm.h b/engines/sci/engine/vm.h
index 7a8abe9c32b..b114fb1849a 100644
--- a/engines/sci/engine/vm.h
+++ b/engines/sci/engine/vm.h
@@ -374,12 +374,6 @@ ExecStack *send_selector(EngineState *s, reg_t send_obj, reg_t work_obj,
  */
 void run_vm(EngineState *s);
 
-/**
- * Debugger functionality
- * @param[in] s					The state at which debugging should take place
- */
-void script_debug(EngineState *s);
-
 /**
  * Looks up a selector and returns its type and value
  * varindex is written to iff it is non-NULL and the selector indicates a property of the object.


Commit: 90f8cb2613c2f6a895ce0853f568d9c55b641575
    https://github.com/scummvm/scummvm/commit/90f8cb2613c2f6a895ce0853f568d9c55b641575
Author: sluicebox (22204938+sluicebox at users.noreply.github.com)
Date: 2024-06-13T14:30:30-06:00

Commit Message:
SCI: Implement SCI1.1 AudioLoc behavior

- Fixes LSL6 CD (SCI16 version) Electroshock freeze, bug #15165
- Improves LB2 CD "Ra Ra Amon Ra" chant scene

Neither of these scenes are perfectly reproduced in ScummVM yet, but
they are better than they were. They accidentally rely on precise
undocumented/undiscovered audio driver behavior when digital sound
and speech are played at the same time and interrupt each other.

These scripts do conflicting things that had no effect in the original
floppy versions, but caused conflicts once CD speech was added later.
They still appeared to work, but only by accident, and so no one would
have noticed the problems at the time. When LSL6 was ported to SCI32,
the Electroshock script was discovered and rewritten to be normal.

This commit implements two missing pieces of interpreter behavior:

1. processUpdateCues stops the sound if it's a digital sample and
   the audio driver's AudioLoc function returns -1. To replicate
   this, we query our two separate components that play digital
   samples and speech.

2. kDoAudio(AudioLoc) returns the audio driver's AudioLoc result.
   SSCI's audio driver could have been playing a digital sample or
   speech, but we do these in two separate components, and we were
   only querying one of them. Now we query both and produce the
   same results as the original.

Changed paths:
    engines/sci/engine/ksound.cpp
    engines/sci/sound/music.cpp
    engines/sci/sound/music.h
    engines/sci/sound/soundcmd.cpp
    engines/sci/sound/soundcmd.h


diff --git a/engines/sci/engine/ksound.cpp b/engines/sci/engine/ksound.cpp
index f44e218ea6a..8b9e7e54d0f 100644
--- a/engines/sci/engine/ksound.cpp
+++ b/engines/sci/engine/ksound.cpp
@@ -242,9 +242,25 @@ reg_t kDoAudio(EngineState *s, int argc, reg_t *argv) {
 		debugC(kDebugLevelSound, "kDoAudio: resume");
 		g_sci->_audio->resumeAudio();
 		break;
-	case kSciAudioPosition:
-		//debugC(kDebugLevelSound, "kDoAudio: get position");	// too verbose
-		return make_reg(0, g_sci->_audio->getAudioPosition());
+	case kSciAudioPosition: {
+		// SSCI queried the audio driver's AudioLoc function and returned the result.
+		// The driver returned the location in ticks if audio was playing, otherwise -1.
+		// The driver could only play one piece of audio at a time, and it could have
+		// been playing either a digital sample from kDoSound or speech from kDoAudio.
+		// We have two separate components for these interfaces, so we must check both.
+		int audioPosition = g_sci->_audio->getAudioPosition();
+		if (audioPosition == -1) {
+			// kDoAudio is not playing speech, so now we check the kDoSound interface.
+			// SoundCommandParser does not keep track of the audio position in ticks
+			// for digital samples, so we can't return the real position. Scripts only
+			// care about the exact tick value for speech, otherwise it only matters
+			// if the result is -1 or not, so just return 1 if a sample is playing.
+			if (g_sci->_soundCmd->isDigitalSamplePlaying()) {
+				audioPosition = 1;
+			}
+		}
+		return make_reg(0, audioPosition);
+	}
 	case kSciAudioRate:
 		debugC(kDebugLevelSound, "kDoAudio: set audio rate to %d", argv[1].toUint16());
 		g_sci->_audio->setAudioRate(argv[1].toUint16());
diff --git a/engines/sci/sound/music.cpp b/engines/sci/sound/music.cpp
index 2dd6be9b3b3..8e2bc0add67 100644
--- a/engines/sci/sound/music.cpp
+++ b/engines/sci/sound/music.cpp
@@ -642,7 +642,7 @@ void SciMusic::soundPlay(MusicEntry *pSnd, bool restoring) {
 			return;
 		}
 #endif
-		if (_currentlyPlayingSample && _pMixer->isSoundHandleActive(_currentlyPlayingSample->hCurrentAud)) {
+		if (isDigitalSamplePlaying()) {
 			// Another sample is already playing, we have to stop that one
 			// SSCI is only able to play 1 sample at a time
 			// In Space Quest 5 room 250 the player is able to open the air-hatch and kill himself.
@@ -1590,6 +1590,9 @@ void SciMusic::resetDeviceChannel(int devChannel, bool mainThread) {
 	}
 }
 
-
+bool SciMusic::isDigitalSamplePlaying() const {
+	return _currentlyPlayingSample != nullptr &&
+		   _pMixer->isSoundHandleActive(_currentlyPlayingSample->hCurrentAud);
+}
 
 } // End of namespace Sci
diff --git a/engines/sci/sound/music.h b/engines/sci/sound/music.h
index bfa3deb1e49..ce8bcc58924 100644
--- a/engines/sci/sound/music.h
+++ b/engines/sci/sound/music.h
@@ -217,7 +217,7 @@ public:
 	uint32 soundGetTempo() const { return _dwTempo; }
 	MusicType soundGetMusicType() const { return _musicType; }
 
-	bool soundIsActive(MusicEntry *pSnd) {
+	bool isSoundActive(MusicEntry *pSnd) {
 		assert(pSnd->pStreamAud != 0);
 		return _pMixer->isSoundHandleActive(pSnd->hCurrentAud);
 	}
@@ -284,6 +284,8 @@ public:
 	// The parsers need to know this for the dontMap channels...
 	bool isDeviceChannelMapped(int devChannel) const;
 
+	bool isDigitalSamplePlaying() const;
+
 private:
 	MusicList _playList;
 	bool _soundOn;
diff --git a/engines/sci/sound/soundcmd.cpp b/engines/sci/sound/soundcmd.cpp
index 8009f2d7e66..d2639d0bad5 100644
--- a/engines/sci/sound/soundcmd.cpp
+++ b/engines/sci/sound/soundcmd.cpp
@@ -587,6 +587,26 @@ void SoundCommandParser::processUpdateCues(reg_t obj) {
 			return;
 		}
 #endif
+		// SCI1.1 stopped the sample if the audio driver reported that no audio was playing.
+		// We have two separate components that could be playing digital audio instead of
+		// one driver, so we must check them both. This behavior is necessary to handle cases
+		// where scripts played a sample with kDoSound and speech with kDoAudio at the same
+		// time, and relied on them both signaling even though one interrupts the other.
+		// Fixes LSL6 CD Electroshock scene from freezing in room 380, sHookUpLarry state 5.
+		// This script only worked by accident, and these lines were rewritten for SCI32.
+		// LB2 CD's "Ra Ra Amon Ra" chant in room 710 also accidentally relies on this.
+		if (getSciVersion() == SCI_VERSION_1_1) {
+			// SSCI queried the audio driver's AudioLoc function. If it returned -1 then
+			// it stopped the sound, but it could have been playing any sample or speech.
+			int audioPosition = _audio->getAudioPosition();
+			if (audioPosition == -1) {
+				if (!isDigitalSamplePlaying()) {
+					processStopSound(obj, true);
+					return;
+				}
+			}
+		}
+
 		// Update digital sound effect slots
 		uint currentLoopCounter = 0;
 
@@ -599,7 +619,7 @@ void SoundCommandParser::processUpdateCues(reg_t obj) {
 			musicSlot->sampleLoopCounter = currentLoopCounter;
 		}
 		if (musicSlot->status == kSoundPlaying) {
-			if (!_music->soundIsActive(musicSlot)) {
+			if (!_music->isSoundActive(musicSlot)) {
 				processStopSound(obj, true);
 			} else {
 				_music->updateAudioStreamTicker(musicSlot);
@@ -896,6 +916,10 @@ void SoundCommandParser::updateSci0Cues() {
 	}
 }
 
+bool SoundCommandParser::isDigitalSamplePlaying() const {
+	return _music->isDigitalSamplePlaying();
+}
+
 void SoundCommandParser::clearPlayList() {
 	_music->clearPlayList();
 }
diff --git a/engines/sci/sound/soundcmd.h b/engines/sci/sound/soundcmd.h
index bc0f98f9034..93678827d5c 100644
--- a/engines/sci/sound/soundcmd.h
+++ b/engines/sci/sound/soundcmd.h
@@ -81,6 +81,8 @@ public:
 	 */
 	void updateSci0Cues();
 
+	bool isDigitalSamplePlaying() const;
+
 	reg_t kDoSoundInit(EngineState *s, int argc, reg_t *argv);
 	reg_t kDoSoundPlay(EngineState *s, int argc, reg_t *argv);
 	reg_t kDoSoundMute(EngineState *s, int argc, reg_t *argv);




More information about the Scummvm-git-logs mailing list