diff --git a/engines/tsage/core.cpp b/engines/tsage/core.cpp index 873bbc56a56..41ee0214325 100644 --- a/engines/tsage/core.cpp +++ b/engines/tsage/core.cpp @@ -3425,8 +3425,9 @@ void SceneHandler::postInit(SceneObjectList *OwnerList) { _globals->_scenePalette.loadPalette(0); _globals->_scenePalette.refresh(); - // TODO: Bunch of other scene related setup goes here _globals->_soundManager.postInit(); + _globals->_soundManager.buildDriverList(true); + _globals->_soundManager.installConfigDrivers(); _globals->_game->start(); } diff --git a/engines/tsage/sound.cpp b/engines/tsage/sound.cpp index 73ce7a1f531..e08885a51aa 100644 --- a/engines/tsage/sound.cpp +++ b/engines/tsage/sound.cpp @@ -45,15 +45,18 @@ SoundManager::SoundManager() { _suspendCtr = 0; _disableCtr = 0; _field153 = 0; - _field16D = 0; + _driversDetected = false; } SoundManager::~SoundManager() { if (__sndmgrReady) { for (Common::List::iterator i = _soundList.begin(); i != _soundList.end(); ++i) (*i)->stop(); - for (Common::List::iterator i = _installedDrivers.begin(); i != _installedDrivers.end(); ++i) - unInstallDriver(*i); + for (Common::List::iterator i = _installedDrivers.begin(); i != _installedDrivers.end(); ) { + int driverNum = (*i)->_driverNum; + ++i; + unInstallDriver(driverNum); + } _sfTerminate(); } } @@ -67,70 +70,154 @@ void SoundManager::postInit() { } } -void SoundManager::saveNotifier(bool postFlag) { - _globals->_soundManager.saveNotifierProc(postFlag); +Common::List &SoundManager::buildDriverList(bool detectFlag) { + assert(__sndmgrReady); + _availableDrivers.clear(); + + // 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); + + _driversDetected = true; + return _availableDrivers; } -void SoundManager::saveNotifierProc(bool postFlag) { - warning("TODO: SoundManager::saveNotifierProc"); -} - -void SoundManager::loadNotifier(bool postFlag) { - _globals->_soundManager.loadNotifierProc(postFlag); -} - -void SoundManager::loadNotifierProc(bool postFlag) { - warning("TODO: SoundManager::loadNotifierProc"); -} - -void SoundManager::listenerSynchronize(Serializer &s) { - s.validate("SoundManager"); - warning("TODO: SoundManager listenerSynchronize"); -} - -void SoundManager::checkResVersion(const byte *soundData) { - int maxVersion = READ_LE_UINT16(soundData + 4); - int minVersion = READ_LE_UINT16(soundData + 6); - - if (_globals->_soundManager._minVersion < minVersion) - error("Attempt to play/prime sound resource that is too new"); - if (_globals->_soundManager._minVersion > maxVersion) - error("Attempt to play/prime sound resource that is too old"); -} - -/*--------------------------------------------------------------------------*/ - -void SoundManager::suspendSoundServer() { - ++_globals->_soundManager._suspendCtr; -} - - -void SoundManager::restartSoundServer() { - if (_globals->_soundManager._suspendCtr > 0) - --_globals->_soundManager._suspendCtr; -} - -void SoundManager::unInstallDriver(SoundDriver *driver) { +void SoundManager::installConfigDrivers() { } -Common::List &SoundManager::buildDriverList(bool flag) { - assert(__sndmgrReady); - _driverList.clear(); - - warning("TODO: SoundManager::buildDriverList"); - return _driverList; -} - -Common::List &SoundManager::getDriverList(bool flag) { - if (flag) - return _driverList; +Common::List &SoundManager::getDriverList(bool detectFlag) { + if (detectFlag) + return _availableDrivers; else return buildDriverList(false); } void SoundManager::dumpDriverList() { - _driverList.clear(); + _availableDrivers.clear(); +} + +void SoundManager::disableSoundServer() { + ++_disableCtr; +} + +void SoundManager::enableSoundServer() { + if (_disableCtr > 0) + --_disableCtr; +} + +void SoundManager::suspendSoundServer() { + ++_suspendCtr; +} + +void SoundManager::restartSoundServer() { + if (_suspendCtr > 0) + --_suspendCtr; +} + +/** + * 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::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 + _sfInstallPatchBank(bankData); + DEALLOCATE(bankData); + } else { + // Could not locate patch bank data, so unload the driver + _sfUnInstallDriver(driver); + + // Unmute currently active sounds + for (Common::List::iterator i = _playList.begin(); i != _playList.end(); ++i) + (*i)->mute(false); + + enableSoundServer(); + } + break; + } + } +} + +/** + * Instantiate a driver class for the specified driver number + */ +SoundDriver *SoundManager::instantiateDriver(int driverNum) { + assert(driverNum == ADLIB_DRIVER_NUM); + return new AdlibSoundDriver(); +} + +/** + * Uninstall the specified driver + */ +void SoundManager::unInstallDriver(int driverNum) { + Common::List::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::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::iterator i = _soundList.begin(); i != _soundList.end(); ++i) + (*i)->orientAfterDriverChange(); + + // Unmute currently active sounds + for (Common::List::iterator i = _playList.begin(); i != _playList.end(); ++i) + (*i)->mute(false); + + enableSoundServer(); + } + } +} + +/** + * Returns true if a specified driver number is currently installed + */ +bool SoundManager::isInstalled(int driverNum) const { + Common::List::const_iterator i; + for (i = _installedDrivers.begin(); i != _installedDrivers.end(); ++i) { + if ((*i)->_driverNum == driverNum) + return true; + } + + return false; } void SoundManager::setMasterVol(int volume) { @@ -153,6 +240,16 @@ int SoundManager::determineGroup(const byte *soundData) { return _sfDetermineGroup(soundData); } +void SoundManager::checkResVersion(const byte *soundData) { + int maxVersion = READ_LE_UINT16(soundData + 4); + int minVersion = READ_LE_UINT16(soundData + 6); + + if (_globals->_soundManager._minVersion < minVersion) + error("Attempt to play/prime sound resource that is too new"); + if (_globals->_soundManager._minVersion > maxVersion) + error("Attempt to play/prime sound resource that is too old"); +} + int SoundManager::extractPriority(const byte *soundData) { return READ_LE_UINT16(soundData + 12); } @@ -204,6 +301,29 @@ void SoundManager::rethinkVoiceTypes() { /*--------------------------------------------------------------------------*/ +void SoundManager::saveNotifier(bool postFlag) { + _globals->_soundManager.saveNotifierProc(postFlag); +} + +void SoundManager::saveNotifierProc(bool postFlag) { + warning("TODO: SoundManager::saveNotifierProc"); +} + +void SoundManager::loadNotifier(bool postFlag) { + _globals->_soundManager.loadNotifierProc(postFlag); +} + +void SoundManager::loadNotifierProc(bool postFlag) { + warning("TODO: SoundManager::loadNotifierProc"); +} + +void SoundManager::listenerSynchronize(Serializer &s) { + s.validate("SoundManager"); + warning("TODO: SoundManager listenerSynchronise"); +} + +/*--------------------------------------------------------------------------*/ + void SoundManager::_soSetTimeIndex(int timeIndex) { warning("TODO: _soSetTimeIndex"); } @@ -315,6 +435,18 @@ void SoundManager::_sfExtractGroupMask() { _globals->_soundManager._groupMask = mask; } +bool SoundManager::_sfInstallDriver(SoundDriver *driver) { + return false; +} + +void SoundManager::_sfUnInstallDriver(SoundDriver *driver) { + +} + +void SoundManager::_sfInstallPatchBank(const byte *bankData) { + +} + /*--------------------------------------------------------------------------*/ Sound::Sound() { diff --git a/engines/tsage/sound.h b/engines/tsage/sound.h index 2cc5dec61e7..f52edc121bf 100644 --- a/engines/tsage/sound.h +++ b/engines/tsage/sound.h @@ -33,6 +33,8 @@ namespace tSage { class Sound; #define SOUND_ARR_SIZE 16 +#define ROLAND_DRIVER_NUM 2 +#define ADLIB_DRIVER_NUM 3 struct trackInfoStruct { int count; @@ -40,14 +42,22 @@ struct trackInfoStruct { int arr2[SOUND_ARR_SIZE]; }; +enum SoundDriverStatus {SNDSTATUS_FAILED = 0, SNDSTATUS_DETECTED = 1, SNDSTATUS_SKIPPED = 2}; + class SoundDriverEntry { public: - + int driverNum; + SoundDriverStatus status; + int field2, field6; + Common::String shortDescription; + Common::String longDescription; }; class SoundDriver { -private: +public: Common::String _shortDescription, _longDescription; + int _driverNum; + int _minVersion, _maxVersion; public: const Common::String &getShortDriverDescription() { return _shortDescription; } const Common::String &getLongDriverDescription() { return _longDescription; } @@ -57,7 +67,7 @@ public: class SoundManager : public SaveListener { private: - void unInstallDriver(SoundDriver *driver); + SoundDriver *instantiateDriver(int driverNum); public: bool __sndmgrReady; int _minVersion, _maxVersion; @@ -68,15 +78,13 @@ public: int _disableCtr; int _suspendCtr; int _field153; + bool _driversDetected; Common::List _soundList; - Common::List _driverList; - + Common::List _availableDrivers; Common::List _installedDrivers; int _field89[SOUND_ARR_SIZE]; uint16 _groupList[SOUND_ARR_SIZE]; int _fieldE9[SOUND_ARR_SIZE]; - - int _field16D; public: SoundManager(); ~SoundManager(); @@ -90,9 +98,17 @@ public: static void loadNotifier(bool postFlag); void loadNotifierProc(bool postFlag); - Common::List &buildDriverList(bool flag); - Common::List &getDriverList(bool flag); + void installConfigDrivers(); + Common::List &buildDriverList(bool detectFlag); + Common::List &getDriverList(bool detectFlag); void dumpDriverList(); + void installDriver(int driverNum); + bool isInstalled(int driverNum) const; + void unInstallDriver(int driverNum); + void disableSoundServer(); + void enableSoundServer(); + void suspendSoundServer(); + void restartSoundServer(); void checkResVersion(const byte *soundData); int determineGroup(const byte *soundData); int extractPriority(const byte *soundData); @@ -103,9 +119,7 @@ public: void removeFromSoundList(Sound *sound); void addToPlayList(Sound *sound); void removeFromPlayList(Sound *sound); - void suspendSoundServer(); void rethinkVoiceTypes(); - void restartSoundServer(); void updateSoundVol(Sound *sound); void updateSoundPri(Sound *sound); void updateSoundLoop(Sound *sound); @@ -130,13 +144,15 @@ public: static void _sfSetMasterVol(int volume); static void _sfExtractTrackInfo(trackInfoStruct *trackInfo, const byte *soundData, int groupNum); static void _sfExtractGroupMask(); + static bool _sfInstallDriver(SoundDriver *driver); + static void _sfUnInstallDriver(SoundDriver *driver); + static void _sfInstallPatchBank(const byte *bankData); }; class Sound: public EventHandler { private: void _prime(int soundNum, bool queFlag); void _unPrime(); - void orientAfterDriverChange(); void orientAfterRestore(); public: int _field6; @@ -207,6 +223,8 @@ public: bool getLoop(); void holdAt(int amount); void release(); + + void orientAfterDriverChange(); }; class ASound: public EventHandler { @@ -246,6 +264,11 @@ public: void release() { _sound.release(); } }; +class AdlibSoundDriver: public SoundDriver { +public: + void setVolume(int volume) {} +}; + } // End of namespace tSage #endif