mirror of
https://github.com/libretro/scummvm.git
synced 2025-01-31 07:53:36 +00:00
MYST3: Implement ambient cues
This commit is contained in:
parent
8fafca1949
commit
c2160f0a7d
@ -21,13 +21,16 @@
|
||||
*/
|
||||
|
||||
#include "engines/myst3/ambient.h"
|
||||
#include "engines/myst3/database.h"
|
||||
#include "engines/myst3/myst3.h"
|
||||
#include "engines/myst3/state.h"
|
||||
#include "engines/myst3/sound.h"
|
||||
|
||||
namespace Myst3 {
|
||||
|
||||
Ambient::Ambient(Myst3Engine *vm) :
|
||||
_vm(vm) {
|
||||
_vm(vm),
|
||||
_cueStartFrame(0) {
|
||||
_cueSheet.reset();
|
||||
}
|
||||
|
||||
@ -113,7 +116,61 @@ void Ambient::setCueSheet(uint32 id, int32 volume, int32 heading, int32 headingA
|
||||
_cueSheet.headingAngle = headingAngle;
|
||||
}
|
||||
|
||||
uint16 Ambient::delayForCue(uint32 id) {
|
||||
const AmbientCue &cue = _vm->_db->getAmbientCue(id);
|
||||
|
||||
// Return a delay in frames inside the bounds
|
||||
return _vm->_rnd->getRandomNumberRng(cue.minFrames, cue.maxFrames);
|
||||
}
|
||||
|
||||
uint32 Ambient::nextCueSound(uint32 id) {
|
||||
static uint32 lastId = 0;
|
||||
const AmbientCue &cue = _vm->_db->getAmbientCue(id);
|
||||
|
||||
// Only one sound, no way it can be different from the previous one
|
||||
if (cue.tracks.size() == 1) {
|
||||
return cue.tracks[0];
|
||||
}
|
||||
|
||||
// Make sure the new random sound is different from the last one
|
||||
uint32 soundId;
|
||||
do {
|
||||
uint index = _vm->_rnd->getRandomNumber(cue.tracks.size() - 1);
|
||||
soundId = cue.tracks[index];
|
||||
} while (soundId == lastId);
|
||||
|
||||
lastId = soundId;
|
||||
|
||||
return soundId;
|
||||
}
|
||||
|
||||
void Ambient::updateCue() {
|
||||
if (_cueSheet.id) {
|
||||
if (!_cueStartFrame) {
|
||||
_cueStartFrame = _vm->_state->getFrameCount() + delayForCue(_cueSheet.id);
|
||||
}
|
||||
if (_vm->_state->getFrameCount() >= _cueStartFrame) {
|
||||
_cueStartFrame = 0;
|
||||
uint32 soundId = nextCueSound(_cueSheet.id);
|
||||
|
||||
uint heading;
|
||||
if (_cueSheet.heading == 32766) {
|
||||
heading = _vm->_rnd->getRandomNumberRng(0, 359);
|
||||
} else {
|
||||
heading = _cueSheet.heading;
|
||||
}
|
||||
_vm->_sound->playCue(soundId, _cueSheet.volume, heading, _cueSheet.headingAngle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Ambient::applySounds(uint32 fadeOutDelay) {
|
||||
// Reset the random sounds
|
||||
_cueStartFrame = 0;
|
||||
if (!_cueSheet.id) {
|
||||
_vm->_sound->stopCue();
|
||||
}
|
||||
|
||||
// TODO
|
||||
}
|
||||
|
||||
|
@ -40,7 +40,9 @@ public:
|
||||
void scaleVolume(uint32 volume);
|
||||
|
||||
void addSound(uint32 id, int32 volume, int32 heading, int32 headingAngle, int32 u1, int32 u2);
|
||||
|
||||
void setCueSheet(uint32 id, int32 volume, int32 heading, int32 headingAngle);
|
||||
void updateCue();
|
||||
|
||||
uint32 _scriptAge;
|
||||
uint32 _scriptRoom;
|
||||
@ -70,8 +72,13 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
uint16 delayForCue(uint32 id);
|
||||
uint32 nextCueSound(uint32 id);
|
||||
|
||||
Common::Array<AmbientSound> _sounds;
|
||||
|
||||
AmbientSound _cueSheet;
|
||||
uint32 _cueStartFrame;
|
||||
};
|
||||
|
||||
} /* namespace Myst3 */
|
||||
|
@ -967,7 +967,7 @@ void Database::loadAmbientCues(Common::ReadStreamEndian *s) {
|
||||
}
|
||||
|
||||
const AmbientCue& Database::getAmbientCue(uint16 id) {
|
||||
if (_ambientCues.contains(id))
|
||||
if (!_ambientCues.contains(id))
|
||||
error("Unable to find an ambient cue with id %d", id);
|
||||
|
||||
return _ambientCues.getVal(id);
|
||||
|
@ -20,6 +20,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "engines/myst3/ambient.h"
|
||||
#include "engines/myst3/database.h"
|
||||
#include "engines/myst3/myst3.h"
|
||||
#include "engines/myst3/sound.h"
|
||||
@ -49,17 +50,33 @@ void Sound::playEffect(uint32 id, uint32 volume, uint16 heading, uint16 attenuat
|
||||
channel->play(id, volume, heading, attenuation, 0, 0, 0, kEffect);
|
||||
}
|
||||
|
||||
void Sound::playCue(uint32 id, uint32 volume, uint16 heading, uint16 attenuation) {
|
||||
SoundChannel *channel = _channels[13];
|
||||
channel->play(id, volume, heading, attenuation, 0, 0, 0, kCue);
|
||||
}
|
||||
|
||||
void Sound::stopCue(uint32 fadeDelay) {
|
||||
SoundChannel *channel = _channels[13];
|
||||
if (fadeDelay == 0) {
|
||||
channel->stop();
|
||||
} else {
|
||||
channel->fade(0, -1, 0, fadeDelay);
|
||||
}
|
||||
}
|
||||
|
||||
SoundChannel *Sound::getChannelForSound(uint32 id, SoundType priority) {
|
||||
// if the sound is already playing, return that channel
|
||||
for (uint i = 0; i < kNumChannels; i++)
|
||||
for (uint i = 0; i < kNumChannels - 1; i++)
|
||||
if (_channels[i]->_id == id && _channels[i]->_playing)
|
||||
return _channels[i];
|
||||
|
||||
// else return the first available channel
|
||||
for (uint i = 0; i < kNumChannels; i++)
|
||||
for (uint i = 0; i < kNumChannels - 1; i++)
|
||||
if (!_channels[i]->_playing)
|
||||
return _channels[i];
|
||||
|
||||
// Channel number 13 is reserved for cue sounds
|
||||
|
||||
error("No available channel for sound %d", id);
|
||||
}
|
||||
|
||||
@ -68,6 +85,7 @@ void Sound::update() {
|
||||
_channels[i]->update();
|
||||
|
||||
_vm->runBackgroundSoundScriptsFromNode(_vm->_state->getLocationNode());
|
||||
_vm->_ambient->updateCue();
|
||||
}
|
||||
|
||||
SoundChannel::SoundChannel(Myst3Engine *vm) :
|
||||
@ -151,4 +169,25 @@ void SoundChannel::update() {
|
||||
}
|
||||
}
|
||||
|
||||
void SoundChannel::stop() {
|
||||
if (!_playing)
|
||||
return; // Nothing to do
|
||||
|
||||
_playing = g_system->getMixer()->isSoundHandleActive(_handle);
|
||||
|
||||
if (_playing) {
|
||||
g_system->getMixer()->stopHandle(_handle);
|
||||
_playing = false;
|
||||
}
|
||||
|
||||
_stream = 0;
|
||||
}
|
||||
|
||||
void SoundChannel::fade(uint32 targetVolume, int32 targetHeading, int32 targetAttenuation, uint32 fadeDelay) {
|
||||
//TODO: Implement this mock
|
||||
if (targetVolume == 0) {
|
||||
stop();
|
||||
}
|
||||
}
|
||||
|
||||
} /* namespace Myst3 */
|
||||
|
@ -32,7 +32,7 @@ class Myst3Engine;
|
||||
enum SoundType {
|
||||
kUnk0,
|
||||
kUnk1,
|
||||
kUnk2,
|
||||
kCue,
|
||||
kEffect,
|
||||
kMusic
|
||||
};
|
||||
@ -43,7 +43,9 @@ public:
|
||||
virtual ~SoundChannel();
|
||||
|
||||
void play(uint32 id, uint32 volume, uint16 heading, uint16 attenuation, uint unk1, uint unk2, uint unk3, SoundType type);
|
||||
void fade(uint32 targetVolume, int32 targetHeading, int32 targetAttenuation, uint32 fadeDelay);
|
||||
void update();
|
||||
void stop();
|
||||
|
||||
uint32 _id;
|
||||
bool _playing;
|
||||
@ -66,10 +68,14 @@ public:
|
||||
virtual ~Sound();
|
||||
|
||||
void playEffect(uint32 id, uint32 volume, uint16 heading = 0, uint16 attenuation = 0);
|
||||
|
||||
void playCue(uint32 id, uint32 volume, uint16 heading, uint16 attenuation);
|
||||
void stopCue(uint32 fadeDelay);
|
||||
|
||||
void update();
|
||||
|
||||
private:
|
||||
static const uint kNumChannels = 13;
|
||||
static const uint kNumChannels = 14;
|
||||
|
||||
Myst3Engine *_vm;
|
||||
SoundChannel *_channels[kNumChannels];
|
||||
|
Loading…
x
Reference in New Issue
Block a user