[Scummvm-git-logs] scummvm master -> 1493ca291bf2d362a25cdf470fbe8b0e7f6cb95b
djsrv
dservilla at gmail.com
Sat Aug 7 17:20:53 UTC 2021
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:
0b39f10a08 DIRECTOR: Change _movieChanged to movieChanged
1493ca291b DIRECTOR: Improve empty sound channel behavior
Commit: 0b39f10a08a99dbe6e69cc3b97cecf4491f1e529
https://github.com/scummvm/scummvm/commit/0b39f10a08a99dbe6e69cc3b97cecf4491f1e529
Author: djsrv (dservilla at gmail.com)
Date: 2021-08-07T13:20:23-04:00
Commit Message:
DIRECTOR: Change _movieChanged to movieChanged
Changed paths:
engines/director/sound.cpp
engines/director/sound.h
diff --git a/engines/director/sound.cpp b/engines/director/sound.cpp
index 816dc7d98f..b9c38e4321 100644
--- a/engines/director/sound.cpp
+++ b/engines/director/sound.cpp
@@ -356,18 +356,18 @@ void DirectorSound::playExternalSound(uint16 menu, uint16 submenu, uint8 soundCh
void DirectorSound::changingMovie() {
for (uint i = 0; i < _channels.size(); i++) {
setPuppetSound(SoundID(), i + 1); // disable puppet sound
- _channels[i]._movieChanged = true;
+ _channels[i].movieChanged = true;
}
unloadSampleSounds(); // TODO: we can possibly keep this between movies
}
void DirectorSound::setLastPlaySound(uint8 soundChannel, SoundID soundId) {
_channels[soundChannel - 1].lastPlayingSound = soundId;
- _channels[soundChannel - 1]._movieChanged = false;
+ _channels[soundChannel - 1].movieChanged = false;
}
bool DirectorSound::checkLastPlaySound(uint8 soundChannel, const SoundID &soundId) {
- return !_channels[soundChannel - 1]._movieChanged && _channels[soundChannel - 1].lastPlayingSound == soundId;
+ return !_channels[soundChannel - 1].movieChanged && _channels[soundChannel - 1].lastPlayingSound == soundId;
}
void DirectorSound::stopSound(uint8 soundChannel) {
diff --git a/engines/director/sound.h b/engines/director/sound.h
index 9052a70ae2..900050beca 100644
--- a/engines/director/sound.h
+++ b/engines/director/sound.h
@@ -139,9 +139,9 @@ struct SoundChannel {
// this indicate whether the sound is playing across the movie. Because the cast name may be the same while the actual sounds are changing.
// And we will override the sound when ever the sound is changing. thus we use a flag to indicate whether the movie is changed.
- bool _movieChanged;
+ bool movieChanged;
- SoundChannel(): handle(), lastPlayingSound(SoundID()), volume(255), fade(nullptr), puppet(SoundID()), newPuppet(false), _movieChanged(false) {}
+ SoundChannel(): handle(), lastPlayingSound(SoundID()), volume(255), fade(nullptr), puppet(SoundID()), newPuppet(false), movieChanged(false) {}
};
class DirectorSound {
Commit: 1493ca291bf2d362a25cdf470fbe8b0e7f6cb95b
https://github.com/scummvm/scummvm/commit/1493ca291bf2d362a25cdf470fbe8b0e7f6cb95b
Author: djsrv (dservilla at gmail.com)
Date: 2021-08-07T13:20:23-04:00
Commit Message:
DIRECTOR: Improve empty sound channel behavior
Changed paths:
engines/director/score.cpp
engines/director/sound.cpp
engines/director/sound.h
diff --git a/engines/director/score.cpp b/engines/director/score.cpp
index cf0616a561..4e5be0a8d1 100644
--- a/engines/director/score.cpp
+++ b/engines/director/score.cpp
@@ -727,7 +727,7 @@ void Score::playSoundChannel(uint16 frameId) {
} else if (frame->_soundType1 >= kMinSampledMenu && frame->_soundType1 <= kMaxSampledMenu) {
sound->playExternalSound(frame->_soundType1, frame->_sound1.member, 1);
} else {
- sound->playCastMember(frame->_sound1, 1, false);
+ sound->playCastMember(frame->_sound1, 1);
}
if (sound->isChannelPuppet(2)) {
@@ -735,7 +735,7 @@ void Score::playSoundChannel(uint16 frameId) {
} else if (frame->_soundType2 >= kMinSampledMenu && frame->_soundType2 <= kMaxSampledMenu) {
sound->playExternalSound(frame->_soundType2, frame->_sound2.member, 2);
} else {
- sound->playCastMember(frame->_sound2, 2, false);
+ sound->playCastMember(frame->_sound2, 2);
}
// Channels above 2 are only usable by Lingo.
diff --git a/engines/director/sound.cpp b/engines/director/sound.cpp
index b9c38e4321..d8dbdede4f 100644
--- a/engines/director/sound.cpp
+++ b/engines/director/sound.cpp
@@ -76,10 +76,13 @@ void DirectorSound::playFile(Common::String filename, uint8 soundChannel) {
return;
AudioFileDecoder af(filename);
- Audio::AudioStream *sound = af.getAudioStream(false, DisposeAfterUse::YES);
+ Audio::AudioStream *sound = af.getAudioStream(false, false, DisposeAfterUse::YES);
cancelFade(soundChannel);
_mixer->playStream(Audio::Mixer::kSFXSoundType, &_channels[soundChannel - 1].handle, sound, -1, getChannelVolume(soundChannel));
+
+ // Set the last played sound so that cast member 0 in the sound channel doesn't stop this file.
+ setLastPlayedSound(soundChannel, SoundID(), false);
}
void DirectorSound::playMCI(Audio::AudioStream &stream, uint32 from, uint32 to) {
@@ -104,10 +107,10 @@ void DirectorSound::playStream(Audio::AudioStream &stream, uint8 soundChannel) {
_mixer->playStream(Audio::Mixer::kSFXSoundType, &_channels[soundChannel - 1].handle, &stream, -1, getChannelVolume(soundChannel));
}
-void DirectorSound::playSound(SoundID soundID, uint8 soundChannel) {
+void DirectorSound::playSound(SoundID soundID, uint8 soundChannel, bool forPuppet) {
switch (soundID.type) {
case kSoundCast:
- playCastMember(CastMemberID(soundID.u.cast.member, soundID.u.cast.castLib), soundChannel);
+ playCastMember(CastMemberID(soundID.u.cast.member, soundID.u.cast.castLib), soundChannel, forPuppet);
break;
case kSoundExternal:
playExternalSound(soundID.u.external.menu, soundID.u.external.submenu, soundChannel);
@@ -115,21 +118,47 @@ void DirectorSound::playSound(SoundID soundID, uint8 soundChannel) {
}
}
-void DirectorSound::playCastMember(CastMemberID memberID, uint8 soundChannel, bool allowRepeat) {
+void DirectorSound::playCastMember(CastMemberID memberID, uint8 soundChannel, bool forPuppet) {
if (!isChannelValid(soundChannel))
return;
if (memberID.member == 0) {
- stopSound(soundChannel);
+ // Normally cast member 0 stops the sound.
+ // But there are some sounds where it doesn't. Those are:
+ // 1. playFile
+ // 2. FPlay
+ // 3. non-puppet looping sounds
+ // 4. maybe more?
+ if (shouldStopOnZero(soundChannel)) {
+ stopSound(soundChannel);
+ } else {
+ // Don't stop the currently playing sound, just set the last played sound to 0.
+ setLastPlayedSound(soundChannel, SoundID(), false);
+ }
} else {
CastMember *soundCast = _window->getCurrentMovie()->getCastMember(memberID);
if (soundCast) {
if (soundCast->_type != kCastSound) {
warning("DirectorSound::playCastMember: attempted to play a non-SoundCastMember %s", memberID.asString().c_str());
} else {
- if (!allowRepeat && checkLastPlaySound(soundChannel, memberID))
- return;
bool looping = ((SoundCastMember *)soundCast)->_looping;
+ bool stopOnZero = true;
+
+ if (!forPuppet && isLastPlayedSound(soundChannel, memberID)) {
+ // We just played this sound.
+ // If the sound is not marked "looping", we should not play it again.
+ if (!looping)
+ return;
+
+ // If the sound is not finished yet, we need to wait more before playing it again.
+ if (isChannelActive(soundChannel))
+ return;
+
+ // We know that this is a non-puppet, looping sound.
+ // We don't want to stop it if this channel's cast member changes to 0.
+ stopOnZero = false;
+ }
+
AudioDecoder *ad = ((SoundCastMember *)soundCast)->_audio;
if (!ad) {
warning("DirectorSound::playCastMember: no audio data attached to %s", memberID.asString().c_str());
@@ -137,14 +166,14 @@ void DirectorSound::playCastMember(CastMemberID memberID, uint8 soundChannel, bo
}
Audio::AudioStream *as;
- as = ad->getAudioStream(looping);
+ as = ad->getAudioStream(looping, forPuppet);
if (!as) {
warning("DirectorSound::playCastMember: audio data failed to load from cast");
return;
}
playStream(*as, soundChannel);
- setLastPlaySound(soundChannel, memberID);
+ setLastPlayedSound(soundChannel, memberID, stopOnZero);
}
} else {
warning("DirectorSound::playCastMember: couldn't find %s", memberID.asString().c_str());
@@ -333,7 +362,7 @@ void DirectorSound::playExternalSound(uint16 menu, uint16 submenu, uint8 soundCh
return;
SoundID soundId(kSoundExternal, menu, submenu);
- if (isChannelActive(soundChannel) && checkLastPlaySound(soundChannel, soundId))
+ if (isChannelActive(soundChannel) && isLastPlayedSound(soundChannel, soundId))
return;
if (menu < kMinSampledMenu || menu > kMaxSampledMenu) {
@@ -347,7 +376,7 @@ void DirectorSound::playExternalSound(uint16 menu, uint16 submenu, uint8 soundCh
if (1 <= submenu && submenu <= menuSounds.size()) {
playStream(*(menuSounds[submenu - 1]->getAudioStream()), soundChannel);
- setLastPlaySound(soundChannel, soundId);
+ setLastPlayedSound(soundChannel, soundId);
} else {
warning("DirectorSound::playExternalSound: Could not find sound %d %d", menu, submenu);
}
@@ -361,13 +390,18 @@ void DirectorSound::changingMovie() {
unloadSampleSounds(); // TODO: we can possibly keep this between movies
}
-void DirectorSound::setLastPlaySound(uint8 soundChannel, SoundID soundId) {
- _channels[soundChannel - 1].lastPlayingSound = soundId;
+void DirectorSound::setLastPlayedSound(uint8 soundChannel, SoundID soundId, bool stopOnZero) {
+ _channels[soundChannel - 1].lastPlayedSound = soundId;
+ _channels[soundChannel - 1].stopOnZero = stopOnZero;
_channels[soundChannel - 1].movieChanged = false;
}
-bool DirectorSound::checkLastPlaySound(uint8 soundChannel, const SoundID &soundId) {
- return !_channels[soundChannel - 1].movieChanged && _channels[soundChannel - 1].lastPlayingSound == soundId;
+bool DirectorSound::isLastPlayedSound(uint8 soundChannel, const SoundID &soundId) {
+ return !_channels[soundChannel - 1].movieChanged && _channels[soundChannel - 1].lastPlayedSound == soundId;
+}
+
+bool DirectorSound::shouldStopOnZero(uint8 soundChannel) {
+ return _channels[soundChannel - 1].stopOnZero;
}
void DirectorSound::stopSound(uint8 soundChannel) {
@@ -376,7 +410,7 @@ void DirectorSound::stopSound(uint8 soundChannel) {
cancelFade(soundChannel);
_mixer->stopHandle(_channels[soundChannel - 1].handle);
- setLastPlaySound(soundChannel, SoundID());
+ setLastPlayedSound(soundChannel, SoundID());
return;
}
@@ -385,7 +419,7 @@ void DirectorSound::stopSound() {
cancelFade(i + 1);
_mixer->stopHandle(_channels[i].handle);
- setLastPlaySound(i + 1, SoundID());
+ setLastPlayedSound(i + 1, SoundID());
}
_mixer->stopHandle(_scriptSound);
@@ -424,7 +458,7 @@ void DirectorSound::playPuppetSound(uint8 soundChannel) {
return;
_channels[soundChannel - 1].newPuppet = false;
- playSound(_channels[soundChannel - 1].puppet, soundChannel);
+ playSound(_channels[soundChannel - 1].puppet, soundChannel, true);
}
void DirectorSound::playFPlaySound() {
@@ -476,7 +510,10 @@ void DirectorSound::playFPlaySound() {
_fplayQueue.pop();
looping = true;
}
- as = ad->getAudioStream(looping);
+
+ // FPlay is controlled by Lingo, not the score, like a puppet,
+ // so we'll get the puppet version of the stream.
+ as = ad->getAudioStream(looping, true);
if (!as) {
warning("DirectorSound:playFPlaySound: failed to get audio stream");
@@ -489,6 +526,9 @@ void DirectorSound::playFPlaySound() {
playStream(*as, 1);
delete ad;
}
+
+ // Set the last played sound so that cast member 0 in the sound channel doesn't stop this file.
+ setLastPlayedSound(1, SoundID(), false);
}
void DirectorSound::playFPlaySound(const Common::Array<Common::String> &fplayList) {
@@ -673,7 +713,7 @@ bool SNDDecoder::processBufferCommand(Common::SeekableReadStreamEndian &stream)
return true;
}
-Audio::AudioStream *SNDDecoder::getAudioStream(bool looping, DisposeAfterUse::Flag disposeAfterUse) {
+Audio::AudioStream *SNDDecoder::getAudioStream(bool looping, bool forPuppet, DisposeAfterUse::Flag disposeAfterUse) {
if (!_data)
return nullptr;
byte *buffer = (byte *)malloc(_size);
@@ -683,12 +723,20 @@ Audio::AudioStream *SNDDecoder::getAudioStream(bool looping, DisposeAfterUse::Fl
if (looping) {
if (hasLoopBounds()) {
- return new Audio::SubLoopingAudioStream(stream, 0, Audio::Timestamp(0, _loopStart, _rate), Audio::Timestamp(0, _loopEnd, _rate));
+ // If this is for a puppet, return an automatically looping stream.
+ // Otherwise, the sound will be looped by the score.
+ if (forPuppet)
+ return new Audio::SubLoopingAudioStream(stream, 0, Audio::Timestamp(0, _loopStart, _rate), Audio::Timestamp(0, _loopEnd, _rate));
+ else
+ return new Audio::SubSeekableAudioStream(stream, Audio::Timestamp(0, _loopStart, _rate), Audio::Timestamp(0, _loopEnd, _rate));
} else {
// Not sure if looping sounds can appear without loop bounds.
// Let's just log a warning and loop the entire sound...
warning("SNDDecoder::getAudioStream: Looping sound has no loop bounds");
- return new Audio::LoopingAudioStream(stream, 0);
+ if (forPuppet)
+ return new Audio::LoopingAudioStream(stream, 0);
+ else
+ return stream;
}
}
@@ -704,7 +752,7 @@ AudioFileDecoder::AudioFileDecoder(Common::String &path)
_path = path;
}
-Audio::AudioStream *AudioFileDecoder::getAudioStream(bool looping, DisposeAfterUse::Flag disposeAfterUse) {
+Audio::AudioStream *AudioFileDecoder::getAudioStream(bool looping, bool forPuppet, DisposeAfterUse::Flag disposeAfterUse) {
if (_path.empty())
return nullptr;
@@ -730,10 +778,12 @@ Audio::AudioStream *AudioFileDecoder::getAudioStream(bool looping, DisposeAfterU
}
if (stream) {
- if (looping)
- return new Audio::LoopingAudioStream(stream, 0);
- else
- return stream;
+ if (looping && forPuppet) {
+ // If this is for a puppet, return an automatically looping stream.
+ // Otherwise, the sound will be looped by the score
+ return new Audio::LoopingAudioStream(stream, 0);
+ }
+ return stream;
}
return nullptr;
diff --git a/engines/director/sound.h b/engines/director/sound.h
index 900050beca..81f1848685 100644
--- a/engines/director/sound.h
+++ b/engines/director/sound.h
@@ -129,7 +129,8 @@ struct SoundID {
struct SoundChannel {
Audio::SoundHandle handle;
- SoundID lastPlayingSound;
+ SoundID lastPlayedSound;
+ bool stopOnZero; // Should the sound be stopped when the channel contains cast member 0?
byte volume;
FadeParams *fade;
@@ -141,7 +142,7 @@ struct SoundChannel {
// And we will override the sound when ever the sound is changing. thus we use a flag to indicate whether the movie is changed.
bool movieChanged;
- SoundChannel(): handle(), lastPlayingSound(SoundID()), volume(255), fade(nullptr), puppet(SoundID()), newPuppet(false), movieChanged(false) {}
+ SoundChannel(): handle(), lastPlayedSound(SoundID()), stopOnZero(true), volume(255), fade(nullptr), puppet(SoundID()), newPuppet(false), movieChanged(false) {}
};
class DirectorSound {
@@ -170,8 +171,8 @@ public:
void playFile(Common::String filename, uint8 soundChannel);
void playMCI(Audio::AudioStream &stream, uint32 from, uint32 to);
void playStream(Audio::AudioStream &stream, uint8 soundChannel);
- void playSound(SoundID soundId, uint8 soundChannel);
- void playCastMember(CastMemberID memberID, uint8 soundChannel, bool allowRepeat = true);
+ void playSound(SoundID soundId, uint8 soundChannel, bool forPuppet = false);
+ void playCastMember(CastMemberID memberID, uint8 soundChannel, bool forPuppet = false);
void playExternalSound(uint16 menu, uint16 submenu, uint8 soundChannel);
void playFPlaySound(const Common::Array<Common::String> &fplayList);
void playFPlaySound();
@@ -184,8 +185,9 @@ public:
void loadSampleSounds(uint type);
void unloadSampleSounds();
- void setLastPlaySound(uint8 soundChannel, SoundID soundId);
- bool checkLastPlaySound(uint8 soundChannel, const SoundID &soundId);
+ void setLastPlayedSound(uint8 soundChannel, SoundID soundId, bool stopOnZero = true);
+ bool isLastPlayedSound(uint8 soundChannel, const SoundID &soundId);
+ bool shouldStopOnZero(uint8 soundChannel);
bool isChannelPuppet(uint8 soundChannel);
void setPuppetSound(SoundID soundId, uint8 soundChannel);
@@ -214,7 +216,7 @@ public:
AudioDecoder() {};
virtual ~AudioDecoder() {};
public:
- virtual Audio::AudioStream *getAudioStream(bool looping = false, DisposeAfterUse::Flag disposeAfterUse = DisposeAfterUse::YES) { return nullptr; }
+ virtual Audio::AudioStream *getAudioStream(bool looping = false, bool forPuppet = false, DisposeAfterUse::Flag disposeAfterUse = DisposeAfterUse::YES) { return nullptr; }
};
class SNDDecoder : public AudioDecoder {
@@ -226,7 +228,7 @@ public:
void loadExternalSoundStream(Common::SeekableReadStreamEndian &stream);
bool processCommands(Common::SeekableReadStreamEndian &stream);
bool processBufferCommand(Common::SeekableReadStreamEndian &stream);
- Audio::AudioStream *getAudioStream(bool looping = false, DisposeAfterUse::Flag disposeAfterUse = DisposeAfterUse::YES) override;
+ Audio::AudioStream *getAudioStream(bool looping = false, bool forPuppet = false, DisposeAfterUse::Flag disposeAfterUse = DisposeAfterUse::YES) override;
bool hasLoopBounds();
private:
@@ -246,7 +248,7 @@ public:
void setPath(Common::String &path);
- Audio::AudioStream *getAudioStream(bool looping = false, DisposeAfterUse::Flag disposeAfterUse = DisposeAfterUse::YES) override;
+ Audio::AudioStream *getAudioStream(bool looping = false, bool forPuppet = false, DisposeAfterUse::Flag disposeAfterUse = DisposeAfterUse::YES) override;
private:
Common::String _path;
More information about the Scummvm-git-logs
mailing list