From d9d10d9801d73baf368e4f34de2ec00c0263e552 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Thu, 1 Sep 2016 20:53:01 -0400 Subject: TITANIC: Implement timed changes in volume like the original does --- engines/titanic/core/game_object.cpp | 8 ++--- engines/titanic/sound/proximity.cpp | 2 +- engines/titanic/sound/proximity.h | 2 +- engines/titanic/sound/qmixer.cpp | 41 ++++++++++++++++++++++--- engines/titanic/sound/qmixer.h | 13 ++++++++ engines/titanic/sound/sound_manager.cpp | 5 ++- engines/titanic/true_talk/true_talk_manager.cpp | 14 ++++----- 7 files changed, 67 insertions(+), 18 deletions(-) (limited to 'engines') diff --git a/engines/titanic/core/game_object.cpp b/engines/titanic/core/game_object.cpp index aa6ffda0e3..53ad5de941 100644 --- a/engines/titanic/core/game_object.cpp +++ b/engines/titanic/core/game_object.cpp @@ -468,16 +468,16 @@ void CGameObject::playGlobalSound(const CString &resName, int mode, bool initial switch (handleIndex) { case 0: - prox._channel = 6; + prox._channelMode = 6; break; case 1: - prox._channel = 7; + prox._channelMode = 7; break; case 2: - prox._channel = 8; + prox._channelMode = 8; break; case 3: - prox._channel = 9; + prox._channelMode = 9; break; default: break; diff --git a/engines/titanic/sound/proximity.cpp b/engines/titanic/sound/proximity.cpp index 992e76a872..9e70722520 100644 --- a/engines/titanic/sound/proximity.cpp +++ b/engines/titanic/sound/proximity.cpp @@ -27,7 +27,7 @@ namespace Titanic { CProximity::CProximity() : _field4(0), _channelVolume(100), _fieldC(0), _priorSoundHandle(-1), _field14(0), _frequencyMultiplier(0.0), _field1C(1.875), - _repeated(false), _channel(10), _positioningMode(POSMODE_NONE), _azimuth(0.0), + _repeated(false), _channelMode(10), _positioningMode(POSMODE_NONE), _azimuth(0.0), _range(0.5), _elevation(0), _posX(0.0), _posY(0.0), _posZ(0.0), _hasVelocity(false), _velocityX(0), _velocityY(0), _velocityZ(0), _field54(0), _field58(0), _field5C(0), _freeSoundFlag(false), _endTalkerFn(nullptr), diff --git a/engines/titanic/sound/proximity.h b/engines/titanic/sound/proximity.h index cedb4bd94a..41c2268c2f 100644 --- a/engines/titanic/sound/proximity.h +++ b/engines/titanic/sound/proximity.h @@ -44,7 +44,7 @@ public: double _frequencyMultiplier; double _field1C; bool _repeated; - int _channel; + int _channelMode; PositioningMode _positioningMode; double _azimuth; double _range; diff --git a/engines/titanic/sound/qmixer.cpp b/engines/titanic/sound/qmixer.cpp index b5eb6d0b5c..e0e9c60038 100644 --- a/engines/titanic/sound/qmixer.cpp +++ b/engines/titanic/sound/qmixer.cpp @@ -20,6 +20,7 @@ * */ +#include "common/system.h" #include "titanic/sound/qmixer.h" namespace Titanic { @@ -63,12 +64,22 @@ void QMixer::qsWaveMixFlushChannel(int iChannel, uint flags) { } void QMixer::qsWaveMixSetPanRate(int iChannel, uint flags, uint rate) { - // Not currently implemented in ScummVM + ChannelEntry &channel = _channels[iChannel]; + channel._panRate = rate; + channel._volumeChangeEnd = channel._volumeChangeEnd = 0; } void QMixer::qsWaveMixSetVolume(int iChannel, uint flags, uint volume) { + ChannelEntry &channel = _channels[iChannel]; + + // QMixer volumes go from 0-32767, but we need to convert to 0-255 for ScummVM + assert(volume <= 32767); + byte newVolume = (volume >= 32700) ? 255 : volume * 255 / 32767; - + channel._volumeStart = newVolume; + channel._volumeEnd = volume * 255 / 100; // Convert from 0-100 (percent) to 0-255 + channel._volumeChangeStart = g_system->getMillis(); + channel._volumeChangeEnd = channel._volumeChangeStart + channel._panRate; } void QMixer::qsWaveMixSetSourcePosition(int iChannel, uint flags, const QSVECTOR &position) { @@ -134,6 +145,28 @@ void QMixer::qsWaveMixPump() { for (uint iChannel = 0; iChannel < _channels.size(); ++iChannel) { ChannelEntry &channel = _channels[iChannel]; + // If there's a transition in sound volume in progress, handle it + if (channel._volumeChangeEnd) { + byte oldVolume = channel._volume; + uint currentTicks = g_system->getMillis(); + + if (currentTicks >= channel._volumeChangeEnd) { + // Reached end of transition period + channel._volume = channel._volumeEnd; + channel._volumeChangeStart = channel._volumeChangeEnd = 0; + } else { + // Transition in progress, so figure out new volume + channel._volume = (int)channel._volumeStart + + ((int)channel._volumeEnd - (int)channel._volumeStart) * + (int)(currentTicks - channel._volumeChangeStart) / (int)channel._panRate; + } + + if (channel._volume != oldVolume && !channel._sounds.empty() + && channel._sounds.front()._started) { + _mixer->setChannelVolume(channel._sounds.front()._soundHandle, channel._volume); + } + } + // 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()) { @@ -144,7 +177,7 @@ void QMixer::qsWaveMixPump() { sound._waveFile->_stream->rewind(); _mixer->playStream(sound._waveFile->_soundType, &sound._soundHandle, sound._waveFile->_stream, - -1, 0xff, 0, DisposeAfterUse::NO); + -1, channel._volume, 0, DisposeAfterUse::NO); } else { // Sound is finished if (sound._callback) @@ -164,7 +197,7 @@ void QMixer::qsWaveMixPump() { if (!sound._started) { _mixer->playStream(sound._waveFile->_soundType, &sound._soundHandle, sound._waveFile->_stream, - -1, 0xff, 0, DisposeAfterUse::NO); + -1, channel._volume, 0, DisposeAfterUse::NO); sound._started = true; } } diff --git a/engines/titanic/sound/qmixer.h b/engines/titanic/sound/qmixer.h index 4ba76a8969..6a25484c29 100644 --- a/engines/titanic/sound/qmixer.h +++ b/engines/titanic/sound/qmixer.h @@ -186,7 +186,20 @@ class QMixer { _started(false), _waveFile(waveFile), _callback(callback), _loops(loops), _userData(userData) {} }; struct ChannelEntry { + // Currently playing and any following queued sounds for the channel Common::List _sounds; + // Current channel volume + byte _volume; + // Current time in milliseconds for paning (volume) changes + uint _panRate; + // Fields used to transition between volume levels + uint _volumeChangeStart; + uint _volumeChangeEnd; + byte _volumeStart; + byte _volumeEnd; + + ChannelEntry() : _volume(0), _panRate(0), _volumeChangeStart(0), + _volumeChangeEnd(0), _volumeStart(0), _volumeEnd(0) {} }; private: Audio::Mixer *_mixer; diff --git a/engines/titanic/sound/sound_manager.cpp b/engines/titanic/sound/sound_manager.cpp index 9f3d29e967..81ec5bc475 100644 --- a/engines/titanic/sound/sound_manager.cpp +++ b/engines/titanic/sound/sound_manager.cpp @@ -171,7 +171,7 @@ int QSoundManager::playSound(CWaveFile &waveFile, CProximity &prox) { } } - if (channel >= 0 || (channel = resetChannel(prox._channel)) != -1) { + if (channel >= 0 || (channel = resetChannel(prox._channelMode)) != -1) { return playWave(&waveFile, channel, flags, prox); } @@ -377,6 +377,9 @@ int QSoundManager::playWave(CWaveFile *waveFile, int iChannel, uint flags, CProx if (slotIndex == -1) return -1; + // Set the volume + setChannelVolume(iChannel, prox._channelVolume, prox._channelMode); + switch (prox._positioningMode) { case POSMODE_POLAR: qsWaveMixSetPolarPosition(iChannel, 8, QSPOLAR(prox._azimuth, prox._range, prox._elevation)); diff --git a/engines/titanic/true_talk/true_talk_manager.cpp b/engines/titanic/true_talk/true_talk_manager.cpp index c5fd43ebfd..085f0bd310 100644 --- a/engines/titanic/true_talk/true_talk_manager.cpp +++ b/engines/titanic/true_talk/true_talk_manager.cpp @@ -490,13 +490,13 @@ void CTrueTalkManager::playSpeech(TTtalker *talker, TTroomScript *roomScript, CV // Setup proximities CProximity p1, p2, p3; if (isParrot) { - p1._channel = 3; - p2._channel = 5; - p3._channel = 4; + p1._channelMode = 3; + p2._channelMode = 5; + p3._channelMode = 4; } else { - p1._channel = 0; - p2._channel = 1; - p3._channel = 2; + p1._channelMode = 0; + p2._channelMode = 1; + p3._channelMode = 2; } if (milli > 0) { @@ -513,7 +513,7 @@ void CTrueTalkManager::playSpeech(TTtalker *talker, TTroomScript *roomScript, CV p2._elevation = 0; } - _gameManager->_sound.stopChannel(p1._channel); + _gameManager->_sound.stopChannel(p1._channelMode); if (view) { p1._positioningMode = POSMODE_VECTOR; view->getPosition(p1._posX, p1._posY, p1._posZ); -- cgit v1.2.3