From 8a4cc14b1ae2b81055b710699854e25b02db9be9 Mon Sep 17 00:00:00 2001 From: Sylvain Dupont Date: Fri, 12 Nov 2010 22:31:04 +0000 Subject: TOON: Fix audio crashs and more memory leaks svn-id: r54219 --- engines/toon/anim.cpp | 2 +- engines/toon/audio.cpp | 8 ++++++-- engines/toon/movie.cpp | 5 ++++- engines/toon/movie.h | 3 ++- engines/toon/resource.cpp | 10 ++++++++++ engines/toon/resource.h | 4 +++- engines/toon/toon.cpp | 35 +++++++++++++++++++++++++++++------ engines/toon/toon.h | 6 +++++- 8 files changed, 60 insertions(+), 13 deletions(-) (limited to 'engines/toon') diff --git a/engines/toon/anim.cpp b/engines/toon/anim.cpp index aa85db954e..00cfdad9cc 100644 --- a/engines/toon/anim.cpp +++ b/engines/toon/anim.cpp @@ -108,7 +108,7 @@ bool Animation::loadAnimation(Common::String file) { } } - //delete[] fileData; + _vm->resources()->purgeFileData(); delete[] finalBuffer; return true; } diff --git a/engines/toon/audio.cpp b/engines/toon/audio.cpp index 3fba7d6cd8..2a1e1c2019 100644 --- a/engines/toon/audio.cpp +++ b/engines/toon/audio.cpp @@ -64,6 +64,7 @@ AudioManager::AudioManager(ToonEngine *vm, Audio::Mixer *mixer) : _vm(vm), _mixe } AudioManager::~AudioManager(void) { + _mixer->stopAll(); for (int32 i = 0; i < 4; i++) { closeAudioPack(i); } @@ -130,7 +131,7 @@ void AudioManager::playMusic(Common::String dir, Common::String music) { _currentMusicChannel = 0; } - delete _channels[_currentMusicChannel]; + // 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]->setVolume(_musicMuted ? 0 : 255); _channels[_currentMusicChannel]->play(true, Audio::Mixer::kMusicSoundType); @@ -157,7 +158,7 @@ void AudioManager::playVoice(int32 id, bool genericVoice) { else stream = _audioPacks[1]->getStream(id); - delete _channels[2]; + // 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]->play(false, Audio::Mixer::kSpeechSoundType); _channels[2]->setVolume(_voiceMuted ? 0 : 255); @@ -278,6 +279,9 @@ AudioStreamInstance::~AudioStreamInstance() { int AudioStreamInstance::readBuffer(int16 *buffer, const int numSamples) { debugC(5, kDebugAudio, "readBuffer(buffer, %d)", numSamples); + if(_stopped) + return 0; + handleFade(numSamples); int32 leftSamples = numSamples; int32 destOffset = 0; diff --git a/engines/toon/movie.cpp b/engines/toon/movie.cpp index e56bb82cfa..f0c40366be 100644 --- a/engines/toon/movie.cpp +++ b/engines/toon/movie.cpp @@ -46,7 +46,10 @@ bool ToonstruckSmackerDecoder::loadFile(const Common::String &filename, int forc if (forcedflags & 0x10 || _surface->h == 200) { _header.flags = 4; - delete this->_surface; + if (_surface) { + _surface->free(); + delete _surface; + } _surface = new Graphics::Surface(); _surface->create(640, 400, 1); } diff --git a/engines/toon/movie.h b/engines/toon/movie.h index 4d5efb3343..e89abb56c0 100644 --- a/engines/toon/movie.h +++ b/engines/toon/movie.h @@ -34,6 +34,7 @@ namespace Toon { class ToonstruckSmackerDecoder : public Graphics::SmackerDecoder { public: ToonstruckSmackerDecoder(Audio::Mixer *mixer, Audio::Mixer::SoundType soundType = Audio::Mixer::kSFXSoundType); + virtual ~ToonstruckSmackerDecoder() {} void handleAudioTrack(byte track, uint32 chunkSize, uint32 unpackedSize); bool loadFile(const Common::String &filename, int forcedflags) ; }; @@ -41,7 +42,7 @@ public: class Movie { public: Movie(ToonEngine *vm, ToonstruckSmackerDecoder *decoder); - ~Movie(void); + virtual ~Movie(void); void init() const; void play(Common::String video, int32 flags = 0); diff --git a/engines/toon/resource.cpp b/engines/toon/resource.cpp index f76db47539..3f879df781 100644 --- a/engines/toon/resource.cpp +++ b/engines/toon/resource.cpp @@ -39,6 +39,8 @@ Resources::~Resources() { _pakFiles.pop_back(); delete temp; } + + purgeFileData(); } void Resources::openPackage(Common::String fileName, bool preloadEntirePackage) { @@ -84,6 +86,7 @@ uint8 *Resources::getFileData(Common::String fileName, uint32 *fileSize) { uint8 *memory = (uint8 *)new uint8[*fileSize]; file.read(memory, *fileSize); file.close(); + _allocatedFileData.push_back(memory); return memory; } else { for (uint32 i = 0; i < _pakFiles.size(); i++) { @@ -124,6 +127,13 @@ Common::SeekableReadStream *Resources::openFile(Common::String fileName) { return 0; } } + +void Resources::purgeFileData() { + for (uint32 i = 0; i < _allocatedFileData.size(); i++) { + delete[] _allocatedFileData[i]; + } + _allocatedFileData.clear(); +} Common::SeekableReadStream *PakFile::createReadStream(Common::String fileName) { debugC(1, kDebugResource, "createReadStream(%s)", fileName.c_str()); diff --git a/engines/toon/resource.h b/engines/toon/resource.h index 7e7f3d007a..e117c8e259 100644 --- a/engines/toon/resource.h +++ b/engines/toon/resource.h @@ -69,10 +69,12 @@ public: void openPackage(Common::String file, bool preloadEntirePackage); void closePackage(Common::String fileName); Common::SeekableReadStream *openFile(Common::String file); - uint8 *getFileData(Common::String fileName, uint32 *fileSize); + uint8 *getFileData(Common::String fileName, uint32 *fileSize); // this memory must be copied to your own structures! + void purgeFileData(); protected: ToonEngine *_vm; + Common::Array _allocatedFileData; Common::Array _pakFiles; }; diff --git a/engines/toon/toon.cpp b/engines/toon/toon.cpp index 7b8a12d0b6..f80d6678d2 100644 --- a/engines/toon/toon.cpp +++ b/engines/toon/toon.cpp @@ -793,7 +793,9 @@ ToonEngine::ToonEngine(OSystem *syst, const ADGameDescription *gameDescription) _inventoryIcons = NULL; _inventoryIconSlots = NULL; _genericTexts = NULL; - _audioManager = NULL; + _audioManager = NULL; + + memset(&_scriptData, 0, sizeof(EMCData)); switch (_language) { case Common::EN_GRB: @@ -849,6 +851,8 @@ ToonEngine::~ToonEngine() { delete _genericTexts; delete _roomTexts; delete _script_func; + + _script->unload(&_scriptData); delete _script; delete _saveBufferStream; @@ -864,7 +868,9 @@ ToonEngine::~ToonEngine() { delete _inventoryIcons; delete _inventoryIconSlots; //delete _genericTexts; - //delete _audioManager; + delete _audioManager; + + unloadToonDat(); DebugMan.clearAllDebugChannels(); delete _console; @@ -1125,6 +1131,7 @@ void ToonEngine::loadScene(int32 SceneId, bool forGameLoad) { _drew->update(0); _flux->update(0); + _script->unload(&_scriptData); _script->load(temp, &_scriptData, &_script_func->_opcodes); _script->init(&_scriptState[0], &_scriptData); _script->init(&_scriptState[1], &_scriptData); @@ -1252,6 +1259,8 @@ void ToonEngine::initChapter() { while (_script->run(&status)) waitForScriptStep(); + _script->unload(&data); + setupGeneralPalette(); } @@ -4517,14 +4526,20 @@ bool ToonEngine::loadToonDat() { _numVariant = in.readUint16BE(); - _locationDirNotVisited = loadTextsVariante(in); - _locationDirVisited = loadTextsVariante(in); - _specialInfoLine = loadTextsVariante(in); + _locationDirNotVisited = loadTextsVariants(in); + _locationDirVisited = loadTextsVariants(in); + _specialInfoLine = loadTextsVariants(in); return true; } -char **ToonEngine::loadTextsVariante(Common::File &in) { +void ToonEngine::unloadToonDat() { + unloadTextsVariants(_locationDirNotVisited); + unloadTextsVariants(_locationDirVisited); + unloadTextsVariants(_specialInfoLine); +} + +char **ToonEngine::loadTextsVariants(Common::File &in) { int numTexts; int entryLen; int len; @@ -4560,6 +4575,14 @@ char **ToonEngine::loadTextsVariante(Common::File &in) { return res; } +void ToonEngine::unloadTextsVariants(char **texts) { + if (!texts) + return; + + free(*texts - DATAALIGNMENT); + free(texts); +} + void ToonEngine::makeLineNonWalkable(int32 x, int32 y, int32 x2, int32 y2) { _currentMask->drawLineOnMask(x, y, x2, y2, false); } diff --git a/engines/toon/toon.h b/engines/toon/toon.h index 4c1ad21946..920ec080aa 100644 --- a/engines/toon/toon.h +++ b/engines/toon/toon.h @@ -106,7 +106,9 @@ public: bool showMainmenu(bool &loadedGame); void init(); bool loadToonDat(); - char **loadTextsVariante(Common::File &in); + char **loadTextsVariants(Common::File &in); + void unloadTextsVariants(char **texts); + void unloadToonDat(); void setPaletteEntries(uint8 *palette, int32 offset, int32 num); void fixPaletteEntries(uint8 *palette, int num); void flushPalette(); @@ -200,6 +202,8 @@ public: void waitForScriptStep(); void doMagnifierEffect(); + + bool canSaveGameStateCurrently(); bool canLoadGameStateCurrently(); void pauseEngineIntern(bool pause); -- cgit v1.2.3