[Scummvm-git-logs] scummvm master -> 4b556154520bfc318b23619bb5f6a7b468270a73
neuromancer
noreply at scummvm.org
Sun Nov 2 18:34:31 UTC 2025
This automated email contains information about 14 new commits which have been
pushed to the 'scummvm' repo located at https://api.github.com/repos/scummvm/scummvm .
Summary:
3caaca94f8 PRIVATE: Fix memory leak on cursor change
4b7ec623b6 PRIVATE: Use local InstallShieldV3 objects
6e5dc8d941 PRIVATE: Fix memory leaks when loading Windows cursors
f805443d73 PRIVATE: Fix memory leaks in PrivateEngine
e3bb88f880 PRIVATE: Fix memory leak when decoding a remapped image
dc0079a6b7 PRIVATE: Fix memory leak when loading inventory
dc9faaee98 PRIVATE: Fix memory leak in SettingMaps
14c50f6e9d PRIVATE: Fix leaked Graphics::Surfaces when clearing masks
2268f80337 PRIVATE: Fix memory leak when setting timer
e7ff9e9044 PRIVATE: Fixed memory leak in fCRect
866d676616 PRIVATE: Fix memory leak in parser
28871bbd64 PRIVATE: Fix memory leaks in SymbolMaps and lexer
b3fd1bb2f3 PRIVATE: Fix memory leak when restarting game
4b55615452 PRIVATE: Fix loading cursors in Windows demos
Commit: 3caaca94f877c842bc034fe89969e8f29030e70a
https://github.com/scummvm/scummvm/commit/3caaca94f877c842bc034fe89969e8f29030e70a
Author: sluicebox (22204938+sluicebox at users.noreply.github.com)
Date: 2025-11-02T19:34:22+01:00
Commit Message:
PRIVATE: Fix memory leak on cursor change
Changed paths:
engines/private/cursors.cpp
engines/private/private.cpp
engines/private/private.h
diff --git a/engines/private/cursors.cpp b/engines/private/cursors.cpp
index 973888bd812..3fcefdf0eb7 100644
--- a/engines/private/cursors.cpp
+++ b/engines/private/cursors.cpp
@@ -43,6 +43,8 @@ struct CursorEntry {
};
void PrivateEngine::loadCursors() {
+ _defaultCursor = Graphics::makeDefaultWinCursor();
+
if (_platform == Common::kPlatformWindows) {
const CursorEntry cursorIDReference[] = {
{ "kTurnLeft", "k1", 23 },
@@ -138,7 +140,7 @@ void PrivateEngine::changeCursor(const Common::String &cursor) {
}
if (cursor == "default") {
- CursorMan.replaceCursor(Graphics::makeDefaultWinCursor());
+ CursorMan.replaceCursor(_defaultCursor);
} else {
for (uint i = 0; i < _cursors.size(); i++) {
if (_cursors[i].name == cursor || _cursors[i].aname == cursor) {
diff --git a/engines/private/private.cpp b/engines/private/private.cpp
index 62c3f836683..496e5ff92b6 100644
--- a/engines/private/private.cpp
+++ b/engines/private/private.cpp
@@ -54,6 +54,7 @@ PrivateEngine::PrivateEngine(OSystem *syst, const ADGameDescription *gd)
_compositeSurface(nullptr), _transparentColor(0), _frameImage(nullptr),
_framePalette(nullptr), _maxNumberClicks(0), _sirenWarning(0),
_subtitles(nullptr), _sfxSubtitles(false), _useSubtitles(false),
+ _defaultCursor(nullptr),
_screenW(640), _screenH(480) {
_rnd = new Common::RandomSource("private");
@@ -129,6 +130,7 @@ PrivateEngine::~PrivateEngine() {
delete Gen::g_vm;
delete Settings::g_setts;
+ delete _defaultCursor;
for (uint i = 0; i < _cursors.size(); i++) {
if (_cursors[i].winCursorGroup == nullptr) {
delete _cursors[i].cursor;
diff --git a/engines/private/private.h b/engines/private/private.h
index 81f4e66a8e1..dc52669ad9d 100644
--- a/engines/private/private.h
+++ b/engines/private/private.h
@@ -236,6 +236,7 @@ public:
void drawScreenFrame(const byte *videoPalette);
// Cursors
+ Graphics::Cursor *_defaultCursor;
Common::Array<CursorInfo> _cursors;
Common::String _currentCursor;
void changeCursor(const Common::String &);
Commit: 4b7ec623b65956bcc92a90eda14e8cce2d1184c6
https://github.com/scummvm/scummvm/commit/4b7ec623b65956bcc92a90eda14e8cce2d1184c6
Author: sluicebox (22204938+sluicebox at users.noreply.github.com)
Date: 2025-11-02T19:34:22+01:00
Commit Message:
PRIVATE: Use local InstallShieldV3 objects
Changed paths:
engines/private/cursors.cpp
engines/private/private.cpp
engines/private/private.h
diff --git a/engines/private/cursors.cpp b/engines/private/cursors.cpp
index 3fcefdf0eb7..e6842651678 100644
--- a/engines/private/cursors.cpp
+++ b/engines/private/cursors.cpp
@@ -22,6 +22,8 @@
#include "common/rect.h"
#include "graphics/cursorman.h"
+#include "common/compression/installshieldv3_archive.h"
+
#include "common/formats/winexe_ne.h"
#include "common/formats/winexe_pe.h"
@@ -59,11 +61,12 @@ void PrivateEngine::loadCursors() {
Common::WinResources *exe = nullptr;
Common::ArchiveMemberList members;
- if (_installerArchive.open("SUPPORT/PVTEYE.Z"))
+ Common::InstallShieldV3 installerArchive;
+ if (installerArchive.open("SUPPORT/PVTEYE.Z"))
if (_language == Common::JA_JPN)
- exe = Common::WinResources::createFromEXE(_installerArchive.createReadStreamForMember("PvteyeJ.EXE"));
+ exe = Common::WinResources::createFromEXE(installerArchive.createReadStreamForMember("PvteyeJ.EXE"));
else
- exe = Common::WinResources::createFromEXE(_installerArchive.createReadStreamForMember("PVTEYE.EXE"));
+ exe = Common::WinResources::createFromEXE(installerArchive.createReadStreamForMember("PVTEYE.EXE"));
else {
Common::File file;
if (!file.open("SUPPORT/PVTEYE.EX_")) {
diff --git a/engines/private/private.cpp b/engines/private/private.cpp
index 496e5ff92b6..f4743a084db 100644
--- a/engines/private/private.cpp
+++ b/engines/private/private.cpp
@@ -22,6 +22,7 @@
#include "audio/audiostream.h"
#include "audio/decoders/wave.h"
#include "common/archive.h"
+#include "common/compression/installshieldv3_archive.h"
#include "common/config-manager.h"
#include "common/debug-channels.h"
#include "common/debug.h"
@@ -175,27 +176,28 @@ Common::SeekableReadStream *PrivateEngine::loadAssets() {
return file2;
}
- if (!_installerArchive.open("SUPPORT/ASSETS.Z"))
+ Common::InstallShieldV3 installerArchive;
+ if (!installerArchive.open("SUPPORT/ASSETS.Z"))
error("Failed to open SUPPORT/ASSETS.Z");
// if the full game is used
if (!isDemo()) {
- if (_installerArchive.hasFile("GAME.DAT"))
- return _installerArchive.createReadStreamForMember("GAME.DAT");
- if (_installerArchive.hasFile("GAME.WIN"))
- return _installerArchive.createReadStreamForMember("GAME.WIN");
+ if (installerArchive.hasFile("GAME.DAT"))
+ return installerArchive.createReadStreamForMember("GAME.DAT");
+ if (installerArchive.hasFile("GAME.WIN"))
+ return installerArchive.createReadStreamForMember("GAME.WIN");
error("Unknown version");
return nullptr;
}
// if the demo from archive.org is used
- if (_installerArchive.hasFile("GAME.TXT"))
- return _installerArchive.createReadStreamForMember("GAME.TXT");
+ if (installerArchive.hasFile("GAME.TXT"))
+ return installerArchive.createReadStreamForMember("GAME.TXT");
// if the demo from the full retail CDROM is used
- if (_installerArchive.hasFile("DEMOGAME.DAT"))
- return _installerArchive.createReadStreamForMember("DEMOGAME.DAT");
- if (_installerArchive.hasFile("DEMOGAME.WIN"))
- return _installerArchive.createReadStreamForMember("DEMOGAME.WIN");
+ if (installerArchive.hasFile("DEMOGAME.DAT"))
+ return installerArchive.createReadStreamForMember("DEMOGAME.DAT");
+ if (installerArchive.hasFile("DEMOGAME.WIN"))
+ return installerArchive.createReadStreamForMember("DEMOGAME.WIN");
error("Unknown version");
return nullptr;
diff --git a/engines/private/private.h b/engines/private/private.h
index dc52669ad9d..551471444ea 100644
--- a/engines/private/private.h
+++ b/engines/private/private.h
@@ -22,7 +22,6 @@
#ifndef PRIVATE_H
#define PRIVATE_H
-#include "common/compression/installshieldv3_archive.h"
#include "common/random.h"
#include "common/serializer.h"
#include "engines/engine.h"
@@ -178,7 +177,6 @@ public:
Audio::SoundHandle _bgSoundHandle;
Video::SmackerDecoder *_videoDecoder;
Video::SmackerDecoder *_pausedVideo;
- Common::InstallShieldV3 _installerArchive;
Common::Error run() override;
void restartGame();
Commit: 6e5dc8d941aa5a28524a8de187ee4c7253742145
https://github.com/scummvm/scummvm/commit/6e5dc8d941aa5a28524a8de187ee4c7253742145
Author: sluicebox (22204938+sluicebox at users.noreply.github.com)
Date: 2025-11-02T19:34:22+01:00
Commit Message:
PRIVATE: Fix memory leaks when loading Windows cursors
Changed paths:
engines/private/cursors.cpp
diff --git a/engines/private/cursors.cpp b/engines/private/cursors.cpp
index e6842651678..9e0adfbc89c 100644
--- a/engines/private/cursors.cpp
+++ b/engines/private/cursors.cpp
@@ -60,21 +60,24 @@ void PrivateEngine::loadCursors() {
};
Common::WinResources *exe = nullptr;
+ Common::SeekableReadStream *exeStream = nullptr;
Common::ArchiveMemberList members;
Common::InstallShieldV3 installerArchive;
- if (installerArchive.open("SUPPORT/PVTEYE.Z"))
- if (_language == Common::JA_JPN)
- exe = Common::WinResources::createFromEXE(installerArchive.createReadStreamForMember("PvteyeJ.EXE"));
- else
- exe = Common::WinResources::createFromEXE(installerArchive.createReadStreamForMember("PVTEYE.EXE"));
- else {
- Common::File file;
- if (!file.open("SUPPORT/PVTEYE.EX_")) {
+ if (installerArchive.open("SUPPORT/PVTEYE.Z")) {
+ const char *exeName = (_language == Common::JA_JPN) ? "PvteyeJ.EXE" : "PVTEYE.EXE";
+ exeStream = installerArchive.createReadStreamForMember(exeName);
+ if (exeStream == nullptr) {
+ error("%s not found", exeName);
+ }
+ } else {
+ Common::File *file = new Common::File();
+ if (!file->open("SUPPORT/PVTEYE.EX_")) {
error("PVTEYE.EX_ not found");
}
- exe = Common::WinResources::createFromEXE(file.readStream(file.size()));
+ exeStream = file;
}
+ exe = Common::WinResources::createFromEXE(exeStream);
if (exe == nullptr) {
error("Executable not found");
}
@@ -97,6 +100,9 @@ void PrivateEngine::loadCursors() {
entry++;
}
}
+
+ delete exe;
+ delete exeStream;
} else {
const CursorEntry cursorIDReference[] = {
{ "kTurnLeft", "k1", 133 },
Commit: f805443d7352139706113958216a58ae9d816faa
https://github.com/scummvm/scummvm/commit/f805443d7352139706113958216a58ae9d816faa
Author: sluicebox (22204938+sluicebox at users.noreply.github.com)
Date: 2025-11-02T19:34:22+01:00
Commit Message:
PRIVATE: Fix memory leaks in PrivateEngine
Changed paths:
engines/private/private.cpp
diff --git a/engines/private/private.cpp b/engines/private/private.cpp
index f4743a084db..97e007d9482 100644
--- a/engines/private/private.cpp
+++ b/engines/private/private.cpp
@@ -124,9 +124,24 @@ PrivateEngine::PrivateEngine(OSystem *syst, const ADGameDescription *gd)
}
PrivateEngine::~PrivateEngine() {
- // Dispose your resources here
- delete _frameImage;
+ if (_videoDecoder != _pausedVideo) {
+ delete _pausedVideo;
+ }
+ delete _videoDecoder;
+
+ delete _compositeSurface;
+ if (_frameImage != nullptr) {
+ _frameImage->free();
+ delete _frameImage;
+ }
+ if (_mframeImage != nullptr) {
+ _mframeImage->free();
+ delete _mframeImage;
+ }
+ free(_framePalette);
+
delete _rnd;
+ delete _image;
delete Gen::g_vm;
delete Settings::g_setts;
Commit: e3bb88f880bba3111e4e7af93503a74915dd08b0
https://github.com/scummvm/scummvm/commit/e3bb88f880bba3111e4e7af93503a74915dd08b0
Author: sluicebox (22204938+sluicebox at users.noreply.github.com)
Date: 2025-11-02T19:34:22+01:00
Commit Message:
PRIVATE: Fix memory leak when decoding a remapped image
Changed paths:
engines/private/metaengine.cpp
engines/private/private.cpp
engines/private/private.h
diff --git a/engines/private/metaengine.cpp b/engines/private/metaengine.cpp
index c12475a440c..07276a53dd7 100644
--- a/engines/private/metaengine.cpp
+++ b/engines/private/metaengine.cpp
@@ -67,10 +67,14 @@ Common::Error PrivateMetaEngine::createInstance(OSystem *syst, Engine **engine,
void PrivateMetaEngine::getSavegameThumbnail(Graphics::Surface &thumb) {
byte *palette;
- Graphics::Surface *vs = Private::g_private->decodeImage(Private::g_private->_nextVS, &palette);
+ bool isNewPalette;
+ Graphics::Surface *vs = Private::g_private->decodeImage(Private::g_private->_nextVS, &palette, &isNewPalette);
::createThumbnail(&thumb, (const uint8 *)vs->getPixels(), vs->w, vs->h, palette);
vs->free();
delete vs;
+ if (isNewPalette) {
+ free(palette);
+ }
}
Common::KeymapArray PrivateMetaEngine::initKeymaps(const char *target) const {
diff --git a/engines/private/private.cpp b/engines/private/private.cpp
index 97e007d9482..5712f805734 100644
--- a/engines/private/private.cpp
+++ b/engines/private/private.cpp
@@ -278,18 +278,28 @@ Common::Error PrivateEngine::run() {
// Load the game frame once
byte *palette;
- _frameImage = decodeImage(_framePath, nullptr);
- _mframeImage = decodeImage(_framePath, &palette);
+ bool isNewPalette;
+ _frameImage = decodeImage(_framePath, nullptr, nullptr);
+ _mframeImage = decodeImage(_framePath, &palette, &isNewPalette);
_framePalette = (byte *) malloc(3*256);
memcpy(_framePalette, palette, 3*256);
+ if (isNewPalette) {
+ free(palette);
+ palette = nullptr;
+ }
byte *initialPalette;
- Graphics::Surface *surf = decodeImage("inface/general/inface1.bmp", &initialPalette);
+ bool isNewInitialPalette;
+ Graphics::Surface *surf = decodeImage("inface/general/inface1.bmp", &initialPalette, &isNewInitialPalette);
_compositeSurface->setPalette(initialPalette, 0, 256);
surf->free();
delete surf;
_image->destroy();
+ if (isNewInitialPalette) {
+ free(initialPalette);
+ initialPalette = nullptr;
+ }
// Main event loop
Common::Event event;
@@ -1594,7 +1604,7 @@ void PrivateEngine::stopSound(bool all) {
}
}
-Graphics::Surface *PrivateEngine::decodeImage(const Common::String &name, byte **palette) {
+Graphics::Surface *PrivateEngine::decodeImage(const Common::String &name, byte **palette, bool *isNewPalette) {
debugC(1, kPrivateDebugFunction, "%s(%s)", __FUNCTION__, name.c_str());
Common::Path path = convertPath(name);
Common::ScopedPtr<Common::SeekableReadStream> file(Common::MacResManager::openFileOrDataFork(path));
@@ -1615,13 +1625,26 @@ Graphics::Surface *PrivateEngine::decodeImage(const Common::String &name, byte *
g_system->getPaletteManager()->grabPalette(currentPalette, 0, 256);
newImage = oldImage->convertTo(_pixelFormat, currentPalette);
remapImage(ncolors, oldImage, oldPalette, newImage, currentPalette);
+ if (palette != nullptr) {
+ *palette = currentPalette;
+ if (isNewPalette != nullptr) {
+ *isNewPalette = true;
+ }
+ } else {
+ free(currentPalette);
+ if (isNewPalette != nullptr) {
+ *isNewPalette = false;
+ }
+ }
} else {
currentPalette = const_cast<byte *>(oldPalette);
newImage = oldImage->convertTo(_pixelFormat, currentPalette);
- }
-
- if (palette != nullptr) {
- *palette = currentPalette;
+ if (palette != nullptr) {
+ *palette = currentPalette;
+ }
+ if (isNewPalette != nullptr) {
+ *isNewPalette = false;
+ }
}
return newImage;
@@ -1670,13 +1693,17 @@ void PrivateEngine::remapImage(uint16 ncolors, const Graphics::Surface *oldImage
void PrivateEngine::loadImage(const Common::String &name, int x, int y) {
debugC(1, kPrivateDebugFunction, "%s(%s,%d,%d)", __FUNCTION__, name.c_str(), x, y);
byte *palette;
- Graphics::Surface *surf = decodeImage(name, &palette);
+ bool isNewPalette;
+ Graphics::Surface *surf = decodeImage(name, &palette, &isNewPalette);
_compositeSurface->setPalette(palette, 0, 256);
_compositeSurface->setTransparentColor(_transparentColor);
_compositeSurface->transBlitFrom(*surf, _origin + Common::Point(x, y), _transparentColor);
surf->free();
delete surf;
_image->destroy();
+ if (isNewPalette) {
+ free(palette);
+ }
}
void PrivateEngine::fillRect(uint32 color, Common::Rect rect) {
@@ -1697,7 +1724,8 @@ Graphics::Surface *PrivateEngine::loadMask(const Common::String &name, int x, in
surf->create(_screenW, _screenH, _pixelFormat);
surf->fillRect(_screenRect, _transparentColor);
byte *palette;
- Graphics::Surface *csurf = decodeImage(name, &palette);
+ bool isNewPalette;
+ Graphics::Surface *csurf = decodeImage(name, &palette, &isNewPalette);
uint32 hdiff = 0;
uint32 wdiff = 0;
@@ -1720,6 +1748,10 @@ Graphics::Surface *PrivateEngine::loadMask(const Common::String &name, int x, in
delete csurf;
_image->destroy();
+ if (isNewPalette) {
+ free(palette);
+ }
+
return surf;
}
diff --git a/engines/private/private.h b/engines/private/private.h
index 551471444ea..84f7e01c992 100644
--- a/engines/private/private.h
+++ b/engines/private/private.h
@@ -227,7 +227,7 @@ public:
bool _useSubtitles;
bool _sfxSubtitles;
- Graphics::Surface *decodeImage(const Common::String &file, byte **palette);
+ Graphics::Surface *decodeImage(const Common::String &file, byte **palette, bool *isNewPalette);
//byte *decodePalette(const Common::String &name);
void remapImage(uint16 ncolors, const Graphics::Surface *oldImage, const byte *oldPalette, Graphics::Surface *newImage, const byte *currentPalette);
void loadImage(const Common::String &file, int x, int y);
Commit: dc0079a6b7e9a9bfd461ef6439996cfb46f7af49
https://github.com/scummvm/scummvm/commit/dc0079a6b7e9a9bfd461ef6439996cfb46f7af49
Author: sluicebox (22204938+sluicebox at users.noreply.github.com)
Date: 2025-11-02T19:34:22+01:00
Commit Message:
PRIVATE: Fix memory leak when loading inventory
Changed paths:
engines/private/private.cpp
diff --git a/engines/private/private.cpp b/engines/private/private.cpp
index 5712f805734..911a48ab663 100644
--- a/engines/private/private.cpp
+++ b/engines/private/private.cpp
@@ -1881,6 +1881,7 @@ void PrivateEngine::loadInventory(uint32 x, const Common::Rect &r1, const Common
for (NameList::const_iterator it = inventory.begin(); it != inventory.end(); ++it) {
offset = offset + 22;
Graphics::Surface *surface = loadMask(*it, r1.left, r1.top + offset, true);
+ surface->free();
delete surface;
}
}
Commit: dc9faaee988d3cfbbac0ce3771bc258b24d9d64e
https://github.com/scummvm/scummvm/commit/dc9faaee988d3cfbbac0ce3771bc258b24d9d64e
Author: sluicebox (22204938+sluicebox at users.noreply.github.com)
Date: 2025-11-02T19:34:22+01:00
Commit Message:
PRIVATE: Fix memory leak in SettingMaps
Changed paths:
engines/private/code.cpp
engines/private/grammar.h
diff --git a/engines/private/code.cpp b/engines/private/code.cpp
index 9713d0515e7..a66d787c3bb 100644
--- a/engines/private/code.cpp
+++ b/engines/private/code.cpp
@@ -64,9 +64,20 @@ using namespace Gen;
SettingMaps *g_setts;
+SettingMaps::SettingMaps() :
+ _setting(nullptr) {
+}
+
+SettingMaps::~SettingMaps() {
+ for (uint i = 0; i < _settings.size(); i++) {
+ free(_settings[i]);
+ }
+}
+
/* initialize setting for code generation */
void SettingMaps::init() {
_setting = (Setting *)malloc(sizeof(Setting));
+ _settings.push_back(_setting);
memset((void *)_setting, 0, sizeof(Setting));
g_vm->_prog = (Inst *)&_setting->prog;
diff --git a/engines/private/grammar.h b/engines/private/grammar.h
index 845f038f415..bc0b2d7b8da 100644
--- a/engines/private/grammar.h
+++ b/engines/private/grammar.h
@@ -71,12 +71,18 @@ typedef Common::HashMap<Common::String, Setting *> SettingMap;
class SettingMaps {
public:
+ SettingMaps();
+ ~SettingMaps();
+
Setting *_setting;
SettingMap _map;
void init();
void save(const char *);
void load(const Common::String &);
+
+private:
+ Common::Array<Setting *> _settings;
};
extern SettingMaps *g_setts;
Commit: 14c50f6e9dfa42dd4a340fee29af7dbbf219e43d
https://github.com/scummvm/scummvm/commit/14c50f6e9dfa42dd4a340fee29af7dbbf219e43d
Author: sluicebox (22204938+sluicebox at users.noreply.github.com)
Date: 2025-11-02T19:34:22+01:00
Commit Message:
PRIVATE: Fix leaked Graphics::Surfaces when clearing masks
Changed paths:
engines/private/funcs.cpp
engines/private/private.cpp
diff --git a/engines/private/funcs.cpp b/engines/private/funcs.cpp
index 9e0b1775944..96f2e19f6b2 100644
--- a/engines/private/funcs.cpp
+++ b/engines/private/funcs.cpp
@@ -195,9 +195,6 @@ static void fLoadGame(ArgArray args) {
m.nextSetting = "";
m.flag1 = nullptr;
m.flag2 = nullptr;
- if (g_private->_loadGameMask.surf)
- g_private->_loadGameMask.surf->free();
- delete g_private->_loadGameMask.surf;
g_private->_loadGameMask = m;
g_private->_masks.push_front(m);
}
@@ -211,9 +208,6 @@ static void fSaveGame(ArgArray args) {
m.nextSetting = "";
m.flag1 = nullptr;
m.flag2 = nullptr;
- if (g_private->_saveGameMask.surf)
- g_private->_saveGameMask.surf->free();
- delete g_private->_saveGameMask.surf;
g_private->_saveGameMask = m;
g_private->_masks.push_front(m);
}
@@ -743,9 +737,6 @@ static void fSoundArea(ArgArray args) {
m.nextSetting = "";
m.flag1 = nullptr;
m.flag2 = nullptr;
- if (g_private->_AMRadioArea.surf)
- g_private->_AMRadioArea.surf->free();
- delete g_private->_AMRadioArea.surf;
g_private->_AMRadioArea = m;
g_private->_masks.push_front(m);
} else if (n == "kPoliceRadio") {
@@ -754,9 +745,6 @@ static void fSoundArea(ArgArray args) {
m.nextSetting = "";
m.flag1 = nullptr;
m.flag2 = nullptr;
- if (g_private->_policeRadioArea.surf)
- g_private->_policeRadioArea.surf->free();
- delete g_private->_policeRadioArea.surf;
g_private->_policeRadioArea = m;
g_private->_masks.push_front(m);
} else if (n == "kPhone") {
@@ -765,9 +753,6 @@ static void fSoundArea(ArgArray args) {
m.nextSetting = "";
m.flag1 = nullptr;
m.flag2 = nullptr;
- if (g_private->_phoneArea.surf)
- g_private->_phoneArea.surf->free();
- delete g_private->_phoneArea.surf;
g_private->_phoneArea = m;
g_private->_masks.push_front(m);
} else
diff --git a/engines/private/private.cpp b/engines/private/private.cpp
index 911a48ab663..6d9dc8f019c 100644
--- a/engines/private/private.cpp
+++ b/engines/private/private.cpp
@@ -153,6 +153,14 @@ PrivateEngine::~PrivateEngine() {
}
delete _cursors[i].winCursorGroup;
}
+
+ for (MaskList::const_iterator it = _masks.begin(); it != _masks.end(); ++it) {
+ const MaskInfo &m = *it;
+ if (m.surf != nullptr) {
+ m.surf->free();
+ delete m.surf;
+ }
+ }
}
void PrivateEngine::initializePath(const Common::FSNode &gamePath) {
@@ -478,60 +486,34 @@ void PrivateEngine::initFuncs() {
}
void PrivateEngine::clearAreas() {
+ for (MaskList::const_iterator it = _masks.begin(); it != _masks.end(); ++it) {
+ const MaskInfo &m = *it;
+ if (m.surf != nullptr) {
+ m.surf->free();
+ delete m.surf;
+ }
+ }
+
_exits.clear();
_masks.clear();
_locationMasks.clear();
_memoryMasks.clear();
- if (_loadGameMask.surf)
- _loadGameMask.surf->free();
- delete _loadGameMask.surf;
_loadGameMask.clear();
-
- if (_saveGameMask.surf)
- _saveGameMask.surf->free();
- delete _saveGameMask.surf;
_saveGameMask.clear();
-
- if (_policeRadioArea.surf)
- _policeRadioArea.surf->free();
- delete _policeRadioArea.surf;
_policeRadioArea.clear();
-
- if (_AMRadioArea.surf)
- _AMRadioArea.surf->free();
- delete _AMRadioArea.surf;
_AMRadioArea.clear();
-
- if (_phoneArea.surf)
- _phoneArea.surf->free();
- delete _phoneArea.surf;
_phoneArea.clear();
-
- if (_dossierNextSuspectMask.surf)
- _dossierNextSuspectMask.surf->free();
- delete _dossierNextSuspectMask.surf;
_dossierNextSuspectMask.clear();
-
- if (_dossierPrevSuspectMask.surf)
- _dossierPrevSuspectMask.surf->free();
- delete _dossierPrevSuspectMask.surf;
_dossierPrevSuspectMask.clear();
-
- if (_dossierNextSheetMask.surf)
- _dossierNextSheetMask.surf->free();
- delete _dossierNextSheetMask.surf;
_dossierNextSheetMask.clear();
-
- if (_dossierPrevSheetMask.surf)
- _dossierPrevSheetMask.surf->free();
- delete _dossierPrevSheetMask.surf;
_dossierPrevSheetMask.clear();
for (uint d = 0 ; d < 3; d++) {
- if (_safeDigitArea[d].surf)
+ if (_safeDigitArea[d].surf) {
_safeDigitArea[d].surf->free();
- delete _safeDigitArea[d].surf;
+ delete _safeDigitArea[d].surf;
+ }
_safeDigitArea[d].clear();
_safeDigit[d] = 0;
_safeDigitRect[d] = Common::Rect(0, 0);
@@ -905,9 +887,7 @@ bool PrivateEngine::selectDiaryPrevPage(Common::Point mousePos) {
bool PrivateEngine::selectMemory(const Common::Point &mousePos) {
for (uint i = 0; i < _memoryMasks.size(); i++) {
if (inMask(_memoryMasks[i].surf, mousePos)) {
- _masks.clear();
- _memoryMasks.clear();
- _exits.clear();
+ clearAreas();
_nextMovie = _diaryPages[_currentDiaryPage].memories[i].movie;
_nextSetting = "kDiaryMiddle";
return true;
Commit: 2268f80337f1273a2e1b146c82d007d207fea70d
https://github.com/scummvm/scummvm/commit/2268f80337f1273a2e1b146c82d007d207fea70d
Author: sluicebox (22204938+sluicebox at users.noreply.github.com)
Date: 2025-11-02T19:34:22+01:00
Commit Message:
PRIVATE: Fix memory leak when setting timer
Changed paths:
engines/private/funcs.cpp
engines/private/private.cpp
diff --git a/engines/private/funcs.cpp b/engines/private/funcs.cpp
index 96f2e19f6b2..77574b105d7 100644
--- a/engines/private/funcs.cpp
+++ b/engines/private/funcs.cpp
@@ -781,15 +781,11 @@ static void fTimer(ArgArray args) {
debugC(1, kPrivateDebugScript, "Timer(%d, %s)", args[0].u.val, args[1].u.str);
int32 delay = 1000000 * args[0].u.val;
- // This pointer is necessary since installTimer needs one
- Common::String *s = new Common::String(args[1].u.sym->name->c_str());
if (delay > 0) {
- if (!g_private->installTimer(delay, s))
+ if (!g_private->installTimer(delay, args[1].u.sym->name))
error("Timer installation failed!");
} else if (delay == 0) {
- g_private->_nextSetting = *s;
- // No need to keep the pointer alive
- delete s;
+ g_private->_nextSetting = *(args[1].u.sym->name);
} else {
assert(0);
}
diff --git a/engines/private/private.cpp b/engines/private/private.cpp
index 6d9dc8f019c..ef2e2903f10 100644
--- a/engines/private/private.cpp
+++ b/engines/private/private.cpp
@@ -468,6 +468,7 @@ Common::Error PrivateEngine::run() {
}
}
}
+ removeTimer();
return Common::kNoError;
}
@@ -1824,7 +1825,7 @@ static void timerCallback(void *refCon) {
}
bool PrivateEngine::installTimer(uint32 delay, Common::String *ns) {
- return g_system->getTimerManager()->installTimerProc(&timerCallback, delay, (void *)ns, "timerCallback");
+ return g_system->getTimerManager()->installTimerProc(&timerCallback, delay, ns, "timerCallback");
}
void PrivateEngine::removeTimer() {
Commit: e7ff9e9044077ccfb67ae1bdf6fb8f1a8cdcc002
https://github.com/scummvm/scummvm/commit/e7ff9e9044077ccfb67ae1bdf6fb8f1a8cdcc002
Author: sluicebox (22204938+sluicebox at users.noreply.github.com)
Date: 2025-11-02T19:34:22+01:00
Commit Message:
PRIVATE: Fixed memory leak in fCRect
Changed paths:
engines/private/funcs.cpp
engines/private/private.cpp
engines/private/private.h
diff --git a/engines/private/funcs.cpp b/engines/private/funcs.cpp
index 77574b105d7..d5271c433ea 100644
--- a/engines/private/funcs.cpp
+++ b/engines/private/funcs.cpp
@@ -601,6 +601,7 @@ static void fCRect(ArgArray args) {
d.type = RECT;
d.u.rect = rect;
Gen::push(d);
+ g_private->_rects.push_back(rect);
}
static void fBitmap(ArgArray args) {
diff --git a/engines/private/private.cpp b/engines/private/private.cpp
index ef2e2903f10..5ba621e4e2e 100644
--- a/engines/private/private.cpp
+++ b/engines/private/private.cpp
@@ -161,6 +161,11 @@ PrivateEngine::~PrivateEngine() {
delete m.surf;
}
}
+
+ for (RectList::iterator it = _rects.begin(); it != _rects.end(); ++it) {
+ Common::Rect *r = (*it);
+ delete r;
+ }
}
void PrivateEngine::initializePath(const Common::FSNode &gamePath) {
diff --git a/engines/private/private.h b/engines/private/private.h
index 84f7e01c992..7790651f128 100644
--- a/engines/private/private.h
+++ b/engines/private/private.h
@@ -144,6 +144,7 @@ typedef Common::List<MaskInfo> MaskList;
typedef Common::List<Common::String> SoundList;
typedef Common::List<PhoneInfo> PhoneList;
typedef Common::List<Common::String> InvList;
+typedef Common::List<Common::Rect *> RectList;
// arrays
@@ -382,6 +383,9 @@ public:
// Timers
bool installTimer(uint32, Common::String *);
void removeTimer();
+
+ // VM objects
+ RectList _rects; // created by fCRect
};
extern PrivateEngine *g_private;
Commit: 866d676616725ed6504c2ac1ade10f1ef071e15d
https://github.com/scummvm/scummvm/commit/866d676616725ed6504c2ac1ade10f1ef071e15d
Author: sluicebox (22204938+sluicebox at users.noreply.github.com)
Date: 2025-11-02T19:34:22+01:00
Commit Message:
PRIVATE: Fix memory leak in parser
Changed paths:
engines/private/lexer.cpp
engines/private/lexer.l
diff --git a/engines/private/lexer.cpp b/engines/private/lexer.cpp
index e0e7eb2df39..2012f4e19c1 100644
--- a/engines/private/lexer.cpp
+++ b/engines/private/lexer.cpp
@@ -2197,6 +2197,7 @@ int parse(const char *code) {
yy_switch_to_buffer(bp);
PRIVATE_parse();
yy_delete_buffer(bp);
+ yylex_destroy();
return 0;
}
diff --git a/engines/private/lexer.l b/engines/private/lexer.l
index d56061f0344..c631a738469 100644
--- a/engines/private/lexer.l
+++ b/engines/private/lexer.l
@@ -87,6 +87,7 @@ int parse(const char *code) {
yy_switch_to_buffer(bp);
PRIVATE_parse();
yy_delete_buffer(bp);
+ yylex_destroy();
return 0;
}
Commit: 28871bbd645941fb1f8a7590516ea716ac5693b0
https://github.com/scummvm/scummvm/commit/28871bbd645941fb1f8a7590516ea716ac5693b0
Author: sluicebox (22204938+sluicebox at users.noreply.github.com)
Date: 2025-11-02T19:34:22+01:00
Commit Message:
PRIVATE: Fix memory leaks in SymbolMaps and lexer
Changed paths:
engines/private/lexer.cpp
engines/private/lexer.l
engines/private/symbol.cpp
engines/private/symbol.h
diff --git a/engines/private/lexer.cpp b/engines/private/lexer.cpp
index 2012f4e19c1..279ca26a182 100644
--- a/engines/private/lexer.cpp
+++ b/engines/private/lexer.cpp
@@ -1182,7 +1182,7 @@ return RANDOMTOK;
case 20:
YY_RULE_SETUP
#line 72 "engines/private/lexer.l"
-PRIVATE_lval.s = scumm_strdup(PRIVATE_text); return NAME;
+PRIVATE_lval.s = g_private->maps.string(PRIVATE_text); return NAME;
YY_BREAK
case 21:
YY_RULE_SETUP
@@ -1192,7 +1192,7 @@ PRIVATE_lval.sym = g_private->maps.constant(NUM, atoi(PRIVATE_text), NULL); retu
case 22:
YY_RULE_SETUP
#line 74 "engines/private/lexer.l"
-PRIVATE_lval.sym = g_private->maps.constant(STRING, 0, scumm_strdup(PRIVATE_text)); return STRING;
+PRIVATE_lval.sym = g_private->maps.constant(STRING, 0, PRIVATE_text); return STRING;
YY_BREAK
case 23:
/* rule 23 can match eol */
diff --git a/engines/private/lexer.l b/engines/private/lexer.l
index c631a738469..67783b7cfae 100644
--- a/engines/private/lexer.l
+++ b/engines/private/lexer.l
@@ -69,9 +69,9 @@ FALSE return FALSETOK;
TRUE return TRUETOK;
NULL return NULLTOK;
Random return RANDOMTOK;
-[A-Za-z_][A-Za-z_0-9]* PRIVATE_lval.s = scumm_strdup(PRIVATE_text); return NAME;
+[A-Za-z_][A-Za-z_0-9]* PRIVATE_lval.s = g_private->maps.string(PRIVATE_text); return NAME;
[\-]?[0-9]+ PRIVATE_lval.sym = g_private->maps.constant(NUM, atoi(PRIVATE_text), NULL); return NUM;
-\"[^\"\r\n]*\" PRIVATE_lval.sym = g_private->maps.constant(STRING, 0, scumm_strdup(PRIVATE_text)); return STRING;
+\"[^\"\r\n]*\" PRIVATE_lval.sym = g_private->maps.constant(STRING, 0, PRIVATE_text); return STRING;
[\r|\n]+ /* ignore return */;
[ \t]+ /* ignore whitespace */;
. return *yytext;
diff --git a/engines/private/symbol.cpp b/engines/private/symbol.cpp
index a296b4ac155..d7d8eddf1b9 100644
--- a/engines/private/symbol.cpp
+++ b/engines/private/symbol.cpp
@@ -49,6 +49,17 @@
namespace Private {
+SymbolMaps::~SymbolMaps() {
+ freeSymbolMap(settings);
+ freeSymbolMap(variables);
+ freeSymbolMap(cursors);
+ freeSymbolMap(locations);
+ freeSymbolMap(rects);
+ freeSymbolList(constants);
+ freeSymbolList(names);
+ freeStringMap(strings);
+}
+
void SymbolMaps::defineSymbol(const char *n, Common::Rect *r) {
Common::String s(n);
stringToDefine.push(s);
@@ -91,7 +102,7 @@ static Symbol *install(const Common::String &n, int t, int d, const char *s, Com
sp->u.val = d;
//debug("installing NAME: %s %d", name->c_str(), d);
} else if (t == STRING)
- sp->u.str = scumm_strdup(s); // FIXME: leaks a string here.
+ sp->u.str = scumm_strdup(s);
else if (t == RECT)
sp->u.rect = r;
else
@@ -102,6 +113,19 @@ static Symbol *install(const Common::String &n, int t, int d, const char *s, Com
return sp;
}
+void SymbolMaps::freeSymbolMap(SymbolMap &symbols) {
+ for (SymbolMap::iterator it = symbols.begin(); it != symbols.end(); ++it) {
+ Symbol *s = it->_value;
+ delete s->name;
+ if (s->type == STRING) {
+ free(s->u.str);
+ } else if (s->type == RECT) {
+ delete s->u.rect;
+ }
+ free(s);
+ }
+}
+
/* lookup some name in some symbol table */
Symbol *SymbolMaps::lookupRect(Common::String *n) {
assert(rects.contains(*n));
@@ -118,15 +142,14 @@ Symbol *SymbolMaps::lookupLocation(Common::String *n) {
return lookup(*n, locations);
}
-/* lookup some name in some symbol table */
Symbol *SymbolMaps::lookupName(const char *n) {
-
Symbol *s = (Symbol *)malloc(sizeof(Symbol));
Common::String *name = new Common::String(n);
s->name = name;
s->type = NAME;
s->u.val = 0;
+ names.push_back(s);
return s;
}
@@ -171,7 +194,7 @@ Symbol *SymbolMaps::constant(int t, int d, const char *s) {
if (t == NUM || t == NAME)
sp->u.val = d;
else if (t == STRING)
- sp->u.str = s;
+ sp->u.str = scumm_strdup(s);
else
assert(0);
@@ -179,4 +202,32 @@ Symbol *SymbolMaps::constant(int t, int d, const char *s) {
return sp;
}
+void SymbolMaps::freeSymbolList(SymbolList &symbols) {
+ for (SymbolList::iterator it = symbols.begin(); it != symbols.end(); ++it) {
+ Symbol *s = (*it);
+ delete s->name;
+ if (s->type == STRING) {
+ free(s->u.str);
+ }
+ free(s);
+ }
+}
+
+char *SymbolMaps::string(const char *in) {
+ Common::String str(in);
+ char *out;
+ if (!strings.tryGetVal(in, out)) {
+ out = scumm_strdup(in);
+ strings[str] = out;
+ }
+ return out;
+}
+
+void SymbolMaps::freeStringMap(StringMap &strings) {
+ for (StringMap::iterator it = strings.begin(); it != strings.end(); ++it) {
+ char *s = it->_value;
+ free(s);
+ }
+}
+
} // End of namespace Private
diff --git a/engines/private/symbol.h b/engines/private/symbol.h
index d9f4568a829..b57adc1e5d9 100644
--- a/engines/private/symbol.h
+++ b/engines/private/symbol.h
@@ -37,7 +37,7 @@ typedef struct Symbol { /* symbol table entry */
short type; /* NAME, NUM, STRING or RECT */
union {
int val; /* NAME or NUM */
- const char *str; /* STRING */
+ char *str; /* STRING */
Common::Rect *rect; /* RECT */
} u;
} Symbol;
@@ -48,7 +48,8 @@ void setSymbol(Symbol *, int);
typedef Common::HashMap<Common::String, Symbol *> SymbolMap;
typedef Common::List<Common::String> NameList;
-typedef Common::List<Symbol *> ConstantList;
+typedef Common::List<Symbol *> SymbolList;
+typedef Common::HashMap<Common::String, char *> StringMap;
typedef Common::Queue<Common::String> StringQueue;
typedef Common::Queue<Common::Rect *> RectQueue;
@@ -58,17 +59,26 @@ private:
StringQueue stringToDefine;
RectQueue rectToDefine;
+ static void freeSymbolMap(SymbolMap &symbols);
+ static void freeSymbolList(SymbolList &symbols);
+ static void freeStringMap(StringMap &strings);
public:
SymbolMap settings;
SymbolMap variables;
SymbolMap cursors;
SymbolMap locations;
SymbolMap rects;
- ConstantList constants;
+ SymbolList constants;
+ SymbolList names;
NameList variableList;
NameList locationList;
+ StringMap strings;
+
+ SymbolMaps() { }
+ ~SymbolMaps();
+
Symbol *constant(int t, int d, const char *s);
Symbol *lookupVariable(Common::String *n);
Symbol *lookupLocation(Common::String *n);
@@ -76,6 +86,7 @@ public:
Symbol *lookupName(const char *n);
void installAll(const char *n);
void defineSymbol(const char *, Common::Rect *);
+ char *string(const char *in);
};
} // End of namespace Private
Commit: b3fd1bb2f3851b89b893d5f9e1dc09b5258394ed
https://github.com/scummvm/scummvm/commit/b3fd1bb2f3851b89b893d5f9e1dc09b5258394ed
Author: sluicebox (22204938+sluicebox at users.noreply.github.com)
Date: 2025-11-02T19:34:22+01:00
Commit Message:
PRIVATE: Fix memory leak when restarting game
Pausing a video and then starting a new game leaked the video decoder
Changed paths:
engines/private/private.cpp
diff --git a/engines/private/private.cpp b/engines/private/private.cpp
index 5ba621e4e2e..b4dc6dcc234 100644
--- a/engines/private/private.cpp
+++ b/engines/private/private.cpp
@@ -1216,6 +1216,11 @@ void PrivateEngine::restartGame() {
// Movies
_repeatedMovieExit = "";
_playedMovies.clear();
+ if (_videoDecoder != _pausedVideo) {
+ delete _pausedVideo;
+ }
+ delete _videoDecoder;
+ _videoDecoder = nullptr;
_pausedVideo = nullptr;
// Pause
Commit: 4b556154520bfc318b23619bb5f6a7b468270a73
https://github.com/scummvm/scummvm/commit/4b556154520bfc318b23619bb5f6a7b468270a73
Author: sluicebox (22204938+sluicebox at users.noreply.github.com)
Date: 2025-11-02T19:34:22+01:00
Commit Message:
PRIVATE: Fix loading cursors in Windows demos
Changed paths:
engines/private/cursors.cpp
diff --git a/engines/private/cursors.cpp b/engines/private/cursors.cpp
index 9e0adfbc89c..c2b3d18828f 100644
--- a/engines/private/cursors.cpp
+++ b/engines/private/cursors.cpp
@@ -64,10 +64,16 @@ void PrivateEngine::loadCursors() {
Common::ArchiveMemberList members;
Common::InstallShieldV3 installerArchive;
if (installerArchive.open("SUPPORT/PVTEYE.Z")) {
- const char *exeName = (_language == Common::JA_JPN) ? "PvteyeJ.EXE" : "PVTEYE.EXE";
- exeStream = installerArchive.createReadStreamForMember(exeName);
+ const char *exeNames[] = {
+ "PVTEYE.EXE",
+ "PvteyeJ.EXE", // Japan
+ "PVTDEMO.EXE"
+ };
+ for (uint i = 0; i < ARRAYSIZE(exeNames) && exeStream == nullptr; i++) {
+ exeStream = installerArchive.createReadStreamForMember(exeNames[i]);
+ }
if (exeStream == nullptr) {
- error("%s not found", exeName);
+ error("Executable not found in PVTEYE.Z");
}
} else {
Common::File *file = new Common::File();
More information about the Scummvm-git-logs
mailing list