/* ScummVM - Graphic Adventure Engine * * ScummVM is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT * file distributed with this source distribution. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * */ #include "bladerunner/ambient_sounds.h" #include "bladerunner/audio_player.h" #include "bladerunner/bladerunner.h" #include "bladerunner/gameinfo.h" #include "common/debug.h" #include "common/system.h" namespace BladeRunner { #define NON_LOOPING_SOUNDS 25 #define LOOPING_SOUNDS 3 AmbientSounds::AmbientSounds(BladeRunnerEngine *vm) : _vm(vm) { _nonLoopingSounds = new NonLoopingSound[NON_LOOPING_SOUNDS]; _loopingSounds = new LoopingSound[LOOPING_SOUNDS]; _ambientVolume = 65; for (int i = 0; i != NON_LOOPING_SOUNDS; ++i) { NonLoopingSound &track = _nonLoopingSounds[i]; track.isActive = false; } for (int i = 0; i != LOOPING_SOUNDS; ++i) { LoopingSound &track = _loopingSounds[i]; track.isActive = false; } } AmbientSounds::~AmbientSounds() { delete[] _nonLoopingSounds; delete[] _loopingSounds; } static inline void sort(int &a, int &b) { if (a > b) { int t = a; a = b; b = t; } } 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); addSoundByName( name, timeRangeBegin, timeRangeEnd, volumeRangeBegin, volumeRangeEnd, unk1RangeBegin, unk1RangeEnd, unk2RangeBegin, unk2RangeEnd, priority, unk3 ); } void AmbientSounds::addLoopingSound(int sfx_id, int volume, int unk, int fadeInTime) { const char *name = _vm->_gameInfo->getSfxTrack(sfx_id); int32 hash = mix_id(name); if (findLoopingTrackByHash(hash) >= 0) return; int i = findAvailableLoopingTrack(); if (i == -1) return; int actualVolume = volume * _ambientVolume / 100; int balance = 0; _vm->_audioPlayer->playAud(name, actualVolume, balance, balance, 100, AudioPlayer::LOOP | AudioPlayer::OVERRIDE_VOLUME); } void AmbientSounds::tick() { uint32 now = g_system->getMillis(); for (int i = 0; i != NON_LOOPING_SOUNDS; ++i) { NonLoopingSound &track = _nonLoopingSounds[i]; if (!track.isActive || track.nextPlayTime > now) continue; int pan1, pan2; pan1 = _vm->_rnd.getRandomNumberRng(track.pan1begin, track.pan1end); if (track.pan2begin == -101) { pan2 = pan1; } else { pan2 = _vm->_rnd.getRandomNumberRng(track.pan2begin, track.pan2end); } track.volume = _vm->_rnd.getRandomNumberRng(track.volume1, track.volume2); 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); } } int AmbientSounds::findAvailableNonLoopingTrack() { for (int i = 0; i != NON_LOOPING_SOUNDS; ++i) { if (!_nonLoopingSounds[i].isActive) return i; } return -1; } int AmbientSounds::findNonLoopingTrackByHash(int32 hash) { for (int i = 0; i != NON_LOOPING_SOUNDS; ++i) { NonLoopingSound &track = _nonLoopingSounds[i]; if (track.isActive && track.hash == hash) return i; } return -1; } int AmbientSounds::findAvailableLoopingTrack() { for (int i = 0; i != LOOPING_SOUNDS; ++i) { if (!_loopingSounds[i].isActive) return i; } return -1; } int AmbientSounds::findLoopingTrackByHash(int32 hash) { for (int i = 0; i != LOOPING_SOUNDS; ++i) { LoopingSound &track = _loopingSounds[i]; 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) { int i = findAvailableNonLoopingTrack(); if (i < 0) return; NonLoopingSound &track = _nonLoopingSounds[i]; uint32 now = g_system->getMillis(); 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; } } // End of namespace BladeRunner