TSAGE: Added saving/restoring of playing sounds to savegames
This commit is contained in:
parent
c4a5fa8506
commit
97137e6b27
5 changed files with 100 additions and 20 deletions
|
@ -21,11 +21,13 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "common/savefile.h"
|
#include "common/savefile.h"
|
||||||
|
#include "common/mutex.h"
|
||||||
#include "graphics/palette.h"
|
#include "graphics/palette.h"
|
||||||
#include "graphics/scaler.h"
|
#include "graphics/scaler.h"
|
||||||
#include "graphics/thumbnail.h"
|
#include "graphics/thumbnail.h"
|
||||||
#include "tsage/globals.h"
|
#include "tsage/globals.h"
|
||||||
#include "tsage/saveload.h"
|
#include "tsage/saveload.h"
|
||||||
|
#include "tsage/sound.h"
|
||||||
#include "tsage/tsage.h"
|
#include "tsage/tsage.h"
|
||||||
|
|
||||||
namespace tSage {
|
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) {
|
Common::Error Saver::save(int slot, const Common::String &saveName) {
|
||||||
assert(!getMacroRestoreFlag());
|
assert(!getMacroRestoreFlag());
|
||||||
|
Common::StackLock slock1(_globals->_soundManager._serverDisabledMutex);
|
||||||
|
|
||||||
// Signal any objects registered for notification
|
// Signal any objects registered for notification
|
||||||
_saveNotifiers.notify(false);
|
_saveNotifiers.notify(false);
|
||||||
|
@ -149,6 +152,7 @@ Common::Error Saver::save(int slot, const Common::String &saveName) {
|
||||||
|
|
||||||
Common::Error Saver::restore(int slot) {
|
Common::Error Saver::restore(int slot) {
|
||||||
assert(!getMacroRestoreFlag());
|
assert(!getMacroRestoreFlag());
|
||||||
|
Common::StackLock slock1(_globals->_soundManager._serverDisabledMutex);
|
||||||
|
|
||||||
// Signal any objects registered for notification
|
// Signal any objects registered for notification
|
||||||
_loadNotifiers.notify(false);
|
_loadNotifiers.notify(false);
|
||||||
|
@ -205,7 +209,7 @@ Common::Error Saver::restore(int slot) {
|
||||||
|
|
||||||
// Final post-restore notifications
|
// Final post-restore notifications
|
||||||
_macroRestoreFlag = false;
|
_macroRestoreFlag = false;
|
||||||
_loadNotifiers.notify(false);
|
_loadNotifiers.notify(true);
|
||||||
|
|
||||||
return Common::kNoError;
|
return Common::kNoError;
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,7 @@ namespace tSage {
|
||||||
|
|
||||||
typedef void (*SaveNotifierFn)(bool postFlag);
|
typedef void (*SaveNotifierFn)(bool postFlag);
|
||||||
|
|
||||||
#define TSAGE_SAVEGAME_VERSION 5
|
#define TSAGE_SAVEGAME_VERSION 6
|
||||||
|
|
||||||
class SavedObject;
|
class SavedObject;
|
||||||
|
|
||||||
|
|
|
@ -235,7 +235,11 @@ void SceneManager::listenerSynchronize(Serializer &s) {
|
||||||
|
|
||||||
if (s.isLoading()) {
|
if (s.isLoading()) {
|
||||||
changeScene(_sceneNumber);
|
changeScene(_sceneNumber);
|
||||||
checkScene();
|
|
||||||
|
if (_nextSceneNumber != -1) {
|
||||||
|
sceneChange();
|
||||||
|
_nextSceneNumber = -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_globals->_sceneManager._scrollerRect.synchronize(s);
|
_globals->_sceneManager._scrollerRect.synchronize(s);
|
||||||
|
|
|
@ -44,7 +44,6 @@ SoundManager::SoundManager() {
|
||||||
|
|
||||||
_groupsAvail = 0;
|
_groupsAvail = 0;
|
||||||
_newVolume = _masterVol = 127;
|
_newVolume = _masterVol = 127;
|
||||||
_suspendedCount = 0;
|
|
||||||
_driversDetected = false;
|
_driversDetected = false;
|
||||||
_needToRethink = false;
|
_needToRethink = false;
|
||||||
|
|
||||||
|
@ -53,6 +52,8 @@ SoundManager::SoundManager() {
|
||||||
|
|
||||||
SoundManager::~SoundManager() {
|
SoundManager::~SoundManager() {
|
||||||
if (__sndmgrReady) {
|
if (__sndmgrReady) {
|
||||||
|
Common::StackLock slock(_serverDisabledMutex);
|
||||||
|
|
||||||
for (Common::List<Sound *>::iterator i = _soundList.begin(); i != _soundList.end(); ) {
|
for (Common::List<Sound *>::iterator i = _soundList.begin(); i != _soundList.end(); ) {
|
||||||
Sound *s = *i;
|
Sound *s = *i;
|
||||||
++i;
|
++i;
|
||||||
|
@ -342,6 +343,18 @@ void SoundManager::_sfSoundServer() {
|
||||||
if (sfManager()._newVolume != sfManager()._masterVol)
|
if (sfManager()._newVolume != sfManager()._masterVol)
|
||||||
_sfSetMasterVol(sfManager()._newVolume);
|
_sfSetMasterVol(sfManager()._newVolume);
|
||||||
|
|
||||||
|
// If a time index has been set for any sound, fast forward to it
|
||||||
|
SynchronizedList<Sound *>::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
|
// Handle any fading if necessary
|
||||||
_sfProcessFading();
|
_sfProcessFading();
|
||||||
|
|
||||||
|
@ -474,7 +487,7 @@ void SoundManager::saveNotifier(bool postFlag) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoundManager::saveNotifierProc(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) {
|
void SoundManager::loadNotifier(bool postFlag) {
|
||||||
|
@ -482,12 +495,37 @@ void SoundManager::loadNotifier(bool postFlag) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoundManager::loadNotifierProc(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<Sound *>::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<Sound *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) {
|
||||||
|
Sound *s = *i;
|
||||||
|
s->orientAfterRestore();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoundManager::listenerSynchronize(Serializer &s) {
|
void SoundManager::listenerSynchronize(Serializer &s) {
|
||||||
s.validate("SoundManager");
|
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() {
|
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
|
// pointer lists based on the handles. Since in ScummVM we're just using pointers directly, this
|
||||||
// method doesn't need any implementation
|
// method doesn't need any implementation
|
||||||
}
|
}
|
||||||
|
@ -1379,6 +1417,7 @@ Sound::Sound() {
|
||||||
_fadeCounter = 0;
|
_fadeCounter = 0;
|
||||||
_stopAfterFadeFlag = false;
|
_stopAfterFadeFlag = false;
|
||||||
_timer = 0;
|
_timer = 0;
|
||||||
|
_newTimeIndex = 0;
|
||||||
_loopTimer = 0;
|
_loopTimer = 0;
|
||||||
_trackInfo._numTracks = 0;
|
_trackInfo._numTracks = 0;
|
||||||
_primed = false;
|
_primed = false;
|
||||||
|
@ -1411,6 +1450,36 @@ Sound::~Sound() {
|
||||||
stop();
|
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) {
|
void Sound::play(int soundNum) {
|
||||||
prime(soundNum);
|
prime(soundNum);
|
||||||
_soundManager->addToPlayList(this);
|
_soundManager->addToPlayList(this);
|
||||||
|
@ -1436,6 +1505,7 @@ void Sound::_prime(int soundResID, bool dontQueue) {
|
||||||
if (_primed)
|
if (_primed)
|
||||||
unPrime();
|
unPrime();
|
||||||
|
|
||||||
|
_soundResID = soundResID;
|
||||||
if (_soundResID != -1) {
|
if (_soundResID != -1) {
|
||||||
// Sound number specified
|
// Sound number specified
|
||||||
_isEmpty = false;
|
_isEmpty = false;
|
||||||
|
@ -1501,12 +1571,13 @@ void Sound::orientAfterDriverChange() {
|
||||||
_trackInfo._numTracks = 0;
|
_trackInfo._numTracks = 0;
|
||||||
_primed = false;
|
_primed = false;
|
||||||
_prime(_soundResID, true);
|
_prime(_soundResID, true);
|
||||||
|
|
||||||
setTimeIndex(timeIndex);
|
setTimeIndex(timeIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Sound::orientAfterRestore() {
|
void Sound::orientAfterRestore() {
|
||||||
if (_isEmpty) {
|
if (!_isEmpty) {
|
||||||
int timeIndex = getTimeIndex();
|
int timeIndex = getTimeIndex();
|
||||||
_primed = false;
|
_primed = false;
|
||||||
_prime(_soundResID, true);
|
_prime(_soundResID, true);
|
||||||
|
@ -1585,11 +1656,8 @@ void Sound::fade(int fadeDest, int fadeSteps, int fadeTicks, bool stopAfterFadeF
|
||||||
}
|
}
|
||||||
|
|
||||||
void Sound::setTimeIndex(uint32 timeIndex) {
|
void Sound::setTimeIndex(uint32 timeIndex) {
|
||||||
if (_primed) {
|
if (_primed)
|
||||||
mute(true);
|
_newTimeIndex = timeIndex;
|
||||||
_soSetTimeIndex(timeIndex);
|
|
||||||
mute(false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 Sound::getTimeIndex() const {
|
uint32 Sound::getTimeIndex() const {
|
||||||
|
@ -1665,6 +1733,7 @@ void Sound::_soPrimeSound(bool dontQueue) {
|
||||||
}
|
}
|
||||||
|
|
||||||
_timer = 0;
|
_timer = 0;
|
||||||
|
_newTimeIndex = 0;
|
||||||
_loopTimer = 0;
|
_loopTimer = 0;
|
||||||
_soPrimeChannelData();
|
_soPrimeChannelData();
|
||||||
}
|
}
|
||||||
|
@ -1685,6 +1754,8 @@ void Sound::_soSetTimeIndex(uint timeIndex) {
|
||||||
_soundManager->_needToRethink = true;
|
_soundManager->_needToRethink = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
--timeIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
_soundManager->_soTimeIndexFlag = false;
|
_soundManager->_soTimeIndexFlag = false;
|
||||||
|
|
|
@ -123,7 +123,6 @@ struct VoiceStructEntryType0 {
|
||||||
int _channelNum3;
|
int _channelNum3;
|
||||||
int _priority3;
|
int _priority3;
|
||||||
int _field1A;
|
int _field1A;
|
||||||
int _field1B;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct VoiceStructEntryType1 {
|
struct VoiceStructEntryType1 {
|
||||||
|
@ -166,7 +165,7 @@ private:
|
||||||
public:
|
public:
|
||||||
bool __sndmgrReady;
|
bool __sndmgrReady;
|
||||||
int _ourSndResVersion, _ourDrvResVersion;
|
int _ourSndResVersion, _ourDrvResVersion;
|
||||||
Common::List<Sound *> _playList;
|
SynchronizedList<Sound *> _playList;
|
||||||
Common::List<SoundDriver *> _installedDrivers;
|
Common::List<SoundDriver *> _installedDrivers;
|
||||||
VoiceTypeStruct *_voiceTypeStructPtrs[SOUND_ARR_SIZE];
|
VoiceTypeStruct *_voiceTypeStructPtrs[SOUND_ARR_SIZE];
|
||||||
uint32 _groupsAvail;
|
uint32 _groupsAvail;
|
||||||
|
@ -174,9 +173,8 @@ public:
|
||||||
int _newVolume;
|
int _newVolume;
|
||||||
Common::Mutex _serverDisabledMutex;
|
Common::Mutex _serverDisabledMutex;
|
||||||
Common::Mutex _serverSuspendedMutex;
|
Common::Mutex _serverSuspendedMutex;
|
||||||
int _suspendedCount;
|
|
||||||
bool _driversDetected;
|
bool _driversDetected;
|
||||||
Common::List<Sound *> _soundList;
|
SynchronizedList<Sound *> _soundList;
|
||||||
Common::List<SoundDriverEntry> _availableDrivers;
|
Common::List<SoundDriverEntry> _availableDrivers;
|
||||||
bool _needToRethink;
|
bool _needToRethink;
|
||||||
// Misc flags
|
// Misc flags
|
||||||
|
@ -255,7 +253,6 @@ class Sound: public EventHandler {
|
||||||
private:
|
private:
|
||||||
void _prime(int soundResID, bool dontQueue);
|
void _prime(int soundResID, bool dontQueue);
|
||||||
void _unPrime();
|
void _unPrime();
|
||||||
void orientAfterRestore();
|
|
||||||
public:
|
public:
|
||||||
bool _stoppedAsynchronously;
|
bool _stoppedAsynchronously;
|
||||||
int _soundResID;
|
int _soundResID;
|
||||||
|
@ -276,7 +273,8 @@ public:
|
||||||
int _fadeTicks;
|
int _fadeTicks;
|
||||||
int _fadeCounter;
|
int _fadeCounter;
|
||||||
bool _stopAfterFadeFlag;
|
bool _stopAfterFadeFlag;
|
||||||
uint _timer;
|
uint32 _timer;
|
||||||
|
uint32 _newTimeIndex;
|
||||||
int _loopTimer;
|
int _loopTimer;
|
||||||
int _chProgram[SOUND_ARR_SIZE];
|
int _chProgram[SOUND_ARR_SIZE];
|
||||||
int _chModulation[SOUND_ARR_SIZE];
|
int _chModulation[SOUND_ARR_SIZE];
|
||||||
|
@ -306,6 +304,9 @@ public:
|
||||||
Sound();
|
Sound();
|
||||||
~Sound();
|
~Sound();
|
||||||
|
|
||||||
|
void synchronize(Serializer &s);
|
||||||
|
void orientAfterRestore();
|
||||||
|
|
||||||
void play(int soundResID);
|
void play(int soundResID);
|
||||||
void stop();
|
void stop();
|
||||||
void prime(int soundResID);
|
void prime(int soundResID);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue