From 57612224ca76c34832599a13938b99fd68bff7bf Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 1 May 2011 15:23:30 +1000 Subject: [PATCH] TSAGE: Implemented the methods of the Sound class --- engines/tsage/sound.cpp | 368 +++++++++++++++++++++++++++++++++++----- engines/tsage/sound.h | 106 +++++++++--- 2 files changed, 403 insertions(+), 71 deletions(-) diff --git a/engines/tsage/sound.cpp b/engines/tsage/sound.cpp index 793409d1235..0db43506eaa 100644 --- a/engines/tsage/sound.cpp +++ b/engines/tsage/sound.cpp @@ -29,6 +29,7 @@ #include "tsage/globals.h" #include "tsage/debugger.h" #include "tsage/graphics.h" +#include "tsage/tsage.h" namespace tSage { @@ -61,127 +62,406 @@ void SoundManager::listenerSynchronise(Serialiser &s) { /*--------------------------------------------------------------------------*/ -void Sound::play(int soundNum, int volume) { +void SoundManager::checkResVersion(const byte *soundData) { + int minVersion = READ_LE_UINT16(soundData + 4); + int maxVersion = READ_LE_UINT16(soundData + 6); + if (_globals->_soundManager._minVersion >= maxVersion) + error("Attempt to play/prime sound resource that is too new"); + if (_globals->_soundManager._minVersion > minVersion) + error("Attempt to play/prime sound resource that is too old"); +} + +int SoundManager::determineGroup(const byte *soundData) { + return _sfDetermineGroup(soundData); +} + +int SoundManager::extractPriority(const byte *soundData) { + return READ_LE_UINT16(soundData + 12); +} + +int SoundManager::extractLoop(const byte *soundData) { + return READ_LE_UINT16(soundData + 14); +} + +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::extractTrackInfo(trackInfoStruct *data, const byte *soundData, int groupNum) { + +} + +void SoundManager::suspendSoundServer() { + ++_globals->_soundManager._suspendCtr; +} + +void SoundManager::rethinkVoiceTypes() { + _sfRethinkVoiceTypes(); +} + +void SoundManager::restartSoundServer() { + if (_globals->_soundManager._suspendCtr > 0) + --_globals->_soundManager._suspendCtr; +} + +void SoundManager::updateSoundVol(Sound *sound) { + _sfUpdateVolume(sound); +} + +void SoundManager::updateSoundPri(Sound *sound) { + _sfUpdatePriority(sound); +} + +void SoundManager::updateSoundLoop(Sound *sound) { + _sfUpdateLoop(sound); +} + +/*--------------------------------------------------------------------------*/ + +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) { + if ((v & _globals->_soundManager._groupMask) == v) + return v; + + p = soundData + 6 + (READ_LE_UINT16(p + 4) * 4); + } + + return 0; +} + +void SoundManager::_sfAddToPlayList(Sound*soundData) { + +} + +void SoundManager::_sfRemoveFromPlayList(Sound *sound) { + +} + +bool SoundManager::_sfIsOnPlayList(Sound *sound) { + ++_globals->_soundManager._suspendCtr; + bool result = contains(_globals->_soundManager._playList, sound); + --_globals->_soundManager._suspendCtr; + + return result; +} + +void SoundManager::_sfRethinkVoiceTypes() { + +} + +void SoundManager::_sfUpdateVolume(Sound *sound) { + _sfDereferenceAll(); + sub_233EE(sound); +} + +void SoundManager::_sfDereferenceAll() { + +} + +void SoundManager::sub_233EE(Sound *sound) { + +} + +void SoundManager::_sfUpdatePriority(Sound *sound) { + +} + +void SoundManager::_sfUpdateLoop(Sound *sound) { + +} + +/*--------------------------------------------------------------------------*/ + +Sound::Sound() { + _field6 = 0; + _soundNum = 0; + _groupNum = 0; + _soundPriority = 0; + _priority2 = -1; + _loop = true; + _loopFlag2 = true; + _priority = 0; + _volume = 127; + _loopFlag = false; + _pauseCtr = 0; + _muteCtr = 0; + _holdAt = false; + _cueValue = -1; + _volume1 = -1; + _field1F = 0; + _volume2 = 0; + _field21 = 0; + _field22 = 0; + _timeIndex = 0; + _field26 = 0; + _trackInfo.count = 0; + _primed = false; + _field26C = 0; + _field26E = NULL; +} + +void Sound::play(int soundNum) { + prime(soundNum); + _globals->_soundManager.addToPlayList(this); } void Sound::stop() { - + _globals->_soundManager.removeFromPlayList(this); + _unPrime(); } void Sound::prime(int soundNum) { - -} - -void Sound::prime(int soundNum, int v2) { - -} - -void Sound::_unPrime() { - + if (_soundNum != -1) { + stop(); + _prime(soundNum, false); + } } void Sound::unPrime() { + stop(); +} +void Sound::_prime(int soundNum, bool queFlag) { + if (_primed) + unPrime(); + + if (_soundNum != -1) { + // Sound number specified + _field26E = NULL; + byte *soundData = _resourceManager->getResource(RES_SOUND, soundNum, 0); + _globals->_soundManager.checkResVersion(soundData); + _groupNum = _globals->_soundManager.determineGroup(soundData); + _soundPriority = _globals->_soundManager.extractPriority(soundData); + _loop = _globals->_soundManager.extractLoop(soundData); + _globals->_soundManager.extractTrackInfo(&_trackInfo, soundData, _groupNum); + + for (int idx = 0; idx < _trackInfo.count; ++idx) { + _trackInfo.handleList[idx] = _resourceManager->getResource(RES_SOUND, soundNum, _trackInfo.rlbList[idx]); + } + + DEALLOCATE(soundData); + } else { + // No sound specified + _groupNum = 0; + _soundPriority = 0; + _loop = 0; + _trackInfo.count = 0; + _trackInfo.handleList[0] = ALLOCATE(200); + _field26E = ALLOCATE(200); + } + + if (queFlag) + _globals->_soundManager.addToSoundList(this); + + _primed = true; +} + +void Sound::_unPrime() { + if (_primed) { + if (_field26C) { + DEALLOCATE(_trackInfo.handleList[0]); + DEALLOCATE(_field26E); + _field26E = NULL; + } else { + for (int idx = 0; idx < _trackInfo.count; ++idx) { + DEALLOCATE(_trackInfo.handleList[idx]); + } + } + + _trackInfo.count = 0; + _globals->_soundManager.removeFromSoundList(this); + + _primed = false; + _field6 = 0; + } +} + +void Sound::orientAfterDriverChange() { + if (!_field26C) { + int timeIndex = getTimeIndex(); + + for (int idx = 0; idx < _trackInfo.count; ++idx) + DEALLOCATE(_trackInfo.handleList[idx]); + + _trackInfo.count = 0; + _primed = false; + _prime(_soundNum, true); + setTimeIndex(timeIndex); + } +} + +void Sound::orientAfterRestore() { + if (_field26C) { + int timeIndex = getTimeIndex(); + _primed = false; + _prime(_soundNum, true); + setTimeIndex(timeIndex); + } } void Sound::go() { + if (!_primed) + error("Attempt to execute Sound::go() on an unprimed Sound"); + _globals->_soundManager.addToPlayList(this); } void Sound::halt(void) { - + _globals->_soundManager.removeFromPlayList(this); } int Sound::getSoundNum() const { - return 0; + return _soundNum; } -bool Sound::isPlaying() const { - return false; +bool Sound::isPlaying() { + return _globals->_soundManager.isOnPlayList(this); } bool Sound::isPrimed() const { - return false; + return _primed; } bool Sound::isPaused() const { - return false; + return _pauseCtr != 0; } bool Sound::isMuted() const { - return false; + return _muteCtr != 0; } -void Sound::pause() { +void Sound::pause(bool flag) { + _globals->_soundManager.suspendSoundServer(); + if (flag) + ++_pauseCtr; + else if (_pauseCtr > 0) + --_pauseCtr; + + _globals->_soundManager.rethinkVoiceTypes(); + _globals->_soundManager.restartSoundServer(); } -void Sound::mute() { +void Sound::mute(bool flag) { + _globals->_soundManager.suspendSoundServer(); + if (flag) + ++_muteCtr; + else if (_muteCtr > 0) + --_muteCtr; + + _globals->_soundManager.rethinkVoiceTypes(); + _globals->_soundManager.restartSoundServer(); } -void Sound::fadeIn() { +void Sound::fade(int volume1, int volume2, int v3, int v4) { + _globals->_soundManager.suspendSoundServer(); -} + if (volume1 > 127) + volume1 = 127; + if (volume2 > 127) + volume2 = 127; + if (v3 > 255) + v3 = 255; -void Sound::fadeOut(EventHandler *evtHandler) { - -} - -void Sound::fade(int v1, int v2, int v3, int v4) { + _volume1 = volume1; + _volume2 = volume2; + _field1F = v3; + _field21 = 0; + _field22 = v4; + _globals->_soundManager.restartSoundServer(); } void Sound::setTimeIndex(uint32 timeIndex) { - + if (_primed) { + mute(true); + SoundManager::_soSetTimeIndex(timeIndex); + mute(false); + } } uint32 Sound::getTimeIndex() const { - return 0; + return _timeIndex; } -bool Sound::getCueValue() const { - return false; +int Sound::getCueValue() const { + return _cueValue; } -void Sound::setCueValue(bool flag) { - +void Sound::setCueValue(int cueValue) { + _cueValue = cueValue; } void Sound::setVol(int volume) { + if (volume > 127) + volume = 127; + if (_volume != volume) { + _volume = volume; + if (isPlaying()) + _globals->_soundManager.updateSoundVol(this); + } } int Sound::getVol() const { - return 0; + return _volume; } -void Sound::setPri(int v) { - +void Sound::setPri(int priority) { + if (priority > 127) + priority = 127; + _priority2 = priority; + _globals->_soundManager.updateSoundPri(this); } void Sound::setLoop(bool flag) { - + _loopFlag2 = flag; + _globals->_soundManager.updateSoundLoop(this); } int Sound::getPri() const { - return 0; + return _priority; } bool Sound::getLoop() { - return false; + return _loopFlag; } -void Sound::holdAt(int v) { - +void Sound::holdAt(int amount) { + if (amount > 127) + amount = 127; + _holdAt = amount; } void Sound::release() { - + _holdAt = -1; } - /*--------------------------------------------------------------------------*/ ASound::ASound(): EventHandler() { @@ -200,7 +480,7 @@ void ASound::dispatch() { if (!_sound.getCueValue()) { _cueFlag = false; - _sound.setCueValue(true); + _sound.setCueValue(1); if (_action) _action->signal(); diff --git a/engines/tsage/sound.h b/engines/tsage/sound.h index 7a21b9df3f6..20edd702923 100644 --- a/engines/tsage/sound.h +++ b/engines/tsage/sound.h @@ -27,12 +27,37 @@ #define TSAGE_SOUND_H #include "common/scummsys.h" +#include "common/list.h" #include "tsage/saveload.h" #include "tsage/core.h" namespace tSage { +class Sound; + +struct trackInfoStruct { + int count; + int rlbList[32]; + byte *handleList[75]; +}; + class SoundManager : public SaveListener { +public: + int _minVersion, _maxVersion; + Common::List _playList; + void *driverList2[16]; + int _field89[16]; + int _fieldA9[16]; + int _fieldE9[16]; + int _field109[16]; + uint32 _groupMask; + int volume; + int _disableCtr; + int _suspendCtr; + int _field153; + Common::List _soundList; + Common::List _driverList; + int _field16D; public: void dispatch() {} virtual void listenerSynchronise(Serialiser &s); @@ -43,27 +68,54 @@ public: void saveNotifierProc(bool postFlag); static void loadNotifier(bool postFlag); void loadNotifierProc(bool postFlag); + + void checkResVersion(const byte *soundData); + int determineGroup(const byte *soundData); + int extractPriority(const byte *soundData); + int extractLoop(const byte *soundData); + void addToSoundList(Sound *sound); + void removeFromSoundList(Sound *sound); + void addToPlayList(Sound *sound); + void removeFromPlayList(Sound *sound); + bool isOnPlayList(Sound *sound); + void extractTrackInfo(trackInfoStruct *data, const byte *soundData, int groupNum); + void suspendSoundServer(); + void rethinkVoiceTypes(); + void restartSoundServer(); + void updateSoundVol(Sound *sound); + void updateSoundPri(Sound *sound); + void updateSoundLoop(Sound *sound); + + // _so methods + static void _soSetTimeIndex(int timeIndex); + static int _sfDetermineGroup(const byte *soundData); + static void _sfAddToPlayList(Sound *sound); + static void _sfRemoveFromPlayList(Sound *sound); + static bool _sfIsOnPlayList(Sound *sound); + static void _sfRethinkVoiceTypes(); + static void _sfUpdateVolume(Sound *sound); + static void _sfDereferenceAll(); + static void sub_233EE(Sound *sound); + static void _sfUpdatePriority(Sound *sound); + static void _sfUpdateLoop(Sound *sound); + }; #define SOUND_ARR_SIZE 16 -struct trackInfoStruct { - int count; - int rlbList[32]; - uint32 handleList[75]; -}; - class Sound: public EventHandler { private: - void _prime(int soundNum, int v2); + void _prime(int soundNum, bool queFlag); void _unPrime(); + void orientAfterDriverChange(); + void orientAfterRestore(); public: int _field6; int _soundNum; - int _fieldA; - int _fieldE; + int _groupNum; + int _soundPriority; int _priority2; - int _field10; + int _loop; bool _loopFlag2; int _priority; int _volume; @@ -71,10 +123,10 @@ public: int _pauseCtr; int _muteCtr; int _holdAt; - bool _cueValue; - int _field1E; + int _cueValue; + int _volume1; int _field1F; - int _field20; + int _volume2; int _field21; int _field22; uint _timeIndex; @@ -95,35 +147,35 @@ public: int _field268; bool _primed; int _field26C; - int _field26E; + byte *_field26E; public: - void play(int soundNum, int volume = 127); + Sound(); + + void play(int soundNum); void stop(); void prime(int soundNum); void unPrime(); void go(); void halt(void); + bool isPlaying(); int getSoundNum() const; - bool isPlaying() const; bool isPrimed() const; bool isPaused() const; bool isMuted() const; - void pause(); - void mute(); - void fadeIn(); - void fadeOut(EventHandler *evtHandler); + void pause(bool flag); + void mute(bool flag); void fade(int v1, int v2, int v3, int v4); void setTimeIndex(uint32 timeIndex); uint32 getTimeIndex() const; - bool getCueValue() const; - void setCueValue(bool flag); + int getCueValue() const; + void setCueValue(int cueValue); void setVol(int volume); int getVol() const; - void setPri(int v); + void setPri(int priority); void setLoop(bool flag); int getPri() const; bool getLoop(); - void holdAt(int v); + void holdAt(int amount); void release(); }; @@ -143,12 +195,12 @@ public: void unPrime(); void go() { _sound.go(); } void hault(void) { _sound.halt(); } + bool isPlaying() { return _sound.isPlaying(); } int getSoundNum() const { return _sound.getSoundNum(); } - bool isPlaying() const { return _sound.isPlaying(); } bool isPaused() const { return _sound.isPaused(); } bool isMuted() const { return _sound.isMuted(); } - void pause() { _sound.pause(); } - void mute() { _sound.mute(); } + void pause(bool flag) { _sound.pause(flag); } + void mute(bool flag) { _sound.mute(flag); } void fadeIn() { fade(127, 5, 10, 0, NULL); } void fadeOut(Action *action) { fade(0, 5, 10, 1, action); } void fade(int v1, int v2, int v3, int v4, Action *action);