diff options
author | Paul Gilbert | 2016-08-11 20:03:55 -0400 |
---|---|---|
committer | Paul Gilbert | 2016-08-11 20:03:55 -0400 |
commit | b680af7f609594a89dd9acd8227c7d19259f8e6d (patch) | |
tree | 6baa83daa6423bb9eb144bbb4380ec6f9f2af6c4 /engines | |
parent | e8ea243a1468168d78d4c2d61f5d22a7421f8f2e (diff) | |
download | scummvm-rg350-b680af7f609594a89dd9acd8227c7d19259f8e6d.tar.gz scummvm-rg350-b680af7f609594a89dd9acd8227c7d19259f8e6d.tar.bz2 scummvm-rg350-b680af7f609594a89dd9acd8227c7d19259f8e6d.zip |
TITANIC: Fleshing out QSound simulation methods
Diffstat (limited to 'engines')
-rw-r--r-- | engines/titanic/sound/qmixer.cpp | 60 | ||||
-rw-r--r-- | engines/titanic/sound/qmixer.h | 21 | ||||
-rw-r--r-- | engines/titanic/sound/sound_manager.cpp | 10 | ||||
-rw-r--r-- | engines/titanic/sound/wave_file.cpp | 26 | ||||
-rw-r--r-- | engines/titanic/sound/wave_file.h | 12 |
5 files changed, 111 insertions, 18 deletions
diff --git a/engines/titanic/sound/qmixer.cpp b/engines/titanic/sound/qmixer.cpp index da707c9527..da4f6725a5 100644 --- a/engines/titanic/sound/qmixer.cpp +++ b/engines/titanic/sound/qmixer.cpp @@ -28,7 +28,10 @@ QMixer::QMixer(Audio::Mixer *mixer) : _mixer(mixer) { } bool QMixer::qsWaveMixInitEx(const QMIXCONFIG &config) { - // Not currently implemented in ScummVM + assert(_channels.empty()); + assert(config.iChannels > 0 && config.iChannels < 256); + + _channels.resize(config.iChannels); return true; } @@ -48,6 +51,7 @@ int QMixer::qsWaveMixEnableChannel(int iChannel, uint flags, bool enabled) { void QMixer::qsWaveMixCloseSession() { _mixer->stopAll(); + _channels.clear(); } void QMixer::qsWaveMixFreeWave(Audio::SoundHandle &handle) { @@ -94,18 +98,62 @@ void QMixer::qsWaveMixSetSourceVelocity(int iChannel, uint flags, const QSVECTOR // Not currently implemented in ScummVM } -int QMixer::qsWaveMixPlayEx(int iChannel, uint flags, CWaveFile *mixWave, int loops, const QMIXPLAYPARAMS ¶ms) { - // Not currently implemented in ScummVM +int QMixer::qsWaveMixPlayEx(int iChannel, uint flags, CWaveFile *waveFile, int loops, const QMIXPLAYPARAMS ¶ms) { + if (iChannel == -1) { + // Find a free channel + for (iChannel = 0; iChannel < (int)_channels.size(); ++iChannel) { + if (_channels[iChannel]._sounds.empty()) + break; + } + assert(iChannel != (int)_channels.size()); + } + + // If the new sound replaces current ones, then clear the channel + ChannelEntry &channel = _channels[iChannel]; + if (flags & QMIX_CLEARQUEUE) { + if (!channel._sounds.empty() && channel._sounds.front()._started) + _mixer->stopHandle(channel._sounds.front()._soundHandle); + + channel._sounds.clear(); + } + + // Add the sound to the channel + channel._sounds.push_back(SoundEntry(waveFile, params.callback, params.dwUser)); + qsWaveMixPump(); + return 0; } bool QMixer::qsWaveMixIsChannelDone(int iChannel) const { - // Not currently implemented in ScummVM - return true; + return _channels[iChannel]._sounds.empty(); } void QMixer::qsWaveMixPump() { - // TODO: Handle checking for done sounds, and calling their end functions + // Iterate through each of the channels + for (uint iChannel = 0; iChannel < _channels.size(); ++iChannel) { + ChannelEntry &channel = _channels[iChannel]; + + // If the playing sound on the channel is finished, then call + // the callback registered for it, and remove it from the list + if (!channel._sounds.empty()) { + SoundEntry &sound = channel._sounds.front(); + if (sound._started && !_mixer->isSoundHandleActive(sound._soundHandle)) { + sound._callback(iChannel, sound._waveFile, sound._userData); + channel._sounds.erase(channel._sounds.begin()); + } + } + + // If there's an unstarted sound at the front of a channel's + // sound list, then start it playing + if (!channel._sounds.empty()) { + SoundEntry &sound = channel._sounds.front(); + if (!sound._started) { + _mixer->playStream(sound._waveFile->_soundType, + &sound._soundHandle, sound._waveFile->_stream); + sound._started = true; + } + } + } } } // End of namespace Titanic z diff --git a/engines/titanic/sound/qmixer.h b/engines/titanic/sound/qmixer.h index fa4604cd2e..32a5e58347 100644 --- a/engines/titanic/sound/qmixer.h +++ b/engines/titanic/sound/qmixer.h @@ -152,9 +152,12 @@ struct QMIXPLAYPARAMS { int lEndLoop; int lEnd; const void *lpChannelParams; // initialize with these parameters + // Properties introduced by ScummVM + Audio::Mixer::SoundType _soundType; QMIXPLAYPARAMS() : dwSize(36), lpImage(nullptr), hwndNotify(0), callback(nullptr), - dwUser(nullptr), lStart(0), lStartLoop(0), lEndLoop(0), lEnd(0), lpChannelParams(nullptr) {} + dwUser(nullptr), lStart(0), lStartLoop(0), lEndLoop(0), lEnd(0), + lpChannelParams(nullptr), _soundType(Audio::Mixer::SoundType::kPlainSoundType) {} }; /** @@ -169,8 +172,24 @@ struct QMIXPLAYPARAMS { * currently ignored, and all sounds play at full volume. */ class QMixer { + struct SoundEntry { + bool _started; + CWaveFile *_waveFile; + Audio::SoundHandle _soundHandle; + LPQMIXDONECALLBACK _callback; + void *_userData; + SoundEntry() : _started(false), _waveFile(nullptr), _callback(nullptr), + _userData(nullptr) {} + + SoundEntry(CWaveFile *waveFile, LPQMIXDONECALLBACK callback, void *userData) : + _started(false), _waveFile(waveFile), _callback(callback), _userData(userData) {} + }; + struct ChannelEntry { + Common::List<SoundEntry> _sounds; + }; private: Audio::Mixer *_mixer; + Common::Array<ChannelEntry> _channels; public: QMixer(Audio::Mixer *mixer); virtual ~QMixer() {} diff --git a/engines/titanic/sound/sound_manager.cpp b/engines/titanic/sound/sound_manager.cpp index d466488ceb..8d92e0cf8c 100644 --- a/engines/titanic/sound/sound_manager.cpp +++ b/engines/titanic/sound/sound_manager.cpp @@ -143,7 +143,15 @@ CWaveFile *QSoundManager::loadSpeech(CDialogueFile *dialogueFile, int speechId) } CWaveFile *QSoundManager::loadMusic(const CString &name) { - return loadSound(name); + CWaveFile *waveFile = new CWaveFile(); + + // Try to load the specified sound + if (!waveFile->loadMusic(name)) { + delete waveFile; + return nullptr; + } + + return waveFile; } int QSoundManager::playSound(CWaveFile &waveFile, CProximity &prox) { diff --git a/engines/titanic/sound/wave_file.cpp b/engines/titanic/sound/wave_file.cpp index 7093856217..16bc9deda4 100644 --- a/engines/titanic/sound/wave_file.cpp +++ b/engines/titanic/sound/wave_file.cpp @@ -28,11 +28,12 @@ namespace Titanic { -CWaveFile::CWaveFile() : _owner(nullptr), _stream(nullptr), _soundType(SOUND_SFX) { +CWaveFile::CWaveFile() : _owner(nullptr), _stream(nullptr), + _soundType(Audio::Mixer::SoundType::kPlainSoundType) { } CWaveFile::CWaveFile(QSoundManager *owner) : _owner(owner), _stream(nullptr), - _soundType(SOUND_SFX) { + _soundType(Audio::Mixer::SoundType::kPlainSoundType) { } CWaveFile::~CWaveFile() { @@ -57,7 +58,8 @@ bool CWaveFile::loadSound(const CString &name) { Common::SeekableReadStream *stream = file.readStream(); _size = stream->size(); _stream = Audio::makeWAVStream(stream->readStream(_size), DisposeAfterUse::YES); - _soundType = SOUND_SFX; + _soundType = Audio::Mixer::SoundType::kSFXSoundType; + return true; } @@ -72,7 +74,23 @@ bool CWaveFile::loadSpeech(CDialogueFile *dialogueFile, int speechIndex) { _size = res->_size; _stream = Audio::makeWAVStream(new Common::MemoryReadStream(data, _size, DisposeAfterUse::YES), DisposeAfterUse::YES); - _soundType = SOUND_SPEECH; + _soundType = Audio::Mixer::SoundType::kSpeechSoundType; + + return true; +} + +bool CWaveFile::loadMusic(const CString &name) { + assert(!_stream); + + StdCWadFile file; + if (!file.open(name)) + return false; + + Common::SeekableReadStream *stream = file.readStream(); + _size = stream->size(); + _stream = Audio::makeWAVStream(stream->readStream(_size), DisposeAfterUse::YES); + _soundType = Audio::Mixer::SoundType::kMusicSoundType; + return true; } diff --git a/engines/titanic/sound/wave_file.h b/engines/titanic/sound/wave_file.h index 33b2a8dedf..8c86c509bc 100644 --- a/engines/titanic/sound/wave_file.h +++ b/engines/titanic/sound/wave_file.h @@ -32,11 +32,6 @@ namespace Titanic { class QSoundManager; -enum SoundType { - SOUND_SFX = 0, - SOUND_SPEECH = 1 -}; - class CWaveFile { private: uint _size; @@ -44,7 +39,7 @@ public: QSoundManager *_owner; Audio::AudioStream *_stream; Audio::SoundHandle _soundHandle; - SoundType _soundType; + Audio::Mixer::SoundType _soundType; public: CWaveFile(); CWaveFile(QSoundManager *owner); @@ -68,6 +63,11 @@ public: bool loadSpeech(CDialogueFile *dialogueFile, int speechIndex); /** + * Tries to load the specified music wave file + */ + bool loadMusic(const CString &name); + + /** * Returns true if the wave file has data loaded */ bool isLoaded() const { return _stream != nullptr; } |