[Scummvm-git-logs] scummvm branch-2-6 -> db3453145243c89018712b366ccb961647f9ac04

NMIError noreply at scummvm.org
Sun Jul 3 19:37:28 UTC 2022


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

Summary:
c76d13a34c CHEWY: Fix cutscene volume and panning
db34531452 CHEWY: Disable speech panning


Commit: c76d13a34c80e96fa391169455bf1a0162794e5d
    https://github.com/scummvm/scummvm/commit/c76d13a34c80e96fa391169455bf1a0162794e5d
Author: Coen Rampen (crampen at gmail.com)
Date: 2022-07-03T21:37:16+02:00

Commit Message:
CHEWY: Fix cutscene volume and panning

This commit fixes the initial volume and panning for SFX and music in
cutscenes. These were set on the sound handle of the previous SFX or music
track played, which would not affect the new sound.

Changed paths:
    engines/chewy/atds.cpp
    engines/chewy/dialogs/options.cpp
    engines/chewy/r_event.cpp
    engines/chewy/sound.cpp
    engines/chewy/sound.h
    engines/chewy/video/cfo_decoder.cpp
    engines/chewy/video/cfo_decoder.h
    engines/chewy/video/video_player.cpp


diff --git a/engines/chewy/atds.cpp b/engines/chewy/atds.cpp
index 1320832259b..05fe089b02c 100644
--- a/engines/chewy/atds.cpp
+++ b/engines/chewy/atds.cpp
@@ -607,6 +607,13 @@ void Atdsys::print_aad(int16 scrX, int16 scrY) {
 			if (g_engine->_sound->speechEnabled() &&
 					_aadv._strHeader->_vocNr - ATDS_VOC_OFFSET != -1) {
 				if (_atdsv._vocNr != _aadv._strHeader->_vocNr - ATDS_VOC_OFFSET) {
+					// TODO Panning does not work properly during cutscenes.
+					// The x position seems to be fixed, probably that of the
+					// character in the (now invisible) game screen, so all
+					// cutscene voices are panned to the same position. I don't
+					// know if the x position of the character speaking in the
+					// cutscene is available somehow; otherwise panning must be
+					// disabled (fixed center) during cutscenes.
 					_atdsv._vocNr = _aadv._strHeader->_vocNr - ATDS_VOC_OFFSET;
 					const int16 vocx = _G(moveState)[personId].Xypos[0] -
 								 _G(gameState).scrollx + _G(spieler_mi)[personId].HotX;
diff --git a/engines/chewy/dialogs/options.cpp b/engines/chewy/dialogs/options.cpp
index e895f2ff884..e93df89cebb 100644
--- a/engines/chewy/dialogs/options.cpp
+++ b/engines/chewy/dialogs/options.cpp
@@ -100,12 +100,12 @@ void Options::execute(TafInfo *ti) {
 				8 + ti->correction[(SCHNULL_BAND << 1) + 1], 0);
 		}
 
-		const int soundVolume = MAX(1, g_engine->_sound->getSoundVolume() * 32 / Audio::Mixer::kMaxMixerVolume);
+		const int soundVolume = MAX(1, g_engine->_sound->getUserSoundVolume() * 32 / Audio::Mixer::kMaxMixerVolume);
 		_G(out)->pop_box(32 - 2, 104 - 12, 42 + 4, 136 + 2, 192, 183, 182);
 		_G(out)->printxy(32 + 3, 104 - 10, 15, 300, 0, "S");
 		_G(out)->boxFill(33, 136 - soundVolume, 42, 136, 15);
 
-		const int musicVolume = MAX(1, g_engine->_sound->getMusicVolume() * 32 / Audio::Mixer::kMaxMixerVolume);
+		const int musicVolume = MAX(1, g_engine->_sound->getUserMusicVolume() * 32 / Audio::Mixer::kMaxMixerVolume);
 		_G(out)->pop_box(52 - 2, 104 - 12, 62 + 4, 136 + 2, 192, 183, 182);
 		_G(out)->printxy(52 + 3, 104 - 10, 31, 300, 0, "M");
 		_G(out)->boxFill(53, 136 - musicVolume, 62, 136, 31);
@@ -193,11 +193,11 @@ void Options::execute(TafInfo *ti) {
 				key = Common::KEYCODE_ESCAPE;
 				break;
 			case 7: // S volume gauge
-				g_engine->_sound->setSoundVolume(MIN(32, 136 - g_events->_mousePos.y) * Audio::Mixer::kMaxMixerVolume / 32);
+				g_engine->_sound->setUserSoundVolume(MIN(32, 136 - g_events->_mousePos.y) * Audio::Mixer::kMaxMixerVolume / 32);
 				g_engine->syncSoundSettings();
 				break;
 			case 8: // M volume gauge
-				g_engine->_sound->setMusicVolume(MIN(32, 136 - g_events->_mousePos.y) * Audio::Mixer::kMaxMixerVolume / 32);
+				g_engine->_sound->setUserMusicVolume(MIN(32, 136 - g_events->_mousePos.y) * Audio::Mixer::kMaxMixerVolume / 32);
 				g_engine->syncSoundSettings();
 				break;
 
diff --git a/engines/chewy/r_event.cpp b/engines/chewy/r_event.cpp
index 8e29c99277b..c956e1e974e 100644
--- a/engines/chewy/r_event.cpp
+++ b/engines/chewy/r_event.cpp
@@ -754,9 +754,9 @@ void flic_cut(int16 nr) {
 		break;
 
 	case FCUT_112:
-		g_engine->_sound->setMusicVolume(32 * Audio::Mixer::kMaxChannelVolume / 120);
+		g_engine->_sound->setActiveMusicVolume(32);
 		g_engine->_video->playVideo(nr);
-		g_engine->_sound->setMusicVolume(5 * Audio::Mixer::kMaxChannelVolume / 120);
+		g_engine->_sound->setActiveMusicVolume(5);
 		break;
 
 	case FCUT_133:
diff --git a/engines/chewy/sound.cpp b/engines/chewy/sound.cpp
index 1cfa1a2de68..6674b4f40d7 100644
--- a/engines/chewy/sound.cpp
+++ b/engines/chewy/sound.cpp
@@ -66,11 +66,8 @@ void Sound::playSound(uint8 *data, uint32 size, uint channel, bool loop, uint16
 			dispose),
 		loop ? 0 : 1);
 
-	assert(volume >= 0 && volume < 64);
-	assert(balance >= 0 && balance < 128);
-
 	_mixer->playStream(Audio::Mixer::kSFXSoundType, &_soundHandle[channel], stream, -1,
-		volume * Audio::Mixer::kMaxChannelVolume / 63, MIN(127, (balance - 63) * 2));
+		convertVolume(volume), convertBalance(balance));
 }
 
 void Sound::pauseSound(uint channel) {
@@ -98,37 +95,24 @@ bool Sound::isSoundActive(uint channel) const {
 	return _mixer->isSoundHandleActive(_soundHandle[channel]);
 }
 
-void Sound::setSoundVolume(uint volume) {
+void Sound::setUserSoundVolume(uint volume) {
 	_userSoundVolume = volume;
 	if (soundEnabled())
 		ConfMan.setInt("sfx_volume", volume);
 }
 
-int Sound::getSoundVolume() const {
+int Sound::getUserSoundVolume() const {
 	return _userSoundVolume;
 }
 
-void Sound::pushVolume() {
-	/* _soundVolume = _mixer->getVolumeForSoundType(Audio::Mixer::kSFXSoundType);
-	_speechVolume = _mixer->getVolumeForSoundType(Audio::Mixer::kSpeechSoundType);
-	_musicVolume = _mixer->getVolumeForSoundType(Audio::Mixer::kMusicSoundType);*/
-}
-
-void Sound::popVolume() {
-	/* assert(_soundVolume >= 0 && _speechVolume >= 0 && _musicVolume >= 0);
-	_mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, _soundVolume);
-	_mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, _speechVolume);
-	_mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, _musicVolume);*/
-}
-
 void Sound::setSoundChannelVolume(uint channel, uint volume) {
 	assert(channel < MAX_SOUND_EFFECTS);
-	_mixer->setChannelVolume(_soundHandle[channel], volume);
+	_mixer->setChannelVolume(_soundHandle[channel], convertVolume(volume));
 }
 
 void Sound::setSoundChannelBalance(uint channel, int8 balance) {
 	assert(channel < MAX_SOUND_EFFECTS);
-	_mixer->setChannelBalance(_soundHandle[channel], balance);
+	_mixer->setChannelBalance(_soundHandle[channel], convertBalance(balance));
 }
 
 void Sound::playMusic(int16 num, bool loop) {
@@ -142,11 +126,11 @@ void Sound::playMusic(int16 num, bool loop) {
 	delete[] data;
 }
 
-void Sound::playMusic(uint8 *data, uint32 size) {
+void Sound::playMusic(uint8 *data, uint32 size, uint8 volume) {
 	TMFStream *stream = new TMFStream(new Common::MemoryReadStream(data, size), 0);
 	_curMusic = -1;
 
-	_mixer->playStream(Audio::Mixer::kMusicSoundType, &_musicHandle, stream);
+	_mixer->playStream(Audio::Mixer::kMusicSoundType, &_musicHandle, stream, -1, convertVolume(volume));
 }
 
 void Sound::pauseMusic() {
@@ -166,16 +150,21 @@ bool Sound::isMusicActive() const {
 	return _mixer->isSoundHandleActive(_musicHandle);
 }
 
-void Sound::setMusicVolume(uint volume) {
+void Sound::setUserMusicVolume(uint volume) {
 	_userMusicVolume = volume;
 	if (musicEnabled())
 		ConfMan.setInt("music_volume", volume);
 }
 
-int Sound::getMusicVolume() const {
+int Sound::getUserMusicVolume() const {
 	return _userMusicVolume;
 }
 
+void Sound::setActiveMusicVolume(uint8 volume) {
+	if (isMusicActive())
+		_mixer->setChannelVolume(_musicHandle, convertVolume(volume));
+}
+
 void Sound::playSpeech(int num, bool waitForFinish, uint16 balance) {
 	if (isSpeechActive())
 		stopSpeech();
@@ -194,10 +183,8 @@ void Sound::playSpeech(int num, bool waitForFinish, uint16 balance) {
 		new Common::MemorySeekableReadWriteStream(data, size, DisposeAfterUse::YES),
 		DisposeAfterUse::YES);
 
-	assert(balance >= 0 && balance < 128);
-
 	_mixer->playStream(Audio::Mixer::kSpeechSoundType, &_speechHandle, stream,
-		-1 , 255, MIN(127, (balance - 63) * 2));
+		-1, Audio::Mixer::kMaxChannelVolume, convertBalance(balance));
 
 	if (waitForFinish) {
 		// Wait for speech to finish
@@ -237,7 +224,7 @@ void Sound::waitForSpeechToFinish() {
 
 void Sound::setSpeechBalance(uint16 balance) {
 	if (isSpeechActive()) {
-		_mixer->setChannelBalance(_speechHandle, balance);
+		_mixer->setChannelBalance(_speechHandle, convertBalance(balance));
 	}
 }
 
@@ -346,4 +333,14 @@ void Sound::playRoomMusic(int16 roomNum) {
 	}
 }
 
+uint8 Sound::convertVolume(uint16 volume) {
+	assert(volume >= 0 && volume < 64);
+	return volume * Audio::Mixer::kMaxChannelVolume / 63;
+}
+
+int8 Sound::convertBalance(uint16 balance) {
+	assert(balance >= 0 && balance < 128);
+	return MIN(127, (balance - 63) * 2);
+}
+
 } // namespace Chewy
diff --git a/engines/chewy/sound.h b/engines/chewy/sound.h
index eb3d3021065..921aa61a074 100644
--- a/engines/chewy/sound.h
+++ b/engines/chewy/sound.h
@@ -50,21 +50,26 @@ public:
 	void stopSound(uint channel = 0);
 	void stopAllSounds();
 	bool isSoundActive(uint channel) const;
-	void setSoundVolume(uint volume);
-	int getSoundVolume() const;
+	void setUserSoundVolume(uint volume);
+	int getUserSoundVolume() const;
+	// Sets the volume of the sound effect curently active on the specified
+	// channel. Does not affect the next sound effect played on the channel.
 	void setSoundChannelVolume(uint channel, uint volume);
+	// Sets the balance of the sound effect curently active on the specified
+	// channel. Does not affect the next sound effect played on the channel.
 	void setSoundChannelBalance(uint channel, int8 balance);
-	void pushVolume();
-	void popVolume();
 
 	void playMusic(int16 num, bool loop = false);
-	void playMusic(uint8 *data, uint32 size);
+	void playMusic(uint8 *data, uint32 size, uint8 volume = 63);
 	void pauseMusic();
 	void resumeMusic();
 	void stopMusic();
 	bool isMusicActive() const;
-	void setMusicVolume(uint volume);
-	int getMusicVolume() const;
+	void setUserMusicVolume(uint volume);
+	int getUserMusicVolume() const;
+	// Sets the volume of the currently active music track. Does not affect the
+	// next music track played.
+	void setActiveMusicVolume(uint8 volume);
 	void playRoomMusic(int16 roomNum);
 
 	void playSpeech(int num, bool waitForFinish, uint16 balance = 63);
@@ -72,6 +77,8 @@ public:
 	void resumeSpeech();
 	void stopSpeech();
 	bool isSpeechActive() const;
+	// Sets the balance of the currently playing speech sample. Does not affect
+	// the next speech sample played.
 	void setSpeechBalance(uint16 balance = 63);
 
 	void stopAll();
@@ -96,6 +103,13 @@ public:
 	void syncSoundSettings();
 
 private:
+	// Converts volume from the scale used by the game data (0 - 63) to the
+	// ScummVM mixer channel scale (0 - 255).
+	uint8 convertVolume(uint16 volume);
+	// Converts balance from the scale used by the game data (0 - 127) to the
+	// ScummVM mixer channel scale (-127 - 127).
+	int8 convertBalance(uint16 balance);
+
 	Audio::Mixer *_mixer;
 	Audio::SoundHandle _soundHandle[MAX_SOUND_EFFECTS];
 	Audio::SoundHandle _musicHandle;
diff --git a/engines/chewy/video/cfo_decoder.cpp b/engines/chewy/video/cfo_decoder.cpp
index dc9c4de53a6..6db9dbc31e7 100644
--- a/engines/chewy/video/cfo_decoder.cpp
+++ b/engines/chewy/video/cfo_decoder.cpp
@@ -83,6 +83,10 @@ CfoDecoder::CfoVideoTrack::CfoVideoTrack(Common::SeekableReadStream *stream, uin
 
 	_musicData = nullptr;
 	_musicSize = 0;
+
+	Common::fill(_sfxBalances, _sfxBalances + ARRAYSIZE(_sfxBalances), 63);
+	_sfxGlobalVolume = 63;
+	_musicVolume = 63;
 }
 
 CfoDecoder::CfoVideoTrack::~CfoVideoTrack() {
@@ -219,7 +223,7 @@ void CfoDecoder::CfoVideoTrack::handleCustomFrame() {
 			break;
 		case kChunkPlayMusic:
 			// Used in videos 0, 18, 34, 71
-			_sound->playMusic(_musicData, _musicSize);
+			_sound->playMusic(_musicData, _musicSize, _musicVolume);
 			break;
 		case kChunkPlaySeq:
 			error("Unused chunk kChunkPlaySeq found");
@@ -246,8 +250,10 @@ void CfoDecoder::CfoVideoTrack::handleCustomFrame() {
 			} while (_sound->isMusicActive() && musicLoops < 100);
 			break;
 		case kChunkSetMusicVolume:
-			volume = _fileStream->readUint16LE() * Audio::Mixer::kMaxChannelVolume / 63;
-			_sound->setMusicVolume(volume);
+			volume = _fileStream->readUint16LE();
+
+			_musicVolume = volume;
+			_sound->setActiveMusicVolume(volume);
 			break;
 		case kChunkSetLoopMode:
 			error("Unused chunk kChunkSetLoopMode found");
@@ -262,18 +268,21 @@ void CfoDecoder::CfoVideoTrack::handleCustomFrame() {
 			repeat = _fileStream->readUint16LE();
 			assert(number < MAX_SOUND_EFFECTS);
 
-			//_sound->setSoundVolume(volume);
-			_sound->playSound(_soundEffects[number], _soundEffectSize[number], channel, repeat, volume, 63, DisposeAfterUse::NO);
+			_sound->playSound(_soundEffects[number], _soundEffectSize[number], channel, repeat,
+				volume * _sfxGlobalVolume / 63, _sfxBalances[channel], DisposeAfterUse::NO);
 			break;
 		case kChunkSetSoundVolume:
-			volume = _fileStream->readUint16LE() * Audio::Mixer::kMaxChannelVolume / 63;
-			_sound->setSoundVolume(volume);
+			volume = _fileStream->readUint16LE();
+			assert(volume >= 0 && volume < 64);
+			_sfxGlobalVolume = volume;
+			// This is only used once in the credits video, before any sounds
+			// are played, so no need to update volume of active sounds.
 			break;
 		case kChunkSetChannelVolume:
 			channel = _fileStream->readUint16LE();
-			volume = _fileStream->readUint16LE() * Audio::Mixer::kMaxChannelVolume / 63;
+			volume = _fileStream->readUint16LE();
 
-			_sound->setSoundChannelVolume(channel, volume);
+			_sound->setSoundChannelVolume(channel, volume * _sfxGlobalVolume / 63);
 			break;
 		case kChunkFreeSoundEffect:
 			number = _fileStream->readUint16LE();
@@ -293,7 +302,9 @@ void CfoDecoder::CfoVideoTrack::handleCustomFrame() {
 			break;
 		case kChunkSetBalance:
 			channel = _fileStream->readUint16LE();
-			balance = (_fileStream->readUint16LE() * 2) - 127;
+			balance = _fileStream->readUint16LE();
+
+			_sfxBalances[channel] = balance;
 			_sound->setSoundChannelBalance(channel, balance);
 			break;
 		case kChunkSetSpeed:
diff --git a/engines/chewy/video/cfo_decoder.h b/engines/chewy/video/cfo_decoder.h
index c087cd125e9..41c7864bf4d 100644
--- a/engines/chewy/video/cfo_decoder.h
+++ b/engines/chewy/video/cfo_decoder.h
@@ -62,6 +62,10 @@ private:
 		uint32 _soundEffectSize[MAX_SOUND_EFFECTS];
 		uint8 *_musicData;
 		uint32 _musicSize;
+
+		uint8 _sfxBalances[MAX_SOUND_EFFECTS];
+		uint8 _sfxGlobalVolume;
+		uint8 _musicVolume;
 	};
 };
 
diff --git a/engines/chewy/video/video_player.cpp b/engines/chewy/video/video_player.cpp
index 57b947e2a87..380da53f660 100644
--- a/engines/chewy/video/video_player.cpp
+++ b/engines/chewy/video/video_player.cpp
@@ -36,7 +36,6 @@ bool VideoPlayer::playVideo(uint num, bool stopMusic) {
 	CfoDecoder *cfoDecoder = new CfoDecoder(g_engine->_sound);
 	VideoResource *videoResource = new VideoResource("cut.tap");
 	Common::SeekableReadStream *videoStream = videoResource->getVideoStream(num);
-	g_engine->_sound->pushVolume();
 	_playCount = 0;
 
 	if (stopMusic) {
@@ -102,7 +101,6 @@ bool VideoPlayer::playVideo(uint num, bool stopMusic) {
 
 	g_system->getPaletteManager()->setPalette(curPalette, 0, 256);
 	_G(cur)->showCursor();
-	g_engine->_sound->popVolume();
 
 	delete videoResource;
 	delete cfoDecoder;


Commit: db3453145243c89018712b366ccb961647f9ac04
    https://github.com/scummvm/scummvm/commit/db3453145243c89018712b366ccb961647f9ac04
Author: Coen Rampen (crampen at gmail.com)
Date: 2022-07-03T21:37:16+02:00

Commit Message:
CHEWY: Disable speech panning

It does not work properly in cutscenes and the original game does not seem to
pan speech at all.

Changed paths:
    engines/chewy/atds.cpp
    engines/chewy/sprite.cpp


diff --git a/engines/chewy/atds.cpp b/engines/chewy/atds.cpp
index 05fe089b02c..d8c7f27c59c 100644
--- a/engines/chewy/atds.cpp
+++ b/engines/chewy/atds.cpp
@@ -607,17 +607,8 @@ void Atdsys::print_aad(int16 scrX, int16 scrY) {
 			if (g_engine->_sound->speechEnabled() &&
 					_aadv._strHeader->_vocNr - ATDS_VOC_OFFSET != -1) {
 				if (_atdsv._vocNr != _aadv._strHeader->_vocNr - ATDS_VOC_OFFSET) {
-					// TODO Panning does not work properly during cutscenes.
-					// The x position seems to be fixed, probably that of the
-					// character in the (now invisible) game screen, so all
-					// cutscene voices are panned to the same position. I don't
-					// know if the x position of the character speaking in the
-					// cutscene is available somehow; otherwise panning must be
-					// disabled (fixed center) during cutscenes.
 					_atdsv._vocNr = _aadv._strHeader->_vocNr - ATDS_VOC_OFFSET;
-					const int16 vocx = _G(moveState)[personId].Xypos[0] -
-								 _G(gameState).scrollx + _G(spieler_mi)[personId].HotX;
-					g_engine->_sound->playSpeech(_atdsv._vocNr, false, getStereoPos(vocx));
+					g_engine->_sound->playSpeech(_atdsv._vocNr, false);
 				}
 
 				if (_atdsv._vocNr >= 0 && !g_engine->_sound->isSpeechActive())
diff --git a/engines/chewy/sprite.cpp b/engines/chewy/sprite.cpp
index 7753b457228..e7207fe0aff 100644
--- a/engines/chewy/sprite.cpp
+++ b/engines/chewy/sprite.cpp
@@ -505,14 +505,8 @@ bool startAtsWait(int16 txtNr, int16 txtMode, int16 col, int16 mode) {
 			shown = _G(atds)->start_ats(txtNr, txtMode, col, mode, &vocNr);
 
 			if (g_engine->_sound->speechEnabled())  {
-				const int16 vocx = _G(moveState)[P_CHEWY].Xypos[0] - _G(gameState).scrollx + _G(spieler_mi)[P_CHEWY].HotX;
-
 				if (vocNr >= 0) {
-					g_engine->_sound->playSpeech(vocNr, false, _G(atds)->getStereoPos(vocx));
-				} else {
-					// Not sure if the game alters speech balance while speech
-					// plays, but the old code behaved this way.
-					g_engine->_sound->setSpeechBalance(_G(atds)->getStereoPos(vocx));
+					g_engine->_sound->playSpeech(vocNr, false);
 				}
 
 				setupScreen(DO_SETUP);




More information about the Scummvm-git-logs mailing list