From a65366edeae0384a33a12aedf408ddb41e24763e Mon Sep 17 00:00:00 2001 From: neuromancer Date: Thu, 18 Feb 2021 21:19:05 -0300 Subject: [PATCH] PRIVATE: fix memory leaks --- engines/private/funcs.cpp | 30 ++++++++++++++++++---------- engines/private/grammar.h | 1 - engines/private/private.cpp | 40 +++++++++++++++++++++++++++---------- engines/private/private.h | 6 ++++-- 4 files changed, 53 insertions(+), 24 deletions(-) diff --git a/engines/private/funcs.cpp b/engines/private/funcs.cpp index 43e14e7232b..17cc9fc32df 100644 --- a/engines/private/funcs.cpp +++ b/engines/private/funcs.cpp @@ -42,7 +42,7 @@ void fChgMode(ArgArray args) { g_private->_mode = args[0].u.val; Common::String *s = new Common::String(args[1].u.str); - g_private->_nextSetting = s; + g_private->setNextSetting(s); if (g_private->_mode == 0) { g_private->setOrigin(kOriginZero); @@ -104,7 +104,7 @@ void fgoto(ArgArray args) { // assert types debugC(1, kPrivateDebugScript, "goto(%s)", args[0].u.str); Common::String *s = new Common::String(args[0].u.str); - g_private->_nextSetting = s; + g_private->setNextSetting(s); } @@ -112,7 +112,7 @@ void fSyncSound(ArgArray args) { // assert types debugC(1, kPrivateDebugScript, "SyncSound(%s, %s)", args[0].u.str, args[1].u.str); Common::String *nextSetting = new Common::String(args[1].u.str); - g_private->_nextSetting = nextSetting; + g_private->setNextSetting(nextSetting); Common::String s(args[0].u.str); if (s != "\"\"") { @@ -135,6 +135,7 @@ void fLoadGame(ArgArray args) { m->nextSetting = NULL; m->flag1 = NULL; m->flag2 = NULL; + free(g_private->_loadGameMask); g_private->_loadGameMask = m; g_private->_masks.push_front(*m); } @@ -149,6 +150,7 @@ void fSaveGame(ArgArray args) { m->nextSetting = NULL; m->flag1 = NULL; m->flag2 = NULL; + free(g_private->_saveGameMask); g_private->_saveGameMask = m; g_private->_masks.push_front(*m); } @@ -171,7 +173,7 @@ void fPoliceBust(ArgArray args) { if (args[1].u.val == 2) { // Unclear what it means } else if (args[1].u.val == 3) { - g_private->_nextSetting = new Common::String(kMainDesktop); + g_private->setNextSetting(new Common::String(kMainDesktop)); g_private->_mode = 0; g_private->setOrigin(kOriginZero); } else @@ -199,8 +201,9 @@ void fBustMovie(ArgArray args) { g_private->playSound(s, 1, false, false); } + delete g_private->_nextMovie; g_private->_nextMovie = new Common::String(pv); - g_private->_nextSetting = new Common::String(args[0].u.str); + g_private->setNextSetting(new Common::String(args[0].u.str)); } void fDossierAdd(ArgArray args) { @@ -452,14 +455,15 @@ void fViewScreen(ArgArray args) { void fTransition(ArgArray args) { // assert types debugC(1, kPrivateDebugScript, "Transition(%s, %s)", args[0].u.str, args[1].u.str); + delete g_private->_nextMovie; g_private->_nextMovie = new Common::String(args[0].u.str); - g_private->_nextSetting = new Common::String(args[1].u.str); + g_private->setNextSetting(new Common::String(args[1].u.str)); } void fResume(ArgArray args) { // assert types debugC(1, kPrivateDebugScript, "Resume(%d)", args[0].u.val); // this value is always 1 - g_private->_nextSetting = g_private->_pausedSetting; + g_private->setNextSetting(g_private->_pausedSetting); g_private->_pausedSetting = NULL; g_private->_mode = 1; g_private->setOrigin(kOriginOne); @@ -472,16 +476,17 @@ void fMovie(ArgArray args) { Common::String *nextSetting = new Common::String(args[1].u.str); if (!g_private->_playedMovies.contains(*movie) && *movie != "\"\"") { + delete g_private->_nextMovie; g_private->_nextMovie = movie; g_private->_playedMovies.setVal(*movie, true); - g_private->_nextSetting = nextSetting; + g_private->setNextSetting(nextSetting); } else if (*movie == "\"\"") { g_private->_repeatedMovieExit = *nextSetting; debugC(1, kPrivateDebugScript, "repeated movie exit is %s", nextSetting->c_str()); } else { debugC(1, kPrivateDebugScript, "movie %s already played", movie->c_str()); - g_private->_nextSetting = &(g_private->_repeatedMovieExit); + g_private->setNextSetting(new Common::String(g_private->_repeatedMovieExit)); } } @@ -626,6 +631,7 @@ void fSoundArea(ArgArray args) { m->nextSetting = NULL; m->flag1 = NULL; m->flag2 = NULL; + free(g_private->_AMRadioArea); g_private->_AMRadioArea = m; g_private->_masks.push_front(*m); } else if (n == "kPoliceRadio") { @@ -636,6 +642,7 @@ void fSoundArea(ArgArray args) { m->nextSetting = NULL; m->flag1 = NULL; m->flag2 = NULL; + free(g_private->_policeRadioArea); g_private->_policeRadioArea = m; g_private->_masks.push_front(*m); } else if (n == "kPhone") { @@ -646,6 +653,7 @@ void fSoundArea(ArgArray args) { m->nextSetting = NULL; m->flag1 = NULL; m->flag2 = NULL; + free(g_private->_phoneArea); g_private->_phoneArea = m; g_private->_masks.push_front(*m); } @@ -659,7 +667,7 @@ void fAskSave(ArgArray args) { // This is not needed, since scummvm will take care of this debugC(1, kPrivateDebugScript, "WARNING: AskSave is partially implemented"); Common::String *s = new Common::String(args[0].u.str); - g_private->_nextSetting = s; + g_private->setNextSetting(s); } void fTimer(ArgArray args) { @@ -675,7 +683,7 @@ void fTimer(ArgArray args) { if (delay > 0) { assert(g_private->installTimer(delay, s)); } else if (delay == 0) { - g_private->_nextSetting = s; + g_private->setNextSetting(s); } else { assert(0); } diff --git a/engines/private/grammar.h b/engines/private/grammar.h index 7dfeb0fc10e..f38f9db65db 100644 --- a/engines/private/grammar.h +++ b/engines/private/grammar.h @@ -75,7 +75,6 @@ typedef struct Setting { // Settings - typedef Common::HashMap SettingMap; class SettingMaps { diff --git a/engines/private/private.cpp b/engines/private/private.cpp index beaad2c4849..2a8fa2df1d8 100644 --- a/engines/private/private.cpp +++ b/engines/private/private.cpp @@ -121,6 +121,13 @@ void PrivateEngine::initializePath(const Common::FSNode &gamePath) { SearchMan.addDirectory(gamePath.getPath(), gamePath, 0, 10); } +void PrivateEngine::setNextSetting(Common::String *_ns) { + if (_ns) + debug("deleting %s", _ns->c_str()); + delete _nextSetting; + _nextSetting = _ns; +} + void PrivateEngine::setOrigin(const int point[2]) { delete _origin; _origin = new Common::Point(point[0], point[1]);; @@ -190,7 +197,7 @@ Common::Error PrivateEngine::run() { if (saveSlot >= 0) { // load the savegame loadGameState(saveSlot); } else { - _nextSetting = new Common::String(kGoIntro); + setNextSetting(new Common::String(kGoIntro)); } while (!shouldQuit()) { @@ -251,12 +258,14 @@ Common::Error PrivateEngine::run() { removeTimer(); _videoDecoder = new Video::SmackerDecoder(); playVideo(*_nextMovie); + delete(_nextMovie); _nextMovie = NULL; continue; } if (_nextVS != NULL && *_currentSetting == kMainDesktop) { loadImage(*_nextVS, 160, 120); + drawScreen(); } if (_videoDecoder) { @@ -276,9 +285,10 @@ Common::Error PrivateEngine::run() { removeTimer(); debugC(1, kPrivateDebugFunction, "Executing %s", _nextSetting->c_str()); clearAreas(); - _currentSetting = _nextSetting; + // This pointer will be free after load + _currentSetting = new Common::String(*_nextSetting); settings.load(_nextSetting); - _nextSetting = NULL; + setNextSetting(NULL); execute(prog); changeCursor("default"); drawScreen(); @@ -293,12 +303,20 @@ Common::Error PrivateEngine::run() { void PrivateEngine::clearAreas() { _exits.clear(); _masks.clear(); + + free(_loadGameMask); _loadGameMask = NULL; + free(_saveGameMask); _saveGameMask = NULL; + free(_policeRadioArea); _policeRadioArea = NULL; + free(_AMRadioArea); _AMRadioArea = NULL; + free(_phoneArea); _phoneArea = NULL; + free(_dossierNextSuspectMask); _dossierNextSuspectMask = NULL; + free(_dossierPrevSuspectMask); _dossierPrevSuspectMask = NULL; } @@ -334,9 +352,9 @@ void PrivateEngine::checkPoliceBust() { uint policeIndex = maps.variables.getVal(kPoliceIndex)->u.val; _policeBustSetting = _currentSetting; if (policeIndex <= 13) { - _nextSetting = new Common::String(kPOGoBustMovie); + setNextSetting(new Common::String(kPOGoBustMovie)); } else { - _nextSetting = new Common::String(kPoliceBustFromMO); + setNextSetting(new Common::String(kPoliceBustFromMO)); } clearAreas(); _policeBustEnabled = false; @@ -421,7 +439,7 @@ void PrivateEngine::selectPauseMovie(Common::Point mousePos) { if (!window.contains(mousePos)) { if ( _pausedSetting == NULL) { _pausedSetting = _currentSetting; - _nextSetting = new Common::String(kPauseMovie); + setNextSetting(new Common::String(kPauseMovie)); } } } @@ -458,7 +476,7 @@ void PrivateEngine::selectExit(Common::Point mousePos) { } if (ns != NULL) { //debug("Exit selected %s", ns->c_str()); - _nextSetting = ns; + setNextSetting(new Common::String(*ns)); } } @@ -492,7 +510,7 @@ void PrivateEngine::selectMask(Common::Point mousePos) { } if (ns != NULL) { //debug("Mask selected %s", ns->c_str()); - _nextSetting = ns; + setNextSetting(new Common::String(*ns)); } } @@ -577,6 +595,7 @@ bool PrivateEngine::selectDossierNextSuspect(Common::Point mousePos) { loadDossier(); drawMask(_dossierNextSuspectMask->surf); drawMask(_dossierPrevSuspectMask->surf); + drawScreen(); } return true; } @@ -594,6 +613,7 @@ bool PrivateEngine::selectDossierPrevSuspect(Common::Point mousePos) { loadDossier(); drawMask(_dossierNextSuspectMask->surf); drawMask(_dossierPrevSuspectMask->surf); + drawScreen(); } return true; } @@ -655,7 +675,7 @@ void PrivateEngine::restartGame() { Common::Error PrivateEngine::loadGameStream(Common::SeekableReadStream *stream) { Common::Serializer s(stream, nullptr); debugC(1, kPrivateDebugFunction, "loadGameStream"); - _nextSetting = new Common::String(kStartGame); + setNextSetting(new Common::String(kStartGame)); int val; for (NameList::iterator it = maps.variableList.begin(); it != maps.variableList.end(); ++it) { @@ -1012,7 +1032,7 @@ char *PrivateEngine::getRandomPhoneClip(const char *clip, int i, int j) { // Timers void timerCallback(void *refCon) { g_private->removeTimer(); - g_private->_nextSetting = (Common::String *)refCon; + g_private->setNextSetting((Common::String *)refCon); } bool PrivateEngine::installTimer(uint32 delay, Common::String *ns) { diff --git a/engines/private/private.h b/engines/private/private.h index 6bb344913a9..7685fba62a6 100644 --- a/engines/private/private.h +++ b/engines/private/private.h @@ -121,7 +121,7 @@ typedef Common::HashMap PlayedMediaTable; class PrivateEngine : public Engine { private: Common::RandomSource *_rnd; - + Common::String *_nextSetting; Graphics::PixelFormat _pixelFormat; Image::ImageDecoder *_image; int _screenW, _screenH; @@ -198,7 +198,9 @@ public: // global state const Common::Point *_origin; void setOrigin(const int[2]); - Common::String *_nextSetting; + + void setNextSetting(Common::String *); + Common::String *_currentSetting; bool _toTake;