2011-02-14 20:37:27 +11:00
|
|
|
/* 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.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2011-05-18 20:32:40 +10:00
|
|
|
#include "common/config-manager.h"
|
2011-02-14 20:37:27 +11:00
|
|
|
#include "tsage/core.h"
|
|
|
|
#include "tsage/globals.h"
|
|
|
|
#include "tsage/debugger.h"
|
|
|
|
#include "tsage/graphics.h"
|
2011-05-01 15:23:30 +10:00
|
|
|
#include "tsage/tsage.h"
|
2011-02-14 20:37:27 +11:00
|
|
|
|
|
|
|
namespace tSage {
|
|
|
|
|
2011-05-27 21:19:06 +10:00
|
|
|
static SoundManager *_soundManager = NULL;
|
|
|
|
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
|
2011-05-01 19:28:30 +10:00
|
|
|
SoundManager::SoundManager() {
|
2011-05-27 21:19:06 +10:00
|
|
|
_soundManager = this;
|
2011-05-01 19:28:30 +10:00
|
|
|
__sndmgrReady = false;
|
|
|
|
_minVersion = 0x102;
|
|
|
|
_maxVersion = 0x10A;
|
|
|
|
|
2011-05-02 21:30:20 +10:00
|
|
|
for (int i = 0; i < SOUND_ARR_SIZE; ++i) {
|
|
|
|
_field89[i] = 0;
|
|
|
|
_groupList[i] = 0;
|
|
|
|
_fieldE9[i] = 0;
|
2011-05-01 19:28:30 +10:00
|
|
|
_field109[i] = 0;
|
2011-05-18 20:32:40 +10:00
|
|
|
_voiceStructPtrs[i] = NULL;
|
2011-05-02 21:30:20 +10:00
|
|
|
}
|
2011-05-01 19:28:30 +10:00
|
|
|
|
|
|
|
_groupMask = 0;
|
|
|
|
_volume = 127;
|
|
|
|
_suspendCtr = 0;
|
|
|
|
_disableCtr = 0;
|
2011-05-12 23:09:48 +10:00
|
|
|
_suspendedCount = 0;
|
2011-05-04 23:13:15 +10:00
|
|
|
_driversDetected = false;
|
2011-05-18 20:32:40 +10:00
|
|
|
_needToRethink = false;
|
2011-05-01 19:28:30 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
SoundManager::~SoundManager() {
|
|
|
|
if (__sndmgrReady) {
|
|
|
|
for (Common::List<Sound *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i)
|
|
|
|
(*i)->stop();
|
2011-05-04 23:13:15 +10:00
|
|
|
for (Common::List<SoundDriver *>::iterator i = _installedDrivers.begin(); i != _installedDrivers.end(); ) {
|
2011-05-18 20:32:40 +10:00
|
|
|
SoundDriver *driver = *i;
|
2011-05-04 23:13:15 +10:00
|
|
|
++i;
|
2011-05-18 20:32:40 +10:00
|
|
|
delete driver;
|
2011-05-04 23:13:15 +10:00
|
|
|
}
|
2011-05-01 19:28:30 +10:00
|
|
|
_sfTerminate();
|
|
|
|
}
|
2011-05-27 21:19:06 +10:00
|
|
|
|
|
|
|
_soundManager = NULL;
|
2011-05-01 19:28:30 +10:00
|
|
|
}
|
|
|
|
|
2011-02-14 20:37:27 +11:00
|
|
|
void SoundManager::postInit() {
|
2011-05-01 19:28:30 +10:00
|
|
|
if (!__sndmgrReady) {
|
|
|
|
_saver->addSaveNotifier(&SoundManager::saveNotifier);
|
|
|
|
_saver->addLoadNotifier(&SoundManager::loadNotifier);
|
|
|
|
_saver->addListener(this);
|
|
|
|
__sndmgrReady = true;
|
|
|
|
}
|
2011-02-14 20:37:27 +11:00
|
|
|
}
|
|
|
|
|
2011-05-18 20:32:40 +10:00
|
|
|
/**
|
|
|
|
* Loops through all the loaded sounds, and stops any that have been flagged for stopping
|
|
|
|
*/
|
|
|
|
void SoundManager::dispatch() {
|
|
|
|
Common::List<Sound *>::iterator i = _soundList.begin();
|
|
|
|
while (i != _soundList.end()) {
|
|
|
|
Sound *sound = *i;
|
|
|
|
++i;
|
|
|
|
|
|
|
|
// If the sound is flagged for stopping, then stop it
|
|
|
|
if (sound->_stopFlag) {
|
|
|
|
sound->stop();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void SoundManager::syncSounds() {
|
|
|
|
bool mute = false;
|
|
|
|
if (ConfMan.hasKey("mute"))
|
|
|
|
mute = ConfMan.getBool("mute");
|
|
|
|
|
|
|
|
bool music_mute = mute;
|
|
|
|
bool sfx_mute = mute;
|
|
|
|
|
|
|
|
if (!mute) {
|
|
|
|
music_mute = ConfMan.getBool("music_mute");
|
|
|
|
sfx_mute = ConfMan.getBool("sfx_mute");
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get the new music and sfx volumes
|
|
|
|
int musicVolume = music_mute ? 0 : MIN(255, ConfMan.getInt("music_volume"));
|
|
|
|
int sfxVolume = sfx_mute ? 0 : MIN(255, ConfMan.getInt("sfx_volume"));
|
|
|
|
|
|
|
|
warning("Set volume music=%d sfx=%d", musicVolume, sfxVolume);
|
|
|
|
this->setMasterVol(musicVolume / 2);
|
|
|
|
}
|
|
|
|
|
2011-05-04 23:13:15 +10:00
|
|
|
Common::List<SoundDriverEntry> &SoundManager::buildDriverList(bool detectFlag) {
|
|
|
|
assert(__sndmgrReady);
|
|
|
|
_availableDrivers.clear();
|
2011-02-14 20:37:27 +11:00
|
|
|
|
2011-05-04 23:13:15 +10:00
|
|
|
// Build up a list of available drivers. Currently we only implement an Adlib driver
|
|
|
|
SoundDriverEntry sd;
|
|
|
|
sd.driverNum = ADLIB_DRIVER_NUM;
|
|
|
|
sd.status = detectFlag ? SNDSTATUS_DETECTED : SNDSTATUS_SKIPPED;
|
|
|
|
sd.field2 = 0;
|
|
|
|
sd.field6 = 15000;
|
|
|
|
sd.shortDescription = "Adlib or SoundBlaster";
|
|
|
|
sd.longDescription = "3812fm";
|
|
|
|
_availableDrivers.push_back(sd);
|
2011-02-14 20:37:27 +11:00
|
|
|
|
2011-05-04 23:13:15 +10:00
|
|
|
_driversDetected = true;
|
|
|
|
return _availableDrivers;
|
2011-02-14 20:37:27 +11:00
|
|
|
}
|
|
|
|
|
2011-05-04 23:13:15 +10:00
|
|
|
void SoundManager::installConfigDrivers() {
|
2011-05-07 14:13:52 +10:00
|
|
|
installDriver(ADLIB_DRIVER_NUM);
|
2011-02-14 20:37:27 +11:00
|
|
|
}
|
|
|
|
|
2011-05-04 23:13:15 +10:00
|
|
|
Common::List<SoundDriverEntry> &SoundManager::getDriverList(bool detectFlag) {
|
|
|
|
if (detectFlag)
|
|
|
|
return _availableDrivers;
|
|
|
|
else
|
|
|
|
return buildDriverList(false);
|
2011-02-14 20:37:27 +11:00
|
|
|
}
|
|
|
|
|
2011-05-04 23:13:15 +10:00
|
|
|
void SoundManager::dumpDriverList() {
|
|
|
|
_availableDrivers.clear();
|
|
|
|
}
|
2011-04-27 22:22:20 +10:00
|
|
|
|
2011-05-04 23:13:15 +10:00
|
|
|
void SoundManager::disableSoundServer() {
|
|
|
|
++_disableCtr;
|
2011-04-27 21:23:47 +10:00
|
|
|
}
|
|
|
|
|
2011-05-04 23:13:15 +10:00
|
|
|
void SoundManager::enableSoundServer() {
|
|
|
|
if (_disableCtr > 0)
|
|
|
|
--_disableCtr;
|
|
|
|
}
|
2011-05-01 19:28:30 +10:00
|
|
|
|
|
|
|
void SoundManager::suspendSoundServer() {
|
2011-05-04 23:13:15 +10:00
|
|
|
++_suspendCtr;
|
2011-05-01 19:28:30 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
void SoundManager::restartSoundServer() {
|
2011-05-04 23:13:15 +10:00
|
|
|
if (_suspendCtr > 0)
|
|
|
|
--_suspendCtr;
|
2011-05-01 19:28:30 +10:00
|
|
|
}
|
|
|
|
|
2011-05-04 23:13:15 +10:00
|
|
|
/**
|
|
|
|
* Install the specified driver number
|
|
|
|
*/
|
|
|
|
void SoundManager::installDriver(int driverNum) {
|
|
|
|
// If driver is already installed, no need to install it
|
|
|
|
if (isInstalled(driverNum))
|
|
|
|
return;
|
|
|
|
|
|
|
|
// Instantiate the sound driver
|
|
|
|
SoundDriver *driver = instantiateDriver(driverNum);
|
|
|
|
if (!driver)
|
|
|
|
return;
|
|
|
|
|
|
|
|
assert((_maxVersion >= driver->_minVersion) && (_maxVersion <= driver->_maxVersion));
|
|
|
|
|
|
|
|
// Mute any loaded sounds
|
|
|
|
disableSoundServer();
|
|
|
|
for (Common::List<Sound *>::iterator i = _playList.begin(); i != _playList.end(); ++i)
|
|
|
|
(*i)->mute(true);
|
|
|
|
|
|
|
|
// Install the driver
|
|
|
|
if (!_sfInstallDriver(driver))
|
|
|
|
error("Sound driver initialization failed");
|
|
|
|
|
|
|
|
switch (driverNum) {
|
|
|
|
case ROLAND_DRIVER_NUM:
|
|
|
|
case ADLIB_DRIVER_NUM: {
|
|
|
|
// Handle loading bank infomation
|
|
|
|
byte *bankData = _resourceManager->getResource(RES_BANK, ROLAND_DRIVER_NUM, 0, true);
|
|
|
|
if (bankData) {
|
|
|
|
// Install the patch bank data
|
2011-05-12 23:09:48 +10:00
|
|
|
_sfInstallPatchBank(driver, bankData);
|
2011-05-04 23:13:15 +10:00
|
|
|
DEALLOCATE(bankData);
|
|
|
|
} else {
|
|
|
|
// Could not locate patch bank data, so unload the driver
|
|
|
|
_sfUnInstallDriver(driver);
|
|
|
|
|
|
|
|
// Unmute currently active sounds
|
|
|
|
for (Common::List<Sound *>::iterator i = _playList.begin(); i != _playList.end(); ++i)
|
|
|
|
(*i)->mute(false);
|
2011-05-01 19:28:30 +10:00
|
|
|
|
2011-05-04 23:13:15 +10:00
|
|
|
enableSoundServer();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2011-05-01 19:28:30 +10:00
|
|
|
}
|
|
|
|
|
2011-05-04 23:13:15 +10:00
|
|
|
/**
|
|
|
|
* Instantiate a driver class for the specified driver number
|
|
|
|
*/
|
|
|
|
SoundDriver *SoundManager::instantiateDriver(int driverNum) {
|
|
|
|
assert(driverNum == ADLIB_DRIVER_NUM);
|
|
|
|
return new AdlibSoundDriver();
|
2011-05-01 19:28:30 +10:00
|
|
|
}
|
|
|
|
|
2011-05-04 23:13:15 +10:00
|
|
|
/**
|
|
|
|
* Uninstall the specified driver
|
|
|
|
*/
|
|
|
|
void SoundManager::unInstallDriver(int driverNum) {
|
|
|
|
Common::List<SoundDriver *>::const_iterator i;
|
|
|
|
for (i = _installedDrivers.begin(); i != _installedDrivers.end(); ++i) {
|
|
|
|
if ((*i)->_driverNum == driverNum) {
|
|
|
|
// Found driver to remove
|
|
|
|
|
|
|
|
// Mute any loaded sounds
|
|
|
|
disableSoundServer();
|
|
|
|
for (Common::List<Sound *>::iterator i = _playList.begin(); i != _playList.end(); ++i)
|
|
|
|
(*i)->mute(true);
|
|
|
|
|
|
|
|
// Uninstall the driver
|
|
|
|
_sfUnInstallDriver(*i);
|
|
|
|
|
|
|
|
// Re-orient all the loaded sounds
|
|
|
|
for (Common::List<Sound *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i)
|
|
|
|
(*i)->orientAfterDriverChange();
|
|
|
|
|
|
|
|
// Unmute currently active sounds
|
|
|
|
for (Common::List<Sound *>::iterator i = _playList.begin(); i != _playList.end(); ++i)
|
|
|
|
(*i)->mute(false);
|
|
|
|
|
|
|
|
enableSoundServer();
|
|
|
|
}
|
|
|
|
}
|
2011-05-01 19:28:30 +10:00
|
|
|
}
|
|
|
|
|
2011-05-04 23:13:15 +10:00
|
|
|
/**
|
|
|
|
* Returns true if a specified driver number is currently installed
|
|
|
|
*/
|
|
|
|
bool SoundManager::isInstalled(int driverNum) const {
|
|
|
|
Common::List<SoundDriver *>::const_iterator i;
|
|
|
|
for (i = _installedDrivers.begin(); i != _installedDrivers.end(); ++i) {
|
|
|
|
if ((*i)->_driverNum == driverNum)
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
2011-05-01 19:28:30 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
void SoundManager::setMasterVol(int volume) {
|
|
|
|
_sfSetMasterVol(volume);
|
|
|
|
}
|
|
|
|
|
|
|
|
int SoundManager::getMasterVol() const {
|
|
|
|
return _volume;
|
|
|
|
}
|
|
|
|
|
|
|
|
void SoundManager::loadSound(int soundNum, bool showErrors) {
|
|
|
|
// This method preloaded the data associated with a given sound, so is now redundant
|
|
|
|
}
|
|
|
|
|
|
|
|
void SoundManager::unloadSound(int soundNum) {
|
|
|
|
// This method signalled the resource manager to unload the data for a sound, and is now redundant
|
|
|
|
}
|
|
|
|
|
2011-05-01 15:23:30 +10:00
|
|
|
int SoundManager::determineGroup(const byte *soundData) {
|
|
|
|
return _sfDetermineGroup(soundData);
|
|
|
|
}
|
|
|
|
|
2011-05-04 23:13:15 +10:00
|
|
|
void SoundManager::checkResVersion(const byte *soundData) {
|
|
|
|
int maxVersion = READ_LE_UINT16(soundData + 4);
|
|
|
|
int minVersion = READ_LE_UINT16(soundData + 6);
|
|
|
|
|
2011-05-27 21:19:06 +10:00
|
|
|
if (_soundManager->_minVersion < minVersion)
|
2011-05-04 23:13:15 +10:00
|
|
|
error("Attempt to play/prime sound resource that is too new");
|
2011-05-27 21:19:06 +10:00
|
|
|
if (_soundManager->_minVersion > maxVersion)
|
2011-05-04 23:13:15 +10:00
|
|
|
error("Attempt to play/prime sound resource that is too old");
|
|
|
|
}
|
|
|
|
|
2011-05-01 15:23:30 +10:00
|
|
|
int SoundManager::extractPriority(const byte *soundData) {
|
|
|
|
return READ_LE_UINT16(soundData + 12);
|
|
|
|
}
|
|
|
|
|
|
|
|
int SoundManager::extractLoop(const byte *soundData) {
|
|
|
|
return READ_LE_UINT16(soundData + 14);
|
|
|
|
}
|
|
|
|
|
2011-05-01 19:28:30 +10:00
|
|
|
void SoundManager::extractTrackInfo(trackInfoStruct *trackInfo, const byte *soundData, int groupNum) {
|
|
|
|
_sfExtractTrackInfo(trackInfo, soundData, groupNum);
|
|
|
|
}
|
|
|
|
|
2011-05-01 15:23:30 +10:00
|
|
|
void SoundManager::addToSoundList(Sound *sound) {
|
|
|
|
if (!contains(_soundList, sound))
|
|
|
|
_soundList.push_back(sound);
|
|
|
|
}
|
|
|
|
|
|
|
|
void SoundManager::removeFromSoundList(Sound *sound) {
|
|
|
|
_soundList.remove(sound);
|
|
|
|
}
|
|
|
|
|
|
|
|
void SoundManager::addToPlayList(Sound *sound) {
|
|
|
|
_sfAddToPlayList(sound);
|
|
|
|
}
|
|
|
|
|
|
|
|
void SoundManager::removeFromPlayList(Sound *sound) {
|
|
|
|
_sfRemoveFromPlayList(sound);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool SoundManager::isOnPlayList(Sound *sound) {
|
|
|
|
return _sfIsOnPlayList(sound);
|
|
|
|
}
|
|
|
|
|
|
|
|
void SoundManager::updateSoundVol(Sound *sound) {
|
|
|
|
_sfUpdateVolume(sound);
|
|
|
|
}
|
|
|
|
|
|
|
|
void SoundManager::updateSoundPri(Sound *sound) {
|
|
|
|
_sfUpdatePriority(sound);
|
|
|
|
}
|
|
|
|
|
|
|
|
void SoundManager::updateSoundLoop(Sound *sound) {
|
|
|
|
_sfUpdateLoop(sound);
|
|
|
|
}
|
|
|
|
|
2011-05-01 19:28:30 +10:00
|
|
|
void SoundManager::rethinkVoiceTypes() {
|
|
|
|
_sfRethinkVoiceTypes();
|
|
|
|
}
|
|
|
|
|
2011-05-18 20:32:40 +10:00
|
|
|
void SoundManager::_sfSoundServer() {
|
|
|
|
if (!sfManager()._disableCtr && !sfManager()._suspendCtr)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (sfManager()._needToRethink) {
|
|
|
|
_sfRethinkVoiceTypes();
|
|
|
|
sfManager()._needToRethink = false;
|
|
|
|
} else {
|
|
|
|
_sfDereferenceAll();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Handle any fading if necessary
|
|
|
|
do {
|
|
|
|
_sfProcessFading();
|
|
|
|
} while (sfManager()._suspendCtr > 0);
|
|
|
|
sfManager()._suspendCtr = 0;
|
|
|
|
|
|
|
|
// Poll all sound drivers in case they need it
|
|
|
|
for (Common::List<SoundDriver *>::iterator i = sfManager()._installedDrivers.begin();
|
|
|
|
i != sfManager()._installedDrivers.end(); ++i) {
|
|
|
|
(*i)->poll();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void SoundManager::_sfProcessFading() {
|
|
|
|
//TODO
|
|
|
|
}
|
|
|
|
|
2011-05-24 20:07:41 +10:00
|
|
|
void SoundManager::_sfUpdateVoiceStructs() {
|
|
|
|
for (int voiceIndex = 0; voiceIndex < SOUND_ARR_SIZE; ++voiceIndex) {
|
|
|
|
VoiceStruct *vs = sfManager()._voiceStructPtrs[voiceIndex];
|
|
|
|
|
|
|
|
for (uint idx = 0; idx < vs->_entries.size(); ++idx) {
|
|
|
|
VoiceStructEntry &vse = vs->_entries[idx];
|
|
|
|
|
|
|
|
if (vs->_voiceType == VOICETYPE_0) {
|
|
|
|
vse._field4 = vse._fieldC;
|
|
|
|
vse._field6 = vse._fieldE;
|
|
|
|
vse._field8 = vse._field10;
|
|
|
|
vse._field9 = vse._field11;
|
|
|
|
vse._fieldA = vse._field12;
|
|
|
|
} else {
|
|
|
|
vse._field8 = vse._fieldE;
|
|
|
|
vse._fieldA = vse._field10;
|
|
|
|
vse._fieldC = vse._field12;
|
|
|
|
vse._fieldD = vse._field13;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-05-01 15:23:30 +10:00
|
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
|
2011-05-04 23:13:15 +10:00
|
|
|
void SoundManager::saveNotifier(bool postFlag) {
|
2011-05-27 21:19:06 +10:00
|
|
|
_soundManager->saveNotifierProc(postFlag);
|
2011-05-04 23:13:15 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
void SoundManager::saveNotifierProc(bool postFlag) {
|
|
|
|
warning("TODO: SoundManager::saveNotifierProc");
|
|
|
|
}
|
|
|
|
|
|
|
|
void SoundManager::loadNotifier(bool postFlag) {
|
2011-05-27 21:19:06 +10:00
|
|
|
_soundManager->loadNotifierProc(postFlag);
|
2011-05-04 23:13:15 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
void SoundManager::loadNotifierProc(bool postFlag) {
|
|
|
|
warning("TODO: SoundManager::loadNotifierProc");
|
|
|
|
}
|
|
|
|
|
|
|
|
void SoundManager::listenerSynchronize(Serializer &s) {
|
|
|
|
s.validate("SoundManager");
|
|
|
|
warning("TODO: SoundManager listenerSynchronise");
|
|
|
|
}
|
|
|
|
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
|
2011-05-07 14:13:52 +10:00
|
|
|
SoundManager &SoundManager::sfManager() {
|
2011-05-27 21:19:06 +10:00
|
|
|
return *_soundManager;
|
2011-05-07 14:13:52 +10:00
|
|
|
}
|
|
|
|
|
2011-05-01 15:23:30 +10:00
|
|
|
void SoundManager::_soSetTimeIndex(int timeIndex) {
|
|
|
|
warning("TODO: _soSetTimeIndex");
|
|
|
|
}
|
|
|
|
|
|
|
|
int SoundManager::_sfDetermineGroup(const byte *soundData) {
|
|
|
|
const byte *p = soundData + READ_LE_UINT16(soundData + 8);
|
|
|
|
uint32 v;
|
|
|
|
while ((v = READ_LE_UINT32(p)) != 0) {
|
2011-05-27 21:19:06 +10:00
|
|
|
if ((v & _soundManager->_groupMask) == v)
|
2011-05-01 15:23:30 +10:00
|
|
|
return v;
|
|
|
|
|
2011-05-02 21:30:20 +10:00
|
|
|
p += 6 + (READ_LE_UINT16(p + 4) * 4);
|
2011-05-01 15:23:30 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2011-05-07 14:13:52 +10:00
|
|
|
void SoundManager::_sfAddToPlayList(Sound *sound) {
|
|
|
|
++sfManager()._suspendCtr;
|
|
|
|
_sfDoAddToPlayList(sound);
|
2011-05-18 20:32:40 +10:00
|
|
|
sound->_stopFlag = false;
|
2011-05-07 14:13:52 +10:00
|
|
|
_sfRethinkVoiceTypes();
|
|
|
|
--sfManager()._suspendCtr;
|
2011-05-01 15:23:30 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
void SoundManager::_sfRemoveFromPlayList(Sound *sound) {
|
2011-05-07 14:13:52 +10:00
|
|
|
++sfManager()._suspendCtr;
|
|
|
|
if (_sfDoRemoveFromPlayList(sound))
|
|
|
|
_sfRethinkVoiceTypes();
|
|
|
|
--sfManager()._suspendCtr;
|
2011-05-01 15:23:30 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
bool SoundManager::_sfIsOnPlayList(Sound *sound) {
|
2011-05-27 21:19:06 +10:00
|
|
|
++_soundManager->_suspendCtr;
|
|
|
|
bool result = contains(_soundManager->_playList, sound);
|
|
|
|
--_soundManager->_suspendCtr;
|
2011-05-01 15:23:30 +10:00
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2011-05-12 23:09:48 +10:00
|
|
|
void SoundManager::_sfRethinkSoundDrivers() {
|
2011-05-18 20:32:40 +10:00
|
|
|
// Free any existing entries
|
|
|
|
for (int idx = 0; idx < SOUND_ARR_SIZE; ++idx) {
|
|
|
|
if (sfManager()._voiceStructPtrs[idx]) {
|
|
|
|
delete sfManager()._voiceStructPtrs[idx];
|
|
|
|
sfManager()._voiceStructPtrs[idx] = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int idx = 0; idx < SOUND_ARR_SIZE; ++idx) {
|
|
|
|
byte flag = 0xff;
|
|
|
|
int total = 0;
|
|
|
|
|
|
|
|
// Loop through the sound drivers
|
|
|
|
for (Common::List<SoundDriver *>::iterator i = sfManager()._installedDrivers.begin();
|
|
|
|
i != sfManager()._installedDrivers.end(); ++i) {
|
|
|
|
// Process the group data for each sound driver
|
|
|
|
SoundDriver *driver = *i;
|
|
|
|
const byte *groupData = driver->_groupOffset->pData;
|
|
|
|
|
|
|
|
while (*groupData != 0xff) {
|
|
|
|
byte byteVal = *groupData++;
|
|
|
|
|
|
|
|
if (byteVal == idx) {
|
|
|
|
byte byteVal2 = *groupData++;
|
|
|
|
if (flag == 0xff)
|
|
|
|
flag = byteVal2;
|
|
|
|
else {
|
|
|
|
assert(flag == byteVal2);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!flag) {
|
|
|
|
while (*groupData++ != 0xff)
|
|
|
|
++total;
|
|
|
|
} else {
|
|
|
|
total += *groupData;
|
|
|
|
groupData += 2;
|
|
|
|
}
|
|
|
|
} else if (*groupData++ == 0) {
|
|
|
|
while (*groupData != 0xff)
|
|
|
|
++groupData;
|
|
|
|
++groupData;
|
|
|
|
} else {
|
|
|
|
groupData += 2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (total) {
|
|
|
|
int dataSize = !flag ? total * 28 + 30 : total * 26 + 30;
|
|
|
|
debugC(9, ktSageSound, "data Size = %d\n", dataSize);
|
|
|
|
|
|
|
|
VoiceStruct *vs = new VoiceStruct();
|
|
|
|
sfManager()._voiceStructPtrs[idx] = vs;
|
|
|
|
|
|
|
|
if (!flag) {
|
2011-05-24 20:07:41 +10:00
|
|
|
vs->_voiceType = VOICETYPE_0;
|
2011-05-18 20:32:40 +10:00
|
|
|
vs->_field1 = total;
|
|
|
|
} else {
|
2011-05-24 20:07:41 +10:00
|
|
|
vs->_voiceType = VOICETYPE_1;
|
2011-05-18 20:32:40 +10:00
|
|
|
vs->_field1 = vs->_field2 = total;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (Common::List<SoundDriver *>::iterator i = sfManager()._installedDrivers.begin();
|
|
|
|
i != sfManager()._installedDrivers.end(); ++i) {
|
|
|
|
// Process the group data for each sound driver
|
|
|
|
SoundDriver *driver = *i;
|
|
|
|
const byte *groupData = driver->_groupOffset->pData;
|
|
|
|
|
|
|
|
while (*groupData != 0xff) {
|
|
|
|
byte byteVal = *groupData++;
|
|
|
|
|
|
|
|
if (byteVal == idx) {
|
|
|
|
if (!flag) {
|
|
|
|
while ((byteVal = *groupData++) != 0xff) {
|
|
|
|
VoiceStructEntry ve;
|
|
|
|
ve._field1 = (byteVal & 0x80) ? 0 : 1;
|
|
|
|
ve._driver = driver;
|
|
|
|
ve._field4 = 0;
|
|
|
|
ve._field6 = 0;
|
|
|
|
ve._field8 = 0;
|
|
|
|
ve._field9 = 0;
|
|
|
|
ve._fieldA = 0;
|
|
|
|
|
|
|
|
vs->_entries.push_back(ve);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
byteVal = *groupData;
|
|
|
|
groupData += 2;
|
|
|
|
|
|
|
|
for (int idx = 0; idx < byteVal; ++idx) {
|
|
|
|
VoiceStructEntry ve;
|
|
|
|
ve._field0 = idx;
|
|
|
|
ve._driver = driver;
|
|
|
|
ve._field4 = 0xff;
|
|
|
|
ve._field6 = 0;
|
|
|
|
ve._field8 = 0;
|
|
|
|
ve._fieldA = 0;
|
|
|
|
ve._fieldC = 0;
|
|
|
|
ve._fieldD = 0;
|
|
|
|
|
|
|
|
vs->_entries.push_back(ve);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (*groupData++ != 0) {
|
|
|
|
while (*groupData != 0xff)
|
|
|
|
++groupData;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2011-05-12 23:09:48 +10:00
|
|
|
}
|
|
|
|
|
2011-05-01 15:23:30 +10:00
|
|
|
void SoundManager::_sfRethinkVoiceTypes() {
|
2011-05-24 20:07:41 +10:00
|
|
|
++sfManager()._suspendCtr;
|
|
|
|
_sfDereferenceAll();
|
|
|
|
|
|
|
|
for (int voiceIndex = 0; voiceIndex < SOUND_ARR_SIZE; ++voiceIndex) {
|
|
|
|
VoiceStruct *vs = sfManager()._voiceStructPtrs[voiceIndex];
|
|
|
|
if (!vs)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (vs->_voiceType == VOICETYPE_0) {
|
|
|
|
for (uint idx = 0; idx < vs->_entries.size(); ++idx) {
|
|
|
|
VoiceStructEntry &vse = vs->_entries[idx];
|
|
|
|
vse._field14 = vse._field4;
|
|
|
|
vse._field16 = vse._field6;
|
|
|
|
vse._field18 = vse._field8;
|
|
|
|
vse._field19 = vse._field9;
|
|
|
|
vse._field1A = vse._fieldA;
|
|
|
|
vse._field4 = 0;
|
|
|
|
vse._field6 = 0;
|
|
|
|
vse._field8 = 0;
|
|
|
|
vse._field9 = 0;
|
|
|
|
vse._fieldA = 0;
|
|
|
|
vse._fieldC = 0;
|
|
|
|
vse._fieldE = 0;
|
|
|
|
vse._field10 = 0;
|
|
|
|
vse._field11 = 0;
|
|
|
|
vse._field12 = 0;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
for (uint idx = 0; idx < vs->_entries.size(); ++idx) {
|
|
|
|
VoiceStructEntry &vse = vs->_entries[idx];
|
|
|
|
vse._field14 = vse._field8;
|
|
|
|
vse._field16 = vse._fieldA;
|
|
|
|
vse._field18 = vse._fieldC;
|
|
|
|
vse._field19 = vse._fieldD;
|
|
|
|
vse._field8 = 0;
|
|
|
|
vse._fieldA = 0;
|
|
|
|
vse._fieldC = 0;
|
|
|
|
vse._fieldD = 0;
|
|
|
|
vse._fieldE = 0;
|
|
|
|
vse._field10 = 0;
|
|
|
|
vse._field12 = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-05-27 20:55:09 +10:00
|
|
|
// int var2 = 0;
|
2011-05-24 20:07:41 +10:00
|
|
|
for (Common::List<Sound *>::iterator playIterator = sfManager()._playList.begin();
|
|
|
|
playIterator != sfManager()._playList.end(); ++playIterator) {
|
|
|
|
|
|
|
|
}
|
2011-05-01 15:23:30 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
void SoundManager::_sfUpdateVolume(Sound *sound) {
|
|
|
|
_sfDereferenceAll();
|
2011-05-07 14:13:52 +10:00
|
|
|
_sfDoUpdateVolume(sound);
|
2011-05-01 15:23:30 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
void SoundManager::_sfDereferenceAll() {
|
2011-05-07 14:13:52 +10:00
|
|
|
// Orignal used handles for both the driver list and voiceStructPtrs list. This method then refreshed
|
|
|
|
// pointer lists based on the handles. Since in ScummVM we're just using pointers directly, this
|
|
|
|
// method doesn't need any implementation
|
2011-05-01 15:23:30 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
void SoundManager::_sfUpdatePriority(Sound *sound) {
|
2011-05-27 21:19:06 +10:00
|
|
|
++_soundManager->_suspendCtr;
|
2011-05-01 15:23:30 +10:00
|
|
|
|
2011-05-07 14:13:52 +10:00
|
|
|
int tempPriority = (sound->_priority2 == 255) ? sound->_soundPriority : sound->_priority;
|
|
|
|
if (sound->_priority != tempPriority) {
|
|
|
|
sound->_priority = tempPriority;
|
|
|
|
if (_sfDoRemoveFromPlayList(sound)) {
|
|
|
|
_sfDoAddToPlayList(sound);
|
|
|
|
_sfRethinkVoiceTypes();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-05-27 21:19:06 +10:00
|
|
|
--_soundManager->_suspendCtr;
|
2011-05-01 15:23:30 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
void SoundManager::_sfUpdateLoop(Sound *sound) {
|
2011-05-07 14:13:52 +10:00
|
|
|
if (sound->_loopFlag2)
|
|
|
|
sound->_loopFlag = sound->_loop;
|
|
|
|
else
|
|
|
|
sound->_loopFlag = sound->_loopFlag2;
|
2011-04-27 21:23:47 +10:00
|
|
|
}
|
|
|
|
|
2011-05-01 19:28:30 +10:00
|
|
|
void SoundManager::_sfSetMasterVol(int volume) {
|
|
|
|
if (volume > 127)
|
|
|
|
volume = 127;
|
|
|
|
|
2011-05-27 21:19:06 +10:00
|
|
|
if (volume != _soundManager->_volume) {
|
|
|
|
_soundManager->_volume = volume;
|
2011-05-01 19:28:30 +10:00
|
|
|
|
2011-05-27 21:19:06 +10:00
|
|
|
for (Common::List<SoundDriver *>::iterator i = _soundManager->_installedDrivers.begin();
|
|
|
|
i != _soundManager->_installedDrivers.end(); ++i) {
|
2011-05-24 20:07:41 +10:00
|
|
|
(*i)->setMasterVolume(volume);
|
2011-05-01 19:28:30 +10:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void SoundManager::_sfExtractTrackInfo(trackInfoStruct *trackInfo, const byte *soundData, int groupNum) {
|
2011-05-28 09:07:30 +10:00
|
|
|
trackInfo->_maxTrack = 0;
|
2011-05-01 19:28:30 +10:00
|
|
|
|
|
|
|
const byte *p = soundData + READ_LE_UINT16(soundData + 8);
|
|
|
|
uint32 v;
|
|
|
|
while ((v = READ_LE_UINT32(p)) != 0) {
|
|
|
|
while ((v == 0x80000000) || (v == (uint)groupNum)) {
|
|
|
|
int count = READ_LE_UINT16(p + 4);
|
|
|
|
p += 6;
|
|
|
|
|
|
|
|
for (int idx = 0; idx < count; ++idx) {
|
2011-05-28 09:07:30 +10:00
|
|
|
if (trackInfo->_maxTrack == 16) {
|
|
|
|
trackInfo->_maxTrack = -1;
|
2011-05-01 19:28:30 +10:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2011-05-28 09:07:30 +10:00
|
|
|
trackInfo->_rlbList[trackInfo->_maxTrack] = READ_LE_UINT16(p);
|
|
|
|
trackInfo->_arr2[trackInfo->_maxTrack] = READ_LE_UINT16(p + 2);
|
|
|
|
++trackInfo->_maxTrack;
|
2011-05-01 19:28:30 +10:00
|
|
|
p += 4;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-05-02 21:30:20 +10:00
|
|
|
p += 6 + (READ_LE_UINT16(p + 4) * 4);
|
2011-05-01 19:28:30 +10:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void SoundManager::_sfTerminate() {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2011-05-02 21:30:20 +10:00
|
|
|
void SoundManager::_sfExtractGroupMask() {
|
|
|
|
uint32 mask = 0;
|
|
|
|
for (int idx = 0; idx < SOUND_ARR_SIZE; ++idx)
|
2011-05-27 21:19:06 +10:00
|
|
|
mask |= _soundManager->_groupList[idx];
|
2011-05-02 21:30:20 +10:00
|
|
|
|
2011-05-27 21:19:06 +10:00
|
|
|
_soundManager->_groupMask = mask;
|
2011-05-02 21:30:20 +10:00
|
|
|
}
|
|
|
|
|
2011-05-04 23:13:15 +10:00
|
|
|
bool SoundManager::_sfInstallDriver(SoundDriver *driver) {
|
2011-05-12 23:09:48 +10:00
|
|
|
if (!driver->open())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
sfManager()._installedDrivers.push_back(driver);
|
2011-05-18 20:32:40 +10:00
|
|
|
driver->_groupOffset = driver->getGroupData();
|
|
|
|
driver->_groupMask = READ_LE_UINT32(driver->_groupOffset);
|
2011-05-12 23:09:48 +10:00
|
|
|
|
|
|
|
_sfExtractGroupMask();
|
|
|
|
_sfRethinkSoundDrivers();
|
2011-05-24 20:07:41 +10:00
|
|
|
driver->setMasterVolume(sfManager()._volume);
|
2011-05-12 23:09:48 +10:00
|
|
|
|
|
|
|
return true;
|
2011-05-04 23:13:15 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
void SoundManager::_sfUnInstallDriver(SoundDriver *driver) {
|
2011-05-12 23:09:48 +10:00
|
|
|
sfManager()._installedDrivers.remove(driver);
|
2011-05-18 20:32:40 +10:00
|
|
|
delete driver;
|
2011-05-04 23:13:15 +10:00
|
|
|
|
2011-05-12 23:09:48 +10:00
|
|
|
_sfExtractGroupMask();
|
|
|
|
_sfRethinkSoundDrivers();
|
2011-05-04 23:13:15 +10:00
|
|
|
}
|
|
|
|
|
2011-05-12 23:09:48 +10:00
|
|
|
void SoundManager::_sfInstallPatchBank(SoundDriver *driver, const byte *bankData) {
|
|
|
|
driver->installPatchBank(bankData);
|
2011-05-04 23:13:15 +10:00
|
|
|
}
|
|
|
|
|
2011-05-07 14:13:52 +10:00
|
|
|
/**
|
|
|
|
* Adds the specified sound in the playing sound list, inserting in order of priority
|
|
|
|
*/
|
|
|
|
void SoundManager::_sfDoAddToPlayList(Sound *sound) {
|
|
|
|
++sfManager()._suspendCtr;
|
|
|
|
|
|
|
|
Common::List<Sound *>::iterator i = sfManager()._playList.begin();
|
|
|
|
while ((i != sfManager()._playList.end()) && (sound->_priority > (*i)->_priority))
|
|
|
|
++i;
|
|
|
|
|
|
|
|
sfManager()._playList.insert(i, sound);
|
|
|
|
--sfManager()._suspendCtr;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Removes the specified sound from the play list
|
|
|
|
*/
|
|
|
|
bool SoundManager::_sfDoRemoveFromPlayList(Sound *sound) {
|
|
|
|
++sfManager()._suspendCtr;
|
|
|
|
|
|
|
|
bool result = false;
|
|
|
|
for (Common::List<Sound *>::iterator i = sfManager()._playList.begin(); i != sfManager()._playList.end(); ++i) {
|
|
|
|
if (*i == sound) {
|
|
|
|
result = true;
|
|
|
|
sfManager()._playList.erase(i);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
--sfManager()._suspendCtr;
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
void SoundManager::_sfDoUpdateVolume(Sound *sound) {
|
2011-05-27 21:19:06 +10:00
|
|
|
++_soundManager->_suspendCtr;
|
2011-05-07 14:13:52 +10:00
|
|
|
|
2011-05-24 20:07:41 +10:00
|
|
|
for (int voiceIndex = 0; voiceIndex < SOUND_ARR_SIZE; ++voiceIndex) {
|
|
|
|
VoiceStruct *vs = sfManager()._voiceStructPtrs[voiceIndex];
|
|
|
|
if (!vs)
|
2011-05-07 14:13:52 +10:00
|
|
|
continue;
|
2011-05-24 20:07:41 +10:00
|
|
|
|
|
|
|
for (uint idx = 0; idx < vs->_entries.size(); ++idx) {
|
|
|
|
VoiceStructEntry &vse = vs->_entries[idx];
|
|
|
|
SoundDriver *driver = vse._driver;
|
|
|
|
|
|
|
|
if (vs->_voiceType == VOICETYPE_0) {
|
|
|
|
if (!vse._field4 && !vse._field6) {
|
|
|
|
int vol = sound->_volume * sound->_field48[vse._field8] / 127;
|
|
|
|
driver->setVolume0(voiceIndex, vse._field0, 7, vol);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (!vse._field8 && !vse._fieldA) {
|
|
|
|
int vol = sound->_volume * sound->_field48[vse._fieldC] / 127;
|
|
|
|
driver->setVolume1(voiceIndex, vse._field0, 7, vol);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2011-05-07 14:13:52 +10:00
|
|
|
}
|
|
|
|
|
2011-05-27 21:19:06 +10:00
|
|
|
--_soundManager->_suspendCtr;
|
2011-05-07 14:13:52 +10:00
|
|
|
}
|
|
|
|
|
2011-05-01 15:23:30 +10:00
|
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
Sound::Sound() {
|
2011-05-18 20:32:40 +10:00
|
|
|
_stopFlag = false;
|
2011-05-01 15:23:30 +10:00
|
|
|
_soundNum = 0;
|
|
|
|
_groupNum = 0;
|
|
|
|
_soundPriority = 0;
|
|
|
|
_priority2 = -1;
|
|
|
|
_loop = true;
|
|
|
|
_loopFlag2 = true;
|
|
|
|
_priority = 0;
|
|
|
|
_volume = 127;
|
|
|
|
_loopFlag = false;
|
|
|
|
_pauseCtr = 0;
|
|
|
|
_muteCtr = 0;
|
2011-05-18 20:32:40 +10:00
|
|
|
_holdAt = 0xff;
|
2011-05-01 15:23:30 +10:00
|
|
|
_cueValue = -1;
|
|
|
|
_volume1 = -1;
|
2011-05-12 23:09:48 +10:00
|
|
|
_volume3 = 0;
|
2011-05-01 15:23:30 +10:00
|
|
|
_volume2 = 0;
|
2011-05-12 23:09:48 +10:00
|
|
|
_volume5 = 0;
|
|
|
|
_volume4 = 0;
|
2011-05-01 15:23:30 +10:00
|
|
|
_timeIndex = 0;
|
|
|
|
_field26 = 0;
|
2011-05-28 09:07:30 +10:00
|
|
|
_trackInfo._maxTrack = 0;
|
2011-05-01 15:23:30 +10:00
|
|
|
_primed = false;
|
2011-05-26 20:30:30 +10:00
|
|
|
_isEmpty = false;
|
2011-05-01 15:23:30 +10:00
|
|
|
_field26E = NULL;
|
|
|
|
}
|
|
|
|
|
2011-05-27 20:55:09 +10:00
|
|
|
Sound::~Sound() {
|
|
|
|
stop();
|
|
|
|
}
|
|
|
|
|
2011-05-01 15:23:30 +10:00
|
|
|
void Sound::play(int soundNum) {
|
|
|
|
prime(soundNum);
|
2011-05-27 21:19:06 +10:00
|
|
|
_soundManager->addToPlayList(this);
|
2011-05-01 15:23:30 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
void Sound::stop() {
|
2011-05-27 21:19:06 +10:00
|
|
|
_soundManager->removeFromPlayList(this);
|
2011-05-01 15:23:30 +10:00
|
|
|
_unPrime();
|
|
|
|
}
|
|
|
|
|
2011-04-27 22:22:20 +10:00
|
|
|
void Sound::prime(int soundNum) {
|
2011-05-01 15:23:30 +10:00
|
|
|
if (_soundNum != -1) {
|
|
|
|
stop();
|
|
|
|
_prime(soundNum, false);
|
|
|
|
}
|
|
|
|
}
|
2011-04-27 21:23:47 +10:00
|
|
|
|
2011-05-01 15:23:30 +10:00
|
|
|
void Sound::unPrime() {
|
|
|
|
stop();
|
2011-04-27 21:23:47 +10:00
|
|
|
}
|
|
|
|
|
2011-05-01 15:23:30 +10:00
|
|
|
void Sound::_prime(int soundNum, bool queFlag) {
|
|
|
|
if (_primed)
|
|
|
|
unPrime();
|
|
|
|
|
|
|
|
if (_soundNum != -1) {
|
|
|
|
// Sound number specified
|
2011-05-26 20:30:30 +10:00
|
|
|
_isEmpty = false;
|
2011-05-01 15:23:30 +10:00
|
|
|
_field26E = NULL;
|
|
|
|
byte *soundData = _resourceManager->getResource(RES_SOUND, soundNum, 0);
|
2011-05-27 21:19:06 +10:00
|
|
|
_soundManager->checkResVersion(soundData);
|
|
|
|
_groupNum = _soundManager->determineGroup(soundData);
|
|
|
|
_soundPriority = _soundManager->extractPriority(soundData);
|
|
|
|
_loop = _soundManager->extractLoop(soundData);
|
|
|
|
_soundManager->extractTrackInfo(&_trackInfo, soundData, _groupNum);
|
2011-05-01 15:23:30 +10:00
|
|
|
|
2011-05-28 09:07:30 +10:00
|
|
|
for (int idx = 0; idx <= _trackInfo._maxTrack; ++idx) {
|
2011-05-26 20:30:30 +10:00
|
|
|
_trackInfo._handleList[idx] = _resourceManager->getResource(RES_SOUND, soundNum, _trackInfo._rlbList[idx]);
|
2011-05-01 15:23:30 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
DEALLOCATE(soundData);
|
|
|
|
} else {
|
|
|
|
// No sound specified
|
2011-05-26 20:30:30 +10:00
|
|
|
_isEmpty = true;
|
2011-05-01 15:23:30 +10:00
|
|
|
_groupNum = 0;
|
|
|
|
_soundPriority = 0;
|
|
|
|
_loop = 0;
|
2011-05-28 09:07:30 +10:00
|
|
|
_trackInfo._maxTrack = 0;
|
2011-05-26 20:30:30 +10:00
|
|
|
_trackInfo._handleList[0] = ALLOCATE(200);
|
2011-05-01 15:23:30 +10:00
|
|
|
_field26E = ALLOCATE(200);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (queFlag)
|
2011-05-27 21:19:06 +10:00
|
|
|
_soundManager->addToSoundList(this);
|
2011-04-27 22:22:20 +10:00
|
|
|
|
2011-05-01 15:23:30 +10:00
|
|
|
_primed = true;
|
2011-04-27 22:22:20 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
void Sound::_unPrime() {
|
2011-05-01 15:23:30 +10:00
|
|
|
if (_primed) {
|
2011-05-26 20:30:30 +10:00
|
|
|
if (_isEmpty) {
|
|
|
|
DEALLOCATE(_trackInfo._handleList[0]);
|
2011-05-01 15:23:30 +10:00
|
|
|
DEALLOCATE(_field26E);
|
|
|
|
_field26E = NULL;
|
|
|
|
} else {
|
2011-05-28 09:07:30 +10:00
|
|
|
for (int idx = 0; idx <= _trackInfo._maxTrack; ++idx) {
|
2011-05-26 20:30:30 +10:00
|
|
|
DEALLOCATE(_trackInfo._handleList[idx]);
|
2011-05-01 15:23:30 +10:00
|
|
|
}
|
|
|
|
}
|
2011-04-27 21:23:47 +10:00
|
|
|
|
2011-05-28 09:07:30 +10:00
|
|
|
_trackInfo._maxTrack = 0;
|
2011-05-27 21:19:06 +10:00
|
|
|
_soundManager->removeFromSoundList(this);
|
2011-05-01 15:23:30 +10:00
|
|
|
|
|
|
|
_primed = false;
|
2011-05-18 20:32:40 +10:00
|
|
|
_stopFlag = false;
|
2011-05-01 15:23:30 +10:00
|
|
|
}
|
2011-04-27 21:23:47 +10:00
|
|
|
}
|
|
|
|
|
2011-05-01 15:23:30 +10:00
|
|
|
void Sound::orientAfterDriverChange() {
|
2011-05-26 20:30:30 +10:00
|
|
|
if (!_isEmpty) {
|
2011-05-01 15:23:30 +10:00
|
|
|
int timeIndex = getTimeIndex();
|
|
|
|
|
2011-05-28 09:07:30 +10:00
|
|
|
for (int idx = 0; idx <= _trackInfo._maxTrack; ++idx)
|
2011-05-26 20:30:30 +10:00
|
|
|
DEALLOCATE(_trackInfo._handleList[idx]);
|
2011-05-01 15:23:30 +10:00
|
|
|
|
2011-05-28 09:07:30 +10:00
|
|
|
_trackInfo._maxTrack = 0;
|
2011-05-01 15:23:30 +10:00
|
|
|
_primed = false;
|
|
|
|
_prime(_soundNum, true);
|
|
|
|
setTimeIndex(timeIndex);
|
|
|
|
}
|
|
|
|
}
|
2011-04-27 21:23:47 +10:00
|
|
|
|
2011-05-01 15:23:30 +10:00
|
|
|
void Sound::orientAfterRestore() {
|
2011-05-26 20:30:30 +10:00
|
|
|
if (_isEmpty) {
|
2011-05-01 15:23:30 +10:00
|
|
|
int timeIndex = getTimeIndex();
|
|
|
|
_primed = false;
|
|
|
|
_prime(_soundNum, true);
|
|
|
|
setTimeIndex(timeIndex);
|
|
|
|
}
|
2011-04-27 21:23:47 +10:00
|
|
|
}
|
|
|
|
|
2011-04-27 22:22:20 +10:00
|
|
|
void Sound::go() {
|
2011-05-01 15:23:30 +10:00
|
|
|
if (!_primed)
|
|
|
|
error("Attempt to execute Sound::go() on an unprimed Sound");
|
2011-04-27 22:22:20 +10:00
|
|
|
|
2011-05-27 21:19:06 +10:00
|
|
|
_soundManager->addToPlayList(this);
|
2011-04-27 21:23:47 +10:00
|
|
|
}
|
|
|
|
|
2011-04-27 22:22:20 +10:00
|
|
|
void Sound::halt(void) {
|
2011-05-27 21:19:06 +10:00
|
|
|
_soundManager->removeFromPlayList(this);
|
2011-04-27 22:22:20 +10:00
|
|
|
}
|
2011-04-27 21:23:47 +10:00
|
|
|
|
2011-04-27 22:22:20 +10:00
|
|
|
int Sound::getSoundNum() const {
|
2011-05-01 15:23:30 +10:00
|
|
|
return _soundNum;
|
2011-04-27 21:23:47 +10:00
|
|
|
}
|
|
|
|
|
2011-05-01 15:23:30 +10:00
|
|
|
bool Sound::isPlaying() {
|
2011-05-27 21:19:06 +10:00
|
|
|
return _soundManager->isOnPlayList(this);
|
2011-04-27 22:22:20 +10:00
|
|
|
}
|
2011-04-27 21:23:47 +10:00
|
|
|
|
2011-04-27 22:22:20 +10:00
|
|
|
bool Sound::isPrimed() const {
|
2011-05-01 15:23:30 +10:00
|
|
|
return _primed;
|
2011-04-27 21:23:47 +10:00
|
|
|
}
|
|
|
|
|
2011-04-27 22:22:20 +10:00
|
|
|
bool Sound::isPaused() const {
|
2011-05-01 15:23:30 +10:00
|
|
|
return _pauseCtr != 0;
|
2011-04-27 22:22:20 +10:00
|
|
|
}
|
2011-04-27 21:23:47 +10:00
|
|
|
|
2011-04-27 22:22:20 +10:00
|
|
|
bool Sound::isMuted() const {
|
2011-05-01 15:23:30 +10:00
|
|
|
return _muteCtr != 0;
|
2011-04-27 21:23:47 +10:00
|
|
|
}
|
|
|
|
|
2011-05-01 15:23:30 +10:00
|
|
|
void Sound::pause(bool flag) {
|
2011-05-27 21:19:06 +10:00
|
|
|
_soundManager->suspendSoundServer();
|
2011-04-27 21:23:47 +10:00
|
|
|
|
2011-05-01 15:23:30 +10:00
|
|
|
if (flag)
|
|
|
|
++_pauseCtr;
|
|
|
|
else if (_pauseCtr > 0)
|
|
|
|
--_pauseCtr;
|
2011-04-27 21:23:47 +10:00
|
|
|
|
2011-05-27 21:19:06 +10:00
|
|
|
_soundManager->rethinkVoiceTypes();
|
|
|
|
_soundManager->restartSoundServer();
|
2011-04-27 21:23:47 +10:00
|
|
|
}
|
|
|
|
|
2011-05-01 15:23:30 +10:00
|
|
|
void Sound::mute(bool flag) {
|
2011-05-27 21:19:06 +10:00
|
|
|
_soundManager->suspendSoundServer();
|
2011-05-01 15:23:30 +10:00
|
|
|
|
|
|
|
if (flag)
|
|
|
|
++_muteCtr;
|
|
|
|
else if (_muteCtr > 0)
|
|
|
|
--_muteCtr;
|
2011-04-27 21:23:47 +10:00
|
|
|
|
2011-05-27 21:19:06 +10:00
|
|
|
_soundManager->rethinkVoiceTypes();
|
|
|
|
_soundManager->restartSoundServer();
|
2011-04-27 21:23:47 +10:00
|
|
|
}
|
|
|
|
|
2011-05-12 23:09:48 +10:00
|
|
|
void Sound::fade(int volume1, int volume2, int volume3, int volume4) {
|
2011-05-27 21:19:06 +10:00
|
|
|
_soundManager->suspendSoundServer();
|
2011-04-27 22:22:20 +10:00
|
|
|
|
2011-05-01 15:23:30 +10:00
|
|
|
if (volume1 > 127)
|
|
|
|
volume1 = 127;
|
|
|
|
if (volume2 > 127)
|
|
|
|
volume2 = 127;
|
2011-05-12 23:09:48 +10:00
|
|
|
if (volume3 > 255)
|
|
|
|
volume3 = 255;
|
2011-04-27 21:23:47 +10:00
|
|
|
|
2011-05-01 15:23:30 +10:00
|
|
|
_volume1 = volume1;
|
|
|
|
_volume2 = volume2;
|
2011-05-12 23:09:48 +10:00
|
|
|
_volume3 = volume3;
|
|
|
|
_volume5 = 0;
|
|
|
|
_volume4 = volume4;
|
2011-04-27 21:23:47 +10:00
|
|
|
|
2011-05-27 21:19:06 +10:00
|
|
|
_soundManager->restartSoundServer();
|
2011-04-27 21:23:47 +10:00
|
|
|
}
|
|
|
|
|
2011-04-27 22:22:20 +10:00
|
|
|
void Sound::setTimeIndex(uint32 timeIndex) {
|
2011-05-01 15:23:30 +10:00
|
|
|
if (_primed) {
|
|
|
|
mute(true);
|
|
|
|
SoundManager::_soSetTimeIndex(timeIndex);
|
|
|
|
mute(false);
|
|
|
|
}
|
2011-04-27 21:23:47 +10:00
|
|
|
}
|
|
|
|
|
2011-04-27 22:22:20 +10:00
|
|
|
uint32 Sound::getTimeIndex() const {
|
2011-05-01 15:23:30 +10:00
|
|
|
return _timeIndex;
|
2011-04-27 22:22:20 +10:00
|
|
|
}
|
|
|
|
|
2011-05-01 15:23:30 +10:00
|
|
|
int Sound::getCueValue() const {
|
|
|
|
return _cueValue;
|
2011-04-27 21:23:47 +10:00
|
|
|
}
|
|
|
|
|
2011-05-01 15:23:30 +10:00
|
|
|
void Sound::setCueValue(int cueValue) {
|
|
|
|
_cueValue = cueValue;
|
2011-04-27 21:23:47 +10:00
|
|
|
}
|
|
|
|
|
2011-04-27 22:22:20 +10:00
|
|
|
void Sound::setVol(int volume) {
|
2011-05-01 15:23:30 +10:00
|
|
|
if (volume > 127)
|
|
|
|
volume = 127;
|
2011-04-27 21:23:47 +10:00
|
|
|
|
2011-05-01 15:23:30 +10:00
|
|
|
if (_volume != volume) {
|
|
|
|
_volume = volume;
|
|
|
|
if (isPlaying())
|
2011-05-27 21:19:06 +10:00
|
|
|
_soundManager->updateSoundVol(this);
|
2011-05-01 15:23:30 +10:00
|
|
|
}
|
2011-04-27 21:23:47 +10:00
|
|
|
}
|
|
|
|
|
2011-04-27 22:22:20 +10:00
|
|
|
int Sound::getVol() const {
|
2011-05-01 15:23:30 +10:00
|
|
|
return _volume;
|
2011-04-27 21:23:47 +10:00
|
|
|
}
|
|
|
|
|
2011-05-01 15:23:30 +10:00
|
|
|
void Sound::setPri(int priority) {
|
|
|
|
if (priority > 127)
|
|
|
|
priority = 127;
|
|
|
|
_priority2 = priority;
|
2011-05-27 21:19:06 +10:00
|
|
|
_soundManager->updateSoundPri(this);
|
2011-04-27 22:22:20 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
void Sound::setLoop(bool flag) {
|
2011-05-01 15:23:30 +10:00
|
|
|
_loopFlag2 = flag;
|
2011-05-27 21:19:06 +10:00
|
|
|
_soundManager->updateSoundLoop(this);
|
2011-04-27 21:23:47 +10:00
|
|
|
}
|
|
|
|
|
2011-04-27 22:22:20 +10:00
|
|
|
int Sound::getPri() const {
|
2011-05-01 15:23:30 +10:00
|
|
|
return _priority;
|
2011-04-27 22:22:20 +10:00
|
|
|
}
|
2011-04-27 21:23:47 +10:00
|
|
|
|
2011-04-27 22:22:20 +10:00
|
|
|
bool Sound::getLoop() {
|
2011-05-01 15:23:30 +10:00
|
|
|
return _loopFlag;
|
2011-04-27 21:23:47 +10:00
|
|
|
}
|
|
|
|
|
2011-05-01 15:23:30 +10:00
|
|
|
void Sound::holdAt(int amount) {
|
|
|
|
if (amount > 127)
|
|
|
|
amount = 127;
|
|
|
|
_holdAt = amount;
|
2011-04-27 22:22:20 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
void Sound::release() {
|
2011-05-01 15:23:30 +10:00
|
|
|
_holdAt = -1;
|
2011-04-27 22:22:20 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
ASound::ASound(): EventHandler() {
|
|
|
|
_action = NULL;
|
2011-05-18 20:32:40 +10:00
|
|
|
_cueValue = -1;
|
2011-04-27 22:22:20 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
void ASound::synchronize(Serializer &s) {
|
|
|
|
EventHandler::synchronize(s);
|
2011-05-24 21:37:27 +10:00
|
|
|
|
2011-04-27 22:22:20 +10:00
|
|
|
SYNC_POINTER(_action);
|
2011-05-18 20:32:40 +10:00
|
|
|
s.syncAsByte(_cueValue);
|
2011-04-27 22:22:20 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
void ASound::dispatch() {
|
|
|
|
EventHandler::dispatch();
|
|
|
|
|
2011-05-18 20:32:40 +10:00
|
|
|
int cueValue = _sound.getCueValue();
|
|
|
|
if (cueValue != -1) {
|
|
|
|
_cueValue = cueValue;
|
|
|
|
_sound.setCueValue(-1);
|
2011-04-27 22:22:20 +10:00
|
|
|
|
|
|
|
if (_action)
|
|
|
|
_action->signal();
|
|
|
|
}
|
|
|
|
|
2011-05-18 20:32:40 +10:00
|
|
|
if (_cueValue != -1) {
|
2011-04-27 22:22:20 +10:00
|
|
|
if (!_sound.isPrimed()) {
|
2011-05-18 20:32:40 +10:00
|
|
|
_cueValue = -1;
|
2011-04-27 22:22:20 +10:00
|
|
|
if (_action) {
|
|
|
|
_action->signal();
|
|
|
|
_action = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASound::play(int soundNum, Action *action, int volume) {
|
|
|
|
_action = action;
|
2011-05-18 20:32:40 +10:00
|
|
|
_cueValue = 0;
|
2011-04-27 22:22:20 +10:00
|
|
|
|
|
|
|
setVol(volume);
|
|
|
|
_sound.play(soundNum);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASound::stop() {
|
|
|
|
_sound.stop();
|
|
|
|
_action = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASound::prime(int soundNum, Action *action) {
|
|
|
|
_action = action;
|
2011-05-18 20:32:40 +10:00
|
|
|
_cueValue = 0;
|
2011-04-27 22:22:20 +10:00
|
|
|
_sound.prime(soundNum);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASound::unPrime() {
|
|
|
|
_sound.unPrime();
|
|
|
|
_action = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASound::fade(int v1, int v2, int v3, int v4, Action *action) {
|
|
|
|
if (action)
|
|
|
|
_action = action;
|
|
|
|
|
|
|
|
_sound.fade(v1, v2, v3, v4);
|
|
|
|
}
|
2011-04-27 21:23:47 +10:00
|
|
|
|
2011-05-12 23:09:48 +10:00
|
|
|
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
SoundDriver::SoundDriver() {
|
|
|
|
_driverNum = 0;
|
|
|
|
_minVersion = _maxVersion = 0;
|
|
|
|
_groupMask = 0;
|
|
|
|
}
|
|
|
|
|
2011-05-18 20:32:40 +10:00
|
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
const byte adlib_group_data[] = { 1, 1, 9, 1, 0xff };
|
|
|
|
|
|
|
|
AdlibSoundDriver::AdlibSoundDriver() {
|
2011-05-24 20:07:41 +10:00
|
|
|
_minVersion = 0x102;
|
2011-05-27 20:55:09 +10:00
|
|
|
_maxVersion = 0x10A;
|
2011-05-24 20:07:41 +10:00
|
|
|
|
|
|
|
|
2011-05-18 20:32:40 +10:00
|
|
|
_groupData.groupMask = 1;
|
|
|
|
_groupData.v1 = 0x46;
|
|
|
|
_groupData.v2 = 0;
|
|
|
|
_groupData.pData = &adlib_group_data[0];
|
|
|
|
}
|
|
|
|
|
2011-02-14 20:37:27 +11:00
|
|
|
} // End of namespace tSage
|