ResidualVM logo ResidualVM website - Forums - Contact us BuildBot - Doxygen - Wiki curved edge

ambient.cpp

Go to the documentation of this file.
00001 /* ResidualVM - A 3D game interpreter
00002  *
00003  * ResidualVM is the legal property of its developers, whose names
00004  * are too numerous to list here. Please refer to the AUTHORS
00005  * file distributed with this source distribution.
00006  *
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License
00009  * as published by the Free Software Foundation; either version 2
00010  * of the License, or (at your option) any later version.
00011  *
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00020  *
00021  */
00022 
00023 #include "engines/myst3/ambient.h"
00024 #include "engines/myst3/database.h"
00025 #include "engines/myst3/myst3.h"
00026 #include "engines/myst3/state.h"
00027 #include "engines/myst3/sound.h"
00028 
00029 namespace Myst3 {
00030 
00031 Ambient::Ambient(Myst3Engine *vm) :
00032     _vm(vm),
00033     _cueStartTick(0) {
00034     _cueSheet.reset();
00035 }
00036 
00037 Ambient::~Ambient() {
00038 }
00039 
00040 void Ambient::playCurrentNode(uint32 volume, uint32 fadeOutDelay) {
00041     if (!fadeOutDelay) fadeOutDelay = 1;
00042 
00043     uint32 node = _vm->_state->getLocationNode();
00044     uint32 room = _vm->_state->getLocationRoom();
00045     uint32 age = _vm->_state->getLocationAge();
00046 
00047     // Load sound descriptors
00048     loadNode(node, room, age);
00049 
00050     // Adjust volume
00051     scaleVolume(volume);
00052 
00053     // Play sounds
00054     applySounds(fadeOutDelay);
00055 }
00056 
00057 void Ambient::scaleVolume(uint32 volume) {
00058     for (uint i = 0; i < _sounds.size(); i++)
00059         _sounds[i].volume = _sounds[i].volume * volume / 100;
00060 }
00061 
00062 void Ambient::loadNode(uint32 node, uint32 room, uint32 age) {
00063     _sounds.clear();
00064     _cueSheet.reset();
00065 
00066     if (!node)
00067         node = _vm->_state->getLocationNode();
00068 
00069     _vm->_state->setAmbiantPreviousFadeOutDelay(_vm->_state->getAmbiantFadeOutDelay());
00070 
00071     _scriptAge = age;
00072     _scriptRoom = room;
00073 
00074     _vm->runAmbientScripts(node);
00075 
00076     if (_sounds.size() == 0)
00077         _vm->runAmbientScripts(32766);
00078 }
00079 
00080 void Ambient::addSound(uint32 id, int32 volume, int32 heading, int32 headingAngle, int32 u1, int32 fadeOutDelay) {
00081     if (!volume)
00082         volume = 1;
00083 
00084     AmbientSound s;
00085 
00086     if (volume >= 0) {
00087         s.volume = volume;
00088         s.volumeFlag = 0;
00089     } else {
00090         s.volume = -volume;
00091         s.volumeFlag = 1;
00092     }
00093 
00094     s.id = id;
00095     s.heading = heading;
00096     s.headingAngle = headingAngle;
00097     s.u1 = u1;
00098     s.fadeOutDelay = fadeOutDelay;
00099 
00100     _sounds.push_back(s);
00101 }
00102 
00103 void Ambient::setCueSheet(uint32 id, int32 volume, int32 heading, int32 headingAngle) {
00104     _cueSheet.reset();
00105 
00106     if (volume >= 0) {
00107         _cueSheet.volume = volume;
00108         _cueSheet.volumeFlag = 0;
00109     } else {
00110         _cueSheet.volume = -volume;
00111         _cueSheet.volumeFlag = 1;
00112     }
00113 
00114     _cueSheet.id = id;
00115     _cueSheet.heading = heading;
00116     _cueSheet.headingAngle = headingAngle;
00117 }
00118 
00119 uint16 Ambient::delayForCue(uint32 id) {
00120     const AmbientCue &cue = _vm->_db->getAmbientCue(id);
00121 
00122     // Return a delay in frames inside the bounds
00123     return _vm->_rnd->getRandomNumberRng(cue.minFrames, cue.maxFrames);
00124 }
00125 
00126 uint32 Ambient::nextCueSound(uint32 id) {
00127     static uint32 lastId = 0;
00128     const AmbientCue &cue = _vm->_db->getAmbientCue(id);
00129 
00130     // Only one sound, no way it can be different from the previous one
00131     if (cue.tracks.size() == 1) {
00132         return cue.tracks[0];
00133     }
00134 
00135     // Make sure the new random sound is different from the last one
00136     uint32 soundId;
00137     do {
00138         uint index = _vm->_rnd->getRandomNumber(cue.tracks.size() - 1);
00139         soundId = cue.tracks[index];
00140     } while (soundId == lastId);
00141 
00142     lastId = soundId;
00143 
00144     return soundId;
00145 }
00146 
00147 void Ambient::updateCue() {
00148     if (_cueSheet.id) {
00149         if (!_cueStartTick) {
00150             _cueStartTick = _vm->_state->getTickCount() + delayForCue(_cueSheet.id);
00151         }
00152         if (_vm->_state->getTickCount() >= _cueStartTick) {
00153             _cueStartTick = 0;
00154             uint32 soundId = nextCueSound(_cueSheet.id);
00155 
00156             uint heading;
00157             if (_cueSheet.heading == 32766) {
00158                 heading = _vm->_rnd->getRandomNumberRng(0, 359);
00159             } else {
00160                 heading = _cueSheet.heading;
00161             }
00162             _vm->_sound->playCue(soundId, _cueSheet.volume, heading, _cueSheet.headingAngle);
00163         }
00164     }
00165 }
00166 
00167 void Ambient::applySounds(uint32 fadeOutDelay) {
00168     // Reset the random sounds
00169     _cueStartTick = 0;
00170     if (!_cueSheet.id) {
00171         _vm->_sound->stopCue(fadeOutDelay);
00172     }
00173 
00174     // Age all sounds
00175     _vm->_sound->age();
00176 
00177     // Setup the selected sounds
00178     for (uint i = 0; i < _sounds.size(); i++) {
00179         const AmbientSound &sound = _sounds[i];
00180 
00181         bool existingChannel;
00182         SoundChannel *channel = _vm->_sound->getChannelForSound(sound.id, kAmbient, &existingChannel);
00183 
00184         // The sound was already playing
00185         if (!existingChannel) {
00186             uint volume = 0;
00187 //          if (sound.volumeFlag) // TODO: Used in the original
00188                 volume = sound.volume;
00189 
00190             channel->play(sound.id, volume, sound.heading, sound.headingAngle, true, kAmbient);
00191         }
00192 
00193         if (channel->_playing) {
00194             channel->fade(sound.volume, sound.heading, sound.headingAngle, fadeOutDelay);
00195             channel->_age = 0;
00196             channel->_ambientFadeOutDelay = sound.fadeOutDelay;
00197         }
00198     }
00199 
00200     // Fade out old playing ambient sounds
00201     _vm->_sound->fadeOutOldSounds(fadeOutDelay);
00202 }
00203 
00204 } // End of namespace Myst3


Generated on Sat May 18 2019 05:00:54 for ResidualVM by doxygen 1.7.1
curved edge   curved edge