diff options
Diffstat (limited to 'engines/bladerunner/ambient_sounds.cpp')
-rw-r--r-- | engines/bladerunner/ambient_sounds.cpp | 258 |
1 files changed, 190 insertions, 68 deletions
diff --git a/engines/bladerunner/ambient_sounds.cpp b/engines/bladerunner/ambient_sounds.cpp index aaf6c016d3..7790b03506 100644 --- a/engines/bladerunner/ambient_sounds.cpp +++ b/engines/bladerunner/ambient_sounds.cpp @@ -34,7 +34,7 @@ namespace BladeRunner { #define NON_LOOPING_SOUNDS 25 #define LOOPING_SOUNDS 3 -AmbientSounds::AmbientSounds(BladeRunnerEngine *vm) : _vm(vm) { +AmbientSounds::AmbientSounds(BladeRunnerEngine *vm) : _vm(vm) { _nonLoopingSounds = new NonLoopingSound[NON_LOOPING_SOUNDS]; _loopingSounds = new LoopingSound[LOOPING_SOUNDS]; _ambientVolume = 65; @@ -64,45 +64,133 @@ static inline void sort(int &a, int &b) { } void AmbientSounds::addSound( - int id, - int timeRangeBegin, int timeRangeEnd, - int volumeRangeBegin, int volumeRangeEnd, - int unk1RangeBegin, int unk1RangeEnd, - int unk2RangeBegin, int unk2RangeEnd, - int priority, int unk3) { - const char *name = _vm->_gameInfo->getSfxTrack(id); - - sort(volumeRangeBegin, volumeRangeEnd); - sort(unk1RangeBegin, unk1RangeEnd); - sort(unk2RangeBegin, unk2RangeEnd); + int sfxId, + int timeMin, int timeMax, + int volumeMin, int volumeMax, + int panStartMin, int panStartMax, + int panEndMin, int panEndMax, + int priority, int unk) { + const char *name = _vm->_gameInfo->getSfxTrack(sfxId); + + sort(volumeMin, volumeMax); + sort(panStartMin, panStartMax); + sort(panEndMin, panEndMax); addSoundByName( - name, - timeRangeBegin, timeRangeEnd, - volumeRangeBegin, volumeRangeEnd, - unk1RangeBegin, unk1RangeEnd, - unk2RangeBegin, unk2RangeEnd, - priority, unk3 - ); + name, + timeMin, timeMax, + volumeMin, volumeMax, + panStartMin, panStartMax, + panEndMin, panEndMax, + priority, unk + ); } -void AmbientSounds::addLoopingSound(int sfx_id, int volume, int unk, int fadeInTime) { - const char *name = _vm->_gameInfo->getSfxTrack(sfx_id); +void AmbientSounds::removeNonLoopingSound(int sfxId, bool stopPlaying) { + const char *name = _vm->_gameInfo->getSfxTrack(sfxId); + int32 hash = mix_id(name); + int index = findNonLoopingTrackByHash(hash); + if (index >= 0) { + removeNonLoopingSoundByIndex(index, stopPlaying); + } +} + +void AmbientSounds::removeAllNonLoopingSounds(bool stopPlaying) { + for (int i = 0; i < NON_LOOPING_SOUNDS; i++) { + removeNonLoopingSoundByIndex(i, stopPlaying); + } +} + +void AmbientSounds::addSpeech(int actorId, int sentenceId, int timeMin, int timeMax, int volumeMin, int volumeMax, int panStartMin, int panStartMax, int panEndMin, int panEndMax, int priority, int unk) { + sort(volumeMin, volumeMax); + sort(panStartMin, panStartMax); + sort(panEndMin, panEndMax); + + char name[13]; + sprintf(name, "%02d-%04d.AUD", actorId, sentenceId); //TODO somewhere here should be also language code + addSoundByName(name, + timeMin, timeMax, + volumeMin, volumeMax, + panStartMin, panStartMax, + panEndMin, panEndMax, + priority, unk); +} + +void AmbientSounds::playSound(int sfxId, int volume, int panStart, int panEnd, int priority) { + const char *name = _vm->_gameInfo->getSfxTrack(sfxId); + + _vm->_audioPlayer->playAud(name, volume * _ambientVolume / 100, panStart, panEnd, priority, AudioPlayer::OVERRIDE_VOLUME); +} + +void AmbientSounds::addLoopingSound(int sfxId, int volume, int pan, int delay) { + const char *name = _vm->_gameInfo->getSfxTrack(sfxId); int32 hash = mix_id(name); - if (findLoopingTrackByHash(hash) >= 0) + if (findLoopingTrackByHash(hash) >= 0) { return; + } int i = findAvailableLoopingTrack(); - if (i == -1) + if (i == -1) { return; + } + LoopingSound &track = _loopingSounds[i]; + + track.isActive = true; + strcpy(track.name, name); + track.hash = hash; + track.pan = pan; + track.volume = volume; + + int actualVolumeStart = volume * _ambientVolume / 100; + int actualVolumeEnd = actualVolumeStart; + + if (delay > 0) { + actualVolumeStart = 0; + } + + track.audioPlayerTrack = _vm->_audioPlayer->playAud(name, actualVolumeStart, pan, pan, 99, AudioPlayer::LOOP | AudioPlayer::OVERRIDE_VOLUME); + + if (track.audioPlayerTrack == -1) { + removeLoopingSoundByIndex(i, 0); + } else { + if (delay) { + _vm->_audioPlayer->adjustVolume(track.audioPlayerTrack, actualVolumeEnd, delay, false); + } + } +} + +void AmbientSounds::adjustLoopingSound(int sfxId, int volume, int pan, int delay) { + const char *name = _vm->_gameInfo->getSfxTrack(sfxId); + int32 hash = mix_id(name); + int index = findLoopingTrackByHash(hash); - int actualVolume = volume * _ambientVolume / 100; + if (index >= 0 && _loopingSounds[index].audioPlayerTrack != -1 && _vm->_audioPlayer->isActive(_loopingSounds[index].audioPlayerTrack)) { + if (volume != -1) { + _loopingSounds[index].volume = volume; + _vm->_audioPlayer->adjustVolume(_loopingSounds[index].audioPlayerTrack, _ambientVolume * volume / 100, delay, false); + } + if (pan != -101) { + _loopingSounds[index].pan = pan; + _vm->_audioPlayer->adjustPan(_loopingSounds[index].audioPlayerTrack, pan, delay); + } + } +} - int balance = 0; +void AmbientSounds::removeLoopingSound(int sfxId, int delay) { + const char *name = _vm->_gameInfo->getSfxTrack(sfxId); + int32 hash = mix_id(name); + int index = findLoopingTrackByHash(hash); + if (index >= 0) { + removeLoopingSoundByIndex(index, delay); + } +} - _vm->_audioPlayer->playAud(name, actualVolume, balance, balance, 100, AudioPlayer::LOOP | AudioPlayer::OVERRIDE_VOLUME); +void AmbientSounds::removeAllLoopingSounds(int delay) { + for (int i = 0; i < LOOPING_SOUNDS; i++) { + removeLoopingSoundByIndex(i, delay); + } } void AmbientSounds::tick() { @@ -111,37 +199,38 @@ void AmbientSounds::tick() { for (int i = 0; i != NON_LOOPING_SOUNDS; ++i) { NonLoopingSound &track = _nonLoopingSounds[i]; - if (!track.isActive || track.nextPlayTime > now) + if (!track.isActive || track.nextPlayTime > now) { continue; + } - int pan1, pan2; - - pan1 = _vm->_rnd.getRandomNumberRng(track.pan1begin, track.pan1end); - if (track.pan2begin == -101) { - pan2 = pan1; + int panEnd; + int panStart = _vm->_rnd.getRandomNumberRng(track.panStartMin, track.panStartMax); + if (track.panEndMin == -101) { + panEnd = panStart; } else { - pan2 = _vm->_rnd.getRandomNumberRng(track.pan2begin, track.pan2end); + panEnd = _vm->_rnd.getRandomNumberRng(track.panEndMin, track.panEndMax); } - track.volume = _vm->_rnd.getRandomNumberRng(track.volume1, track.volume2); + track.volume = _vm->_rnd.getRandomNumberRng(track.volumeMin, track.volumeMax); - track.audio_player_track = _vm->_audioPlayer->playAud( - track.name, - track.volume * _ambientVolume / 100, - pan1, pan2, - track.priority, - AudioPlayer::OVERRIDE_VOLUME - ); - - track.nextPlayTime = now + _vm->_rnd.getRandomNumberRng(track.time1, track.time2); + track.audioPlayerTrack = _vm->_audioPlayer->playAud( + track.name, + track.volume * _ambientVolume / 100, + panStart, + panEnd, + track.priority, + AudioPlayer::OVERRIDE_VOLUME + ); + track.nextPlayTime = now + _vm->_rnd.getRandomNumberRng(track.timeMin, track.timeMax); } } int AmbientSounds::findAvailableNonLoopingTrack() { for (int i = 0; i != NON_LOOPING_SOUNDS; ++i) { - if (!_nonLoopingSounds[i].isActive) + if (!_nonLoopingSounds[i].isActive) { return i; + } } return -1; @@ -151,8 +240,9 @@ int AmbientSounds::findNonLoopingTrackByHash(int32 hash) { for (int i = 0; i != NON_LOOPING_SOUNDS; ++i) { NonLoopingSound &track = _nonLoopingSounds[i]; - if (track.isActive && track.hash == hash) + if (track.isActive && track.hash == hash) { return i; + } } return -1; @@ -160,8 +250,9 @@ int AmbientSounds::findNonLoopingTrackByHash(int32 hash) { int AmbientSounds::findAvailableLoopingTrack() { for (int i = 0; i != LOOPING_SOUNDS; ++i) { - if (!_loopingSounds[i].isActive) + if (!_loopingSounds[i].isActive) { return i; + } } return -1; @@ -171,46 +262,77 @@ int AmbientSounds::findLoopingTrackByHash(int32 hash) { for (int i = 0; i != LOOPING_SOUNDS; ++i) { LoopingSound &track = _loopingSounds[i]; - if (track.isActive && track.hash == hash) + if (track.isActive && track.hash == hash) { return i; + } } return -1; } void AmbientSounds::addSoundByName( - const char *name, - int timeRangeBegin, int timeRangeEnd, - int volumeRangeBegin, int volumeRangeEnd, - int pan1begin, int pan1end, - int pan2begin, int pan2end, - int priority, int unk3) { + const char *name, + int timeMin, int timeMax, + int volumeMin, int volumeMax, + int panStartMin, int panStartMax, + int panEndMin, int panEndMax, + int priority, int unk) { if (strlen(name) > 12) { error("AmbientSounds::addSoundByName: Overlong name '%s'", name); } int i = findAvailableNonLoopingTrack(); - if (i < 0) + if (i < 0) { return; + } NonLoopingSound &track = _nonLoopingSounds[i]; - uint32 now = g_system->getMillis(); + uint32 now = _vm->getTotalPlayTime(); - track.isActive = true; + track.isActive = true; strcpy(track.name, name); - track.hash = mix_id(name); - track.time1 = 1000 * timeRangeBegin; - track.time2 = 1000 * timeRangeEnd; - track.nextPlayTime = now + _vm->_rnd.getRandomNumberRng(track.time1, track.time2); - track.volume1 = volumeRangeBegin; - track.volume2 = volumeRangeEnd; - track.volume = 0; - track.pan1begin = pan1begin; - track.pan1end = pan1end; - track.pan2begin = pan2begin; - track.pan2end = pan2end; - track.priority = priority; + track.hash = mix_id(name); + track.timeMin = 1000 * timeMin; + track.timeMax = 1000 * timeMax; + track.nextPlayTime = now + _vm->_rnd.getRandomNumberRng(track.timeMin, track.timeMax); + track.volumeMin = volumeMin; + track.volumeMax = volumeMax; + track.volume = 0; + track.panStartMin = panStartMin; + track.panStartMax = panStartMax; + track.panEndMin = panEndMin; + track.panEndMax = panEndMax; + track.priority = priority; +} + +void AmbientSounds::removeNonLoopingSoundByIndex(int index, bool stopPlaying) { + NonLoopingSound &track = _nonLoopingSounds[index]; + if (stopPlaying) { + if (track.isActive && track.audioPlayerTrack != -1 && _vm->_audioPlayer->isActive(track.audioPlayerTrack)) { + _vm->_audioPlayer->stop(track.audioPlayerTrack, stopPlaying); + } + } + track.isActive = false; + track.audioPlayerTrack = -1; + // track.field_45 = 0; +} + +void AmbientSounds::removeLoopingSoundByIndex(int index, int delay) { + LoopingSound &track = _loopingSounds[index]; + if (track.isActive && track.audioPlayerTrack != -1 && _vm->_audioPlayer->isActive(track.audioPlayerTrack)) { + if (delay > 0) { + _vm->_audioPlayer->adjustVolume(track.audioPlayerTrack, 0, delay, false); + } else { + _vm->_audioPlayer->stop(track.audioPlayerTrack, false); + } + } + track.isActive = false; + track.name[0] = 0; + track.hash = 0; + track.audioPlayerTrack = -1; + track.volume = 0; + track.pan = 0; } } // End of namespace BladeRunner |