From d2910fe758ef7dac8657a3a9faa85383a6cf0e9a Mon Sep 17 00:00:00 2001 From: Torbjörn Andersson Date: Fri, 26 Jan 2007 18:21:41 +0000 Subject: Added separate function for playing cutscene lead-in/out sounds, and made sure that these are stopped whenever the engine is going to do a mass killing of game resources, e.g. when restoring or restarting the game. Should fix bug #1645480. (This was a regression added during the rewrite to support DXA.) svn-id: r25204 --- engines/sword2/animation.cpp | 21 ++------------------- engines/sword2/function.cpp | 2 +- engines/sword2/layers.cpp | 2 +- engines/sword2/logic.cpp | 2 +- engines/sword2/mouse.cpp | 2 +- engines/sword2/resman.cpp | 12 ++++++------ engines/sword2/sound.cpp | 43 ++++++++++++++++++++++++++++++++++++++++--- engines/sword2/sound.h | 12 +++++++++++- engines/sword2/startup.cpp | 2 +- 9 files changed, 64 insertions(+), 34 deletions(-) diff --git a/engines/sword2/animation.cpp b/engines/sword2/animation.cpp index e4739d0923..3f9cbb482e 100644 --- a/engines/sword2/animation.cpp +++ b/engines/sword2/animation.cpp @@ -308,9 +308,6 @@ void MoviePlayer::play(int32 leadIn, int32 leadOut) { bool terminate = false; bool textVisible = false; bool startNextText = false; - byte *data; - uint32 len; - Audio::SoundHandle leadInHandle, leadOutHandle; uint32 flags = Audio::Mixer::FLAG_16BITS; // This happens if the user quits during the "eye" cutscene. @@ -318,14 +315,7 @@ void MoviePlayer::play(int32 leadIn, int32 leadOut) { return; if (leadIn) { - data = _vm->_resman->openResource(leadIn); - len = _vm->_resman->fetchLen(leadIn) - ResHeader::size(); - - assert(_vm->_resman->fetchType(data) == WAV_FILE); - - data += ResHeader::size(); - - _vm->_sound->playFx(&leadInHandle, data, len, Audio::Mixer::kMaxChannelVolume, 0, false, Audio::Mixer::kMusicSoundType); + _vm->_sound->playMovieSound(leadIn, kLeadInSound); } savePalette(); @@ -377,14 +367,7 @@ void MoviePlayer::play(int32 leadIn, int32 leadOut) { } if (leadOut && _currentFrame == _leadOutFrame) { - data = _vm->_resman->openResource(leadOut); - len = _vm->_resman->fetchLen(leadOut) - ResHeader::size(); - - assert(_vm->_resman->fetchType(data) == WAV_FILE); - - data += ResHeader::size(); - - _vm->_sound->playFx(&leadOutHandle, data, len, Audio::Mixer::kMaxChannelVolume, 0, false, Audio::Mixer::kMusicSoundType); + _vm->_sound->playMovieSound(leadOut, kLeadOutSound); } syncFrame(); diff --git a/engines/sword2/function.cpp b/engines/sword2/function.cpp index a8748544c0..3812a4f5a3 100644 --- a/engines/sword2/function.cpp +++ b/engines/sword2/function.cpp @@ -2333,7 +2333,7 @@ int32 Logic::fnSmackerLeadOut(int32 *params) { int32 Logic::fnStopAllFx(int32 *params) { // params: none - _vm->_sound->clearFxQueue(); + _vm->_sound->clearFxQueue(false); return IR_CONT; } diff --git a/engines/sword2/layers.cpp b/engines/sword2/layers.cpp index b64ae1de83..5d9f78799e 100644 --- a/engines/sword2/layers.cpp +++ b/engines/sword2/layers.cpp @@ -52,7 +52,7 @@ void Screen::initBackground(int32 res, int32 new_palette) { assert(res); - _vm->_sound->clearFxQueue(); + _vm->_sound->clearFxQueue(false); waitForFade(); debug(1, "CHANGED TO LOCATION \"%s\"", _vm->_resman->fetchName(res)); diff --git a/engines/sword2/logic.cpp b/engines/sword2/logic.cpp index 3fd7dcb696..40b431fccc 100644 --- a/engines/sword2/logic.cpp +++ b/engines/sword2/logic.cpp @@ -216,7 +216,7 @@ void Logic::expressChangeSession(uint32 sesh_id) { // Various clean-ups _router->clearWalkGridList(); - _vm->_sound->clearFxQueue(); + _vm->_sound->clearFxQueue(false); _router->freeAllRouteMem(); } diff --git a/engines/sword2/mouse.cpp b/engines/sword2/mouse.cpp index 066a785a64..594429fe15 100644 --- a/engines/sword2/mouse.cpp +++ b/engines/sword2/mouse.cpp @@ -1356,7 +1356,7 @@ void Mouse::addHuman() { _vm->_screen->setPalette(0, 1, white, RDPAL_INSTANT); // Stops all fx & clears the queue - eg. when leaving a room - _vm->_sound->clearFxQueue(); + _vm->_sound->clearFxQueue(false); // Trash all object resources so they load in fresh & restart // their logic scripts diff --git a/engines/sword2/resman.cpp b/engines/sword2/resman.cpp index 69dbd24131..49ee60530f 100644 --- a/engines/sword2/resman.cpp +++ b/engines/sword2/resman.cpp @@ -538,10 +538,10 @@ void ResourceManager::remove(int res) { void ResourceManager::removeAll() { // We need to clear the FX queue, because otherwise the sound system - // will still believe that the sound resources are in memory, and that - // it's ok to close them. + // will still believe that the sound resources are in memory. We also + // need to kill the movie lead-in/out. - _vm->_sound->clearFxQueue(); + _vm->_sound->clearFxQueue(false); for (uint i = 0; i < _totalResFiles; i++) remove(i); @@ -555,10 +555,10 @@ void ResourceManager::killAll(bool wantInfo) { int nuked = 0; // We need to clear the FX queue, because otherwise the sound system - // will still believe that the sound resources are in memory, and that - // it's ok to close them. + // will still believe that the sound resources are in memory. We also + // need to kill the movie lead-in/out. - _vm->_sound->clearFxQueue(); + _vm->_sound->clearFxQueue(true); for (uint i = 0; i < _totalResFiles; i++) { // Don't nuke the global variables or the player object! diff --git a/engines/sword2/sound.cpp b/engines/sword2/sound.cpp index d8b6b99cea..561b7dc45e 100644 --- a/engines/sword2/sound.cpp +++ b/engines/sword2/sound.cpp @@ -89,7 +89,7 @@ Sound::Sound(Sword2Engine *vm) { Sound::~Sound() { _vm->_mixer->setupPremix(0); - clearFxQueue(); + clearFxQueue(true); stopMusic(true); stopSpeech(); @@ -121,15 +121,25 @@ void Sound::setReverseStereo(bool reverse) { } /** - * Stop all sounds, close their resources and clear the FX queue. + * Stop all sounds, close their resources and clear the FX queue. This is used + * when going from one room to another, among other things. */ -void Sound::clearFxQueue() { +void Sound::clearFxQueue(bool killMovieSounds) { for (int i = 0; i < FXQ_LENGTH; i++) { if (_fxQueue[i].resource) { stopFx(i); } } + + // We aren't just going to change rooms or anything like that, we are + // killing off resources (e.g. when restoring or restarting). We need + // to also kill any movie lead-in/out sounds. + + if (killMovieSounds) { + _vm->_mixer->stopHandle(_leadInHandle); + _vm->_mixer->stopHandle(_leadOutHandle); + } } /** @@ -174,6 +184,33 @@ void Sound::processFxQueue() { } } +/** + * This function is used by the cutscene player to play the movie lead-in/out. + * @param res The sound resource to play + * @param type Either kLeadInSound or kLeadOutSound + */ + +void Sound::playMovieSound(int32 res, int type) { + Audio::SoundHandle *handle; + + if (type == kLeadInSound) + handle = &_leadInHandle; + else + handle = &_leadOutHandle; + + if (_vm->_mixer->isSoundHandleActive(*handle)) { + _vm->_mixer->stopHandle(*handle); + } + + byte *data = _vm->_resman->openResource(res); + uint32 len = _vm->_resman->fetchLen(res) - ResHeader::size(); + + assert(_vm->_resman->fetchType(data) == WAV_FILE); + data += ResHeader::size(); + + _vm->_sound->playFx(handle, data, len, Audio::Mixer::kMaxChannelVolume, 0, false, Audio::Mixer::kMusicSoundType); +} + /** * Queue a sound effect for playing later. * @param res the sound resource number diff --git a/engines/sword2/sound.h b/engines/sword2/sound.h index 32299c38bb..b941f98b4c 100644 --- a/engines/sword2/sound.h +++ b/engines/sword2/sound.h @@ -53,6 +53,11 @@ enum { kFlacMode }; +enum { + kLeadInSound, + kLeadOutSound +}; + enum { // These three types correspond to types set by the scripts FX_SPOT = 0, @@ -171,6 +176,9 @@ private: Common::Mutex _mutex; + Audio::SoundHandle _leadInHandle; + Audio::SoundHandle _leadOutHandle; + struct FxQueueEntry { Audio::SoundHandle handle; // sound handle uint32 resource; // resource id of sample @@ -220,7 +228,7 @@ public: // End of AudioStream API - void clearFxQueue(); + void clearFxQueue(bool killMovieSounds); void processFxQueue(); void setReverseStereo(bool reverse); @@ -250,6 +258,8 @@ public: void pauseAllSound(); void unpauseAllSound(); + void playMovieSound(int32 res, int type); + void queueFx(int32 res, int32 type, int32 delay, int32 volume, int32 pan); int32 playFx(FxQueueEntry *fx); int32 playFx(Audio::SoundHandle *handle, byte *data, uint32 len, uint8 vol, int8 pan, bool loop, Audio::Mixer::SoundType soundType); diff --git a/engines/sword2/startup.cpp b/engines/sword2/startup.cpp index b8b0587ac7..d7b1c0f934 100644 --- a/engines/sword2/startup.cpp +++ b/engines/sword2/startup.cpp @@ -134,7 +134,7 @@ void Sword2Engine::registerStartPoint(int32 key, char *name) { void Sword2Engine::runStart(int start) { // Restarting - stop sfx, music & speech! - _sound->clearFxQueue(); + _sound->clearFxQueue(true); _logic->fnStopMusic(NULL); _sound->unpauseSpeech(); _sound->stopSpeech(); -- cgit v1.2.3