[Scummvm-git-logs] scummvm master -> de0c1ff238aefac4b6ea8c4f91f13a91902306c9
antoniou79
noreply at scummvm.org
Mon Apr 24 06:45:32 UTC 2023
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:
c9016cb2f2 BLADERUNNER: Notes and minor fixes for sound
de0c1ff238 BLADERUNNER: Comment fix and notes for some Luther cues
Commit: c9016cb2f2a6b23bd9c3ca8661599726b88ae505
https://github.com/scummvm/scummvm/commit/c9016cb2f2a6b23bd9c3ca8661599726b88ae505
Author: antoniou79 (a.antoniou79 at gmail.com)
Date: 2023-04-24T09:43:51+03:00
Commit Message:
BLADERUNNER: Notes and minor fixes for sound
Also added a dedicated debugSound channel for debugging
Fixes include closer conformance to original code (for entering/exiting ESPER and VK), and a change in assigning a track slot to a new track with priority equal to the lowest existing (it will now take the place of the old stored track). Also Music::adjustVolume() now takes the target volume as argument and stores it in the track volume field similar to how Music::adjustPan works.
Changed paths:
engines/bladerunner/actor.cpp
engines/bladerunner/ambient_sounds.cpp
engines/bladerunner/ambient_sounds.h
engines/bladerunner/audio_mixer.cpp
engines/bladerunner/audio_mixer.h
engines/bladerunner/audio_player.cpp
engines/bladerunner/audio_player.h
engines/bladerunner/audio_speech.cpp
engines/bladerunner/audio_speech.h
engines/bladerunner/bladerunner.h
engines/bladerunner/detection.cpp
engines/bladerunner/music.cpp
engines/bladerunner/music.h
engines/bladerunner/script/script.cpp
engines/bladerunner/ui/end_credits.cpp
engines/bladerunner/ui/esper.cpp
engines/bladerunner/ui/esper.h
engines/bladerunner/ui/vk.cpp
engines/bladerunner/ui/vk.h
engines/bladerunner/vqa_player.cpp
diff --git a/engines/bladerunner/actor.cpp b/engines/bladerunner/actor.cpp
index 23e54d08d5a..037e2fa8150 100644
--- a/engines/bladerunner/actor.cpp
+++ b/engines/bladerunner/actor.cpp
@@ -1581,6 +1581,7 @@ int Actor::soundVolume() const {
}
// overrideRange argument was added to allow for more accurate sound balance on occasion (if required)
+// overrideRange value should be in [35, 100]
int Actor::soundPan(uint8 overrideRange) const {
Vector3 screenPosition = _vm->_view->calculateScreenPosition(_position);
// By default map [0..640] to [-overrideRange..overrideRange] (default range [-35..35])
diff --git a/engines/bladerunner/ambient_sounds.cpp b/engines/bladerunner/ambient_sounds.cpp
index bc6de09d400..f02a6fdce7a 100644
--- a/engines/bladerunner/ambient_sounds.cpp
+++ b/engines/bladerunner/ambient_sounds.cpp
@@ -42,10 +42,13 @@ AmbientSounds::AmbientSounds(BladeRunnerEngine *vm) {
// In our BladeRunner engine ambient sounds do not have a distinct sound type of their own,
// so they are treated as kAmbientSoundType (default type, see: ambient_sounds.h).
//
- // _ambientVolume here sets a percentage to be appied on the specified track volume
- // before sending it to the audio player
- // (setting _ambientVolume to 100 renders it indifferent)
- _ambientVolume = BLADERUNNER_ORIGINAL_SETTINGS ? 65 : 100;
+ // _ambientVolumeFactorOriginalEngine here sets a percentage to be applied on the ambient audio tracks' volume
+ // before sending them to the audio player.
+ // This is how the original engine set the volume via the in-game KIA volume slider controls.
+ // Setting _ambientVolumeFactorOriginalEngine to 100, for the purposes ScummVM engine, renders it indifferent,
+ // so sound volume can be controlled by ScummVM's Global Main Menu / ConfMan/ syncSoundSettings().
+ // Note however that _ambientVolumeFactorOriginalEngine is also changed when entering and exiting ESPER and possibly VK modes.
+ _ambientVolumeFactorOriginalEngine = BLADERUNNER_ORIGINAL_SETTINGS ? 65 : 100;
for (int i = 0; i != kNonLoopingSounds; ++i) {
NonLoopingSound &track = _nonLoopingSounds[i];
@@ -109,33 +112,39 @@ static inline void sort(uint32 *a, uint32 *b) {
// addSound() will add a track to the non-looping tracks array list
// it will use the kAmbientSoundType for Mixer's Sound Type.
// see AmbientSounds::tick()
-void AmbientSounds::addSound(
- int sfxId,
- uint32 delayMinSeconds, uint32 delayMaxSeconds,
- int volumeMin, int volumeMax,
- int panStartMin, int panStartMax,
- int panEndMin, int panEndMax,
- int priority, int unk) {
-
-#if BLADERUNNER_ORIGINAL_BUGS
-#else
- sort(&delayMinSeconds, &delayMaxSeconds);
-#endif // BLADERUNNER_ORIGINAL_BUGS
- sort(&volumeMin, &volumeMax);
- sort(&panStartMin, &panStartMax);
- sort(&panEndMin, &panEndMax);
-
- addSoundByName(
- _vm->_gameInfo->getSfxTrack(sfxId),
- delayMinSeconds, delayMaxSeconds,
- volumeMin, volumeMax,
- panStartMin, panStartMax,
- panEndMin, panEndMax,
- priority, unk
- );
+// Used also by:
+// Ambient_Sounds_Add_Sound()
+// Spinner::chooseDestination()
+// Calls:
+// addSoundByName()
+//
+// volumeMin, volumeMax should be in [0, 100]
+// panStartMin, panStartMax should be in [-100, 100]
+// panEndMin, panEndMax should be in [-100, 100], with "-101" being a special value for skipping pan (balance) adjustment
+// priority should be in [0, 100]
+void AmbientSounds::addSound(int sfxId,
+ uint32 delayMinSeconds, uint32 delayMaxSeconds,
+ int volumeMin, int volumeMax,
+ int panStartMin, int panStartMax,
+ int panEndMin, int panEndMax,
+ int priority, int unk) {
+ debugC(6, kDebugSound, "AmbientSounds::addSound id:%d dMin:%d,dMax:%d vMin:%d,vMax:%d pSMin:%d,pSMax:%d pEMin:%d,pEMax:%d pr:%d unk:%d",
+ sfxId,
+ delayMinSeconds, delayMaxSeconds,
+ volumeMin, volumeMax,
+ panStartMin,panStartMax,
+ panEndMin, panEndMax,
+ priority, unk);
+ addSoundByName(_vm->_gameInfo->getSfxTrack(sfxId),
+ delayMinSeconds, delayMaxSeconds,
+ volumeMin, volumeMax,
+ panStartMin, panStartMax,
+ panEndMin, panEndMax,
+ priority, unk);
}
void AmbientSounds::removeNonLoopingSound(int sfxId, bool stopPlaying) {
+ debugC(6, kDebugSound, "AmbientSounds::removeNonLoopingSound id:%d stop:%d", sfxId, stopPlaying? 1: 0);
int32 hash = MIXArchive::getHash(_vm->_gameInfo->getSfxTrack(sfxId));
int index = findNonLoopingTrackByHash(hash);
if (index >= 0) {
@@ -144,6 +153,7 @@ void AmbientSounds::removeNonLoopingSound(int sfxId, bool stopPlaying) {
}
void AmbientSounds::removeAllNonLoopingSounds(bool stopPlaying) {
+ debugC(6, kDebugSound, "AmbientSounds::removeAllNonLoopingSounds stop:%d", stopPlaying? 1: 0);
for (int i = 0; i < kNonLoopingSounds; ++i) {
removeNonLoopingSoundByIndex(i, stopPlaying);
}
@@ -153,38 +163,65 @@ void AmbientSounds::removeAllNonLoopingSounds(bool stopPlaying) {
// addSpeech() will add a track to the non-looping tracks array list
// it will use the kAmbientSoundType for Mixer's Sound Type
// see AmbientSounds::tick()
-void AmbientSounds::addSpeech(int actorId, int sentenceId, uint32 delayMinSeconds, uint32 delayMaxSeconds, int volumeMin, int volumeMax, int panStartMin, int panStartMax, int panEndMin, int panEndMax, int priority, int unk) {
-#if BLADERUNNER_ORIGINAL_BUGS
-#else
- sort(&delayMinSeconds, &delayMaxSeconds);
-#endif // BLADERUNNER_ORIGINAL_BUGS
- sort(&volumeMin, &volumeMax);
- sort(&panStartMin, &panStartMax);
- sort(&panEndMin, &panEndMax);
-
+// Mainly used for dispatch radio ambient sounds and blimp announcements.
+// Called by:
+// Ambient_Sounds_Add_Speech_Sound()
+// Calls:
+// addSoundByName()
+//
+// volumeMin, volumeMax should be in [0, 100]
+// panStartMin, panStartMax should be in [-100, 100]
+// panEndMin, panEndMax should be in [-100, 100], with "-101" being a special value for skipping pan (balance) adjustment
+// priority should be in [0, 100]
+void AmbientSounds::addSpeech(int actorId, int sentenceId,
+ uint32 delayMinSeconds, uint32 delayMaxSeconds,
+ int volumeMin, int volumeMax,
+ int panStartMin, int panStartMax,
+ int panEndMin, int panEndMax,
+ int priority, int unk) {
+ debugC(6, kDebugSound, "AmbientSounds::addSpeech id:%d-%d dMin:%d,dMax:%d vMin:%d,vMax:%d pSMin:%d,pSMax:%d pEMin:%d,pEMax:%d pr:%d unk:%d",
+ actorId, sentenceId,
+ delayMinSeconds, delayMaxSeconds,
+ volumeMin, volumeMax,
+ panStartMin,panStartMax,
+ panEndMin, panEndMax,
+ priority, unk);
Common::String name = Common::String::format( "%02d-%04d%s.AUD", actorId, sentenceId, _vm->_languageCode.c_str());
addSoundByName(name,
- delayMinSeconds, delayMaxSeconds,
- volumeMin, volumeMax,
- panStartMin, panStartMax,
- panEndMin, panEndMax,
- priority, unk);
+ delayMinSeconds, delayMaxSeconds,
+ volumeMin, volumeMax,
+ panStartMin, panStartMax,
+ panEndMin, panEndMax,
+ priority, unk);
}
// Explicitly plays a sound effect (sfx) track (specified by id)
// It does not add it as a track to the non-looping tracks array list
// It uses the parameter "type" as the mixer's sound type - which determines the volume setting in effect.
// By default sound type is kAmbientSoundType (see ambient_sounds.h).
+//
+// volume should be in [0, 100]
+// panStart should be in [-100, 100]
+// panEnd should be in [-100, 100]
+// priority should be in [0, 100]
void AmbientSounds::playSound(int sfxId, int volume, int panStart, int panEnd, int priority, Audio::Mixer::SoundType type) {
- _vm->_audioPlayer->playAud(_vm->_gameInfo->getSfxTrack(sfxId), volume * _ambientVolume / 100, panStart, panEnd, priority, kAudioPlayerOverrideVolume, type);
+ debugC(6, kDebugSound, "AmbientSounds::playSound id:%d v:%d pS:%d pE:%d pr:%d typ:%d", sfxId, volume, panStart, panEnd, priority, (int32) type);
+ _vm->_audioPlayer->playAud(_vm->_gameInfo->getSfxTrack(sfxId), (volume * _ambientVolumeFactorOriginalEngine) / 100, panStart, panEnd, priority, kAudioPlayerOverrideVolume, type);
}
// Explicitly plays a speech cue
// It does not add it as a track to the non-looping tracks array list
// It uses mixer's sound type kSpeechSoundType - which determines the volume setting in effect (Speech)
+//
+// volume should be in [0, 100]
+// panStart should be in [-100, 100]
+// panEnd should be in [-100, 100]
+// priority should be in [0, 100]
void AmbientSounds::playSpeech(int actorId, int sentenceId, int volume, int panStart, int panEnd, int priority) {
+ debugC(6, kDebugSound, "AmbientSounds::playSpeech id:%d-%d v:%d pS:%d pE:%d pr:%d", actorId, sentenceId, volume, panStart, panEnd, priority);
Common::String name = Common::String::format( "%02d-%04d%s.AUD", actorId, sentenceId, _vm->_languageCode.c_str());
- _vm->_audioPlayer->playAud(name, volume * _ambientVolume / 100, panStart, panEnd, priority, kAudioPlayerOverrideVolume, Audio::Mixer::kSpeechSoundType);
+ // (volume * _ambientVolume) / 100 should result in a value in [0, 100]
+ _vm->_audioPlayer->playAud(name, (volume * _ambientVolumeFactorOriginalEngine) / 100, panStart, panEnd, priority, kAudioPlayerOverrideVolume, Audio::Mixer::kSpeechSoundType);
}
// Looping Sound will use paramerter "type" as the mixer's SoundType when playing this track.
@@ -197,7 +234,11 @@ void AmbientSounds::playSpeech(int actorId, int sentenceId, int volume, int panS
// which is skipped for *both* looping and non-looping tracks in save() and load() code
// However, the issue is negligible; the default SoundType for looping tracks is overridden
// only in one special case so far (restored content Outtake "FLYTRU_E.VQA", see: outtake.cpp)
+//
+// volume should be in [0, 100]
+// pan should be in [-100, 100]
void AmbientSounds::addLoopingSound(int sfxId, int volume, int pan, uint32 delaySeconds, Audio::Mixer::SoundType type) {
+ debugC(6, kDebugSound, "AmbientSounds::addLoopingSound id:%d v:%d p:%d d:%u typ:%d", sfxId, volume, pan, delaySeconds, (int32) type);
const Common::String &name = _vm->_gameInfo->getSfxTrack(sfxId);
int32 hash = MIXArchive::getHash(name);
@@ -218,13 +259,16 @@ void AmbientSounds::addLoopingSound(int sfxId, int volume, int pan, uint32 delay
track.volume = volume;
track.soundType = (int32) type;
- int actualVolumeStart = volume * _ambientVolume / 100;
+ int actualVolumeStart = (volume * _ambientVolumeFactorOriginalEngine) / 100;
int actualVolumeEnd = actualVolumeStart;
if (delaySeconds > 0u) {
actualVolumeStart = 0;
}
+ // actualVolumeStart should be in [0, 100]
+ // pan should be in [-100, 100]
+ // priority should be in [0, 100]
track.audioPlayerTrack = _vm->_audioPlayer->playAud(name, actualVolumeStart, pan, pan, 99, kAudioPlayerLoop | kAudioPlayerOverrideVolume, type);
if (track.audioPlayerTrack == -1) {
@@ -236,14 +280,17 @@ void AmbientSounds::addLoopingSound(int sfxId, int volume, int pan, uint32 delay
}
}
+// volume should be in [0, 100], with "-1" being a special value for skipping volume adjustment
+// pan should be in [-100, 100], with "-101" being a special value for skipping pan (balance) adjustment
void AmbientSounds::adjustLoopingSound(int sfxId, int volume, int pan, uint32 delaySeconds) {
+ debugC(6, kDebugSound, "AmbientSounds::adjustLoopingSound id:%d v:%d p:%d d:%u", sfxId, volume, pan, delaySeconds);
int32 hash = MIXArchive::getHash(_vm->_gameInfo->getSfxTrack(sfxId));
int index = findLoopingTrackByHash(hash);
if (index >= 0 && _loopingSounds[index].audioPlayerTrack != -1 && _vm->_audioPlayer->isActive(_loopingSounds[index].audioPlayerTrack)) {
if (volume != -1) {
_loopingSounds[index].volume = volume;
- _vm->_audioPlayer->adjustVolume(_loopingSounds[index].audioPlayerTrack, _ambientVolume * volume / 100, delaySeconds, false);
+ _vm->_audioPlayer->adjustVolume(_loopingSounds[index].audioPlayerTrack, (volume * _ambientVolumeFactorOriginalEngine) / 100, delaySeconds, false);
}
if (pan != -101) {
_loopingSounds[index].pan = pan;
@@ -253,6 +300,7 @@ void AmbientSounds::adjustLoopingSound(int sfxId, int volume, int pan, uint32 de
}
void AmbientSounds::removeLoopingSound(int sfxId, uint32 delaySeconds) {
+ debugC(6, kDebugSound, "AmbientSounds::removeLoopingSound id:%d d:%u", sfxId, delaySeconds);
int32 hash = MIXArchive::getHash(_vm->_gameInfo->getSfxTrack(sfxId));
int index = findLoopingTrackByHash(hash);
if (index >= 0) {
@@ -261,6 +309,7 @@ void AmbientSounds::removeLoopingSound(int sfxId, uint32 delaySeconds) {
}
void AmbientSounds::removeAllLoopingSounds(uint32 delaySeconds) {
+ debugC(6, kDebugSound, "AmbientSounds::removeAllLoopingSounds d:%u", delaySeconds);
for (int i = 0; i < kLoopingSounds; ++i) {
removeLoopingSoundByIndex(i, delaySeconds);
}
@@ -280,10 +329,12 @@ void AmbientSounds::tick() {
int panEnd;
int panStart = _vm->_rnd.getRandomNumberRng(track.panStartMin, track.panStartMax);
- if (track.panEndMin == -101) {
- panEnd = panStart;
- } else {
+ // typically when using the -101 special value, both panEndMin and panEndMax have this value
+ // -101 here means "do not adjust the panning for the track (while it's playing)"
+ if (track.panEndMin != -101) {
panEnd = _vm->_rnd.getRandomNumberRng(track.panEndMin, track.panEndMax);
+ } else {
+ panEnd = panStart;
}
track.volume = _vm->_rnd.getRandomNumberRng(track.volumeMin, track.volumeMax);
@@ -293,7 +344,7 @@ void AmbientSounds::tick() {
mixerAmbientSoundType = (Audio::Mixer::SoundType) track.soundType;
}
track.audioPlayerTrack = _vm->_audioPlayer->playAud(track.name,
- track.volume * _ambientVolume / 100,
+ (track.volume * _ambientVolumeFactorOriginalEngine) / 100,
panStart,
panEnd,
track.priority,
@@ -305,11 +356,19 @@ void AmbientSounds::tick() {
}
}
+// TODO Evaluate if for ScummVM we can avoid using and modifying _ambientVolumeFactorOriginalEngine altogether.
+// While we no longer use the original engine's mechanism to set the ambient sounds volume
+// with the AmbientSounds::setVolume() public method, when using the in-game KIA volume slider,
+// we do use this method as did the original engine to temporarily set the volume levels
+// in ESPER and VK modes.
+// This affects only looping ambient sounds.
+// volume should be in [0, 100]
void AmbientSounds::setVolume(int volume) {
+ debugC(6, kDebugSound, "AmbientSounds::setVolume v:%d", volume);
if (_loopingSounds) {
for (int i = 0; i < kLoopingSounds; ++i) {
if (_loopingSounds[i].isActive && _loopingSounds[i].audioPlayerTrack != -1) {
- int newVolume = _loopingSounds[i].volume * volume / 100;
+ int newVolume = (_loopingSounds[i].volume * volume) / 100;
if (_vm->_audioPlayer->isActive(_loopingSounds[i].audioPlayerTrack)) {
_vm->_audioPlayer->adjustVolume(_loopingSounds[i].audioPlayerTrack, newVolume, 1u, false);
} else {
@@ -327,14 +386,15 @@ void AmbientSounds::setVolume(int volume) {
}
}
}
- _ambientVolume = volume;
+ _ambientVolumeFactorOriginalEngine = volume;
}
int AmbientSounds::getVolume() const {
- return _ambientVolume;
+ return _ambientVolumeFactorOriginalEngine;
}
void AmbientSounds::playSample() {
+ // Original uses priority 0 here also
playSound(kSfxSPIN1A, 100, 0, 0, 0);
}
@@ -382,13 +442,16 @@ int AmbientSounds::findLoopingTrackByHash(int32 hash) const {
return -1;
}
-void AmbientSounds::addSoundByName(
- const Common::String &name,
- uint32 delayMinSeconds, uint32 delayMaxSeconds,
- int volumeMin, int volumeMax,
- int panStartMin, int panStartMax,
- int panEndMin, int panEndMax,
- int priority, int unk) {
+// volumeMin, volumeMax should be in [0, 100]
+// panStartMin, panStartMax should be in [-100, 100]
+// panEndMin, panEndMax should be in [-100, 100], with "-101" being a special value for skipping pan (balance) adjustment
+// priority should be in [0, 100]
+void AmbientSounds::addSoundByName(const Common::String &name,
+ uint32 delayMinSeconds, uint32 delayMaxSeconds,
+ int volumeMin, int volumeMax,
+ int panStartMin, int panStartMax,
+ int panEndMin, int panEndMax,
+ int priority, int unk) {
int i = findAvailableNonLoopingTrack();
if (i < 0) {
@@ -399,13 +462,12 @@ void AmbientSounds::addSoundByName(
uint32 now = _vm->_time->current();
-#if BLADERUNNER_ORIGINAL_BUGS
-#else
+#if !BLADERUNNER_ORIGINAL_BUGS
sort(&delayMinSeconds, &delayMaxSeconds);
+#endif // BLADERUNNER_ORIGINAL_BUGS
sort(&volumeMin, &volumeMax);
sort(&panStartMin, &panStartMax);
sort(&panEndMin, &panEndMax);
-#endif // BLADERUNNER_ORIGINAL_BUGS
track.isActive = true;
track.name = name;
@@ -594,11 +656,13 @@ void AmbientSounds::load(SaveFileReadStream &f) {
if (track.soundType >= 0) {
mixerAmbientSoundType = (Audio::Mixer::SoundType) track.soundType;
}
+ // Looping sound (loaded) gets high priority (99)
+ // Also started with volume at 1 (but adjusted below appropriately)
track.audioPlayerTrack = _vm->_audioPlayer->playAud(track.name, 1, track.pan, track.pan, 99, kAudioPlayerLoop | kAudioPlayerOverrideVolume, mixerAmbientSoundType);
if (track.audioPlayerTrack == -1) {
removeLoopingSoundByIndex(i, 0u);
} else {
- _vm->_audioPlayer->adjustVolume(track.audioPlayerTrack, _ambientVolume * track.volume / 100, 2u, false);
+ _vm->_audioPlayer->adjustVolume(track.audioPlayerTrack, (track.volume * _ambientVolumeFactorOriginalEngine) / 100, 2u, false);
}
}
}
diff --git a/engines/bladerunner/ambient_sounds.h b/engines/bladerunner/ambient_sounds.h
index eb797c6991f..98b45f64c03 100644
--- a/engines/bladerunner/ambient_sounds.h
+++ b/engines/bladerunner/ambient_sounds.h
@@ -22,6 +22,8 @@
#ifndef BLADERUNNER_AMBIENT_SOUNDS_H
#define BLADERUNNER_AMBIENT_SOUNDS_H
+#include "bladerunner/bladerunner.h" // For BLADERUNNER_ORIGINAL_SETTINGS symbol
+
#include "audio/audiostream.h"
#include "audio/mixer.h"
@@ -47,15 +49,15 @@ class AmbientSounds {
uint32 delayMax; // milliseconds
uint32 nextPlayTimeStart; // milliseconds
uint32 nextPlayTimeDiff; // milliseconds
- int volumeMin;
- int volumeMax;
- int volume;
- int panStartMin;
- int panStartMax;
- int panEndMin;
- int panEndMax;
- int priority;
- int32 soundType; // new - not stored in saved games
+ int volumeMin; // should be in [0, 100]
+ int volumeMax; // should be in [0, 100]
+ int volume; // should be in [0, 100] (calculated as a random value within [volumeMin, volumeMax]
+ int panStartMin; // should be in [-100, 100]
+ int panStartMax; // should be in [-100, 100]
+ int panEndMin; // should be in [-100, 100], with "-101" being a special value for skipping pan (balance) adjustment
+ int panEndMax; // should be in [-100, 100], with "-101" being a special value for skipping pan (balance) adjustment
+ int priority; // should be in [0, 100]
+ int32 soundType; // new - not stored in saved games
};
struct LoopingSound {
@@ -63,8 +65,8 @@ class AmbientSounds {
Common::String name;
int32 hash;
int audioPlayerTrack;
- int volume;
- int pan;
+ int volume; // should be in [0, 100]
+ int pan; // should be in [-100, 100]
int32 soundType; // new - not stored in saved games
};
@@ -72,30 +74,27 @@ class AmbientSounds {
NonLoopingSound *_nonLoopingSounds;
LoopingSound *_loopingSounds;
- int _ambientVolume;
+ int _ambientVolumeFactorOriginalEngine; // should be in [0, 100]
public:
AmbientSounds(BladeRunnerEngine *vm);
~AmbientSounds();
- void addSound(
- int sfxId,
- uint32 delayMinSeconds, uint32 delayMaxSeconds,
- int volumeMin, int volumeMax,
- int panStartMin, int panStartMax,
- int panEndMin, int panEndMax,
- int priority, int unk
- );
+ void addSound(int sfxId,
+ uint32 delayMinSeconds, uint32 delayMaxSeconds,
+ int volumeMin, int volumeMax,
+ int panStartMin, int panStartMax,
+ int panEndMin, int panEndMax,
+ int priority, int unk);
void removeNonLoopingSound(int sfxId, bool stopPlaying);
void removeAllNonLoopingSounds(bool stopPlaying);
- void addSpeech(
- int actorId, int sentenceId,
- uint32 delayMinSeconds, uint32 delayMaxSeconds,
- int volumeMin, int volumeMax,
- int panStartMin, int panStartMax,
- int panEndMin, int panEndMax,
- int priority, int unk);
+ void addSpeech(int actorId, int sentenceId,
+ uint32 delayMinSeconds, uint32 delayMaxSeconds,
+ int volumeMin, int volumeMax,
+ int panStartMin, int panStartMax,
+ int panEndMin, int panEndMax,
+ int priority, int unk);
void playSound(int sfxId, int volume, int panStart, int panEnd, int priority, Audio::Mixer::SoundType type = kAmbientSoundType);
void playSpeech(int actorId, int sentenceId, int volume, int panStart, int panEnd, int priority);
@@ -122,13 +121,12 @@ private:
int findAvailableLoopingTrack() const;
int findLoopingTrackByHash(int32 hash) const;
- void addSoundByName(
- const Common::String &name,
- uint32 delayMinSeconds, uint32 delayMaxSeconds,
- int volumeMin, int volumeMax,
- int panStartMin, int panStartMax,
- int panEndMin, int panEndMax,
- int priority, int unk);
+ void addSoundByName(const Common::String &name,
+ uint32 delayMinSeconds, uint32 delayMaxSeconds,
+ int volumeMin, int volumeMax,
+ int panStartMin, int panStartMax,
+ int panEndMin, int panEndMax,
+ int priority, int unk);
void removeNonLoopingSoundByIndex(int index, bool stopPlaying);
void removeLoopingSoundByIndex(int index, uint32 delaySeconds);
diff --git a/engines/bladerunner/audio_mixer.cpp b/engines/bladerunner/audio_mixer.cpp
index b4d0a793d83..55d1e700a23 100644
--- a/engines/bladerunner/audio_mixer.cpp
+++ b/engines/bladerunner/audio_mixer.cpp
@@ -54,15 +54,17 @@ AudioMixer::~AudioMixer() {
_vm->getTimerManager()->removeTimerProc(timerCallback);
}
+// volume should be in [0, 100]
+// pan should be in [-100, 100]
+// priority should be in [0, 100]
int AudioMixer::play(Audio::Mixer::SoundType type, Audio::RewindableAudioStream *stream, int priority, bool loop, int volume, int pan, void (*endCallback)(int, void *), void *callbackData, uint32 trackDurationMs) {
Common::StackLock lock(_mutex);
-
- int channel = -1;
+ int channelToAssign = -1;
int lowestPriority = 1000000;
int lowestPriorityChannel = -1;
for (int i = 0; i < kUsableChannels; ++i) {
if (!_channels[i].isPresent) {
- channel = i;
+ channelToAssign = i;
break;
}
if (_channels[i].priority < lowestPriority) {
@@ -70,22 +72,28 @@ int AudioMixer::play(Audio::Mixer::SoundType type, Audio::RewindableAudioStream
lowestPriorityChannel = i;
}
}
- if (channel == -1) {
+
+ // If there's no available channel found
+ if (channelToAssign == -1) {
+ // Give up if the lowest priority channel still has greater priority (lowestPriority).
+ // NOTE If the new priority is *equal* to the existing lowestPriority,
+ // then the new audio will replace the old one.
if (priority < lowestPriority) {
//debug("No available audio channel found - giving up");
return -1;
}
+ // Otherwise, stop the lowest priority channel, and assign the slot to the new one.
//debug("Stopping lowest priority channel %d with lower prio %d!", lowestPriorityChannel, lowestPriority);
stop(lowestPriorityChannel, 0u);
- channel = lowestPriorityChannel;
+ channelToAssign = lowestPriorityChannel;
}
- return playInChannel(channel, type, stream, priority, loop, volume, pan, endCallback, callbackData, trackDurationMs);
+ return playInChannel(channelToAssign, type, stream, priority, loop, volume, pan, endCallback, callbackData, trackDurationMs);
}
+// volume should be in [0, 100]
int AudioMixer::playMusic(Audio::RewindableAudioStream *stream, int volume, void(*endCallback)(int, void *), void *callbackData, uint32 trackDurationMs) {
Common::StackLock lock(_mutex);
-
return playInChannel(kMusicChannel, Audio::Mixer::kMusicSoundType, stream, 100, false, volume, 0, endCallback, callbackData, trackDurationMs);
}
@@ -109,6 +117,9 @@ void AudioMixer::stop(int channel, uint32 time) {
}
}
+// volume should be in [0, 100]
+// pan should be in [-100, 100]
+// priority should be in [0, 100]
int AudioMixer::playInChannel(int channel, Audio::Mixer::SoundType type, Audio::RewindableAudioStream *stream, int priority, bool loop, int volume, int pan, void(*endCallback)(int, void *), void *callbackData, uint32 trackDurationMs) {
_channels[channel].isPresent = true;
_channels[channel].stream = stream;
@@ -137,13 +148,15 @@ int AudioMixer::playInChannel(int channel, Audio::Mixer::SoundType type, Audio::
}
_channels[channel].sentToMixer = true;
- _vm->_mixer->playStream(
- type,
- &_channels[channel].handle,
- audioStream,
- -1,
- volume * 255 / 100,
- pan * 127 / 100);
+ // Note: 127 (multiplier for pan) is the max (abs) balance value (see common/mixer.cpp)
+ _vm->_mixer->playStream(type,
+ &_channels[channel].handle,
+ audioStream,
+ -1,
+ (volume * Audio::Mixer::kMaxChannelVolume) / 100, // the resulting value will be a percentage over kMaxChannelVolume
+ // playStream() will get the soundtype volume into consideration
+ // See: Channel::updateChannelVolumes() in audio/mixer.cpp
+ (pan * 127) / 100);
return channel;
}
@@ -160,24 +173,30 @@ void AudioMixer::timerCallback(void *self) {
((AudioMixer *)self)->tick();
}
+// This method sets the target volume (as a percent) and the delta increment or decrement
+// to reach the target in the specified time.
// Note: time tends to be the requested time in seconds multiplied by 60u
-void AudioMixer::adjustVolume(int channel, int newVolume, uint32 time) {
+// targetVolume should be in [0, 100]
+void AudioMixer::adjustVolume(int channel, int targetVolume, uint32 time) {
Common::StackLock lock(_mutex);
if (_channels[channel].isPresent) {
- _channels[channel].volumeTarget = newVolume;
- _channels[channel].volumeDelta = ((newVolume - _channels[channel].volume) / (time / 60.0f)) / (float)kUpdatesPerSecond;
+ _channels[channel].volumeTarget = targetVolume;
+ _channels[channel].volumeDelta = ((targetVolume - _channels[channel].volume) / (time / 60.0f)) / (float)kUpdatesPerSecond;
}
}
+// This method sets the target pan (as a percent) and the delta increment or decrement
+// to reach the target in the specified time.
// Note: time tends to be the requested time in seconds multiplied by 60u
-void AudioMixer::adjustPan(int channel, int newPan, uint32 time) {
+// targetPan should be in [-100, 100]
+void AudioMixer::adjustPan(int channel, int targetPan, uint32 time) {
Common::StackLock lock(_mutex);
if (_channels[channel].isPresent) {
- newPan = CLIP(newPan, -100, 100);
- _channels[channel].panTarget = newPan;
- _channels[channel].panDelta = ((newPan - _channels[channel].pan) / (time / 60.0f)) / (float)kUpdatesPerSecond;
+ targetPan = CLIP(targetPan, -100, 100);
+ _channels[channel].panTarget = targetPan;
+ _channels[channel].panDelta = ((targetPan - _channels[channel].pan) / (time / 60.0f)) / (float)kUpdatesPerSecond;
}
}
@@ -200,7 +219,8 @@ void AudioMixer::tick() {
}
if (channel->sentToMixer) {
- _vm->_mixer->setChannelVolume(channel->handle, (channel->volume * Audio::Mixer::kMaxChannelVolume) / 100); // map [0..100] to [0..kMaxChannelVolume]
+ // map volume value from [0..100] to [0..kMaxChannelVolume]
+ _vm->_mixer->setChannelVolume(channel->handle, (channel->volume * Audio::Mixer::kMaxChannelVolume) / 100);
}
if (channel->volume <= 0.0f) {
@@ -217,7 +237,8 @@ void AudioMixer::tick() {
}
if (channel->sentToMixer) {
- _vm->_mixer->setChannelBalance(channel->handle, (channel->pan * 127) / 100); // map [-100..100] to [-127..127]
+ // map balance value from [-100..100] to [-127..127]
+ _vm->_mixer->setChannelBalance(channel->handle, (channel->pan * 127) / 100);
}
}
diff --git a/engines/bladerunner/audio_mixer.h b/engines/bladerunner/audio_mixer.h
index 08637557035..518271eebf1 100644
--- a/engines/bladerunner/audio_mixer.h
+++ b/engines/bladerunner/audio_mixer.h
@@ -60,12 +60,12 @@ class AudioMixer {
bool loop;
Audio::SoundHandle handle;
Audio::AudioStream *stream;
- float volume;
+ float volume; // should be in [0.0f, 100.0f]. It's percent for the Audio::Mixer::kMaxChannelVolume
float volumeDelta;
- float volumeTarget;
- float pan;
+ float volumeTarget; // should be in [0.0f, 100.0f], as for volume field.
+ float pan; // should be in [-100.0f, 100.0f]. It's percent for 127 (max absolute balance value)
float panDelta;
- float panTarget;
+ float panTarget; // should be in [-100.0f, 100.0f], as for pan field.
void (*endCallback)(int channel, void *data);
void *callbackData;
uint32 timeStarted;
@@ -96,8 +96,8 @@ public:
int playMusic(Audio::RewindableAudioStream *stream, int volume, void(*endCallback)(int, void *), void *callbackData, uint32 trackDurationMs);
void stop(int channel, uint32 time);
- void adjustVolume(int channel, int newVolume, uint32 time);
- void adjustPan(int channel, int newPan, uint32 time);
+ void adjustVolume(int channel, int targetVolume, uint32 time);
+ void adjustPan(int channel, int targetPan, uint32 time);
#if !BLADERUNNER_ORIGINAL_BUGS
void startAppTimerProc(int audioMixAppTimerId, uint32 intervalMillis);
diff --git a/engines/bladerunner/audio_player.cpp b/engines/bladerunner/audio_player.cpp
index f82f023fc83..6fc9d76b83d 100644
--- a/engines/bladerunner/audio_player.cpp
+++ b/engines/bladerunner/audio_player.cpp
@@ -47,10 +47,12 @@ AudioPlayer::AudioPlayer(BladeRunnerEngine *vm) {
_tracks[i].stream = nullptr;
}
- // _sfxVolume here sets a percentage to be appied on the specified track volume
- // before sending it to the audio player
- // (setting _sfxVolume to 100 renders it indifferent)
- _sfxVolume = BLADERUNNER_ORIGINAL_SETTINGS ? 65 : 100;
+ // _sfxVolumeFactorOriginalEngine here sets a percentage to be applied on the audio tracks' volume
+ // before sending them to the audio player.
+ // This is how the original engine set the volume via the in-game KIA volume slider controls.
+ // Setting _sfxVolumeFactorOriginalEngine to 100, for the purposes ScummVM engine, renders it indifferent,
+ // so sound volume can be controlled by ScummVM's Global Main Menu / ConfMan/ syncSoundSettings().
+ _sfxVolumeFactorOriginalEngine = BLADERUNNER_ORIGINAL_SETTINGS ? 65 : 100;
}
AudioPlayer::~AudioPlayer() {
@@ -68,20 +70,26 @@ void AudioPlayer::stopAll() {
}
}
-void AudioPlayer::adjustVolume(int track, int volume, uint32 delaySeconds, bool overrideVolume) {
+// This method sets the target volume (as a percent) for the track
+// and the time (delaySeconds) to reach that target in.
+// volume (and actualVolume) should be in [0, 100]
+void AudioPlayer::adjustVolume(int track, int volume, uint32 delaySeconds, bool explicitVolumeAdjustment) {
if (track < 0 || track >= kTracks || !_tracks[track].isActive || _tracks[track].channel == -1) {
return;
}
int actualVolume = volume;
- if (!overrideVolume) {
- actualVolume = actualVolume * _sfxVolume / 100;
+ if (explicitVolumeAdjustment) {
+ actualVolume = (actualVolume * _sfxVolumeFactorOriginalEngine) / 100;
}
_tracks[track].volume = actualVolume;
_vm->_audioMixer->adjustVolume(_tracks[track].channel, actualVolume, 60u * delaySeconds);
}
+// This method sets the target pan (as a percent) for the track
+// and the time (delaySeconds) to reach that target in.
+// pan should be in [-100, 100]
void AudioPlayer::adjustPan(int track, int pan, uint32 delaySeconds) {
if (track < 0 || track >= kTracks || !_tracks[track].isActive || _tracks[track].channel == -1) {
return;
@@ -91,30 +99,40 @@ void AudioPlayer::adjustPan(int track, int pan, uint32 delaySeconds) {
_vm->_audioMixer->adjustPan(_tracks[track].channel, pan, 60u * delaySeconds);
}
-// We no longer set the _sfxVolume (audio player's default volume percent) via a public method
-// It is set in AudioPlayer::AudioPlayer() constructor and keeps its value constant.
-//void AudioPlayer::setVolume(int volume) {
-// _sfxVolume = volume;
-//}
+#if BLADERUNNER_ORIGINAL_SETTINGS
+// We no longer set the _sfxVolumeFactorOriginalEngine via a public method.
+// For the ScummVM Engine's purposes it is set in AudioPlayer::AudioPlayer() constructor and keeps its value constant.
+void AudioPlayer::setVolume(int volume) {
+ _sfxVolumeFactorOriginalEngine = volume;
+}
int AudioPlayer::getVolume() const {
- return _sfxVolume;
+ return _sfxVolumeFactorOriginalEngine;
}
+#endif // BLADERUNNER_ORIGINAL_SETTINGS
void AudioPlayer::playSample() {
Common::String name;
- int rnd = _vm->_rnd.getRandomNumber(3);
- if (rnd == 0) {
+ switch (_vm->_rnd.getRandomNumber(3)) {
+ case 0:
name = "gunmiss1.aud";
- } else if (rnd == 1) {
+ break;
+
+ case 1:
name = "gunmiss2.aud";
- } else if (rnd == 2) {
+ break;
+
+ case 2:
name = "gunmiss3.aud";
- } else {
+ break;
+
+ default:
name = "gunmiss4.aud";
+ break;
}
+ // Sample plays with priority 100 (max)
playAud(name, 100, 0, 0, 100, 0);
}
@@ -136,41 +154,64 @@ void AudioPlayer::mixerChannelEnded(int channel, void *data) {
audioPlayer->remove(channel);
}
+// This method plays an audio file, at volume "volume" (as a percent, set immediately, no fade-in),
+// with audio balance starting at panStart (as a signed percent) and ending at panEnd.
+// The balance shifting happens throughout the duration of the audio track.
+// volume (and actualVolume) should be in [0, 100]
+// panStart and panEnd should be in [-100, 100]
+// priority should be in [0, 100]
+// The higher the priority, the more likely it is that this track will replace another active one
+// (with the lowest priority), if no available track slots exists.
+// Returns the index of the track slot assigned (for _tracks array) or -1 otherwise (gave up)
+// The code here is very similar to AudioMixer::play()
+// Note that this method calls AudioMixer::play() which also uses the priority value to assign a channel to the track.
+// If that fails, the new track is dropped (gave up).
+// TODO Maybe explain why we need this two step priority check (for track slot and then channel slot)
int AudioPlayer::playAud(const Common::String &name, int volume, int panStart, int panEnd, int priority, byte flags, Audio::Mixer::SoundType type) {
- /* Find first available track or, alternatively, the lowest priority playing track */
- int track = -1;
- int lowestPriority = 1000000;
- int lowestPriorityTrack = -1;
+ debugC(6, kDebugSound, "AudioPlayer::playAud name:%s v:%d pS:%d pE:%d pr:%d type:%d", name.c_str(), volume, panStart, panEnd, priority, (int)type);
+ // Find first available track or, alternatively, the lowest priority playing track
+ int trackSlotToAssign = -1;
+ int lowestPriority = 1000000; // TODO wouldn't a lower value work as well? eg. 1000? Original uses 100 but code is a bit different
+ int lowestPriorityTrackSlot = -1;
+ // Find an available track slot
for (int i = 0; i != kTracks; ++i) {
if (!isActive(i)) {
//debug("Assigned track %i to %s", i, name.c_str());
- track = i;
+ trackSlotToAssign = i;
break;
}
- if (lowestPriorityTrack == -1 || _tracks[i].priority < lowestPriority) {
+ if (lowestPriorityTrackSlot == -1 || _tracks[i].priority < lowestPriority) {
lowestPriority = _tracks[i].priority;
- lowestPriorityTrack = i;
+ lowestPriorityTrackSlot = i;
}
}
- /* If there's no available track, stop the lowest priority track if it's lower than
- * the new priority
- */
- if (track == -1 && lowestPriority < priority) {
- //debug("Stop lowest priority track (with lower prio: %d %d), for %s %d!", lowestPriorityTrack, lowestPriority, name.c_str(), priority);
- stop(lowestPriorityTrack, true);
- track = lowestPriorityTrack;
- }
-
- /* If there's still no available track, give up */
- if (track == -1) {
- //debug("No available track for %s %d - giving up", name.c_str(), priority);
- return -1;
+ // If there's still no available track slot
+ if (trackSlotToAssign == -1) {
+ // Give up if the lowest priority track still has greater priority (lowestPriority).
+#if BLADERUNNER_ORIGINAL_BUGS
+ // NOTE If the new priority is *equal* to the existing lowestPriority,
+ // then the new audio would still not replace the old one.
+ if (priority <= lowestPriority) {
+ return -1;
+ }
+#else
+ // NOTE If the new priority is *equal* to the existing lowestPriority,
+ // then the new audio will replace the old one.
+ if (priority < lowestPriority) {
+ //debug("No available track for %s %d - giving up", name.c_str(), priority);
+ return -1;
+ }
+#endif
+ // Otherwise, stop the lowest priority track, and assign the slot to the new one.
+ //debug("Stop lowest priority track (with lower prio: %d %d), for %s %d!", lowestPriorityTrackSlot, lowestPriority, name.c_str(), priority);
+ stop(lowestPriorityTrackSlot, true);
+ trackSlotToAssign = lowestPriorityTrackSlot;
}
- /* Load audio resource and store in cache. Playback will happen directly from there. */
+ // Load audio resource and store in cache. Playback will happen directly from there.
int32 hash = MIXArchive::getHash(name);
if (!_vm->_audioCache->findByHash(hash)) {
Common::SeekableReadStream *r = _vm->getResourceStream(_vm->_enhancedEdition ? ("audio/" + name) : name);
@@ -195,20 +236,18 @@ int AudioPlayer::playAud(const Common::String &name, int volume, int panStart, i
int actualVolume = volume;
if (!(flags & kAudioPlayerOverrideVolume)) {
- actualVolume = _sfxVolume * volume / 100;
+ actualVolume = (actualVolume * _sfxVolumeFactorOriginalEngine) / 100;
}
- int channel = _vm->_audioMixer->play(
- type,
- audioStream,
- priority,
- flags & kAudioPlayerLoop,
- actualVolume,
- panStart,
- mixerChannelEnded,
- this,
- audioStream->getLength()
- );
+ int channel = _vm->_audioMixer->play(type,
+ audioStream,
+ priority,
+ flags & kAudioPlayerLoop,
+ actualVolume,
+ panStart,
+ mixerChannelEnded,
+ this,
+ audioStream->getLength());
if (channel == -1) {
delete audioStream;
@@ -220,13 +259,13 @@ int AudioPlayer::playAud(const Common::String &name, int volume, int panStart, i
_vm->_audioMixer->adjustPan(channel, panEnd, (60u * audioStream->getLength()) / 1000u);
}
- _tracks[track].isActive = true;
- _tracks[track].channel = channel;
- _tracks[track].priority = priority;
- _tracks[track].volume = actualVolume;
- _tracks[track].stream = audioStream;
+ _tracks[trackSlotToAssign].isActive = true;
+ _tracks[trackSlotToAssign].channel = channel;
+ _tracks[trackSlotToAssign].priority = priority;
+ _tracks[trackSlotToAssign].volume = actualVolume;
+ _tracks[trackSlotToAssign].stream = audioStream;
- return track;
+ return trackSlotToAssign;
}
bool AudioPlayer::isActive(int track) const {
diff --git a/engines/bladerunner/audio_player.h b/engines/bladerunner/audio_player.h
index b0ec5ad6d54..7ae240c74a4 100644
--- a/engines/bladerunner/audio_player.h
+++ b/engines/bladerunner/audio_player.h
@@ -29,7 +29,7 @@
#include "audio/audiostream.h"
#include "audio/mixer.h"
-#include "bladerunner/bladerunner.h" // For BLADERUNNER_ORIGINAL_BUGS symbol
+#include "bladerunner/bladerunner.h" // For BLADERUNNER_ORIGINAL_BUGS and BLADERUNNER_ORIGINAL_SETTINGS symbols
namespace BladeRunner {
@@ -56,8 +56,8 @@ class AudioPlayer {
bool isActive;
int channel;
int priority;
- int volume;
- int pan;
+ int volume; // should be in [0, 100]
+ int pan; // should be in [-100, 100]
AudStream *stream;
};
@@ -65,7 +65,7 @@ class AudioPlayer {
Common::Mutex _mutex;
Track _tracks[kTracks];
- int _sfxVolume;
+ int _sfxVolumeFactorOriginalEngine; // should be in [0, 100] - Unused in ScummVM Engine, used in original engine
public:
AudioPlayer(BladeRunnerEngine *vm);
@@ -76,11 +76,13 @@ public:
uint32 getLength(int track) const;
void stop(int track, bool immediately);
void stopAll();
- void adjustVolume(int track, int volume, uint32 delaySeconds, bool overrideVolume);
+ void adjustVolume(int track, int volume, uint32 delaySeconds, bool explicitVolumeAdjustment);
void adjustPan(int track, int pan, uint32 delaySeconds);
-// void setVolume(int volume);
+#if BLADERUNNER_ORIGINAL_SETTINGS
+ void setVolume(int volume);
int getVolume() const;
+#endif // BLADERUNNER_ORIGINAL_SETTINGS
void playSample();
private:
diff --git a/engines/bladerunner/audio_speech.cpp b/engines/bladerunner/audio_speech.cpp
index 6840b6c0629..3015bcb6cb3 100644
--- a/engines/bladerunner/audio_speech.cpp
+++ b/engines/bladerunner/audio_speech.cpp
@@ -48,10 +48,12 @@ void AudioSpeech::mixerChannelEnded(int channel, void *data) {
AudioSpeech::AudioSpeech(BladeRunnerEngine *vm) {
_vm = vm;
- // _speechVolume here sets a percentage to be appied on the specified voice cue volume
- // before sending it to the audio player
- // (setting _speechVolume to 100 renders it indifferent)
- _speechVolume = BLADERUNNER_ORIGINAL_SETTINGS ? 50 : 100;
+ // _speechVolumeFactorOriginalEngine here sets a percentage to be applied on the voice cues' volume
+ // before sending them to the audio player.
+ // This is how the original engine set the volume via the in-game KIA volume slider controls.
+ // Setting _speechVolumeFactorOriginalEngine to 100, for the purposes ScummVM engine, renders it indifferent,
+ // so sound volume can be controlled by ScummVM's Global Main Menu / ConfMan/ syncSoundSettings().
+ _speechVolumeFactorOriginalEngine = BLADERUNNER_ORIGINAL_SETTINGS ? 50 : 100;
_isActive = false;
_data = new byte[kBufferSize];
_channel = -1;
@@ -66,6 +68,7 @@ AudioSpeech::~AudioSpeech() {
delete[] _data;
}
+// pan should be in [-100, 100]
bool AudioSpeech::playSpeech(const Common::String &name, int pan) {
if (isPlaying()) {
stopSpeech();
@@ -98,16 +101,19 @@ bool AudioSpeech::playSpeech(const Common::String &name, int pan) {
AudStream *audioStream = new AudStream(_data, _vm->_shortyMode ? 33000 : -1);
- _channel = _vm->_audioMixer->play(
- Audio::Mixer::kSpeechSoundType,
- audioStream,
- 100,
- false,
- _speechVolume,
- pan,
- mixerChannelEnded,
- this,
- audioStream->getLength());
+ // Speech plays here with priority 100 (max)
+ // Using directly _speechVolumeFactorOriginalEngine as the volume for audioMixer::play(),
+ // which for the ScummVM engine is 100, so speech volume will be only determined
+ // by the ScummVM volume for the speech sound type.
+ _channel = _vm->_audioMixer->play(Audio::Mixer::kSpeechSoundType,
+ audioStream,
+ 100,
+ false,
+ _speechVolumeFactorOriginalEngine,
+ pan,
+ mixerChannelEnded,
+ this,
+ audioStream->getLength());
_isActive = true;
@@ -128,21 +134,26 @@ bool AudioSpeech::isPlaying() const {
return _isActive;
}
+// volume should be in [0, 100]
+// priority should be in [0, 100]
+// pan is calculated based on actor's position with Actor::soundPan()
bool AudioSpeech::playSpeechLine(int actorId, int sentenceId, int volume, int a4, int priority) {
int pan = _vm->_actors[actorId]->soundPan();
Common::String name = Common::String::format("%02d-%04d%s.AUD", actorId, sentenceId, _vm->_languageCode.c_str());
- return _vm->_audioPlayer->playAud(name, _speechVolume * volume / 100, pan, pan, priority, kAudioPlayerOverrideVolume, Audio::Mixer::kSpeechSoundType);
+ return _vm->_audioPlayer->playAud(name, (volume * _speechVolumeFactorOriginalEngine) / 100, pan, pan, priority, kAudioPlayerOverrideVolume, Audio::Mixer::kSpeechSoundType);
}
-// We no longer set the _speechVolume (speech default volume percent) via a public method
-// It is set in AudioSpeech::AudioSpeech() constructor and keeps its value constant.
-//void AudioSpeech::setVolume(int volume) {
-// _speechVolume = volume;
-//}
+#if BLADERUNNER_ORIGINAL_SETTINGS
+// We no longer set the _speechVolumeFactorOriginalEngine via a public method.
+// For the ScummVM Engine's purposes it is set in AudioSpeech::AudioSpeech() constructor and keeps its value constant.
+void AudioSpeech::setVolume(int volume) {
+ _speechVolumeFactorOriginalEngine = volume;
+}
int AudioSpeech::getVolume() const {
- return _speechVolume;
+ return _speechVolumeFactorOriginalEngine;
}
+#endif // BLADERUNNER_ORIGINAL_SETTINGS
void AudioSpeech::playSample() {
#if BLADERUNNER_ORIGINAL_BUGS
diff --git a/engines/bladerunner/audio_speech.h b/engines/bladerunner/audio_speech.h
index 0f2904d3880..77d033104d7 100644
--- a/engines/bladerunner/audio_speech.h
+++ b/engines/bladerunner/audio_speech.h
@@ -22,6 +22,8 @@
#ifndef BLADERUNNER_AUDIO_SPEECH_H
#define BLADERUNNER_AUDIO_SPEECH_H
+#include "bladerunner/bladerunner.h" // For BLADERUNNER_ORIGINAL_SETTINGS symbol
+
#include "common/str.h"
#include "common/types.h"
@@ -35,7 +37,7 @@ class AudioSpeech {
BladeRunnerEngine *_vm;
- int _speechVolume;
+ int _speechVolumeFactorOriginalEngine; // should be in [0, 100] - Unused in ScummVM Engine, used in original engine
bool _isActive;
int _channel;
byte *_data;
@@ -50,8 +52,10 @@ public:
bool playSpeechLine(int actorId, int sentenceId, int volume, int a4, int priority);
-// void setVolume(int volume);
+#if BLADERUNNER_ORIGINAL_SETTINGS
+ void setVolume(int volume);
int getVolume() const;
+#endif // BLADERUNNER_ORIGINAL_SETTINGS
void playSample();
private:
diff --git a/engines/bladerunner/bladerunner.h b/engines/bladerunner/bladerunner.h
index 30ccf49521b..d76f1c7ac29 100644
--- a/engines/bladerunner/bladerunner.h
+++ b/engines/bladerunner/bladerunner.h
@@ -56,7 +56,8 @@ struct ADGameDescription;
namespace BladeRunner {
enum DebugLevels {
- kDebugScript = 1 << 0
+ kDebugScript = 1 << 0,
+ kDebugSound = 1 << 1
};
class Actor;
diff --git a/engines/bladerunner/detection.cpp b/engines/bladerunner/detection.cpp
index 4ece6b922d3..748cbe6edd4 100644
--- a/engines/bladerunner/detection.cpp
+++ b/engines/bladerunner/detection.cpp
@@ -33,6 +33,7 @@
static const DebugChannelDef debugFlagList[] = {
{BladeRunner::kDebugScript, "Script", "Debug the scripts"},
+ {BladeRunner::kDebugSound, "Sound", "Debug the sound"},
DEBUG_CHANNEL_END
};
diff --git a/engines/bladerunner/music.cpp b/engines/bladerunner/music.cpp
index 83db62dee1a..4719ea3ec35 100644
--- a/engines/bladerunner/music.cpp
+++ b/engines/bladerunner/music.cpp
@@ -33,10 +33,12 @@ namespace BladeRunner {
Music::Music(BladeRunnerEngine *vm) {
_vm = vm;
- // _musicVolume here sets a percentage to be appied on the specified track volume
- // before sending it to the audio player
- // (setting _musicVolume to 100 renders it indifferent)
- _musicVolume = BLADERUNNER_ORIGINAL_SETTINGS ? 65 : 100;
+ // _musicVolumeFactorOriginalEngine here sets a percentage to be applied on the music tracks' volume
+ // before sending them to the audio player.
+ // This is how the original engine set the volume via the in-game KIA volume slider controls.
+ // Setting _musicVolumeFactorOriginalEngine to 100, for the purposes ScummVM engine, renders it indifferent,
+ // so sound volume can be controlled by ScummVM's Global Main Menu / ConfMan/ syncSoundSettings().
+ _musicVolumeFactorOriginalEngine = BLADERUNNER_ORIGINAL_SETTINGS ? 65 : 100;
reset();
}
@@ -69,14 +71,19 @@ void Music::reset() {
_stream = nullptr;
}
+// volume should be in [0, 100]
+// pan should be in [-100, 100]
+// A negative (typically -1) value for timePlaySeconds, means "play the whole music track".
bool Music::play(const Common::String &trackName, int volume, int pan, int32 timeFadeInSeconds, int32 timePlaySeconds, int loop, int32 timeFadeOutSeconds) {
//Common::StackLock lock(_mutex);
- if (_musicVolume <= 0) {
+ // TODO Does this mean that when music volume slider is at mute (0) (in the original engine),
+ // the music track would *not* be "played silently" and would not be loaded nor queued at all?
+ if (_musicVolumeFactorOriginalEngine <= 0) {
return false;
}
- int volumeAdjusted = volume * _musicVolume / 100;
+ int volumeAdjusted = (volume * _musicVolumeFactorOriginalEngine) / 100; //volumeAdjusted will be in [0, 100]
int volumeStart = volumeAdjusted;
if (timeFadeInSeconds > 0) {
volumeStart = 1;
@@ -89,15 +96,16 @@ bool Music::play(const Common::String &trackName, int volume, int pan, int32 tim
// However, if a "next" track already exists,
// then stop the _current track after 2 seconds (force stop current playing track)
// Also the previous "next" track still gets replaced by the new requested one.
- // This can be best test at Animoid Row, Hawker's Circle moving from Izo's Pawn Shop to the Bar.
+ // This can be best tested at Animoid Row, within Hawker's Circle,
+ // moving from Izo's Pawn Shop to the Bar.
// if the requested track is the same as the currently playing,
// update the loop int value of the _current to the new one
// and adjust its fadeIn and balance/pan
- // In these both cases above, the _current track is not (yet) changed.
+ // In both of the above cases, the _current track is not (yet) changed.
if (isPlaying()) {
if (!_current.name.equalsIgnoreCase(trackName)) {
_next.name = trackName;
- _next.volume = volume; // Don't store the adjustedVolume - This is a "target" value for the volume
+ _next.volume = volume; // Don't store the adjusted volume - This is a "target" volume (before any adjustments from volume sliders or special mode like VK)
_next.pan = pan; // This is a "target" value for the pan (balance)
_next.timeFadeInSeconds = timeFadeInSeconds;
_next.timePlaySeconds = timePlaySeconds;
@@ -112,7 +120,11 @@ bool Music::play(const Common::String &trackName, int volume, int pan, int32 tim
if (timeFadeInSeconds < 0) {
timeFadeInSeconds = 0;
}
+#if BLADERUNNER_ORIGINAL_BUGS
adjustVolume(volumeAdjusted, timeFadeInSeconds);
+#else
+ adjustVolume(volume, timeFadeInSeconds);
+#endif // BLADERUNNER_ORIGINAL_BUGS
adjustPan(pan, timeFadeInSeconds);
}
return true;
@@ -153,7 +165,11 @@ bool Music::play(const Common::String &trackName, int volume, int pan, int32 tim
return false;
}
if (timeFadeInSeconds > 0) {
+#if BLADERUNNER_ORIGINAL_BUGS
adjustVolume(volumeAdjusted, timeFadeInSeconds);
+#else
+ adjustVolume(volume, timeFadeInSeconds);
+#endif // BLADERUNNER_ORIGINAL_BUGS
}
_current.name = trackName;
@@ -177,7 +193,7 @@ bool Music::play(const Common::String &trackName, int volume, int pan, int32 tim
#endif //BLADERUNNER_ORIGINAL_BUGS
}
_isPlaying = true;
- _current.volume = volume; // Don't store the adjustedVolume - This is a "target" value for the volume
+ _current.volume = volume; // Don't store the adjusted volume - This is a "target" volume (before any adjustments from volume sliders or special mode like VK)
_current.pan = pan; // This is a "target" value for the pan (balance)
_current.timeFadeInSeconds = timeFadeInSeconds;
_current.timePlaySeconds = timePlaySeconds;
@@ -207,11 +223,19 @@ void Music::stop(uint32 delaySeconds) {
_vm->_audioMixer->stop(_channel, 60u * delaySeconds);
}
+// adjust() is a public method, and note that it accepts special values for its arguments
+// volume should be in [0, 100], with "-1" being a special value for skipping volume adjustment
+// pan should be in [-100, 100], with "-101" being a special value for skipping pan (balance) adjustment
void Music::adjust(int volume, int pan, uint32 delaySeconds) {
+ // value -1 for volume means "do not adjust volume for this music track (while it's playing)"
if (volume != -1) {
- adjustVolume(_musicVolume * volume/ 100, delaySeconds);
+#if BLADERUNNER_ORIGINAL_BUGS
+ adjustVolume((volume * _musicVolumeFactorOriginalEngine)/ 100, delaySeconds);
+#else
+ adjustVolume(volume, delaySeconds);
+#endif // BLADERUNNER_ORIGINAL_BUGS
}
- // -101 is used as a special value to skip adjusting pan
+ // value -101 for pan means "do not adjust pan for this music track (while it's playing)"
if (pan != -101) {
adjustPan(pan, delaySeconds);
}
@@ -221,18 +245,25 @@ bool Music::isPlaying() {
return _channel >= 0 && _isPlaying;
}
+// TODO Evaluate if for ScummVM we can avoid using and modifying _musicVolumeFactorOriginalEngine altogether.
+// While we no longer use the original engine's mechanism to set the music tracks' volume
+// with the Music::setVolume() public method (when using the in-game KIA volume slider),
+// we do use this method as did the original engine to temporarily set the volume levels
+// in VK mode.
+// volume should be in [0, 100]. If volume < 0 then it's treated as 0, and the track is stopped with 2 seconds fade out.
void Music::setVolume(int volume) {
- _musicVolume = volume;
- if (volume <= 0) {
+ // Just don't set the _musicVolumeFactorOriginalEngine to a negative value
+ _musicVolumeFactorOriginalEngine = (volume < 0) ? 0 : volume;
+ if (_musicVolumeFactorOriginalEngine == 0) {
stop(2u);
} else if (isPlaying()) {
// delay is 2 seconds (multiplied by 60u as expected by AudioMixer::adjustVolume())
- _vm->_audioMixer->adjustVolume(_channel, _musicVolume * _current.volume / 100, 120u);
+ _vm->_audioMixer->adjustVolume(_channel, (_current.volume * _musicVolumeFactorOriginalEngine) / 100, 120u);
}
}
-int Music::getVolume() {
- return _musicVolume;
+int Music::getVolume() const {
+ return _musicVolumeFactorOriginalEngine;
}
void Music::playSample() {
@@ -303,15 +334,33 @@ void Music::load(SaveFileReadStream &f) {
}
}
+// volume should be in [0, 100]
+#if BLADERUNNER_ORIGINAL_BUGS
+void Music::adjustVolume(int adjustedVolume, uint32 delaySeconds) {
+ // adjustVolume() takes an "adjusted volume" value as an argument
+ // We don't store that as the target _current.volume. Music::play() stores the proper value
+ // However, adjustVolume() is called from Music::play() but also from Music::adjust() (called by ScriptBase::Music_Adjust()).
+ if (_channel >= 0) {
+ _vm->_audioMixer->adjustVolume(_channel, adjustedVolume, 60u * delaySeconds);
+ }
+}
+#else
void Music::adjustVolume(int volume, uint32 delaySeconds) {
- // adjustVolume takes an "adjusted volume" value as an argument
- // We don't store that as target _current.volume - play() stores the proper value
+ // adjustVolume() takes a "target" volume value as an argument
+ // We store the new volume value as the _current.volume (which is a target volume).
+ // adjustVolume() is called from Music::play() but also from Music::adjust() (called by ScriptBase::Music_Adjust()).
+ _current.volume = volume;
if (_channel >= 0) {
- _vm->_audioMixer->adjustVolume(_channel, volume, 60u * delaySeconds);
+ _vm->_audioMixer->adjustVolume(_channel, (volume * _musicVolumeFactorOriginalEngine) / 100, 60u * delaySeconds);
}
}
+#endif // BLADERUNNER_ORIGINAL_BUGS
+
+// pan should be in [-100, 100]
void Music::adjustPan(int pan, uint32 delaySeconds) {
+ // adjustPan() is called from Music::play() but also from Music::adjust().
+ // We store the new pan value here as the _current.pan (which is a target pan).
_current.pan = pan;
if (_channel >= 0) {
_vm->_audioMixer->adjustPan(_channel, pan, 60u * delaySeconds);
diff --git a/engines/bladerunner/music.h b/engines/bladerunner/music.h
index 8ea6c0bdf66..c8532c9ba5c 100644
--- a/engines/bladerunner/music.h
+++ b/engines/bladerunner/music.h
@@ -25,7 +25,7 @@
#include "common/mutex.h"
#include "common/str.h"
-#include "bladerunner/bladerunner.h" // For BLADERUNNER_ORIGINAL_BUGS symbol
+#include "bladerunner/bladerunner.h" // For BLADERUNNER_ORIGINAL_BUGS and BLADERUNNER_ORIGINAL_SETTINGS symbols
namespace BladeRunner {
@@ -37,8 +37,8 @@ class SaveFileWriteStream;
class Music {
struct Track {
Common::String name;
- int volume; // A value between 0 and 100 - It is the set volume for the track regardless of fadeIn and fadeOut transitions
- int pan; // A value between -100 (left) and 100 (right) (0 is center) - It is the set pan/balance for the track regardless of any ongoing adjustments
+ int volume; // A value in [0, 100] - It is the set (target) volume for the track regardless of fadeIn and fadeOut transitions
+ int pan; // A value in [-100, 100]. -100 is left, 100 is right and 0 is center - It is the set (target) pan/balance for the track regardless of any ongoing adjustments
int32 timeFadeInSeconds; // how long will it take for the track to reach target volume (in seconds)
int32 timePlaySeconds; // how long the track will play before starting fading out (in seconds) - uses timeFadeOutSeconds for fadeout
// -1: Special value for playing the whole track
@@ -49,7 +49,7 @@ class Music {
BladeRunnerEngine *_vm;
Common::Mutex _mutex;
- int _musicVolume;
+ int _musicVolumeFactorOriginalEngine; // should be in [0, 100]
int _channel;
bool _isNextPresent;
bool _isPlaying;
@@ -69,7 +69,7 @@ public:
bool isPlaying();
void setVolume(int volume);
- int getVolume();
+ int getVolume() const;
void playSample();
void save(SaveFileWriteStream &f);
@@ -84,7 +84,11 @@ public:
private:
void reset();
+#if BLADERUNNER_ORIGINAL_BUGS
+ void adjustVolume(int adjustedVolume, uint32 delaySeconds);
+#else
void adjustVolume(int volume, uint32 delaySeconds);
+#endif // BLADERUNNER_ORIGINAL_BUGS
void adjustPan(int pan, uint32 delaySeconds);
void ended();
diff --git a/engines/bladerunner/script/script.cpp b/engines/bladerunner/script/script.cpp
index 9dd4775c859..ee05d8b630a 100644
--- a/engines/bladerunner/script/script.cpp
+++ b/engines/bladerunner/script/script.cpp
@@ -1102,11 +1102,16 @@ int ScriptBase::Random_Query(int min, int max) {
return _vm->_rnd.getRandomNumberRng(min, max);
}
+// volume should be in [0, 100]
+// panStart, panEnd should be in [-100, 100]
+// priority should be in [0, 100]
void ScriptBase::Sound_Play(int id, int volume, int panStart, int panEnd, int priority) {
debugC(6, kDebugScript, "Sound_Play(%d, %d, %d, %d, %d)", id, volume, panStart, panEnd, priority);
_vm->_audioPlayer->playAud(_vm->_gameInfo->getSfxTrack(id), volume, panStart, panEnd, priority);
}
+// volume should be in [0, 100]
+// priority should be in [0, 100]
void ScriptBase::Sound_Play_Speech_Line(int actorId, int sentenceId, int volume, int a4, int priority) {
debugC(kDebugScript, "Sound_Play_Speech_Line(%d, %d, %d, %d, %d)", actorId, sentenceId, volume, a4, priority);
_vm->_audioSpeech->playSpeechLine(actorId, sentenceId, volume, a4, priority);
@@ -1177,11 +1182,16 @@ void ScriptBase::Footstep_Sound_Override_Off() {
_vm->_scene->_set->resetFoodstepSoundOverride();
}
+// volume should be in [0, 100]
+// pan should be in [-100, 100]
+// A negative (typically -1) value for timePlaySeconds, means "play the whole music track"
bool ScriptBase::Music_Play(int musicId, int volume, int pan, int32 timeFadeInSeconds, int32 timePlaySeconds, int loop, int32 timeFadeOutSeconds) {
debugC(kDebugScript, "Music_Play(%d, %d, %d, %d, %d, %d, %d)", musicId, volume, pan, timeFadeInSeconds, timePlaySeconds, loop, timeFadeOutSeconds);
return _vm->_music->play(_vm->_gameInfo->getMusicTrack(musicId), volume, pan, timeFadeInSeconds, timePlaySeconds, loop, timeFadeOutSeconds);
}
+// volume should be in [0, 100], with "-1" being a special value for skipping volume adjustment
+// pan should be in [-100, 100], with "-101" being a special value for skipping pan (balance) adjustment
void ScriptBase::Music_Adjust(int volume, int pan, uint32 delaySeconds) {
debugC(kDebugScript, "Music_Adjust(%d, %d, %u)", volume, pan, delaySeconds);
_vm->_music->adjust(volume, pan, delaySeconds);
@@ -1228,6 +1238,10 @@ void ScriptBase::Outtake_Play(int id, int noLocalization, int container) {
_vm->outtakePlay(id, noLocalization, container);
}
+// volumeMin, volumeMax should be in [0, 100]
+// panStartMin, panStartMax should be in [-100, 100]
+// panEndMin, panEndMax should be in [-100, 100], with "-101" being a special value for skipping pan (balance) adjustment
+// priority should be in [0, 100]
void ScriptBase::Ambient_Sounds_Add_Sound(int sfxId, uint32 delayMinSeconds, uint32 delayMaxSeconds, int volumeMin, int volumeMax, int panStartMin, int panStartMax, int panEndMin, int panEndMax, int priority, int unk) {
debugC(kDebugScript, "Ambient_Sounds_Add_Sound(%d, %u, %u, %d, %d, %d, %d, %d, %d, %d, %d)", sfxId, delayMinSeconds, delayMaxSeconds, volumeMin, volumeMax, panStartMin, panStartMax, panEndMin, panEndMax, priority, unk);
_vm->_ambientSounds->addSound(sfxId, delayMinSeconds, delayMaxSeconds, volumeMin, volumeMax, panStartMin, panStartMax, panEndMin, panEndMax, priority, unk);
@@ -1238,6 +1252,10 @@ void ScriptBase::Ambient_Sounds_Remove_Sound(int sfxId, bool stopPlaying) {
_vm->_ambientSounds->removeNonLoopingSound(sfxId, stopPlaying);
}
+// volumeMin, volumeMax should be in [0, 100]
+// panStartMin, panStartMax should be in [-100, 100]
+// panEndMin, panEndMax should be in [-100, 100], with "-101" being a special value for skipping pan (balance) adjustment
+// priority should be in [0, 100]
void ScriptBase::Ambient_Sounds_Add_Speech_Sound(int actorId, int sentenceId, uint32 delayMinSeconds, uint32 delayMaxSeconds, int volumeMin, int volumeMax, int panStartMin, int panStartMax, int panEndMin, int panEndMax, int priority, int unk) {
debugC(kDebugScript, "Ambient_Sounds_Add_Speech_Sound(%d, %d, %u, %u, %d, %d, %d, %d, %d, %d, %d, %d)", actorId, sentenceId, delayMinSeconds, delayMaxSeconds, volumeMin, volumeMax, panStartMin, panStartMax, panEndMin, panEndMax, priority, unk);
_vm->_ambientSounds->addSpeech(actorId, sentenceId, delayMinSeconds, delayMaxSeconds, volumeMin, volumeMax, panStartMin, panStartMax, panEndMin, panEndMax, priority, unk);
@@ -1245,11 +1263,18 @@ void ScriptBase::Ambient_Sounds_Add_Speech_Sound(int actorId, int sentenceId, ui
// ScriptBase::Ambient_Sounds_Remove_Speech_Sound
+
+// volume should be in [0, 100]
+// panStart, panEnd should be in [-100, 100]
+// priority should be in [0, 100]
void ScriptBase::Ambient_Sounds_Play_Sound(int sfxId, int volume, int panStart, int panEnd, int priority) {
debugC(kDebugScript, "Ambient_Sounds_Play_Sound(%d, %d, %d, %d, %d)", sfxId, volume, panStart, panEnd, priority);
_vm->_ambientSounds->playSound(sfxId, volume, panStart, panEnd, priority);
}
+// volume should be in [0, 100]
+// panStart, panEnd should be in [-100, 100]
+// priority should be in [0, 100]
void ScriptBase::Ambient_Sounds_Play_Speech_Sound(int actorId, int sentenceId, int volume, int panStart, int panEnd, int priority) {
debugC(kDebugScript, "Ambient_Sounds_Play_Speech_Sound(%d, %d, %d, %d, %d, %d)", actorId, sentenceId, volume, panStart, panEnd, priority);
_vm->_ambientSounds->playSpeech(actorId, sentenceId, volume, panStart, panEnd, priority);
@@ -1260,11 +1285,15 @@ void ScriptBase::Ambient_Sounds_Remove_All_Non_Looping_Sounds(bool stopPlaying)
_vm->_ambientSounds->removeAllNonLoopingSounds(stopPlaying);
}
+// volume should be in [0, 100]
+// pan should be in [-100, 100]
void ScriptBase::Ambient_Sounds_Add_Looping_Sound(int sfxId, int volume, int pan, uint32 delaySeconds) {
debugC(kDebugScript, "Ambient_Sounds_Add_Looping_Sound(%d, %d, %d, %u)", sfxId, volume, pan, delaySeconds);
_vm->_ambientSounds->addLoopingSound(sfxId, volume, pan, delaySeconds);
}
+// volume should be in [0, 100], with "-1" being a special value for skipping volume adjustment
+// pan should be in [-100, 100], with "-101" being a special value for skipping pan (balance) adjustment
void ScriptBase::Ambient_Sounds_Adjust_Looping_Sound(int sfxId, int volume, int pan, uint32 delaySeconds) {
debugC(kDebugScript, "Ambient_Sounds_Adjust_Looping_Sound(%d, %d, %d, %u)", sfxId, volume, pan, delaySeconds);
_vm->_ambientSounds->adjustLoopingSound(sfxId, volume, pan, delaySeconds);
diff --git a/engines/bladerunner/ui/end_credits.cpp b/engines/bladerunner/ui/end_credits.cpp
index 040e592ec98..edee3695086 100644
--- a/engines/bladerunner/ui/end_credits.cpp
+++ b/engines/bladerunner/ui/end_credits.cpp
@@ -178,7 +178,6 @@ void EndCredits::show() {
_vm->_ambientSounds->removeAllLoopingSounds(4u);
_vm->_audioSpeech->stopSpeech();
- // ASDF volume is 100 here (correct it should be from 0..100)
_vm->_music->play(_vm->_gameInfo->getMusicTrack(kMusicCredits), 100, 0, 2, -1, kMusicLoopPlayOnce, 3);
Font *fontBig = Font::load(_vm, "TAHOMA24.FON", 1, true);
diff --git a/engines/bladerunner/ui/esper.cpp b/engines/bladerunner/ui/esper.cpp
index 723f19adf58..b76e48373e7 100644
--- a/engines/bladerunner/ui/esper.cpp
+++ b/engines/bladerunner/ui/esper.cpp
@@ -87,9 +87,11 @@ void ESPER::open(Graphics::Surface *surface) {
_vm->_time->pause();
- _ambientVolume = _vm->_ambientSounds->getVolume();
- _vm->_ambientSounds->setVolume(_ambientVolume / 2);
-
+ // NOTE It's probably intentional that music level is not adjusted when entering ESPER mode,
+ // since it is possible to use ESPER in McCoy's apartment while the moody Blade Runner Blues is playing,
+ // and it would not be desirable to have that one's volume lowered further.
+ _ambientVolumeFactorOutsideEsper = _vm->_ambientSounds->getVolume();
+ _vm->_ambientSounds->setVolume(_ambientVolumeFactorOutsideEsper / 2);
reset();
if (!_vm->openArchive("MODE.MIX")) {
@@ -148,7 +150,7 @@ void ESPER::close() {
_vm->_time->resume();
- _vm->_ambientSounds->setVolume(_ambientVolume);
+ _vm->_ambientSounds->setVolume(_ambientVolumeFactorOutsideEsper);
_vm->_scene->resume();
reset();
@@ -514,6 +516,7 @@ void ESPER::wait(uint32 timeout) {
}
}
+// volume should be in [0, 100]
void ESPER::playSound(int soundId, int volume) {
if (_soundId1 == -1) {
_soundId1 = soundId;
diff --git a/engines/bladerunner/ui/esper.h b/engines/bladerunner/ui/esper.h
index 5b8f2bf340f..a2287581f2a 100644
--- a/engines/bladerunner/ui/esper.h
+++ b/engines/bladerunner/ui/esper.h
@@ -177,12 +177,12 @@ class ESPER {
uint32 _timeScrollNextStart;
int _soundId1;
- int _volume1;
+ int _volume1; // should be in [0, 100]
int _soundId2;
- int _volume2;
+ int _volume2; // should be in [0, 100]
int _soundId3;
- int _volume3;
- int _ambientVolume;
+ int _volume3; // should be in [0, 100]
+ int _ambientVolumeFactorOutsideEsper;
public:
ESPER(BladeRunnerEngine *vm);
diff --git a/engines/bladerunner/ui/vk.cpp b/engines/bladerunner/ui/vk.cpp
index 3a6122fab46..4bb2f0f1117 100644
--- a/engines/bladerunner/ui/vk.cpp
+++ b/engines/bladerunner/ui/vk.cpp
@@ -75,12 +75,15 @@ void VK::open(int actorId, int calibrationRatio) {
}
}
- _volumeAmbient = _vm->_ambientSounds->getVolume();
- _volumeMusic = _vm->_music->getVolume();
+ _ambientVolumeFactorOutsideVK = _vm->_ambientSounds->getVolume();
+ _musicVolumeFactorOutsideVK = _vm->_music->getVolume();
+ // Original engine sets volume to 1 for ambient and music
+ _vm->_ambientSounds->setVolume(1);
+ _vm->_music->setVolume(1);
_actorId = actorId;
_calibrationRatio = calibrationRatio;
- _calibration = 0;
+ _calibration = 0; // TODO Original uses a float (0.0) var for calibration. Does this make any difference?
_buttons = new UIImagePicker(_vm, 8);
@@ -175,8 +178,9 @@ void VK::close() {
_shapes->unload();
_vm->closeArchive("MODE.MIX");
- _vm->_music->setVolume(_volumeMusic);
- _vm->_ambientSounds->setVolume(_volumeAmbient);
+
+ _vm->_music->setVolume(_musicVolumeFactorOutsideVK);
+ _vm->_ambientSounds->setVolume(_ambientVolumeFactorOutsideVK);
_vm->_time->resume();
_vm->_scene->resume();
@@ -442,8 +446,8 @@ void VK::reset() {
_shapes->unload();
- _volumeAmbient = 0;
- _volumeMusic = 0;
+ _ambientVolumeFactorOutsideVK = 0;
+ _musicVolumeFactorOutsideVK = 0;
_calibrationRatio = 0;
_calibrationCounter = 0;
diff --git a/engines/bladerunner/ui/vk.h b/engines/bladerunner/ui/vk.h
index ea847defeb9..503cec61ada 100644
--- a/engines/bladerunner/ui/vk.h
+++ b/engines/bladerunner/ui/vk.h
@@ -66,8 +66,8 @@ class VK {
Common::Array<Common::Array<Question> > _questions;
- int _volumeAmbient;
- int _volumeMusic;
+ int _ambientVolumeFactorOutsideVK; // should be in [0, 100]
+ int _musicVolumeFactorOutsideVK; // should be in [0, 100]
int _soundTrackId1;
int _soundTrackId2;
int _soundTrackId3;
@@ -133,7 +133,7 @@ public:
void tick();
- void resume();
+// void resume();
void handleMouseDown(int mouseX, int mouseY, bool mainButton);
void handleMouseUp(int mouseX, int mouseY, bool mainButton);
diff --git a/engines/bladerunner/vqa_player.cpp b/engines/bladerunner/vqa_player.cpp
index b7550d24b65..53981775492 100644
--- a/engines/bladerunner/vqa_player.cpp
+++ b/engines/bladerunner/vqa_player.cpp
@@ -24,6 +24,9 @@
#include "bladerunner/bladerunner.h"
#include "bladerunner/time.h"
#include "bladerunner/audio_player.h"
+#if BLADERUNNER_ORIGINAL_SETTINGS
+#include "bladerunner/audio_speech.h"
+#endif
#include "audio/decoders/raw.h"
@@ -234,7 +237,15 @@ int VQAPlayer::update(bool forceDraw, bool advanceFrame, bool useTime, Graphics:
// Audio stream starts playing, consuming queued "audio frames"
// Note: On its own, the audio will not re-synch with video;
// It plays independently so it can get ahead!
+#if BLADERUNNER_ORIGINAL_SETTINGS
+ _vm->_mixer->playStream(kVQASoundType, &_soundHandle, _audioStream, -1, (_vm->_audioSpeech->getVolume() * Audio::Mixer::kMaxChannelVolume) / 100);
+#else
+ // using the default volume argument (Audio::Mixer::kMaxChannelVolume)
+ // will result in the the configured volume for speech being used,
+ // since playStream() does get the soundtype volume into consideration.
+ // See: Channel::updateChannelVolumes() in audio/mixer.cpp
_vm->_mixer->playStream(kVQASoundType, &_soundHandle, _audioStream);
+#endif // BLADERUNNER_ORIGINAL_SETTINGS
}
_audioStarted = true;
}
Commit: de0c1ff238aefac4b6ea8c4f91f13a91902306c9
https://github.com/scummvm/scummvm/commit/de0c1ff238aefac4b6ea8c4f91f13a91902306c9
Author: antoniou79 (a.antoniou79 at gmail.com)
Date: 2023-04-24T09:43:51+03:00
Commit Message:
BLADERUNNER: Comment fix and notes for some Luther cues
Changed paths:
engines/bladerunner/script/ai/blimp_guy.cpp
engines/bladerunner/script/ai/luther.cpp
diff --git a/engines/bladerunner/script/ai/blimp_guy.cpp b/engines/bladerunner/script/ai/blimp_guy.cpp
index fe8027dcdd2..c9203ed2861 100644
--- a/engines/bladerunner/script/ai/blimp_guy.cpp
+++ b/engines/bladerunner/script/ai/blimp_guy.cpp
@@ -35,7 +35,7 @@ namespace BladeRunner {
// and one cutscene:
// - TB_FLY
// In the in-game scenes (not cutscenes) this speech is played as ambient sound
-// using Ambient_Sounds_Add_Speech_Sound() and is thus not subtitles as of yet.
+// using Ambient_Sounds_Add_Speech_Sound() and is thus not subtitled as of yet.
// TODO: maybe we could support dual subtitles being displayed on-screen for cases when Ambient Speech Sound
// would overlap over character speech.
// The Blimp Guy's speech in the TB_FLY VQA cutscene is subtitled.
diff --git a/engines/bladerunner/script/ai/luther.cpp b/engines/bladerunner/script/ai/luther.cpp
index 3a5d965032b..34d348feeae 100644
--- a/engines/bladerunner/script/ai/luther.cpp
+++ b/engines/bladerunner/script/ai/luther.cpp
@@ -48,9 +48,9 @@ bool AIScriptLuther::Update() {
&& !Game_Flag_Query(kFlagUG16PulledGun)
&& Global_Variable_Query(kVariableChapter) == 4
) {
- Actor_Says(kActorMcCoy, 5720, 12);
- Actor_Says(kActorLuther, 80, 13);
- Actor_Says(kActorLance, 40, 12);
+ Actor_Says(kActorMcCoy, 5720, 12); // Just a moment of your time, please.
+ Actor_Says(kActorLuther, 80, 13); // I am sick and tired of people waving those things around.
+ Actor_Says(kActorLance, 40, 12); // Just give it up. You got no jurisdiction down here.
Game_Flag_Set(kFlagUG16PulledGun);
return false;
}
More information about the Scummvm-git-logs
mailing list