From 97137e6b27a6d64fc2ba45c0c6d1a07d027ee27c Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 22 Jun 2011 23:40:25 +1000 Subject: TSAGE: Added saving/restoring of playing sounds to savegames --- engines/tsage/saveload.cpp | 6 ++- engines/tsage/saveload.h | 2 +- engines/tsage/scenes.cpp | 6 ++- engines/tsage/sound.cpp | 93 ++++++++++++++++++++++++++++++++++++++++------ engines/tsage/sound.h | 13 ++++--- 5 files changed, 100 insertions(+), 20 deletions(-) diff --git a/engines/tsage/saveload.cpp b/engines/tsage/saveload.cpp index 522e40c236..b184e59c9e 100644 --- a/engines/tsage/saveload.cpp +++ b/engines/tsage/saveload.cpp @@ -21,11 +21,13 @@ */ #include "common/savefile.h" +#include "common/mutex.h" #include "graphics/palette.h" #include "graphics/scaler.h" #include "graphics/thumbnail.h" #include "tsage/globals.h" #include "tsage/saveload.h" +#include "tsage/sound.h" #include "tsage/tsage.h" namespace tSage { @@ -105,6 +107,7 @@ void Serializer::validate(int v, Common::Serializer::Version minVersion, Common::Error Saver::save(int slot, const Common::String &saveName) { assert(!getMacroRestoreFlag()); + Common::StackLock slock1(_globals->_soundManager._serverDisabledMutex); // Signal any objects registered for notification _saveNotifiers.notify(false); @@ -149,6 +152,7 @@ Common::Error Saver::save(int slot, const Common::String &saveName) { Common::Error Saver::restore(int slot) { assert(!getMacroRestoreFlag()); + Common::StackLock slock1(_globals->_soundManager._serverDisabledMutex); // Signal any objects registered for notification _loadNotifiers.notify(false); @@ -205,7 +209,7 @@ Common::Error Saver::restore(int slot) { // Final post-restore notifications _macroRestoreFlag = false; - _loadNotifiers.notify(false); + _loadNotifiers.notify(true); return Common::kNoError; } diff --git a/engines/tsage/saveload.h b/engines/tsage/saveload.h index c1c2851f28..0382e4a1fc 100644 --- a/engines/tsage/saveload.h +++ b/engines/tsage/saveload.h @@ -33,7 +33,7 @@ namespace tSage { typedef void (*SaveNotifierFn)(bool postFlag); -#define TSAGE_SAVEGAME_VERSION 5 +#define TSAGE_SAVEGAME_VERSION 6 class SavedObject; diff --git a/engines/tsage/scenes.cpp b/engines/tsage/scenes.cpp index 6352918e39..18b3da2698 100644 --- a/engines/tsage/scenes.cpp +++ b/engines/tsage/scenes.cpp @@ -235,7 +235,11 @@ void SceneManager::listenerSynchronize(Serializer &s) { if (s.isLoading()) { changeScene(_sceneNumber); - checkScene(); + + if (_nextSceneNumber != -1) { + sceneChange(); + _nextSceneNumber = -1; + } } _globals->_sceneManager._scrollerRect.synchronize(s); diff --git a/engines/tsage/sound.cpp b/engines/tsage/sound.cpp index dc7b6599ed..6f061862dc 100644 --- a/engines/tsage/sound.cpp +++ b/engines/tsage/sound.cpp @@ -44,7 +44,6 @@ SoundManager::SoundManager() { _groupsAvail = 0; _newVolume = _masterVol = 127; - _suspendedCount = 0; _driversDetected = false; _needToRethink = false; @@ -53,6 +52,8 @@ SoundManager::SoundManager() { SoundManager::~SoundManager() { if (__sndmgrReady) { + Common::StackLock slock(_serverDisabledMutex); + for (Common::List::iterator i = _soundList.begin(); i != _soundList.end(); ) { Sound *s = *i; ++i; @@ -342,6 +343,18 @@ void SoundManager::_sfSoundServer() { if (sfManager()._newVolume != sfManager()._masterVol) _sfSetMasterVol(sfManager()._newVolume); + // If a time index has been set for any sound, fast forward to it + SynchronizedList::iterator i; + for (i = sfManager()._playList.begin(); i != sfManager()._playList.end(); ++i) { + Sound *s = *i; + if (s->_newTimeIndex != 0) { + s->mute(true); + s->_soSetTimeIndex(s->_newTimeIndex); + s->mute(false); + s->_newTimeIndex = 0; + } + } + // Handle any fading if necessary _sfProcessFading(); @@ -474,7 +487,7 @@ void SoundManager::saveNotifier(bool postFlag) { } void SoundManager::saveNotifierProc(bool postFlag) { - warning("TODO: SoundManager::saveNotifierProc"); + // Nothing needs to be done when saving the game } void SoundManager::loadNotifier(bool postFlag) { @@ -482,12 +495,37 @@ void SoundManager::loadNotifier(bool postFlag) { } void SoundManager::loadNotifierProc(bool postFlag) { - warning("TODO: SoundManager::loadNotifierProc"); + if (!postFlag) { + // Stop any currently playing sounds + if (__sndmgrReady) { + Common::StackLock slock(_serverDisabledMutex); + + for (Common::List::iterator i = _soundList.begin(); i != _soundList.end(); ) { + Sound *s = *i; + ++i; + s->stop(); + } + } + } else { + // Savegame is now loaded, so iterate over the sound list to prime any sounds as necessary + for (Common::List::iterator i = _soundList.begin(); i != _soundList.end(); ++i) { + Sound *s = *i; + s->orientAfterRestore(); + } + } } void SoundManager::listenerSynchronize(Serializer &s) { s.validate("SoundManager"); - warning("TODO: SoundManager listenerSynchronise"); + assert(__sndmgrReady && _driversDetected); + + if (s.getVersion() < 6) + return; + + Common::StackLock slock(_serverDisabledMutex); + _playList.synchronize(s); + + _soundList.synchronize(s); } /*--------------------------------------------------------------------------*/ @@ -1188,7 +1226,7 @@ void SoundManager::_sfUpdateVolume(Sound *sound) { } void SoundManager::_sfDereferenceAll() { - // Orignal used handles for both the driver list and voiceStructPtrs list. This method then refreshed + // Orignal used handles for both the driver list and voiceTypeStructPtrs 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 } @@ -1379,6 +1417,7 @@ Sound::Sound() { _fadeCounter = 0; _stopAfterFadeFlag = false; _timer = 0; + _newTimeIndex = 0; _loopTimer = 0; _trackInfo._numTracks = 0; _primed = false; @@ -1411,6 +1450,36 @@ Sound::~Sound() { stop(); } +void Sound::synchronize(Serializer &s) { + if (s.getVersion() < 6) + return; + + assert(!_remoteReceiver); + + s.syncAsSint16LE(_soundResID); + s.syncAsByte(_primed); + s.syncAsByte(_stoppedAsynchronously); + s.syncAsSint16LE(_group); + s.syncAsSint16LE(_sndResPriority); + s.syncAsSint16LE(_fixedPriority); + s.syncAsSint16LE(_sndResLoop); + s.syncAsSint16LE(_fixedLoop); + s.syncAsSint16LE(_priority); + s.syncAsSint16LE(_volume); + s.syncAsSint16LE(_loop); + s.syncAsSint16LE(_pausedCount); + s.syncAsSint16LE(_mutedCount); + s.syncAsSint16LE(_hold); + s.syncAsSint16LE(_cueValue); + s.syncAsSint16LE(_fadeDest); + s.syncAsSint16LE(_fadeSteps); + s.syncAsUint32LE(_fadeTicks); + s.syncAsUint32LE(_fadeCounter); + s.syncAsByte(_stopAfterFadeFlag); + s.syncAsUint32LE(_timer); + s.syncAsSint16LE(_loopTimer); +} + void Sound::play(int soundNum) { prime(soundNum); _soundManager->addToPlayList(this); @@ -1436,6 +1505,7 @@ void Sound::_prime(int soundResID, bool dontQueue) { if (_primed) unPrime(); + _soundResID = soundResID; if (_soundResID != -1) { // Sound number specified _isEmpty = false; @@ -1501,12 +1571,13 @@ void Sound::orientAfterDriverChange() { _trackInfo._numTracks = 0; _primed = false; _prime(_soundResID, true); + setTimeIndex(timeIndex); } } void Sound::orientAfterRestore() { - if (_isEmpty) { + if (!_isEmpty) { int timeIndex = getTimeIndex(); _primed = false; _prime(_soundResID, true); @@ -1585,11 +1656,8 @@ void Sound::fade(int fadeDest, int fadeSteps, int fadeTicks, bool stopAfterFadeF } void Sound::setTimeIndex(uint32 timeIndex) { - if (_primed) { - mute(true); - _soSetTimeIndex(timeIndex); - mute(false); - } + if (_primed) + _newTimeIndex = timeIndex; } uint32 Sound::getTimeIndex() const { @@ -1665,6 +1733,7 @@ void Sound::_soPrimeSound(bool dontQueue) { } _timer = 0; + _newTimeIndex = 0; _loopTimer = 0; _soPrimeChannelData(); } @@ -1685,6 +1754,8 @@ void Sound::_soSetTimeIndex(uint timeIndex) { _soundManager->_needToRethink = true; break; } + + --timeIndex; } _soundManager->_soTimeIndexFlag = false; diff --git a/engines/tsage/sound.h b/engines/tsage/sound.h index 9a8cfb3cfc..4647e3c564 100644 --- a/engines/tsage/sound.h +++ b/engines/tsage/sound.h @@ -123,7 +123,6 @@ struct VoiceStructEntryType0 { int _channelNum3; int _priority3; int _field1A; - int _field1B; }; struct VoiceStructEntryType1 { @@ -166,7 +165,7 @@ private: public: bool __sndmgrReady; int _ourSndResVersion, _ourDrvResVersion; - Common::List _playList; + SynchronizedList _playList; Common::List _installedDrivers; VoiceTypeStruct *_voiceTypeStructPtrs[SOUND_ARR_SIZE]; uint32 _groupsAvail; @@ -174,9 +173,8 @@ public: int _newVolume; Common::Mutex _serverDisabledMutex; Common::Mutex _serverSuspendedMutex; - int _suspendedCount; bool _driversDetected; - Common::List _soundList; + SynchronizedList _soundList; Common::List _availableDrivers; bool _needToRethink; // Misc flags @@ -255,7 +253,6 @@ class Sound: public EventHandler { private: void _prime(int soundResID, bool dontQueue); void _unPrime(); - void orientAfterRestore(); public: bool _stoppedAsynchronously; int _soundResID; @@ -276,7 +273,8 @@ public: int _fadeTicks; int _fadeCounter; bool _stopAfterFadeFlag; - uint _timer; + uint32 _timer; + uint32 _newTimeIndex; int _loopTimer; int _chProgram[SOUND_ARR_SIZE]; int _chModulation[SOUND_ARR_SIZE]; @@ -306,6 +304,9 @@ public: Sound(); ~Sound(); + void synchronize(Serializer &s); + void orientAfterRestore(); + void play(int soundResID); void stop(); void prime(int soundResID); -- cgit v1.2.3