aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorPaul Gilbert2016-09-01 20:53:01 -0400
committerPaul Gilbert2016-09-01 20:53:01 -0400
commitd9d10d9801d73baf368e4f34de2ec00c0263e552 (patch)
treea1ab111e3d1daf92c6d14208f65fa61494009887 /engines
parent33737ea2dcd97026706dd75f8c2c27fa148c165a (diff)
downloadscummvm-rg350-d9d10d9801d73baf368e4f34de2ec00c0263e552.tar.gz
scummvm-rg350-d9d10d9801d73baf368e4f34de2ec00c0263e552.tar.bz2
scummvm-rg350-d9d10d9801d73baf368e4f34de2ec00c0263e552.zip
TITANIC: Implement timed changes in volume like the original does
Diffstat (limited to 'engines')
-rw-r--r--engines/titanic/core/game_object.cpp8
-rw-r--r--engines/titanic/sound/proximity.cpp2
-rw-r--r--engines/titanic/sound/proximity.h2
-rw-r--r--engines/titanic/sound/qmixer.cpp41
-rw-r--r--engines/titanic/sound/qmixer.h13
-rw-r--r--engines/titanic/sound/sound_manager.cpp5
-rw-r--r--engines/titanic/true_talk/true_talk_manager.cpp14
7 files changed, 67 insertions, 18 deletions
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<SoundEntry> _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);