[Scummvm-git-logs] scummvm master -> 88241a4ec2b003854d257e861372d360c5e2fc9f

dckone noreply at scummvm.org
Mon Mar 2 10:52:43 UTC 2026


This automated email contains information about 11 new commits which have been
pushed to the 'scummvm' repo located at https://api.github.com/repos/scummvm/scummvm .

Summary:
2790da5f03 ALG: add credits
82e34b72d8 ALG: fix issues found in code analysis. PVS-Studio V519, V560, V1048
e62403817a ALG: fix issue from code analysis. PVS-Studio V560
cd68e711ac ALG: fix deference after null. CID 1645437
c3324e2c15 ALG: add missing member initializers
78ef7fe0ec ALG: fix missing initializer. CID 1645426
6c03534a89 ALG: fix uninitialized field. CID 1609013
6932e76eed ALG: fix uninitialized fields in video decoder
207ba6c611 ALG: implemented support for extended saves
76dfec8ce9 ALG: explicitly delete ani arrays after init
88241a4ec2 ALG: added unregisterScriptFunctions for clean-up


Commit: 2790da5f030800e6bbf809f497746e1afacb440c
    https://github.com/scummvm/scummvm/commit/2790da5f030800e6bbf809f497746e1afacb440c
Author: loki (loki at localhost)
Date: 2026-03-02T18:52:34+08:00

Commit Message:
ALG: add credits

Changed paths:
  A engines/alg/credits.pl
    AUTHORS
    doc/docportal/help/credits.rst
    gui/credits.h


diff --git a/AUTHORS b/AUTHORS
index d09edfbbfe5..2942bd98c59 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -98,6 +98,10 @@ ScummVM Team
     Alcachofa:
        Hermann Noll
 
+    ALG:
+       Filippos Karapetis
+       David Kment
+
     Asylum:
        Alex Bevilacqua
        Alex Fontoura
diff --git a/doc/docportal/help/credits.rst b/doc/docportal/help/credits.rst
index 2a051098d05..71a445f9ba1 100644
--- a/doc/docportal/help/credits.rst
+++ b/doc/docportal/help/credits.rst
@@ -223,6 +223,17 @@ Alcachofa
    * - Hermann Noll
      -
 
+ALG
+^^^
+
+.. list-table::
+   :widths: 35 65
+
+   * - Filippos Karapetis
+     -
+   * - David Kment
+     -
+
 Asylum
 ^^^^^^
 
diff --git a/engines/alg/credits.pl b/engines/alg/credits.pl
new file mode 100644
index 00000000000..521189aee81
--- /dev/null
+++ b/engines/alg/credits.pl
@@ -0,0 +1,4 @@
+begin_section("ALG");
+	add_person("Filippos Karapetis", "bluegr", "");
+	add_person("David Kment", "dckone", "");
+end_section();
diff --git a/gui/credits.h b/gui/credits.h
index 69cfe6dcd1a..0b94b684c83 100644
--- a/gui/credits.h
+++ b/gui/credits.h
@@ -141,6 +141,10 @@ static const char *const credits[] = {
 "C1""Alcachofa",
 "C0""Hermann Noll",
 "",
+"C1""ALG",
+"C0""Filippos Karapetis",
+"C0""David Kment",
+"",
 "C1""Asylum",
 "C0""Alex Bevilacqua",
 "C0""Alex Fontoura",


Commit: 82e34b72d8a06223df26796888dc8e16f78ea19c
    https://github.com/scummvm/scummvm/commit/82e34b72d8a06223df26796888dc8e16f78ea19c
Author: loki (loki at localhost)
Date: 2026-03-02T18:52:34+08:00

Commit Message:
ALG: fix issues found in code analysis. PVS-Studio V519, V560, V1048

Changed paths:
    engines/alg/logic/game_drugwars.cpp
    engines/alg/logic/game_johnnyrock.cpp
    engines/alg/scene.cpp


diff --git a/engines/alg/logic/game_drugwars.cpp b/engines/alg/logic/game_drugwars.cpp
index 664f593a886..ce854a7e320 100644
--- a/engines/alg/logic/game_drugwars.cpp
+++ b/engines/alg/logic/game_drugwars.cpp
@@ -1005,7 +1005,6 @@ void GameDrugWars::sceneNxtscnFinishScenario(Scene *scene) {
 			picked = 0x0109;
 		}
 	} else if (_gotTo[13] != 0) {
-		_stage = 13;
 		_stage = 4;
 		picked = 0x017F;
 	} else {
diff --git a/engines/alg/logic/game_johnnyrock.cpp b/engines/alg/logic/game_johnnyrock.cpp
index cc20fcd65ab..2e50b6784a0 100644
--- a/engines/alg/logic/game_johnnyrock.cpp
+++ b/engines/alg/logic/game_johnnyrock.cpp
@@ -429,9 +429,6 @@ bool GameJohnnyRock::fired(Common::Point *point) {
 		_buttonDown = false;
 		return false;
 	}
-	if (_leftDown && !_inMenu) {
-		_leftDown = true;
-	}
 	if (_buttonDown) {
 		if (_thisGameTimer - _machGunTimer > 3) {
 			_buttonDown = false;
diff --git a/engines/alg/scene.cpp b/engines/alg/scene.cpp
index ce7f44b9f19..58187bf07e6 100644
--- a/engines/alg/scene.cpp
+++ b/engines/alg/scene.cpp
@@ -362,7 +362,6 @@ Scene::Scene(const Common::String &name, uint32 startFrame, uint32 endFrame) {
 	_nxtfrm = "DEFAULT";
 	_nxtscn = "DEFAULT";
 	_missedRects = "DEFAULT";
-	_missedRects = "DEFAULT";
 	_scnscrParam = 0;
 	_dataParam1 = 0;
 	_dataParam2 = 0;


Commit: e62403817aa86baaa2d3af999328a2b7d72b15c4
    https://github.com/scummvm/scummvm/commit/e62403817aa86baaa2d3af999328a2b7d72b15c4
Author: loki (loki at localhost)
Date: 2026-03-02T18:52:34+08:00

Commit Message:
ALG: fix issue from code analysis. PVS-Studio V560

Changed paths:
    engines/alg/logic/game_spacepirates.cpp


diff --git a/engines/alg/logic/game_spacepirates.cpp b/engines/alg/logic/game_spacepirates.cpp
index 329c4c7885e..6ae88880887 100644
--- a/engines/alg/logic/game_spacepirates.cpp
+++ b/engines/alg/logic/game_spacepirates.cpp
@@ -864,14 +864,15 @@ uint16 GameSpacePirates::sceneToNumber(Common::String sceneName) {
 uint16 GameSpacePirates::randomUnusedScene(uint8 max) {
 	bool found = false;
 	uint8 randomNum = 0;
-	for (int i = 0; i < max && !found; i++) {
+	for (int i = 0; i < max; i++) {
 		randomNum = _rnd->getRandomNumber(max - 1);
 		if (_randomScenesUsed[randomNum] == 0) {
 			found = true;
+			break;
 		}
 	}
 	if (!found) {
-		for (int i = 0; i < max && !found; i++) {
+		for (int i = 0; i < max; i++) {
 			if (_randomScenesUsed[i] == 0) {
 				found = true;
 				randomNum = i;


Commit: cd68e711ac95ec7726cb2bdbb3bc337c02e2c5f0
    https://github.com/scummvm/scummvm/commit/cd68e711ac95ec7726cb2bdbb3bc337c02e2c5f0
Author: loki (loki at localhost)
Date: 2026-03-02T18:52:34+08:00

Commit Message:
ALG: fix deference after null. CID 1645437

Changed paths:
    engines/alg/scene.cpp


diff --git a/engines/alg/scene.cpp b/engines/alg/scene.cpp
index 58187bf07e6..b7e662fed46 100644
--- a/engines/alg/scene.cpp
+++ b/engines/alg/scene.cpp
@@ -254,13 +254,13 @@ void SceneInfo::addZonesToScenes() {
 					zone = zone->clone();
 					zone->_difficulty = 0;
 					scene->_zones.push_back(zone);
-				}
-				if (zone->_next.empty()) {
-					break;
-				} else {
-					zone = findZone(zone->_next);
-					if (zone == nullptr) {
+					if (zone->_next.empty()) {
 						break;
+					} else {
+						zone = findZone(zone->_next);
+						if (zone == nullptr) {
+							break;
+						}
 					}
 				}
 			}
@@ -272,13 +272,13 @@ void SceneInfo::addZonesToScenes() {
 					zone = zone->clone();
 					zone->_difficulty = 1;
 					scene->_zones.push_back(zone);
-				}
-				if (zone->_next.empty()) {
-					break;
-				} else {
-					zone = findZone(zone->_next);
-					if (zone == nullptr) {
+					if (zone->_next.empty()) {
 						break;
+					} else {
+						zone = findZone(zone->_next);
+						if (zone == nullptr) {
+							break;
+						}
 					}
 				}
 			}
@@ -290,13 +290,13 @@ void SceneInfo::addZonesToScenes() {
 					zone = zone->clone();
 					zone->_difficulty = 2;
 					scene->_zones.push_back(zone);
-				}
-				if (zone->_next.empty()) {
-					break;
-				} else {
-					zone = findZone(zone->_next);
-					if (zone == nullptr) {
+					if (zone->_next.empty()) {
 						break;
+					} else {
+						zone = findZone(zone->_next);
+						if (zone == nullptr) {
+							break;
+						}
 					}
 				}
 			}


Commit: c3324e2c15ac3da9e56d7dbcd6d466402ffd6e59
    https://github.com/scummvm/scummvm/commit/c3324e2c15ac3da9e56d7dbcd6d466402ffd6e59
Author: loki (loki at localhost)
Date: 2026-03-02T18:52:34+08:00

Commit Message:
ALG: add missing member initializers

Changed paths:
    engines/alg/logic/game_bountyhunter.h
    engines/alg/logic/game_crimepatrol.h
    engines/alg/logic/game_drugwars.h
    engines/alg/logic/game_johnnyrock.h
    engines/alg/logic/game_maddog.h
    engines/alg/logic/game_maddog2.h
    engines/alg/logic/game_spacepirates.h


diff --git a/engines/alg/logic/game_bountyhunter.h b/engines/alg/logic/game_bountyhunter.h
index eb962a1e376..7946b37ae7d 100644
--- a/engines/alg/logic/game_bountyhunter.h
+++ b/engines/alg/logic/game_bountyhunter.h
@@ -76,21 +76,21 @@ private:
 	BHScriptFunctionSceneMap _sceneNxtScn;
 
 	// images
-	Graphics::Surface *_shotIcon;
-	Graphics::Surface *_emptyIcon;
-	Graphics::Surface *_shellIcon;
-	Graphics::Surface *_liveIcon;
-	Graphics::Surface *_deadIcon;
-	Graphics::Surface *_playersIcon1;
-	Graphics::Surface *_playersIcon2;
-	Graphics::Surface *_textScoreIcon;
-	Graphics::Surface *_textMenuIcon;
-	Graphics::Surface *_textBlackBarIcon;
-	Common::Array<Graphics::Surface *> *_gun;
-	Common::Array<Graphics::Surface *> *_numbers;
-	Common::Array<Graphics::Surface *> *_bagsIcons;
-	Common::Array<Graphics::Surface *> *_bulletHoleIcon;
-	Common::Array<Graphics::Surface *> *_shotgunHoleIcon;
+	Graphics::Surface *_shotIcon = nullptr;
+	Graphics::Surface *_emptyIcon = nullptr;
+	Graphics::Surface *_shellIcon = nullptr;
+	Graphics::Surface *_liveIcon = nullptr;
+	Graphics::Surface *_deadIcon = nullptr;
+	Graphics::Surface *_playersIcon1 = nullptr;
+	Graphics::Surface *_playersIcon2 = nullptr;
+	Graphics::Surface *_textScoreIcon = nullptr;
+	Graphics::Surface *_textMenuIcon = nullptr;
+	Graphics::Surface *_textBlackBarIcon = nullptr;
+	Common::Array<Graphics::Surface *> *_gun = nullptr;
+	Common::Array<Graphics::Surface *> *_numbers = nullptr;
+	Common::Array<Graphics::Surface *> *_bagsIcons = nullptr;
+	Common::Array<Graphics::Surface *> *_bulletHoleIcon = nullptr;
+	Common::Array<Graphics::Surface *> *_shotgunHoleIcon = nullptr;
 
 	// sounds
 	Audio::SeekableAudioStream *_saveSound = nullptr;
diff --git a/engines/alg/logic/game_crimepatrol.h b/engines/alg/logic/game_crimepatrol.h
index 619aa2c6280..7f45e5ca1be 100644
--- a/engines/alg/logic/game_crimepatrol.h
+++ b/engines/alg/logic/game_crimepatrol.h
@@ -74,14 +74,14 @@ private:
 	CPScriptFunctionSceneMap _sceneNxtScn;
 
 	// images
-	Graphics::Surface *_shotIcon;
-	Graphics::Surface *_emptyIcon;
-	Graphics::Surface *_liveIcon;
-	Graphics::Surface *_deadIcon;
-	Graphics::Surface *_difficultyIcon;
-	Graphics::Surface *_bulletholeIcon;
-	Common::Array<Graphics::Surface *> *_gun;
-	Common::Array<Graphics::Surface *> *_numbers;
+	Graphics::Surface *_shotIcon = nullptr;
+	Graphics::Surface *_emptyIcon = nullptr;
+	Graphics::Surface *_liveIcon = nullptr;
+	Graphics::Surface *_deadIcon = nullptr;
+	Graphics::Surface *_difficultyIcon = nullptr;
+	Graphics::Surface *_bulletholeIcon = nullptr;
+	Common::Array<Graphics::Surface *> *_gun = nullptr;
+	Common::Array<Graphics::Surface *> *_numbers = nullptr;
 
 	// sounds
 	Audio::SeekableAudioStream *_saveSound = nullptr;
diff --git a/engines/alg/logic/game_drugwars.h b/engines/alg/logic/game_drugwars.h
index 43a077a2244..30a9d983d03 100644
--- a/engines/alg/logic/game_drugwars.h
+++ b/engines/alg/logic/game_drugwars.h
@@ -74,14 +74,14 @@ private:
 	DWScriptFunctionSceneMap _sceneNxtScn;
 
 	// images
-	Graphics::Surface *_shotIcon;
-	Graphics::Surface *_emptyIcon;
-	Graphics::Surface *_liveIcon;
-	Graphics::Surface *_deadIcon;
-	Graphics::Surface *_difficultyIcon;
-	Graphics::Surface *_bulletholeIcon;
-	Common::Array<Graphics::Surface *> *_gun;
-	Common::Array<Graphics::Surface *> *_numbers;
+	Graphics::Surface *_shotIcon = nullptr;
+	Graphics::Surface *_emptyIcon = nullptr;
+	Graphics::Surface *_liveIcon = nullptr;
+	Graphics::Surface *_deadIcon = nullptr;
+	Graphics::Surface *_difficultyIcon = nullptr;
+	Graphics::Surface *_bulletholeIcon = nullptr;
+	Common::Array<Graphics::Surface *> *_gun = nullptr;
+	Common::Array<Graphics::Surface *> *_numbers = nullptr;
 
 	// sounds
 	Audio::SeekableAudioStream *_saveSound = nullptr;
diff --git a/engines/alg/logic/game_johnnyrock.h b/engines/alg/logic/game_johnnyrock.h
index c9e66b7c336..628f5e1c7be 100644
--- a/engines/alg/logic/game_johnnyrock.h
+++ b/engines/alg/logic/game_johnnyrock.h
@@ -80,11 +80,11 @@ private:
 	JRScriptFunctionSceneMap _sceneNxtScn;
 
 	// images
-	Common::Array<Graphics::Surface *> *_difficultyIcon;
-	Graphics::Surface *_levelIcon;
-	Graphics::Surface *_bulletholeIcon;
-	Common::Array<Graphics::Surface *> *_gun;
-	Common::Array<Graphics::Surface *> *_numbers;
+	Graphics::Surface *_levelIcon = nullptr;
+	Graphics::Surface *_bulletholeIcon = nullptr;
+	Common::Array<Graphics::Surface *> *_difficultyIcon = nullptr;
+	Common::Array<Graphics::Surface *> *_gun = nullptr;
+	Common::Array<Graphics::Surface *> *_numbers = nullptr;
 
 	// sounds
 	Audio::SeekableAudioStream *_saveSound = nullptr;
diff --git a/engines/alg/logic/game_maddog.h b/engines/alg/logic/game_maddog.h
index 7d0751726b9..c3364835788 100644
--- a/engines/alg/logic/game_maddog.h
+++ b/engines/alg/logic/game_maddog.h
@@ -80,16 +80,16 @@ private:
 	MDScriptFunctionSceneMap _sceneNxtScn;
 
 	// images
-	Graphics::Surface *_shotIcon;
-	Graphics::Surface *_emptyIcon;
-	Graphics::Surface *_liveIcon;
-	Graphics::Surface *_deadIcon;
-	Graphics::Surface *_reloadIcon;
-	Graphics::Surface *_drawIcon;
-	Graphics::Surface *_knifeIcon;
-	Graphics::Surface *_bulletholeIcon;
-	Common::Array<Graphics::Surface *> *_gun;
-	Common::Array<Graphics::Surface *> *_numbers;
+	Graphics::Surface *_shotIcon = nullptr;
+	Graphics::Surface *_emptyIcon = nullptr;
+	Graphics::Surface *_liveIcon = nullptr;
+	Graphics::Surface *_deadIcon = nullptr;
+	Graphics::Surface *_reloadIcon = nullptr;
+	Graphics::Surface *_drawIcon = nullptr;
+	Graphics::Surface *_knifeIcon = nullptr;
+	Graphics::Surface *_bulletholeIcon = nullptr;
+	Common::Array<Graphics::Surface *> *_gun = nullptr;
+	Common::Array<Graphics::Surface *> *_numbers = nullptr;
 
 	// sounds
 	Audio::SeekableAudioStream *_saveSound = nullptr;
diff --git a/engines/alg/logic/game_maddog2.h b/engines/alg/logic/game_maddog2.h
index b0f575b55fd..68d6651edeb 100644
--- a/engines/alg/logic/game_maddog2.h
+++ b/engines/alg/logic/game_maddog2.h
@@ -80,16 +80,16 @@ private:
 	MD2ScriptFunctionSceneMap _sceneNxtScn;
 
 	// images
-	Graphics::Surface *_shotIcon;
-	Graphics::Surface *_emptyIcon;
-	Graphics::Surface *_liveIcon;
-	Graphics::Surface *_deadIcon;
-	Graphics::Surface *_reloadIcon;
-	Graphics::Surface *_drawIcon;
-	Graphics::Surface *_knifeIcon;
-	Graphics::Surface *_bulletholeIcon;
-	Common::Array<Graphics::Surface *> *_gun;
-	Common::Array<Graphics::Surface *> *_numbers;
+	Graphics::Surface *_shotIcon = nullptr;
+	Graphics::Surface *_emptyIcon = nullptr;
+	Graphics::Surface *_liveIcon = nullptr;
+	Graphics::Surface *_deadIcon = nullptr;
+	Graphics::Surface *_reloadIcon = nullptr;
+	Graphics::Surface *_drawIcon = nullptr;
+	Graphics::Surface *_knifeIcon = nullptr;
+	Graphics::Surface *_bulletholeIcon = nullptr;
+	Common::Array<Graphics::Surface *> *_gun = nullptr;
+	Common::Array<Graphics::Surface *> *_numbers = nullptr;
 
 	// sounds
 	Audio::SeekableAudioStream *_saveSound = nullptr;
diff --git a/engines/alg/logic/game_spacepirates.h b/engines/alg/logic/game_spacepirates.h
index 3faed264848..3584182b740 100644
--- a/engines/alg/logic/game_spacepirates.h
+++ b/engines/alg/logic/game_spacepirates.h
@@ -77,16 +77,16 @@ private:
 	SPScriptFunctionSceneMap _sceneMissedRects;
 
 	// images
-	Graphics::Surface *_shotIcon;
-	Graphics::Surface *_emptyIcon;
-	Graphics::Surface *_deadIcon;
-	Graphics::Surface *_liveIcon1;
-	Graphics::Surface *_liveIcon2;
-	Graphics::Surface *_liveIcon3;
-	Graphics::Surface *_difficultyIcon;
-	Graphics::Surface *_bulletholeIcon;
-	Common::Array<Graphics::Surface *> *_gun;
-	Common::Array<Graphics::Surface *> *_numbers;
+	Graphics::Surface *_shotIcon = nullptr;
+	Graphics::Surface *_emptyIcon = nullptr;
+	Graphics::Surface *_deadIcon = nullptr;
+	Graphics::Surface *_liveIcon1 = nullptr;
+	Graphics::Surface *_liveIcon2 = nullptr;
+	Graphics::Surface *_liveIcon3 = nullptr;
+	Graphics::Surface *_difficultyIcon = nullptr;
+	Graphics::Surface *_bulletholeIcon = nullptr;
+	Common::Array<Graphics::Surface *> *_gun = nullptr;
+	Common::Array<Graphics::Surface *> *_numbers = nullptr;
 
 	// sounds
 	Audio::SeekableAudioStream *_saveSound = nullptr;


Commit: 78ef7fe0ec7b31b72df001d9326e4545a5ba8321
    https://github.com/scummvm/scummvm/commit/78ef7fe0ec7b31b72df001d9326e4545a5ba8321
Author: loki (loki at localhost)
Date: 2026-03-02T18:52:34+08:00

Commit Message:
ALG: fix missing initializer. CID 1645426

Changed paths:
    engines/alg/scene.h


diff --git a/engines/alg/scene.h b/engines/alg/scene.h
index 85a7320a7e9..522dcef0acc 100644
--- a/engines/alg/scene.h
+++ b/engines/alg/scene.h
@@ -93,7 +93,7 @@ public:
 	Common::String _ptrfb;
 	Common::Array<Rect *> _rects;
 	Common::String _next;
-	uint8 _difficulty;
+	uint8 _difficulty = 0;
 	void addRect(int16 left, int16 top, int16 right, int16 bottom, const Common::String scene, uint32 score, const Common::String rectHit, const Common::String unknown);
 	Zone *clone();
 };


Commit: 6c03534a895546b0a45c7fdbf3b8ca46b648f7e0
    https://github.com/scummvm/scummvm/commit/6c03534a895546b0a45c7fdbf3b8ca46b648f7e0
Author: loki (loki at localhost)
Date: 2026-03-02T18:52:34+08:00

Commit Message:
ALG: fix uninitialized field. CID 1609013

Changed paths:
    engines/alg/logic/game_maddog.h
    engines/alg/logic/game_maddog2.h


diff --git a/engines/alg/logic/game_maddog.h b/engines/alg/logic/game_maddog.h
index c3364835788..c5149d5efa4 100644
--- a/engines/alg/logic/game_maddog.h
+++ b/engines/alg/logic/game_maddog.h
@@ -126,8 +126,8 @@ private:
 	uint8 _oldShots = 0;
 	uint8 _whichGun = 0;
 	uint8 _oldWhichGun = 0xFF;
-	long int _minF;
-	long int _maxF;
+	long int _minF = 0;
+	long int _maxF = 0;
 
 	uint8 _badMen = 0;
 	uint8 _badMenBits = 0;
diff --git a/engines/alg/logic/game_maddog2.h b/engines/alg/logic/game_maddog2.h
index 68d6651edeb..75ff638769b 100644
--- a/engines/alg/logic/game_maddog2.h
+++ b/engines/alg/logic/game_maddog2.h
@@ -133,8 +133,8 @@ private:
 	uint8 _oldShots = 0;
 	uint8 _whichGun = 0;
 	uint8 _oldWhichGun = 0xFF;
-	long int _minF;
-	long int _maxF;
+	long int _minF = 0;
+	long int _maxF = 0;
 
 	uint16 _dieBits = 0;
 	uint16 _gotTo = 0;


Commit: 6932e76eed57929dbf1f39c24c6e8b2eef49aebb
    https://github.com/scummvm/scummvm/commit/6932e76eed57929dbf1f39c24c6e8b2eef49aebb
Author: loki (loki at localhost)
Date: 2026-03-02T18:52:34+08:00

Commit Message:
ALG: fix uninitialized fields in video decoder

Changed paths:
    engines/alg/video.h


diff --git a/engines/alg/video.h b/engines/alg/video.h
index 67b5b9696d7..f3cfef86d36 100644
--- a/engines/alg/video.h
+++ b/engines/alg/video.h
@@ -47,18 +47,17 @@ public:
 	uint32 getCurrentFrame() const { return _currentFrame; }
 
 private:
-	Common::File *_input;
-	Graphics::Surface *_frame;
-	Audio::PacketizedAudioStream *_audioStream;
+	Common::File *_input = nullptr;
+	Graphics::Surface *_frame = nullptr;
+	Audio::PacketizedAudioStream *_audioStream = nullptr;
 	Audio::SoundHandle _audioHandle;
-	uint8 *_palette;
-	bool _paletteDirty;
-	bool _gotVideoFrame;
-	uint32 _currentFrame;
-	uint32 _size;
-	uint32 _bytesLeft;
-	uint16 _currentChunk;
-
+	uint8 *_palette = nullptr;
+	bool _paletteDirty = false;
+	bool _gotVideoFrame = false;
+	uint32 _currentFrame = 0;
+	uint32 _size = 0;
+	uint32 _bytesLeft = 0;
+	uint16 _currentChunk = 0;
 	uint16 _numChunks = 0;
 	uint16 _frameRate = 0;
 	uint16 _videoMode = 0;


Commit: 207ba6c611645047ad98ae77dfc275afafcf631a
    https://github.com/scummvm/scummvm/commit/207ba6c611645047ad98ae77dfc275afafcf631a
Author: loki (loki at localhost)
Date: 2026-03-02T18:52:34+08:00

Commit Message:
ALG: implemented support for extended saves

Changed paths:
    engines/alg/alg.cpp
    engines/alg/alg.h
    engines/alg/game.h
    engines/alg/logic/game_bountyhunter.cpp
    engines/alg/logic/game_bountyhunter.h
    engines/alg/logic/game_crimepatrol.cpp
    engines/alg/logic/game_crimepatrol.h
    engines/alg/logic/game_drugwars.cpp
    engines/alg/logic/game_drugwars.h
    engines/alg/logic/game_johnnyrock.cpp
    engines/alg/logic/game_johnnyrock.h
    engines/alg/logic/game_maddog.cpp
    engines/alg/logic/game_maddog.h
    engines/alg/logic/game_maddog2.cpp
    engines/alg/logic/game_maddog2.h
    engines/alg/logic/game_spacepirates.cpp
    engines/alg/logic/game_spacepirates.h
    engines/alg/metaengine.cpp


diff --git a/engines/alg/alg.cpp b/engines/alg/alg.cpp
index d1dc7ec046c..399e873e991 100644
--- a/engines/alg/alg.cpp
+++ b/engines/alg/alg.cpp
@@ -20,6 +20,7 @@
  */
 
 #include "common/config-manager.h"
+#include "common/savefile.h"
 #include "engines/util.h"
 
 #include "alg/alg.h"
@@ -96,9 +97,41 @@ Common::Error AlgEngine::run() {
 	return _game->run();
 }
 
+Common::Error AlgEngine::loadGameState(int slot) {
+	Common::InSaveFile *inSaveFile = _saveFileMan->openForLoading(getSaveStateName(0));
+
+	Common::Error result = _game->loadState(inSaveFile) ? Common::kNoError : Common::kReadingFailed;
+
+	delete inSaveFile;
+	return result;
+}
+
+bool AlgEngine::canLoadGameStateCurrently(Common::U32String *msg) {
+	return true;
+}
+
+Common::Error AlgEngine::saveGameState(int slot, const Common::String &desc, bool isAutosave) {
+	Common::OutSaveFile *outSaveFile = _saveFileMan->openForSaving(getSaveStateName(0));
+
+	if (!outSaveFile) {
+		return Common::kWritingFailed;
+	}
+
+	Common::Error result = _game->saveState(outSaveFile) ? Common::kNoError : Common::kWritingFailed;
+	if (result.getCode() == Common::kNoError) {
+		getMetaEngine()->appendExtendedSave(outSaveFile, getTotalPlayTime(), desc, isAutosave);
+	}
+
+	delete outSaveFile;
+	return result;
+}
+
+bool AlgEngine::canSaveGameStateCurrently(Common::U32String *msg) {
+	return true;
+}
+
 bool AlgEngine::hasFeature(EngineFeature f) const {
-	return (f == kSupportsReturnToLauncher) ||
-		   (f == kSupportsLoadingDuringRuntime) ||
+	return (f == kSupportsLoadingDuringRuntime) ||
 		   (f == kSupportsSavingDuringRuntime);
 }
 
diff --git a/engines/alg/alg.h b/engines/alg/alg.h
index b9055954446..b2967943cfb 100644
--- a/engines/alg/alg.h
+++ b/engines/alg/alg.h
@@ -47,11 +47,15 @@ class AlgEngine : public Engine {
 public:
 	AlgEngine(OSystem *syst, const AlgGameDescription *desc);
 	~AlgEngine();
-	Common::Error run();
-	bool hasFeature(EngineFeature f) const;
+	Common::Error run() override;
+	bool hasFeature(EngineFeature f) const override;
 	Common::Platform getPlatform() const;
 	bool isDemo() const;
 	bool useSingleSpeedVideos() const { return _useSingleSpeedVideos; };
+	Common::Error loadGameState(int slot) override;
+	bool canLoadGameStateCurrently(Common::U32String *msg = nullptr) override;
+	Common::Error saveGameState(int slot, const Common::String &desc, bool isAutosave = false) override;
+	bool canSaveGameStateCurrently(Common::U32String *msg = nullptr) override;
 
 private:
 	const AlgGameDescription *_gameDescription;
diff --git a/engines/alg/game.h b/engines/alg/game.h
index 1069d314445..9c703524ff1 100644
--- a/engines/alg/game.h
+++ b/engines/alg/game.h
@@ -40,6 +40,8 @@ public:
 	virtual ~Game();
 	virtual void init();
 	virtual Common::Error run();
+	virtual bool saveState(Common::OutSaveFile *outSaveFile) = 0;
+	virtual bool loadState(Common::InSaveFile *inSaveFile) = 0;
 	bool debug_dumpLibFile();
 	bool _debug_drawRects = false;
 	bool _debug_godMode = false;
diff --git a/engines/alg/logic/game_bountyhunter.cpp b/engines/alg/logic/game_bountyhunter.cpp
index 65a01d01f49..ec18f820afb 100644
--- a/engines/alg/logic/game_bountyhunter.cpp
+++ b/engines/alg/logic/game_bountyhunter.cpp
@@ -692,13 +692,7 @@ bool GameBountyHunter::weaponDown() {
 	return false;
 }
 
-bool GameBountyHunter::saveState() {
-	Common::OutSaveFile *outSaveFile;
-	Common::String saveFileName = _vm->getSaveStateName(0);
-	if (!(outSaveFile = g_system->getSavefileManager()->openForSaving(saveFileName))) {
-		warning("GameBountyHunter::saveState(): Can't create file '%s', game not saved", saveFileName.c_str());
-		return false;
-	}
+bool GameBountyHunter::saveState(Common::OutSaveFile *outSaveFile) {
 	outSaveFile->writeUint32BE(MKTAG('A', 'L', 'G', 'S')); // header
 	outSaveFile->writeByte(0);                             // version, unused for now
 	outSaveFile->writeByte(_currentLevel);
@@ -712,19 +706,11 @@ bool GameBountyHunter::saveState() {
 	}
 	outSaveFile->writeByte(_difficulty);
 	outSaveFile->writeByte(_numPlayers);
-	outSaveFile->finalize();
 	_restartScene = 0;
-	delete outSaveFile;
 	return true;
 }
 
-bool GameBountyHunter::loadState() {
-	Common::InSaveFile *inSaveFile;
-	Common::String saveFileName = _vm->getSaveStateName(0);
-	if (!(inSaveFile = g_system->getSavefileManager()->openForLoading(saveFileName))) {
-		debug("GameBountyHunter::loadState(): Can't load file '%s', game not loaded", saveFileName.c_str());
-		return false;
-	}
+bool GameBountyHunter::loadState(Common::InSaveFile *inSaveFile) {
 	uint32 header = inSaveFile->readUint32BE();
 	if (header != MKTAG('A', 'L', 'G', 'S')) {
 		warning("GameBountyHunter::loadState(): Unkown save file, header: %s", tag2str(header));
@@ -743,7 +729,6 @@ bool GameBountyHunter::loadState() {
 	_difficulty = inSaveFile->readByte();
 	_numPlayers = inSaveFile->readByte();
 	assert(_numPlayers <= 2);
-	delete inSaveFile;
 	return true;
 }
 
@@ -1054,15 +1039,14 @@ void GameBountyHunter::rectShotMenu(Rect *rect) {
 }
 
 void GameBountyHunter::rectSave(Rect *rect) {
-	if (saveState()) {
+	if (_vm->saveGameState(0, "").getCode() == Common::kNoError) {
 		playSound(_saveSound);
 	}
 }
 
 void GameBountyHunter::rectLoad(Rect *rect) {
-	if (loadState()) {
+	if (_vm->loadGameState(0).getCode() == Common::kNoError) {
 		playSound(_loadSound);
-		_restartScene = 0;
 	}
 }
 
diff --git a/engines/alg/logic/game_bountyhunter.h b/engines/alg/logic/game_bountyhunter.h
index 7946b37ae7d..37d9eac47cd 100644
--- a/engines/alg/logic/game_bountyhunter.h
+++ b/engines/alg/logic/game_bountyhunter.h
@@ -205,8 +205,8 @@ private:
 	void displayScores(uint8 player);
 	void displayShotsLeft(uint8 player);
 	bool weaponDown();
-	bool saveState();
-	bool loadState();
+	bool saveState(Common::OutSaveFile *saveFile) override;
+	bool loadState(Common::InSaveFile *inSaveFile) override;
 	Zone *checkZones(Scene *scene, Rect *&hitRect, Common::Point *point);
 	Rect *checkZone(Zone *zone, Common::Point *point);
 
diff --git a/engines/alg/logic/game_crimepatrol.cpp b/engines/alg/logic/game_crimepatrol.cpp
index e773eaaa2f7..b06a27d4cb3 100644
--- a/engines/alg/logic/game_crimepatrol.cpp
+++ b/engines/alg/logic/game_crimepatrol.cpp
@@ -597,13 +597,7 @@ bool GameCrimePatrol::weaponDown() {
 	return false;
 }
 
-bool GameCrimePatrol::saveState() {
-	Common::OutSaveFile *outSaveFile;
-	Common::String saveFileName = _vm->getSaveStateName(0);
-	if (!(outSaveFile = g_system->getSavefileManager()->openForSaving(saveFileName))) {
-		warning("GameCrimePatrol::saveState(): Can't create file '%s', game not saved", saveFileName.c_str());
-		return false;
-	}
+bool GameCrimePatrol::saveState(Common::OutSaveFile *outSaveFile) {
 	outSaveFile->writeUint32BE(MKTAG('A', 'L', 'G', 'S')); // header
 	outSaveFile->writeByte(0);                             // version, unused for now
 	outSaveFile->writeSByte(_stage);
@@ -613,18 +607,10 @@ bool GameCrimePatrol::saveState() {
 	outSaveFile->writeSint32LE(_score);
 	outSaveFile->writeUint16LE(_shots);
 	outSaveFile->writeSByte(_lives);
-	outSaveFile->finalize();
-	delete outSaveFile;
 	return true;
 }
 
-bool GameCrimePatrol::loadState() {
-	Common::InSaveFile *inSaveFile;
-	Common::String saveFileName = _vm->getSaveStateName(0);
-	if (!(inSaveFile = g_system->getSavefileManager()->openForLoading(saveFileName))) {
-		debug("GameCrimePatrol::loadState(): Can't load file '%s', game not loaded", saveFileName.c_str());
-		return false;
-	}
+bool GameCrimePatrol::loadState(Common::InSaveFile *inSaveFile) {
 	uint32 header = inSaveFile->readUint32BE();
 	if (header != MKTAG('A', 'L', 'G', 'S')) {
 		warning("GameCrimePatrol::loadState(): Unkown save file, header: %s", tag2str(header));
@@ -638,7 +624,6 @@ bool GameCrimePatrol::loadState() {
 	_score = inSaveFile->readSint32LE();
 	_shots = inSaveFile->readUint16LE();
 	_lives = inSaveFile->readSByte();
-	delete inSaveFile;
 	_gameInProgress = true;
 	sceneNxtscnGeneric(_stage);
 	return true;
@@ -791,13 +776,13 @@ void GameCrimePatrol::rectShotMenu(Rect *rect) {
 }
 
 void GameCrimePatrol::rectSave(Rect *rect) {
-	if (saveState()) {
+	if (_vm->saveGameState(0, "").getCode() == Common::kNoError) {
 		playSound(_saveSound);
 	}
 }
 
 void GameCrimePatrol::rectLoad(Rect *rect) {
-	if (loadState()) {
+	if (_vm->loadGameState(0).getCode() == Common::kNoError) {
 		playSound(_loadSound);
 	}
 }
diff --git a/engines/alg/logic/game_crimepatrol.h b/engines/alg/logic/game_crimepatrol.h
index 7f45e5ca1be..d58d02513a9 100644
--- a/engines/alg/logic/game_crimepatrol.h
+++ b/engines/alg/logic/game_crimepatrol.h
@@ -180,8 +180,8 @@ private:
 	void displayScores();
 	void displayShotsLeft();
 	bool weaponDown();
-	bool saveState();
-	bool loadState();
+	bool saveState(Common::OutSaveFile *saveFile) override;
+	bool loadState(Common::InSaveFile *inSaveFile) override;
 	Zone *checkZones(Scene *scene, Rect *&hitRect, Common::Point *point);
 
 	// misc game functions
diff --git a/engines/alg/logic/game_drugwars.cpp b/engines/alg/logic/game_drugwars.cpp
index ce854a7e320..1f9597760b2 100644
--- a/engines/alg/logic/game_drugwars.cpp
+++ b/engines/alg/logic/game_drugwars.cpp
@@ -540,13 +540,7 @@ bool GameDrugWars::weaponDown() {
 	return false;
 }
 
-bool GameDrugWars::saveState() {
-	Common::OutSaveFile *outSaveFile;
-	Common::String saveFileName = _vm->getSaveStateName(0);
-	if (!(outSaveFile = g_system->getSavefileManager()->openForSaving(saveFileName))) {
-		warning("GameDrugWars::saveState(): Can't create file '%s', game not saved", saveFileName.c_str());
-		return false;
-	}
+bool GameDrugWars::saveState(Common::OutSaveFile *outSaveFile) {
 	outSaveFile->writeUint32BE(MKTAG('A', 'L', 'G', 'S')); // header
 	outSaveFile->writeByte(0);                             // version, unused for now
 	outSaveFile->writeSByte(_stage);
@@ -561,18 +555,10 @@ bool GameDrugWars::saveState() {
 	outSaveFile->writeByte(_difficulty);
 	outSaveFile->writeString(_curScene);
 	outSaveFile->writeByte(0);
-	outSaveFile->finalize();
-	delete outSaveFile;
 	return true;
 }
 
-bool GameDrugWars::loadState() {
-	Common::InSaveFile *inSaveFile;
-	Common::String saveFileName = _vm->getSaveStateName(0);
-	if (!(inSaveFile = g_system->getSavefileManager()->openForLoading(saveFileName))) {
-		debug("GameDrugWars::loadState(): Can't load file '%s', game not loaded", saveFileName.c_str());
-		return false;
-	}
+bool GameDrugWars::loadState(Common::InSaveFile *inSaveFile) {
 	uint32 header = inSaveFile->readUint32BE();
 	if (header != MKTAG('A', 'L', 'G', 'S')) {
 		warning("GameDrugWars::loadState(): Unkown save file, header: %s", tag2str(header));
@@ -590,7 +576,6 @@ bool GameDrugWars::loadState() {
 	_score = inSaveFile->readSint32LE();
 	_difficulty = inSaveFile->readByte();
 	_curScene = inSaveFile->readString();
-	delete inSaveFile;
 	_gameInProgress = true;
 	changeDifficulty(_difficulty);
 	return true;
@@ -708,13 +693,13 @@ void GameDrugWars::rectShotMenu(Rect *rect) {
 }
 
 void GameDrugWars::rectSave(Rect *rect) {
-	if (saveState()) {
+	if (_vm->saveGameState(0, "").getCode() == Common::kNoError) {
 		playSound(_saveSound);
 	}
 }
 
 void GameDrugWars::rectLoad(Rect *rect) {
-	if (loadState()) {
+	if (_vm->loadGameState(0).getCode() == Common::kNoError) {
 		playSound(_loadSound);
 	}
 }
diff --git a/engines/alg/logic/game_drugwars.h b/engines/alg/logic/game_drugwars.h
index 30a9d983d03..0ad0f17c02a 100644
--- a/engines/alg/logic/game_drugwars.h
+++ b/engines/alg/logic/game_drugwars.h
@@ -159,8 +159,8 @@ private:
 	void displayScores();
 	void displayShotsLeft();
 	bool weaponDown();
-	bool saveState();
-	bool loadState();
+	bool saveState(Common::OutSaveFile *saveFile) override;
+	bool loadState(Common::InSaveFile *inSaveFile) override;
 	Zone *checkZones(Scene *scene, Rect *&hitRect, Common::Point *point);
 
 	// misc game functions
diff --git a/engines/alg/logic/game_johnnyrock.cpp b/engines/alg/logic/game_johnnyrock.cpp
index 2e50b6784a0..48eed94a922 100644
--- a/engines/alg/logic/game_johnnyrock.cpp
+++ b/engines/alg/logic/game_johnnyrock.cpp
@@ -664,13 +664,7 @@ bool GameJohnnyRock::weaponDown() {
 	return false;
 }
 
-bool GameJohnnyRock::saveState() {
-	Common::OutSaveFile *outSaveFile;
-	Common::String saveFileName = _vm->getSaveStateName(0);
-	if (!(outSaveFile = g_system->getSavefileManager()->openForSaving(saveFileName))) {
-		warning("GameJohnnyRock::saveState(): Can't create file '%s', game not saved", saveFileName.c_str());
-		return false;
-	}
+bool GameJohnnyRock::saveState(Common::OutSaveFile *outSaveFile) {
 	outSaveFile->writeUint32BE(MKTAG('A', 'L', 'G', 'S')); // header
 	outSaveFile->writeByte(0);                             // version, unused for now
 	outSaveFile->writeUint16LE(_totalDies);
@@ -736,18 +730,10 @@ bool GameJohnnyRock::saveState() {
 	outSaveFile->writeString(_retScene);
 	outSaveFile->writeByte(0);
 	outSaveFile->writeByte(_randomScenesSavestateIndex);
-	outSaveFile->finalize();
-	delete outSaveFile;
 	return true;
 }
 
-bool GameJohnnyRock::loadState() {
-	Common::InSaveFile *inSaveFile;
-	Common::String saveFileName = _vm->getSaveStateName(0);
-	if (!(inSaveFile = g_system->getSavefileManager()->openForLoading(saveFileName))) {
-		debug("GameJohnnyRock::loadState(): Can't load file '%s', game not loaded", saveFileName.c_str());
-		return false;
-	}
+bool GameJohnnyRock::loadState(Common::InSaveFile *inSaveFile) {
 	uint32 header = inSaveFile->readUint32BE();
 	if (header != MKTAG('A', 'L', 'G', 'S')) {
 		warning("GameJohnnyRock::loadState(): Unkown save file, header: %s", tag2str(header));
@@ -813,7 +799,6 @@ bool GameJohnnyRock::loadState() {
 	_subScene = inSaveFile->readString();
 	_retScene = inSaveFile->readString();
 	_randomScenesSavestateIndex = inSaveFile->readByte();
-	delete inSaveFile;
 	// find out where _random_scenes should point
 	uint16 placeIndex = _entranceIndex[_randomScenesSavestateIndex];
 	if (_randomScenesSavestateIndex < 5) {
@@ -1006,13 +991,13 @@ void GameJohnnyRock::rectShotMenu(Rect *rect) {
 }
 
 void GameJohnnyRock::rectSave(Rect *rect) {
-	if (saveState()) {
+	if (_vm->saveGameState(0, "").getCode() == Common::kNoError) {
 		playSound(_saveSound);
 	}
 }
 
 void GameJohnnyRock::rectLoad(Rect *rect) {
-	if (loadState()) {
+	if (_vm->loadGameState(0).getCode() == Common::kNoError) {
 		playSound(_loadSound);
 	}
 }
diff --git a/engines/alg/logic/game_johnnyrock.h b/engines/alg/logic/game_johnnyrock.h
index 628f5e1c7be..7a126fcd6a5 100644
--- a/engines/alg/logic/game_johnnyrock.h
+++ b/engines/alg/logic/game_johnnyrock.h
@@ -196,8 +196,8 @@ private:
 	void updateMouse();
 	void moveMouse();
 	bool weaponDown();
-	bool saveState();
-	bool loadState();
+	bool saveState(Common::OutSaveFile *saveFile) override;
+	bool loadState(Common::InSaveFile *inSaveFile) override;
 	void doMoneySound();
 	Zone *checkZones(Scene *scene, Rect *&hitRect, Common::Point *point);
 
diff --git a/engines/alg/logic/game_maddog.cpp b/engines/alg/logic/game_maddog.cpp
index 98e3cbedecc..5d814771b93 100644
--- a/engines/alg/logic/game_maddog.cpp
+++ b/engines/alg/logic/game_maddog.cpp
@@ -639,13 +639,7 @@ bool GameMaddog::weaponDown() {
 	return false;
 }
 
-bool GameMaddog::saveState() {
-	Common::OutSaveFile *outSaveFile;
-	Common::String saveFileName = _vm->getSaveStateName(0);
-	if (!(outSaveFile = g_system->getSavefileManager()->openForSaving(saveFileName))) {
-		warning("GameMaddog::saveState(): Can't create file '%s', game not saved", saveFileName.c_str());
-		return false;
-	}
+bool GameMaddog::saveState(Common::OutSaveFile *outSaveFile) {
 	outSaveFile->writeUint32BE(MKTAG('A', 'L', 'G', 'S')); // header
 	outSaveFile->writeByte(0);                             // version, unused for now
 	outSaveFile->writeUint16LE(_beenTo);
@@ -674,18 +668,10 @@ bool GameMaddog::saveState() {
 	outSaveFile->writeByte(0);
 	outSaveFile->writeString(_subScene);
 	outSaveFile->writeByte(0);
-	outSaveFile->finalize();
-	delete outSaveFile;
 	return true;
 }
 
-bool GameMaddog::loadState() {
-	Common::InSaveFile *inSaveFile;
-	Common::String saveFileName = _vm->getSaveStateName(0);
-	if (!(inSaveFile = g_system->getSavefileManager()->openForLoading(saveFileName))) {
-		debug("GameMaddog::loadState(): Can't load file '%s', game not loaded", saveFileName.c_str());
-		return false;
-	}
+bool GameMaddog::loadState(Common::InSaveFile *inSaveFile) {
 	uint32 header = inSaveFile->readUint32BE();
 	if (header != MKTAG('A', 'L', 'G', 'S')) {
 		warning("GameMaddog::loadState(): Unkown save file, header: %s", tag2str(header));
@@ -715,7 +701,6 @@ bool GameMaddog::loadState() {
 	_curScene = inSaveFile->readString();
 	_retScene = inSaveFile->readString();
 	_subScene = inSaveFile->readString();
-	delete inSaveFile;
 	changeDifficulty(_difficulty);
 	return true;
 }
@@ -1153,13 +1138,13 @@ void GameMaddog::rectContinue(Rect *rect) {
 }
 
 void GameMaddog::rectSave(Rect *rect) {
-	if (saveState()) {
+	if (_vm->saveGameState(0, "").getCode() == Common::kNoError) {
 		playSound(_saveSound);
 	}
 }
 
 void GameMaddog::rectLoad(Rect *rect) {
-	if (loadState()) {
+	if (_vm->loadGameState(0).getCode() == Common::kNoError) {
 		playSound(_loadSound);
 	}
 }
diff --git a/engines/alg/logic/game_maddog.h b/engines/alg/logic/game_maddog.h
index c5149d5efa4..91adee66b20 100644
--- a/engines/alg/logic/game_maddog.h
+++ b/engines/alg/logic/game_maddog.h
@@ -170,8 +170,8 @@ private:
 	void moveMouse();
 	void displayScore();
 	bool weaponDown();
-	bool saveState();
-	bool loadState();
+	bool saveState(Common::OutSaveFile *saveFile) override;
+	bool loadState(Common::InSaveFile *inSaveFile) override;
 	Zone *checkZones(Scene *scene, Rect *&hitRect, Common::Point *point);
 
 	// misc game functions
diff --git a/engines/alg/logic/game_maddog2.cpp b/engines/alg/logic/game_maddog2.cpp
index f6868f9b351..57c0f871016 100644
--- a/engines/alg/logic/game_maddog2.cpp
+++ b/engines/alg/logic/game_maddog2.cpp
@@ -652,13 +652,7 @@ bool GameMaddog2::weaponDown() {
 	return false;
 }
 
-bool GameMaddog2::saveState() {
-	Common::OutSaveFile *outSaveFile;
-	Common::String saveFileName = _vm->getSaveStateName(0);
-	if (!(outSaveFile = g_system->getSavefileManager()->openForSaving(saveFileName))) {
-		warning("GameMaddog2::saveState(): Can't create file '%s', game not saved", saveFileName.c_str());
-		return false;
-	}
+bool GameMaddog2::saveState(Common::OutSaveFile *outSaveFile) {
 	outSaveFile->writeUint32BE(MKTAG('A', 'L', 'G', 'S')); // header
 	outSaveFile->writeByte(0);                             // version, unused for now
 	outSaveFile->writeUint16LE(_totalDies);
@@ -690,18 +684,10 @@ bool GameMaddog2::saveState() {
 	outSaveFile->writeByte(0);
 	outSaveFile->writeString(_retScene);
 	outSaveFile->writeByte(0);
-	outSaveFile->finalize();
-	delete outSaveFile;
 	return true;
 }
 
-bool GameMaddog2::loadState() {
-	Common::InSaveFile *inSaveFile;
-	Common::String saveFileName = _vm->getSaveStateName(0);
-	if (!(inSaveFile = g_system->getSavefileManager()->openForLoading(saveFileName))) {
-		debug("GameMaddog2::loadState(): Can't load file '%s', game not loaded", saveFileName.c_str());
-		return false;
-	}
+bool GameMaddog2::loadState(Common::InSaveFile *inSaveFile) {
 	uint32 header = inSaveFile->readUint32BE();
 	if (header != MKTAG('A', 'L', 'G', 'S')) {
 		warning("GameMaddog2::loadState(): Unkown save file, header: %s", tag2str(header));
@@ -733,7 +719,6 @@ bool GameMaddog2::loadState() {
 	_curScene = inSaveFile->readString();
 	_subScene = inSaveFile->readString();
 	_retScene = inSaveFile->readString();
-	delete inSaveFile;
 	changeDifficulty(_difficulty);
 	return true;
 }
@@ -1257,13 +1242,13 @@ void GameMaddog2::rectShotmenu(Rect *rect) {
 }
 
 void GameMaddog2::rectSave(Rect *rect) {
-	if (saveState()) {
+	if (_vm->saveGameState(0, "").getCode() == Common::kNoError) {
 		playSound(_saveSound);
 	}
 }
 
 void GameMaddog2::rectLoad(Rect *rect) {
-	if (loadState()) {
+	if (_vm->loadGameState(0).getCode() == Common::kNoError) {
 		playSound(_loadSound);
 	}
 }
diff --git a/engines/alg/logic/game_maddog2.h b/engines/alg/logic/game_maddog2.h
index 75ff638769b..74d1c5ea475 100644
--- a/engines/alg/logic/game_maddog2.h
+++ b/engines/alg/logic/game_maddog2.h
@@ -178,8 +178,8 @@ private:
 	void moveMouse();
 	void displayScore();
 	bool weaponDown();
-	bool saveState();
-	bool loadState();
+	bool saveState(Common::OutSaveFile *saveFile) override;
+	bool loadState(Common::InSaveFile *inSaveFile) override;
 	Zone *checkZones(Scene *scene, Rect *&hitRect, Common::Point *point);
 
 	// misc game functions
diff --git a/engines/alg/logic/game_spacepirates.cpp b/engines/alg/logic/game_spacepirates.cpp
index 6ae88880887..ca8364ecb19 100644
--- a/engines/alg/logic/game_spacepirates.cpp
+++ b/engines/alg/logic/game_spacepirates.cpp
@@ -664,15 +664,9 @@ bool GameSpacePirates::weaponDown() {
 	return false;
 }
 
-bool GameSpacePirates::saveState() {
+bool GameSpacePirates::saveState(Common::OutSaveFile *outSaveFile) {
 	uint16 sceneNum = sceneToNumber(_curScene);
 	if ((sceneNum < 0xAC || sceneNum > 0xB9) && sceneNum != 0x6F) {
-		Common::OutSaveFile *outSaveFile;
-		Common::String saveFileName = _vm->getSaveStateName(0);
-		if (!(outSaveFile = g_system->getSavefileManager()->openForSaving(saveFileName))) {
-			warning("GameSpacePirates::saveState(): Can't create file '%s', game not saved", saveFileName.c_str());
-			return false;
-		}
 		outSaveFile->writeUint32BE(MKTAG('A', 'L', 'G', 'S')); // header
 		outSaveFile->writeByte(0);                             // version, unused for now
 		outSaveFile->writeSByte(_lives);
@@ -707,20 +701,12 @@ bool GameSpacePirates::saveState() {
 		outSaveFile->writeByte(_shotGrinReaperCount);
 		outSaveFile->writeByte(_crystalsShot);
 		outSaveFile->writeUint32LE(_lastExtraLifeScore);
-		outSaveFile->finalize();
-		delete outSaveFile;
 		return true;
 	}
 	return false;
 }
 
-bool GameSpacePirates::loadState() {
-	Common::InSaveFile *inSaveFile;
-	Common::String saveFileName = _vm->getSaveStateName(0);
-	if (!(inSaveFile = g_system->getSavefileManager()->openForLoading(saveFileName))) {
-		debug("GameSpacePirates::loadState(): Can't load file '%s', game not loaded", saveFileName.c_str());
-		return false;
-	}
+bool GameSpacePirates::loadState(Common::InSaveFile *inSaveFile) {
 	uint32 header = inSaveFile->readUint32BE();
 	if (header != MKTAG('A', 'L', 'G', 'S')) {
 		warning("GameSpacePirates::loadState(): Unkown save file, header: %s", tag2str(header));
@@ -759,7 +745,6 @@ bool GameSpacePirates::loadState() {
 	_shotGrinReaperCount = inSaveFile->readByte();
 	_crystalsShot = inSaveFile->readByte();
 	_lastExtraLifeScore = inSaveFile->readUint32LE();
-	delete inSaveFile;
 	_gameLoaded = true;
 	_gameInProgress = true;
 	_livesLoaded = _lives;
@@ -925,13 +910,13 @@ void GameSpacePirates::rectShotMenu(Rect *rect) {
 }
 
 void GameSpacePirates::rectSave(Rect *rect) {
-	if (saveState()) {
+	if (_vm->saveGameState(0, "").getCode() == Common::kNoError) {
 		playSound(_saveSound);
 	}
 }
 
 void GameSpacePirates::rectLoad(Rect *rect) {
-	if (loadState()) {
+	if (_vm->loadGameState(0).getCode() == Common::kNoError) {
 		playSound(_loadSound);
 	}
 }
diff --git a/engines/alg/logic/game_spacepirates.h b/engines/alg/logic/game_spacepirates.h
index 3584182b740..f3b0312bb2e 100644
--- a/engines/alg/logic/game_spacepirates.h
+++ b/engines/alg/logic/game_spacepirates.h
@@ -157,8 +157,8 @@ private:
 	void displayScores();
 	void displayShotsLeft();
 	bool weaponDown();
-	bool saveState();
-	bool loadState();
+	bool saveState(Common::OutSaveFile *saveFile) override;
+	bool loadState(Common::InSaveFile *inSaveFile) override;
 	Zone *checkZones(Scene *scene, Rect *&hitRect, Common::Point *point);
 
 	// misc game functions
diff --git a/engines/alg/metaengine.cpp b/engines/alg/metaengine.cpp
index 7183f392b53..c5b1b5f5f8c 100644
--- a/engines/alg/metaengine.cpp
+++ b/engines/alg/metaengine.cpp
@@ -63,8 +63,7 @@ public:
 	}
 
 	bool hasFeature(MetaEngineFeature f) const override {
-		return
-			(f == kSimpleSavesNames);
+		return checkExtendedSaves(f);
 	}
 	
 	Common::Error createInstance(OSystem *syst, Engine **engine, const Alg::AlgGameDescription *gd) const override;


Commit: 76dfec8ce9a9db36722388a2cdef16890085d228
    https://github.com/scummvm/scummvm/commit/76dfec8ce9a9db36722388a2cdef16890085d228
Author: loki (loki at localhost)
Date: 2026-03-02T18:52:34+08:00

Commit Message:
ALG: explicitly delete ani arrays after init

Changed paths:
    engines/alg/logic/game_bountyhunter.cpp
    engines/alg/logic/game_crimepatrol.cpp
    engines/alg/logic/game_drugwars.cpp
    engines/alg/logic/game_johnnyrock.cpp
    engines/alg/logic/game_maddog.cpp
    engines/alg/logic/game_maddog2.cpp
    engines/alg/logic/game_spacepirates.cpp


diff --git a/engines/alg/logic/game_bountyhunter.cpp b/engines/alg/logic/game_bountyhunter.cpp
index ec18f820afb..d90b48635c1 100644
--- a/engines/alg/logic/game_bountyhunter.cpp
+++ b/engines/alg/logic/game_bountyhunter.cpp
@@ -168,6 +168,11 @@ void GameBountyHunter::init() {
 	_screen->copyRectToSurface(_background->getPixels(), _background->pitch, 0, 0, _background->w, _background->h);
 
 	moveMouse();
+
+	delete bullets;
+	delete lives;
+	delete players;
+	delete text;
 }
 
 void GameBountyHunter::registerScriptFunctions() {
diff --git a/engines/alg/logic/game_crimepatrol.cpp b/engines/alg/logic/game_crimepatrol.cpp
index b06a27d4cb3..ddfabe78881 100644
--- a/engines/alg/logic/game_crimepatrol.cpp
+++ b/engines/alg/logic/game_crimepatrol.cpp
@@ -131,6 +131,11 @@ void GameCrimePatrol::init() {
 	_screen->copyRectToSurface(_background->getPixels(), _background->pitch, 0, 0, _background->w, _background->h);
 
 	moveMouse();
+
+	delete bullets;
+	delete lives;
+	delete difficlt;
+	delete hole;
 }
 
 void GameCrimePatrol::registerScriptFunctions() {
diff --git a/engines/alg/logic/game_drugwars.cpp b/engines/alg/logic/game_drugwars.cpp
index 1f9597760b2..7905a4ddf6b 100644
--- a/engines/alg/logic/game_drugwars.cpp
+++ b/engines/alg/logic/game_drugwars.cpp
@@ -131,6 +131,11 @@ void GameDrugWars::init() {
 	_screen->copyRectToSurface(_background->getPixels(), _background->pitch, 0, 0, _background->w, _background->h);
 
 	moveMouse();
+
+	delete bullets;
+	delete lives;
+	delete difficlt;
+	delete hole;
 }
 
 void GameDrugWars::registerScriptFunctions() {
diff --git a/engines/alg/logic/game_johnnyrock.cpp b/engines/alg/logic/game_johnnyrock.cpp
index 48eed94a922..7be76a39dd7 100644
--- a/engines/alg/logic/game_johnnyrock.cpp
+++ b/engines/alg/logic/game_johnnyrock.cpp
@@ -115,6 +115,9 @@ void GameJohnnyRock::init() {
 	_screen->copyRectToSurface(_background->getPixels(), _background->pitch, 0, 0, _background->w, _background->h);
 
 	moveMouse();
+
+	delete level;
+	delete hole;
 }
 
 // FIXME: Need to unregisterScriptFunctions() in destructor to delete all allocated JRScriptFunctionRect and prevent reallocation to fix memory leakage here...
diff --git a/engines/alg/logic/game_maddog.cpp b/engines/alg/logic/game_maddog.cpp
index 5d814771b93..e2208a244ec 100644
--- a/engines/alg/logic/game_maddog.cpp
+++ b/engines/alg/logic/game_maddog.cpp
@@ -147,6 +147,12 @@ void GameMaddog::init() {
 	_screen->copyRectToSurface(_background->getPixels(), _background->pitch, 0, 0, _background->w, _background->h);
 
 	moveMouse();
+
+	delete bullet;
+	delete hat;
+	delete shootout;
+	delete knife;
+	delete hole;
 }
 
 void GameMaddog::registerScriptFunctions() {
diff --git a/engines/alg/logic/game_maddog2.cpp b/engines/alg/logic/game_maddog2.cpp
index 57c0f871016..a6ecc90e548 100644
--- a/engines/alg/logic/game_maddog2.cpp
+++ b/engines/alg/logic/game_maddog2.cpp
@@ -144,6 +144,12 @@ void GameMaddog2::init() {
 	_screen->copyRectToSurface(_background->getPixels(), _background->pitch, 0, 0, _background->w, _background->h);
 
 	moveMouse();
+
+	delete bullet;
+	delete hat;
+	delete shootout;
+	delete knife;
+	delete hole;
 }
 
 void GameMaddog2::registerScriptFunctions() {
diff --git a/engines/alg/logic/game_spacepirates.cpp b/engines/alg/logic/game_spacepirates.cpp
index ca8364ecb19..e82beb2a176 100644
--- a/engines/alg/logic/game_spacepirates.cpp
+++ b/engines/alg/logic/game_spacepirates.cpp
@@ -143,6 +143,10 @@ void GameSpacePirates::init() {
 	_screen->copyRectToSurface(_background->getPixels(), _background->pitch, 0, 0, _background->w, _background->h);
 
 	moveMouse();
+
+	delete bullets;
+	delete lives;
+	delete hole;
 }
 
 void GameSpacePirates::registerScriptFunctions() {


Commit: 88241a4ec2b003854d257e861372d360c5e2fc9f
    https://github.com/scummvm/scummvm/commit/88241a4ec2b003854d257e861372d360c5e2fc9f
Author: loki (loki at localhost)
Date: 2026-03-02T18:52:34+08:00

Commit Message:
ALG: added unregisterScriptFunctions for clean-up

Changed paths:
    engines/alg/logic/game_bountyhunter.cpp
    engines/alg/logic/game_bountyhunter.h
    engines/alg/logic/game_crimepatrol.cpp
    engines/alg/logic/game_crimepatrol.h
    engines/alg/logic/game_drugwars.cpp
    engines/alg/logic/game_drugwars.h
    engines/alg/logic/game_johnnyrock.cpp
    engines/alg/logic/game_johnnyrock.h
    engines/alg/logic/game_maddog.cpp
    engines/alg/logic/game_maddog.h
    engines/alg/logic/game_maddog2.cpp
    engines/alg/logic/game_maddog2.h
    engines/alg/logic/game_spacepirates.cpp
    engines/alg/logic/game_spacepirates.h


diff --git a/engines/alg/logic/game_bountyhunter.cpp b/engines/alg/logic/game_bountyhunter.cpp
index d90b48635c1..f456597d9b5 100644
--- a/engines/alg/logic/game_bountyhunter.cpp
+++ b/engines/alg/logic/game_bountyhunter.cpp
@@ -37,6 +37,7 @@ GameBountyHunter::GameBountyHunter(AlgEngine *vm, const AlgGameDescription *gd)
 }
 
 GameBountyHunter::~GameBountyHunter() {
+	unregisterScriptFunctions();
 	if (_shotIcon) {
 		_shotIcon->free();
 		delete _shotIcon;
@@ -329,6 +330,41 @@ void GameBountyHunter::verifyScriptFunctions() {
 	}
 }
 
+void GameBountyHunter::unregisterScriptFunctions() {
+	for (auto func : _rectHitFuncs) {
+		delete &func;
+	}
+	for (auto func : _scenePreOps) {
+		delete &func;
+	}
+	for (auto func : _sceneShowMsg) {
+		delete &func;
+	}
+	for (auto func : _sceneInsOps) {
+		delete &func;
+	}
+	for (auto func : _sceneWepDwn) {
+		delete &func;
+	}
+	for (auto func : _sceneScnScr) {
+		delete &func;
+	}
+	for (auto func : _sceneNxtFrm) {
+		delete &func;
+	}
+	for (auto func : _sceneNxtScn) {
+		delete &func;
+	}
+	_rectHitFuncs.clear();
+	_scenePreOps.clear();
+	_sceneShowMsg.clear();
+	_sceneInsOps.clear();
+	_sceneWepDwn.clear();
+	_sceneScnScr.clear();
+	_sceneNxtFrm.clear();
+	_sceneNxtScn.clear();
+}
+
 BHScriptFunctionRect GameBountyHunter::getScriptFunctionRectHit(Common::String name) {
 	auto it = _rectHitFuncs.find(name);
 	if (it != _rectHitFuncs.end()) {
diff --git a/engines/alg/logic/game_bountyhunter.h b/engines/alg/logic/game_bountyhunter.h
index 37d9eac47cd..7ea7a4adba2 100644
--- a/engines/alg/logic/game_bountyhunter.h
+++ b/engines/alg/logic/game_bountyhunter.h
@@ -61,6 +61,7 @@ private:
 	void init() override;
 	void registerScriptFunctions();
 	void verifyScriptFunctions();
+	void unregisterScriptFunctions();
 	BHScriptFunctionRect getScriptFunctionRectHit(Common::String name);
 	BHScriptFunctionScene getScriptFunctionScene(SceneFuncType type, Common::String name);
 	void callScriptFunctionRectHit(Common::String name, Rect *rect);
diff --git a/engines/alg/logic/game_crimepatrol.cpp b/engines/alg/logic/game_crimepatrol.cpp
index ddfabe78881..64453bafe03 100644
--- a/engines/alg/logic/game_crimepatrol.cpp
+++ b/engines/alg/logic/game_crimepatrol.cpp
@@ -36,6 +36,7 @@ GameCrimePatrol::GameCrimePatrol(AlgEngine *vm, const AlgGameDescription *gd) :
 }
 
 GameCrimePatrol::~GameCrimePatrol() {
+	unregisterScriptFunctions();
 	if (_shotIcon) {
 		_shotIcon->free();
 		delete _shotIcon;
@@ -269,6 +270,41 @@ void GameCrimePatrol::verifyScriptFunctions() {
 	}
 }
 
+void GameCrimePatrol::unregisterScriptFunctions() {
+	for (auto func : _rectHitFuncs) {
+		delete &func;
+	}
+	for (auto func : _scenePreOps) {
+		delete &func;
+	}
+	for (auto func : _sceneShowMsg) {
+		delete &func;
+	}
+	for (auto func : _sceneInsOps) {
+		delete &func;
+	}
+	for (auto func : _sceneWepDwn) {
+		delete &func;
+	}
+	for (auto func : _sceneScnScr) {
+		delete &func;
+	}
+	for (auto func : _sceneNxtFrm) {
+		delete &func;
+	}
+	for (auto func : _sceneNxtScn) {
+		delete &func;
+	}
+	_rectHitFuncs.clear();
+	_scenePreOps.clear();
+	_sceneShowMsg.clear();
+	_sceneInsOps.clear();
+	_sceneWepDwn.clear();
+	_sceneScnScr.clear();
+	_sceneNxtFrm.clear();
+	_sceneNxtScn.clear();
+}
+
 CPScriptFunctionRect GameCrimePatrol::getScriptFunctionRectHit(Common::String name) {
 	auto it = _rectHitFuncs.find(name);
 	if (it != _rectHitFuncs.end()) {
diff --git a/engines/alg/logic/game_crimepatrol.h b/engines/alg/logic/game_crimepatrol.h
index d58d02513a9..dd333ae7006 100644
--- a/engines/alg/logic/game_crimepatrol.h
+++ b/engines/alg/logic/game_crimepatrol.h
@@ -59,6 +59,7 @@ private:
 	Common::Error run() override;
 	void registerScriptFunctions();
 	void verifyScriptFunctions();
+	void unregisterScriptFunctions();
 	CPScriptFunctionRect getScriptFunctionRectHit(Common::String name);
 	CPScriptFunctionScene getScriptFunctionScene(SceneFuncType type, Common::String name);
 	void callScriptFunctionRectHit(Common::String name, Rect *rect);
diff --git a/engines/alg/logic/game_drugwars.cpp b/engines/alg/logic/game_drugwars.cpp
index 7905a4ddf6b..90fac60880f 100644
--- a/engines/alg/logic/game_drugwars.cpp
+++ b/engines/alg/logic/game_drugwars.cpp
@@ -36,6 +36,7 @@ GameDrugWars::GameDrugWars(AlgEngine *vm, const AlgGameDescription *gd) : Game(v
 }
 
 GameDrugWars::~GameDrugWars() {
+	unregisterScriptFunctions();
 	if (_shotIcon) {
 		_shotIcon->free();
 		delete _shotIcon;
@@ -217,6 +218,41 @@ void GameDrugWars::verifyScriptFunctions() {
 	}
 }
 
+void GameDrugWars::unregisterScriptFunctions() {
+	for (auto func : _rectHitFuncs) {
+		delete &func;
+	}
+	for (auto func : _scenePreOps) {
+		delete &func;
+	}
+	for (auto func : _sceneShowMsg) {
+		delete &func;
+	}
+	for (auto func : _sceneInsOps) {
+		delete &func;
+	}
+	for (auto func : _sceneWepDwn) {
+		delete &func;
+	}
+	for (auto func : _sceneScnScr) {
+		delete &func;
+	}
+	for (auto func : _sceneNxtFrm) {
+		delete &func;
+	}
+	for (auto func : _sceneNxtScn) {
+		delete &func;
+	}
+	_rectHitFuncs.clear();
+	_scenePreOps.clear();
+	_sceneShowMsg.clear();
+	_sceneInsOps.clear();
+	_sceneWepDwn.clear();
+	_sceneScnScr.clear();
+	_sceneNxtFrm.clear();
+	_sceneNxtScn.clear();
+}
+
 DWScriptFunctionRect GameDrugWars::getScriptFunctionRectHit(const Common::String &name) {
 	auto it = _rectHitFuncs.find(name);
 	if (it != _rectHitFuncs.end()) {
diff --git a/engines/alg/logic/game_drugwars.h b/engines/alg/logic/game_drugwars.h
index 0ad0f17c02a..8bd9ae1308f 100644
--- a/engines/alg/logic/game_drugwars.h
+++ b/engines/alg/logic/game_drugwars.h
@@ -59,6 +59,7 @@ private:
 	void init() override;
 	void registerScriptFunctions();
 	void verifyScriptFunctions();
+	void unregisterScriptFunctions();
 	DWScriptFunctionRect getScriptFunctionRectHit(const Common::String &name);
 	DWScriptFunctionScene getScriptFunctionScene(SceneFuncType type, const Common::String &name);
 	void callScriptFunctionRectHit(const Common::String &name, Rect *rect);
diff --git a/engines/alg/logic/game_johnnyrock.cpp b/engines/alg/logic/game_johnnyrock.cpp
index 7be76a39dd7..098dca98b95 100644
--- a/engines/alg/logic/game_johnnyrock.cpp
+++ b/engines/alg/logic/game_johnnyrock.cpp
@@ -37,6 +37,7 @@ GameJohnnyRock::GameJohnnyRock(AlgEngine *vm, const AlgGameDescription *gd) : Ga
 }
 
 GameJohnnyRock::~GameJohnnyRock() {
+	unregisterScriptFunctions();
 	for (auto item : *_difficultyIcon) {
 		item->free();
 		delete item;
@@ -120,7 +121,6 @@ void GameJohnnyRock::init() {
 	delete hole;
 }
 
-// FIXME: Need to unregisterScriptFunctions() in destructor to delete all allocated JRScriptFunctionRect and prevent reallocation to fix memory leakage here...
 void GameJohnnyRock::registerScriptFunctions() {
 #define RECT_HIT_FUNCTION(name, func) _rectHitFuncs[name] = new JRScriptFunctionRect(this, &GameJohnnyRock::func);
 	RECT_HIT_FUNCTION("DEFAULT", rectNewScene);
@@ -253,6 +253,41 @@ void GameJohnnyRock::verifyScriptFunctions() {
 	}
 }
 
+void GameJohnnyRock::unregisterScriptFunctions() {
+	for (auto func : _rectHitFuncs) {
+		delete &func;
+	}
+	for (auto func : _scenePreOps) {
+		delete &func;
+	}
+	for (auto func : _sceneShowMsg) {
+		delete &func;
+	}
+	for (auto func : _sceneInsOps) {
+		delete &func;
+	}
+	for (auto func : _sceneWepDwn) {
+		delete &func;
+	}
+	for (auto func : _sceneScnScr) {
+		delete &func;
+	}
+	for (auto func : _sceneNxtFrm) {
+		delete &func;
+	}
+	for (auto func : _sceneNxtScn) {
+		delete &func;
+	}
+	_rectHitFuncs.clear();
+	_scenePreOps.clear();
+	_sceneShowMsg.clear();
+	_sceneInsOps.clear();
+	_sceneWepDwn.clear();
+	_sceneScnScr.clear();
+	_sceneNxtFrm.clear();
+	_sceneNxtScn.clear();
+}
+
 JRScriptFunctionPoint GameJohnnyRock::getScriptFunctionZonePtrFb(Common::String name) {
 	auto it = _zonePtrFb.find(name);
 	if (it != _zonePtrFb.end()) {
diff --git a/engines/alg/logic/game_johnnyrock.h b/engines/alg/logic/game_johnnyrock.h
index 7a126fcd6a5..6568082179b 100644
--- a/engines/alg/logic/game_johnnyrock.h
+++ b/engines/alg/logic/game_johnnyrock.h
@@ -62,6 +62,7 @@ private:
 	void init() override;
 	void registerScriptFunctions();
 	void verifyScriptFunctions();
+	void unregisterScriptFunctions();
 	JRScriptFunctionPoint getScriptFunctionZonePtrFb(Common::String name);
 	JRScriptFunctionRect getScriptFunctionRectHit(Common::String name);
 	JRScriptFunctionScene getScriptFunctionScene(SceneFuncType type, Common::String name);
diff --git a/engines/alg/logic/game_maddog.cpp b/engines/alg/logic/game_maddog.cpp
index e2208a244ec..2fab54649a6 100644
--- a/engines/alg/logic/game_maddog.cpp
+++ b/engines/alg/logic/game_maddog.cpp
@@ -37,6 +37,7 @@ GameMaddog::GameMaddog(AlgEngine *vm, const AlgGameDescription *gd) : Game(vm) {
 }
 
 GameMaddog::~GameMaddog() {
+	unregisterScriptFunctions();
 	if (_shotIcon) {
 		_shotIcon->free();
 		delete _shotIcon;
@@ -275,6 +276,41 @@ void GameMaddog::verifyScriptFunctions() {
 	}
 }
 
+void GameMaddog::unregisterScriptFunctions() {
+	for (auto func : _rectHitFuncs) {
+		delete &func;
+	}
+	for (auto func : _scenePreOps) {
+		delete &func;
+	}
+	for (auto func : _sceneShowMsg) {
+		delete &func;
+	}
+	for (auto func : _sceneInsOps) {
+		delete &func;
+	}
+	for (auto func : _sceneWepDwn) {
+		delete &func;
+	}
+	for (auto func : _sceneScnScr) {
+		delete &func;
+	}
+	for (auto func : _sceneNxtFrm) {
+		delete &func;
+	}
+	for (auto func : _sceneNxtScn) {
+		delete &func;
+	}
+	_rectHitFuncs.clear();
+	_scenePreOps.clear();
+	_sceneShowMsg.clear();
+	_sceneInsOps.clear();
+	_sceneWepDwn.clear();
+	_sceneScnScr.clear();
+	_sceneNxtFrm.clear();
+	_sceneNxtScn.clear();
+}
+
 MDScriptFunctionPoint GameMaddog::getScriptFunctionZonePtrFb(Common::String name) {
 	auto it = _zonePtrFb.find(name);
 	if (it != _zonePtrFb.end()) {
diff --git a/engines/alg/logic/game_maddog.h b/engines/alg/logic/game_maddog.h
index 91adee66b20..dce7f01e515 100644
--- a/engines/alg/logic/game_maddog.h
+++ b/engines/alg/logic/game_maddog.h
@@ -62,6 +62,7 @@ private:
 	void init() override;
 	void registerScriptFunctions();
 	void verifyScriptFunctions();
+	void unregisterScriptFunctions();
 	MDScriptFunctionPoint getScriptFunctionZonePtrFb(Common::String name);
 	MDScriptFunctionRect getScriptFunctionRectHit(Common::String name);
 	MDScriptFunctionScene getScriptFunctionScene(SceneFuncType type, Common::String name);
diff --git a/engines/alg/logic/game_maddog2.cpp b/engines/alg/logic/game_maddog2.cpp
index a6ecc90e548..9a99b019bca 100644
--- a/engines/alg/logic/game_maddog2.cpp
+++ b/engines/alg/logic/game_maddog2.cpp
@@ -37,6 +37,7 @@ GameMaddog2::GameMaddog2(AlgEngine *vm, const AlgGameDescription *gd) : Game(vm)
 }
 
 GameMaddog2::~GameMaddog2() {
+	unregisterScriptFunctions();
 	if (_shotIcon) {
 		_shotIcon->free();
 		delete _shotIcon;
@@ -286,6 +287,41 @@ void GameMaddog2::verifyScriptFunctions() {
 	}
 }
 
+void GameMaddog2::unregisterScriptFunctions() {
+	for (auto func : _rectHitFuncs) {
+		delete &func;
+	}
+	for (auto func : _scenePreOps) {
+		delete &func;
+	}
+	for (auto func : _sceneShowMsg) {
+		delete &func;
+	}
+	for (auto func : _sceneInsOps) {
+		delete &func;
+	}
+	for (auto func : _sceneWepDwn) {
+		delete &func;
+	}
+	for (auto func : _sceneScnScr) {
+		delete &func;
+	}
+	for (auto func : _sceneNxtFrm) {
+		delete &func;
+	}
+	for (auto func : _sceneNxtScn) {
+		delete &func;
+	}
+	_rectHitFuncs.clear();
+	_scenePreOps.clear();
+	_sceneShowMsg.clear();
+	_sceneInsOps.clear();
+	_sceneWepDwn.clear();
+	_sceneScnScr.clear();
+	_sceneNxtFrm.clear();
+	_sceneNxtScn.clear();
+}
+
 MD2ScriptFunctionPoint GameMaddog2::getScriptFunctionZonePtrFb(Common::String name) {
 	auto it = _zonePtrFb.find(name);
 	if (it != _zonePtrFb.end()) {
diff --git a/engines/alg/logic/game_maddog2.h b/engines/alg/logic/game_maddog2.h
index 74d1c5ea475..1e2e8349c32 100644
--- a/engines/alg/logic/game_maddog2.h
+++ b/engines/alg/logic/game_maddog2.h
@@ -62,6 +62,7 @@ private:
 	void init() override;
 	void registerScriptFunctions();
 	void verifyScriptFunctions();
+	void unregisterScriptFunctions();
 	MD2ScriptFunctionPoint getScriptFunctionZonePtrFb(Common::String name);
 	MD2ScriptFunctionRect getScriptFunctionRectHit(Common::String name);
 	MD2ScriptFunctionScene getScriptFunctionScene(SceneFuncType type, Common::String name);
diff --git a/engines/alg/logic/game_spacepirates.cpp b/engines/alg/logic/game_spacepirates.cpp
index e82beb2a176..69171296727 100644
--- a/engines/alg/logic/game_spacepirates.cpp
+++ b/engines/alg/logic/game_spacepirates.cpp
@@ -36,6 +36,7 @@ GameSpacePirates::GameSpacePirates(AlgEngine *vm, const AlgGameDescription *gd)
 }
 
 GameSpacePirates::~GameSpacePirates() {
+	unregisterScriptFunctions();
 	if (_shotIcon) {
 		_shotIcon->free();
 		delete _shotIcon;
@@ -286,6 +287,41 @@ void GameSpacePirates::verifyScriptFunctions() {
 	}
 }
 
+void GameSpacePirates::unregisterScriptFunctions() {
+	for (auto func : _rectHitFuncs) {
+		delete &func;
+	}
+	for (auto func : _scenePreOps) {
+		delete &func;
+	}
+	for (auto func : _sceneShowMsg) {
+		delete &func;
+	}
+	for (auto func : _sceneInsOps) {
+		delete &func;
+	}
+	for (auto func : _sceneWepDwn) {
+		delete &func;
+	}
+	for (auto func : _sceneScnScr) {
+		delete &func;
+	}
+	for (auto func : _sceneNxtFrm) {
+		delete &func;
+	}
+	for (auto func : _sceneNxtScn) {
+		delete &func;
+	}
+	_rectHitFuncs.clear();
+	_scenePreOps.clear();
+	_sceneShowMsg.clear();
+	_sceneInsOps.clear();
+	_sceneWepDwn.clear();
+	_sceneScnScr.clear();
+	_sceneNxtFrm.clear();
+	_sceneNxtScn.clear();
+}
+
 void GameSpacePirates::fixScriptBugs() {
 	auto scenes = _sceneInfo->getScenes();
 	for (auto scene : *scenes) {
diff --git a/engines/alg/logic/game_spacepirates.h b/engines/alg/logic/game_spacepirates.h
index f3b0312bb2e..f87904fdb6c 100644
--- a/engines/alg/logic/game_spacepirates.h
+++ b/engines/alg/logic/game_spacepirates.h
@@ -60,6 +60,7 @@ private:
 	void init() override;
 	void registerScriptFunctions();
 	void verifyScriptFunctions();
+	void unregisterScriptFunctions();
 	void fixScriptBugs();
 	SPScriptFunctionRect getScriptFunctionRectHit(Common::String name);
 	SPScriptFunctionScene getScriptFunctionScene(SceneFuncType type, Common::String name);




More information about the Scummvm-git-logs mailing list