From a373bd4a5385dd251298ad41ca1701bec2331197 Mon Sep 17 00:00:00 2001 From: Sylvain Dupont Date: Sat, 13 Nov 2010 02:44:34 +0000 Subject: TOON: Fix more memory leaks Mainly leaks in audio and animations svn-id: r54223 --- engines/toon/anim.h | 1 + engines/toon/audio.cpp | 13 +++++++++---- engines/toon/audio.h | 3 ++- engines/toon/script_func.cpp | 18 ++++++++++++++++-- engines/toon/toon.cpp | 38 +++++++++++++++++++++++++++++++++++--- 5 files changed, 63 insertions(+), 10 deletions(-) (limited to 'engines') diff --git a/engines/toon/anim.h b/engines/toon/anim.h index 01475276c5..8c5d63dd41 100644 --- a/engines/toon/anim.h +++ b/engines/toon/anim.h @@ -172,6 +172,7 @@ protected: class SceneAnimation { public: + AnimationInstance *_originalAnimInstance; AnimationInstance *_animInstance; Animation *_animation; int32 _id; diff --git a/engines/toon/audio.cpp b/engines/toon/audio.cpp index 2a1e1c2019..d57238c495 100644 --- a/engines/toon/audio.cpp +++ b/engines/toon/audio.cpp @@ -132,7 +132,7 @@ void AudioManager::playMusic(Common::String dir, Common::String music) { } // no need to delete instance here it will automatically deleted by the mixer is done with it - _channels[_currentMusicChannel] = new AudioStreamInstance(this, _mixer, srs, true); + _channels[_currentMusicChannel] = new AudioStreamInstance(this, _mixer, srs, true, true); _channels[_currentMusicChannel]->setVolume(_musicMuted ? 0 : 255); _channels[_currentMusicChannel]->play(true, Audio::Mixer::kMusicSoundType); } @@ -159,7 +159,7 @@ void AudioManager::playVoice(int32 id, bool genericVoice) { stream = _audioPacks[1]->getStream(id); // no need to delete channel 2, it will be deleted by the mixer when the stream is finished - _channels[2] = new AudioStreamInstance(this, _mixer, stream); + _channels[2] = new AudioStreamInstance(this, _mixer, stream, false, true); _channels[2]->play(false, Audio::Mixer::kSpeechSoundType); _channels[2]->setVolume(_voiceMuted ? 0 : 255); @@ -181,7 +181,7 @@ int32 AudioManager::playSFX(int32 id, int volume , bool genericSFX) { for (int32 i = 3; i < 16; i++) { if (!_channels[i]) { - _channels[i] = new AudioStreamInstance(this, _mixer, stream); + _channels[i] = new AudioStreamInstance(this, _mixer, stream, false, true); _channels[i]->play(false, Audio::Mixer::kSFXSoundType); _channels[i]->setVolume(_sfxMuted ? 0 : volume); return i; @@ -238,7 +238,7 @@ void AudioManager::stopMusic() { _channels[1]->stop(true); } -AudioStreamInstance::AudioStreamInstance(AudioManager *man, Audio::Mixer *mixer, Common::SeekableReadStream *stream , bool looping) { +AudioStreamInstance::AudioStreamInstance(AudioManager *man, Audio::Mixer *mixer, Common::SeekableReadStream *stream , bool looping, bool deleteFileStreamAtEnd) { _compBufferSize = 0; _buffer = NULL; _bufferMaxSize = 0; @@ -258,6 +258,7 @@ AudioStreamInstance::AudioStreamInstance(AudioManager *man, Audio::Mixer *mixer, _man = man; _looping = looping; _musicAttenuation = 1000; + _deleteFileStream = deleteFileStreamAtEnd; // preload one packet if (_totalSize > 0) { @@ -274,6 +275,10 @@ AudioStreamInstance::~AudioStreamInstance() { if (_man) _man->removeInstance(this); + + if (_deleteFileStream) { + delete _file; + } } int AudioStreamInstance::readBuffer(int16 *buffer, const int numSamples) { diff --git a/engines/toon/audio.h b/engines/toon/audio.h index dec731e78d..e8c6c44e03 100644 --- a/engines/toon/audio.h +++ b/engines/toon/audio.h @@ -37,7 +37,7 @@ class AudioManager; class AudioStreamInstance : public Audio::AudioStream { public: - AudioStreamInstance(AudioManager *man, Audio::Mixer *mixer, Common::SeekableReadStream *stream, bool looping = false); + AudioStreamInstance(AudioManager *man, Audio::Mixer *mixer, Common::SeekableReadStream *stream, bool looping = false, bool deleteFileStreamAtEnd = false); ~AudioStreamInstance(); void play(bool fade = false, Audio::Mixer::SoundType soundType = Audio::Mixer::kMusicSoundType); void stop(bool fade = false); @@ -92,6 +92,7 @@ protected: bool _looping; int32 _volume; int32 _musicAttenuation; + bool _deleteFileStream; }; class AudioStreamPackage { diff --git a/engines/toon/script_func.cpp b/engines/toon/script_func.cpp index 48ba073561..e2c9540fb2 100644 --- a/engines/toon/script_func.cpp +++ b/engines/toon/script_func.cpp @@ -916,9 +916,13 @@ int32 ScriptFunc::sys_Cmd_Init_Scene_Anim(EMCState *state) { if (sceneAnim->_active) return 0; + delete sceneAnim->_animation; + delete sceneAnim->_animInstance; + sceneAnim->_animation = new Animation(_vm); sceneAnim->_animation->loadAnimation(GetText(12, state)); sceneAnim->_animInstance = _vm->getAnimationManager()->createNewInstance(kAnimationScene); + sceneAnim->_originalAnimInstance = sceneAnim->_animInstance; sceneAnim->_animInstance->setAnimation(sceneAnim->_animation); sceneAnim->_animInstance->setVisible((flags & 1) != 0); sceneAnim->_animInstance->setAnimationRange(stackPos(11), stackPos(11)); @@ -1155,8 +1159,18 @@ int32 ScriptFunc::sys_Cmd_Remove_Scene_Anim(EMCState *state) { SceneAnimation *sceneAnim = _vm->getSceneAnimation(sceneId); sceneAnim->_active = false; _vm->getAnimationManager()->removeInstance(sceneAnim->_animInstance); - sceneAnim->_animation = 0; - sceneAnim->_animInstance = 0; + delete sceneAnim->_animation; + sceneAnim->_animation = NULL; + + // see if one character shares this instance + for (int32 c = 0; c < 32; c++) { + if (_vm->getCharacter(c) && _vm->getCharacter(c)->getAnimationInstance() == sceneAnim->_originalAnimInstance) { + _vm->getCharacter(c)->setAnimationInstance(NULL); + } + } + delete sceneAnim->_originalAnimInstance; + sceneAnim->_originalAnimInstance = NULL; + sceneAnim->_animInstance = NULL; return 0; } diff --git a/engines/toon/toon.cpp b/engines/toon/toon.cpp index 37b4f242d8..e91a895fd3 100644 --- a/engines/toon/toon.cpp +++ b/engines/toon/toon.cpp @@ -829,8 +829,12 @@ ToonEngine::~ToonEngine() { delete _resources; delete _animationManager; delete _moviePlayer; - delete _mainSurface; + if(_mainSurface) { + _mainSurface->free(); + delete _mainSurface; + } + delete[] _finalPalette; delete[] _backupPalette; delete[] _additionalPalette1; @@ -859,6 +863,20 @@ ToonEngine::~ToonEngine() { delete _pathFinding; + + for (int32 i = 0; i < 64; i++) { + if (_sceneAnimations[i]._active) { + // see if one character shares this instance + for (int32 c = 0; c < 32; c++) { + if (_characters[c] && _characters[c]->getAnimationInstance() == _sceneAnimations[i]._animInstance) { + _characters[c]->setAnimationInstance(0); + } + } + delete _sceneAnimations[i]._originalAnimInstance; + delete _sceneAnimations[i]._animation; + } + } + for (int32 i = 0; i < 32; i++) delete _characters[i]; @@ -869,6 +887,7 @@ ToonEngine::~ToonEngine() { delete _inventoryIconSlots; //delete _genericTexts; delete _audioManager; + delete _gameState; unloadToonDat(); @@ -1642,8 +1661,18 @@ void ToonEngine::exitScene() { delete _sceneAnimations[i]._animation; _sceneAnimations[i]._active = false; _animationManager->removeInstance(_sceneAnimations[i]._animInstance); - _sceneAnimations[i]._animInstance = 0; - _sceneAnimations[i]._animation = 0; + + // see if one character shares this instance + for (int32 c = 0; c < 32; c++) { + if (_characters[c] && _characters[c]->getAnimationInstance() == _sceneAnimations[i]._animInstance) { + _characters[c]->setAnimationInstance(NULL); + } + } + + delete _sceneAnimations[i]._originalAnimInstance; + _sceneAnimations[i]._animInstance = NULL; + _sceneAnimations[i]._animation = NULL; + _sceneAnimations[i]._originalAnimInstance = NULL; } } for (int32 i = 0; i < 64; i++) { @@ -4557,6 +4586,8 @@ char **ToonEngine::loadTextsVariants(Common::File &in) { res[0] += DATAALIGNMENT; } else { in.read(pos, entryLen); + free(pos); + continue; } pos += DATAALIGNMENT; @@ -4637,6 +4668,7 @@ void SceneAnimation::load(ToonEngine *vm, Common::ReadStream *stream) { _animInstance = vm->getAnimationManager()->createNewInstance(kAnimationScene); _animInstance->load(stream); vm->getAnimationManager()->addInstance(_animInstance); + _originalAnimInstance = _animInstance; } // load animation if any -- cgit v1.2.3