MYST3: Implement movie volume control

This commit is contained in:
Bastien Bouclet 2014-03-02 12:18:16 +01:00
parent fb023c9253
commit 381be4836f
6 changed files with 97 additions and 20 deletions

View File

@ -22,6 +22,7 @@
#include "engines/myst3/movie.h"
#include "engines/myst3/myst3.h"
#include "engines/myst3/sound.h"
#include "engines/myst3/state.h"
#include "engines/myst3/subtitles.h"
@ -41,7 +42,8 @@ Movie::Movie(Myst3Engine *vm, uint16 id) :
_texture(0),
_force2d(false),
_forceOpaque(false),
_subtitles(0) {
_subtitles(0),
_volume(0) {
const DirectorySubEntry *binkDesc = _vm->getFileDescription(0, id, 0, DirectorySubEntry::kMultitrackMovie);
@ -181,7 +183,11 @@ ScriptedMovie::ScriptedMovie(Myst3Engine *vm, uint16 id) :
_enabled(false),
_disableWhenComplete(false),
_scriptDriven(false),
_isLastFrame(false) {
_isLastFrame(false),
_soundHeading(0),
_soundAttenuation(0),
_volumeVar(0),
_loop(false) {
}
@ -249,6 +255,8 @@ void ScriptedMovie::update() {
}
if (_enabled) {
updateVolume();
if (_nextFrameReadVar) {
int32 nextFrame = _vm->_state->getVar(_nextFrameReadVar);
if (nextFrame > 0 && nextFrame <= (int32)_bink.getFrameCount()) {
@ -303,6 +311,20 @@ void ScriptedMovie::update() {
}
}
void ScriptedMovie::updateVolume() {
int32 volume;
if (_volumeVar) {
volume = _vm->_state->getVar(_volumeVar);
} else {
volume = _volume;
}
int32 mixerVolume, balance;
_vm->_sound->computeVolumeBalance(volume, _soundHeading, _soundAttenuation, &mixerVolume, &balance);
_bink.setVolume(mixerVolume);
_bink.setBalance(balance);
}
ScriptedMovie::~ScriptedMovie() {
}
@ -319,6 +341,8 @@ bool SimpleMovie::update() {
_bink.seekToFrame(_startFrame - 1);
}
_bink.setVolume(_volume * Audio::Mixer::kMaxChannelVolume / 100);
uint16 scriptStartFrame = _vm->_state->getMovieScriptStartFrame();
if (scriptStartFrame && _bink.getCurFrame() > scriptStartFrame) {
uint16 script = _vm->_state->getMovieScript();

View File

@ -51,6 +51,7 @@ public:
void setForceOpaque(bool b) { _forceOpaque = b; }
void setStartFrame(int32 v) { _startFrame = v; }
void setEndFrame(int32 v) { _endFrame = v; }
void setVolume(int32 v) { _volume = v; }
protected:
Myst3Engine *_vm;
@ -74,6 +75,8 @@ protected:
int32 _startFrame;
int32 _endFrame;
int32 _volume;
void loadPosition(const VideoData &videoData);
void drawNextFrameToTexture();
@ -96,12 +99,15 @@ public:
void setPlayingVar(uint16 v) { _playingVar = v; }
void setPosUVar(uint16 v) { _posUVar = v; }
void setPosVVar(uint16 v) { _posVVar = v; }
void setVolumeVar(uint16 v) { _volumeVar = v; }
void setStartFrameVar(uint16 v) { _startFrameVar = v; }
void setCondition(int16 condition) { _condition = condition; }
void setConditionBit(int16 cb) { _conditionBit = cb; }
void setDisableWhenComplete(bool upd) { _disableWhenComplete = upd; }
void setLoop(bool loop) { _loop = loop; }
void setScriptDriven(bool b) { _scriptDriven = b; }
void setSoundHeading(uint16 v) { _soundHeading = v; }
void setSoundAttenuation(uint16 v) { _soundAttenuation = v; }
protected:
bool _enabled;
@ -117,11 +123,17 @@ protected:
uint16 _endFrameVar;
uint16 _posUVar;
uint16 _posVVar;
uint16 _volumeVar;
uint32 _soundHeading;
uint32 _soundAttenuation;
uint16 _nextFrameReadVar;
uint16 _nextFrameWriteVar;
uint16 _playingVar;
void updateVolume();
};
class SimpleMovie : public Movie {

View File

@ -891,6 +891,28 @@ void Myst3Engine::loadMovie(uint16 id, uint16 condition, bool resetCond, bool lo
_state->setMovieForce2d(0);
}
if (_state->getMovieVolume1()) {
movie->setVolume(_state->getMovieVolume1());
_state->setMovieVolume1(0);
} else {
movie->setVolume(_state->getMovieVolume2());
}
if (_state->getMovieVolumeVar()) {
movie->setVolumeVar(_state->getMovieVolumeVar());
_state->setMovieVolumeVar(0);
}
if (_state->getMovieSoundHeading()) {
movie->setSoundHeading(_state->getMovieSoundHeading());
_state->setMovieSoundHeading(0);
}
if (_state->getMoviePanningStrenght()) {
movie->setSoundAttenuation(_state->getMoviePanningStrenght());
_state->setMoviePanningStrenght(0);
}
_movies.push_back(movie);
}
@ -912,6 +934,13 @@ void Myst3Engine::playSimpleMovie(uint16 id, bool fullframe) {
_state->setMovieEndFrame(0);
}
if (_state->getMovieVolume1()) {
movie.setVolume(_state->getMovieVolume1());
_state->setMovieVolume1(0);
} else {
movie.setVolume(_state->getMovieVolume2());
}
if (fullframe) {
movie.setForce2d(_state->getViewType() == kCube);
movie.setForceOpaque(true);

View File

@ -157,6 +157,22 @@ void Sound::compute3DVolumes(int32 heading, uint angle, int32 *left, int32 *righ
}
}
void Sound::computeVolumeBalance(int32 volume, int32 heading, uint attenuation, int32 *mixerVolume, int32 *balance) {
int32 left, right;
_vm->_sound->compute3DVolumes(heading, attenuation, &left, &right);
*mixerVolume = MAX(left, right) * volume * Audio::Mixer::kMaxChannelVolume / 100 / 100;
// Compute balance from the left and right volumes
if (left == right) {
*balance = 0;
} else if (left > right) {
*balance = -127 * (left - right) / left;
} else {
*balance = 127 * (right - left) / right;
}
}
SoundChannel::SoundChannel(Myst3Engine *vm) :
_vm(vm),
_playing(false),
@ -164,7 +180,10 @@ SoundChannel::SoundChannel(Myst3Engine *vm) :
_id(0),
_stream(0),
_age(0),
_ambientFadeOutDelay(0) {
_ambientFadeOutDelay(0),
_volume(0),
_heading(0),
_headingAngle(0) {
}
SoundChannel::~SoundChannel() {
@ -269,23 +288,11 @@ void SoundChannel::stop() {
}
void SoundChannel::setVolume3D(uint32 volume, uint16 heading, uint16 attenuation) {
int32 left, right;
_vm->_sound->compute3DVolumes(heading, attenuation, &left, &right);
// Compute balance from the left and right volumes
int32 pan;
if (left == right) {
pan = 0;
} else if (left > right) {
pan = -127 * (left - right) / left;
} else {
pan = 127 * (right - left) / right;
}
uint mixerVolume = MAX(left, right) * volume * Audio::Mixer::kMaxChannelVolume / 100 / 100;
int32 mixerVolume, balance;
_vm->_sound->computeVolumeBalance(volume, heading, attenuation, &mixerVolume, &balance);
g_system->getMixer()->setChannelVolume(_handle, mixerVolume);
g_system->getMixer()->setChannelBalance(_handle, pan);
g_system->getMixer()->setChannelBalance(_handle, balance);
}
void SoundChannel::fadeOut(uint32 fadeDelay) {

View File

@ -89,14 +89,14 @@ public:
void fadeOutOldSounds(uint32 fadeDelay);
void compute3DVolumes(int32 heading, uint angle, int32 *left, int32 *right);
void computeVolumeBalance(int32 volume, int32 heading, uint attenuation, int32 *mixerVolume, int32 *balance);
private:
static const uint kNumChannels = 14;
Myst3Engine *_vm;
SoundChannel *_channels[kNumChannels];
void compute3DVolumes(int32 heading, uint angle, int32 *left, int32 *right);
};
} /* namespace Myst3 */

View File

@ -130,6 +130,8 @@ public:
DECLARE_VAR(142, MovieStartFrame)
DECLARE_VAR(143, MovieEndFrame)
DECLARE_VAR(144, MovieVolume1)
DECLARE_VAR(145, MovieVolume2)
DECLARE_VAR(146, MovieOverrideSubtitles)
DECLARE_VAR(149, MovieConditionBit)
DECLARE_VAR(150, MoviePreloadToMemory)
@ -139,6 +141,9 @@ public:
DECLARE_VAR(154, MovieStartFrameVar)
DECLARE_VAR(155, MovieEndFrameVar)
DECLARE_VAR(156, MovieForce2d)
DECLARE_VAR(157, MovieVolumeVar)
DECLARE_VAR(158, MovieSoundHeading)
DECLARE_VAR(159, MoviePanningStrenght)
DECLARE_VAR(160, MovieSynchronized)
DECLARE_VAR(163, MovieOverrideCondition)
DECLARE_VAR(164, MovieUVar)