[Scummvm-git-logs] scummvm master -> bd41e8272d6ff8e8ae887ecde39ae6e136742399

tag2015 noreply at scummvm.org
Sat Sep 16 11:34:04 UTC 2023


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

Summary:
ae30f78761 AGS: Engine: support mismatching GUI numbers in legacy saves
47b3cb7de7 AGS: Engine: rename legacysaves config options, bring to consistency
6166993f42 AGS: Engine: fixed WalkStraight() was resetting animation
bd41e8272d Updated build version (3.6.0.52)


Commit: ae30f78761095bb051eece0971725f4a7eb7ae45
    https://github.com/scummvm/scummvm/commit/ae30f78761095bb051eece0971725f4a7eb7ae45
Author: Walter Agazzi (walter.agazzi at protonmail.com)
Date: 2023-09-16T13:32:58+02:00

Commit Message:
AGS: Engine: support mismatching GUI numbers in legacy saves

>From upstream 9d2fa2c26dda45fa53141a625c71ec63601cd9e2

Changed paths:
    engines/ags/engine/ac/game_setup.h
    engines/ags/engine/game/savegame_v321.cpp
    engines/ags/engine/main/config.cpp
    engines/ags/shared/gui/gui_main.cpp
    engines/ags/shared/gui/gui_main.h


diff --git a/engines/ags/engine/ac/game_setup.h b/engines/ags/engine/ac/game_setup.h
index f5b58c86309..b75f3b45bfb 100644
--- a/engines/ags/engine/ac/game_setup.h
+++ b/engines/ags/engine/ac/game_setup.h
@@ -104,6 +104,8 @@ struct GameSetup {
 	bool  override_upscale; // whether upscale old games that supported that
 	// assume game data version when restoring legacy save format
 	GameDataVersion dataver_for_legacysavs = kGameVersion_Undefined;
+	// allow to read mismatching number of guis from legacy save file
+	bool  legacysaves_let_gui_diff = false;
 	// Optional keys for calling built-in save/restore dialogs;
 	// primarily meant for the test runs of the games where save functionality
 	// is not implemented (or does not work correctly).
diff --git a/engines/ags/engine/game/savegame_v321.cpp b/engines/ags/engine/game/savegame_v321.cpp
index 12cd6a9fbb0..ee27f690ade 100644
--- a/engines/ags/engine/game/savegame_v321.cpp
+++ b/engines/ags/engine/game/savegame_v321.cpp
@@ -38,6 +38,7 @@
 #include "ags/engine/ac/game.h"
 #include "ags/shared/ac/game_setup_struct.h"
 #include "ags/engine/ac/game_state.h"
+#include "ags/engine/ac/game_setup.h"
 #include "ags/engine/ac/move_list.h"
 #include "ags/engine/ac/overlay.h"
 #include "ags/shared/ac/sprite_cache.h"
@@ -70,21 +71,6 @@ using namespace AGS::Engine;
 
 static const uint32_t MAGICNUMBER = 0xbeefcafe;
 
-// List of game objects, used to compare with the save contents
-struct ObjectCounts {
-	int CharacterCount = 0;
-	int DialogCount = 0;
-	int InvItemCount = 0;
-	int ViewCount = 0;
-	int GUICount = 0;
-	int GUILabelCount = 0;
-	int GUIButtonCount = 0;
-	int GUIInvWindowCount = 0;
-	int GUIListBoxCount = 0;
-	int GUISliderCount = 0;
-	int GUITextBoxCount = 0;
-};
-
 static HSaveError restore_game_head_dynamic_values(Stream *in, RestoredData &r_data) {
 	r_data.FPS = in->ReadInt32();
 	r_data.CursorMode = in->ReadInt32();
@@ -238,30 +224,62 @@ void ReadAnimatedButtons_Aligned(Stream *in, int num_abuts) {
 	}
 }
 
-inline bool AssertGameContent(HSaveError &err, int new_val, int original_val, const char *content_name) {
-	if (new_val != original_val) {
-		err = new SavegameError(kSvgErr_GameContentAssertion,
-								String::FromFormat("Mismatching number of %s (game: %d, save: %d).",
-												   content_name, original_val, new_val));
+inline bool AssertGameContent(HSaveError &err, int game_val, int sav_val, const char *content_name, bool warn_only = false) {
+	if (game_val != sav_val) {
+		String msg = String::FromFormat("Mismatching number of %s (game: %d, save: %d).", content_name, game_val, sav_val);
+		if (warn_only)
+			Debug::Printf(kDbgMsg_Warn, "WARNING: restored save may be incompatible: %s", msg.GetCStr());
+		else
+			err = new SavegameError(kSvgErr_GameContentAssertion, msg);
+	}
+	return warn_only || (game_val == sav_val);
+}
+
+template<typename TObject>
+inline bool AssertAndCopyGameContent(const std::vector<TObject> &old_list, std::vector<TObject> &new_list,
+									 HSaveError &err, const char *content_name, bool warn_only = false) {
+	if (!AssertGameContent(err, old_list.size(), new_list.size(), content_name, warn_only))
+		return false;
+
+	if (new_list.size() < old_list.size()) {
+		size_t copy_at = new_list.size();
+		new_list.resize(old_list.size());
+		Common::copy(old_list.begin() + copy_at, old_list.end(), new_list.begin() + copy_at);
 	}
-	return new_val == original_val;
+	return true;
 }
 
-static HSaveError restore_game_gui(Stream *in, const ObjectCounts &guiwas) {
+static HSaveError restore_game_gui(Stream *in) {
+	// Legacy saves allowed to resize gui lists, and stored full gui data
+	// (could be unintentional side effect). Here we emulate this for
+	// upgraded games by letting read **less** data from saves, and copying
+	// missing elements from reserved game data.
+	const std::vector<GUIMain> res_guis = std::move(_GP(guis));
+	const std::vector<GUIButton> res_guibuts = std::move(_GP(guibuts));
+	const std::vector<GUIInvWindow> res_guiinv = std::move(_GP(guiinv));
+	const std::vector<GUILabel> res_guilabels = std::move(_GP(guilabels));
+	const std::vector<GUIListBox> res_guilist = std::move(_GP(guilist));
+	const std::vector<GUISlider> res_guislider = std::move(_GP(guislider));
+	const std::vector<GUITextBox> res_guitext = std::move(_GP(guitext));
+
 	HError guierr = GUI::ReadGUI(in, true);
 	if (!guierr)
 		return new SavegameError(kSvgErr_GameObjectInitFailed, guierr);
-	_GP(game).numgui = _GP(guis).size();
 
 	HSaveError err;
-	if (!AssertGameContent(err, _GP(game).numgui, guiwas.GUICount, "GUIs") ||
-		!AssertGameContent(err, _GP(guibuts).size(), guiwas.GUIButtonCount, "GUI Buttons") ||
-		!AssertGameContent(err, _GP(guiinv).size(), guiwas.GUIInvWindowCount, "GUI InvWindows") ||
-		!AssertGameContent(err, _GP(guilabels).size(), guiwas.GUILabelCount, "GUI Labels") ||
-		!AssertGameContent(err, _GP(guilist).size(), guiwas.GUIListBoxCount, "GUI ListBoxes") ||
-		!AssertGameContent(err, _GP(guislider).size(), guiwas.GUISliderCount, "GUI Sliders") ||
-		!AssertGameContent(err, _GP(guitext).size(), guiwas.GUITextBoxCount, "GUI TextBoxes"))
+	const bool warn_only = _GP(usetup).legacysaves_let_gui_diff;
+	if (!AssertAndCopyGameContent(res_guis, _GP(guis), err, "GUIs", warn_only) ||
+		!AssertAndCopyGameContent(res_guibuts, _GP(guibuts), err, "GUI Buttons", warn_only) ||
+		!AssertAndCopyGameContent(res_guiinv, _GP(guiinv), err, "GUI InvWindows", warn_only) ||
+		!AssertAndCopyGameContent(res_guilabels, _GP(guilabels), err, "GUI Labels", warn_only) ||
+		!AssertAndCopyGameContent(res_guilist, _GP(guilist), err, "GUI ListBoxes", warn_only) ||
+		!AssertAndCopyGameContent(res_guislider, _GP(guislider), err, "GUI Sliders", warn_only) ||
+		!AssertAndCopyGameContent(res_guitext, _GP(guitext), err, "GUI TextBoxes", warn_only))
+
 		return err;
+	GUI::RebuildGUI(); // rebuild guis in case they were copied from reserved game data
+
+	_GP(game).numgui = _GP(guis).size();
 	RemoveAllButtonAnimations();
 	int anim_count = in->ReadInt32();
 	ReadAnimatedButtons_Aligned(in, anim_count);
@@ -449,18 +467,13 @@ HSaveError restore_save_data_v321(Stream *in, GameDataVersion data_ver, const Pr
 	for (size_t i = 0; i < MAXGLOBALMES; ++i)
 		mesbk[i] = _GP(game).messages[i];
 
-	ObjectCounts objwas;
-	objwas.CharacterCount = _GP(game).numcharacters;
-	objwas.DialogCount = _GP(game).numdialog;
-	objwas.InvItemCount = _GP(game).numinvitems;
-	objwas.ViewCount = _GP(game).numviews;
-	objwas.GUICount = _GP(game).numgui;
-	objwas.GUIButtonCount = _GP(guibuts).size();
-	objwas.GUIInvWindowCount = _GP(guiinv).size();
-	objwas.GUILabelCount = _GP(guilabels).size();
-	objwas.GUIListBoxCount = _GP(guilist).size();
-	objwas.GUISliderCount = _GP(guislider).size();
-	objwas.GUITextBoxCount = _GP(guitext).size();
+	// List of game objects, used to compare with the save contents
+	struct ObjectCounts {
+		int CharacterCount = _GP(game).numcharacters;
+		int DialogCount = _GP(game).numdialog;
+		int InvItemCount = _GP(game).numinvitems;
+		int ViewCount = _GP(game).numviews;
+	} objwas;
 
 	ReadGameSetupStructBase_Aligned(in, data_ver);
 
@@ -469,10 +482,10 @@ HSaveError restore_save_data_v321(Stream *in, GameDataVersion data_ver, const Pr
 	delete[] _GP(game).load_messages;
 	_GP(game).load_messages = nullptr;
 
-	if (!AssertGameContent(err, _GP(game).numcharacters, objwas.CharacterCount, "Characters") ||
-		!AssertGameContent(err, _GP(game).numdialog, objwas.DialogCount, "Dialogs") ||
-		!AssertGameContent(err, _GP(game).numinvitems, objwas.InvItemCount, "Inventory Items") ||
-		!AssertGameContent(err, _GP(game).numviews, objwas.ViewCount, "Views"))
+	if (!AssertGameContent(err, objwas.CharacterCount, _GP(game).numcharacters, "Characters") ||
+		!AssertGameContent(err, objwas.DialogCount, _GP(game).numdialog, "Dialogs") ||
+		!AssertGameContent(err, objwas.InvItemCount, _GP(game).numinvitems, "Inventory Items") ||
+		!AssertGameContent(err, objwas.ViewCount, _GP(game).numviews, "Views"))
 		return err;
 
 	_GP(game).ReadFromSaveGame_v321(in, data_ver, gswas, compsc, chwas, olddict, mesbk);
@@ -484,7 +497,7 @@ HSaveError restore_save_data_v321(Stream *in, GameDataVersion data_ver, const Pr
 	restore_game_palette(in);
 	restore_game_dialogs(in);
 	restore_game_more_dynamic_values(in);
-	err = restore_game_gui(in, objwas);
+	err = restore_game_gui(in);
 	if (!err)
 		return err;
 	err = restore_game_audiocliptypes(in);
diff --git a/engines/ags/engine/main/config.cpp b/engines/ags/engine/main/config.cpp
index a555c3c1ca8..9853e206ffb 100644
--- a/engines/ags/engine/main/config.cpp
+++ b/engines/ags/engine/main/config.cpp
@@ -377,6 +377,7 @@ void apply_config(const ConfigTree &cfg) {
 		}
 		_GP(usetup).override_upscale = CfgReadBoolInt(cfg, "override", "upscale", _GP(usetup).override_upscale);
 		_GP(usetup).dataver_for_legacysavs = static_cast<GameDataVersion>(CfgReadInt(cfg, "override", "dataver_for_legacysaves", kGameVersion_Undefined));
+		_GP(usetup).legacysaves_let_gui_diff = CfgReadBoolInt(cfg, "override", "legacysaves_let_gui_diff");
 		_GP(usetup).key_save_game = CfgReadInt(cfg, "override", "save_game_key", 0);
 		_GP(usetup).key_restore_game = CfgReadInt(cfg, "override", "restore_game_key", 0);
 	}
diff --git a/engines/ags/shared/gui/gui_main.cpp b/engines/ags/shared/gui/gui_main.cpp
index 2367a2b8974..44217c0cc44 100644
--- a/engines/ags/shared/gui/gui_main.cpp
+++ b/engines/ags/shared/gui/gui_main.cpp
@@ -790,7 +790,8 @@ GUILabelMacro FindLabelMacros(const String &text) {
 	return (GUILabelMacro)macro_flags;
 }
 
-static HError ResortGUI(bool bwcompat_ctrl_zorder = false) {
+HError RebuildGUI() {
+	const bool bwcompat_ctrl_zorder = GameGuiVersion < kGuiVersion_272e;
 	// set up the reverse-lookup array
 	for (auto &gui : _GP(guis)) {
 		HError err = gui.RebuildArray();
@@ -910,7 +911,7 @@ HError ReadGUI(Stream *in, bool is_savegame) {
 			_GP(guilist)[i].ReadFromFile(in, GameGuiVersion);
 		}
 	}
-	return ResortGUI(GameGuiVersion < kGuiVersion_272e);
+	return RebuildGUI();
 }
 
 void WriteGUI(Stream *out) {
diff --git a/engines/ags/shared/gui/gui_main.h b/engines/ags/shared/gui/gui_main.h
index a4978dbec99..1fd189a5a12 100644
--- a/engines/ags/shared/gui/gui_main.h
+++ b/engines/ags/shared/gui/gui_main.h
@@ -255,6 +255,10 @@ HError ReadGUI(Stream *in, bool is_savegame = false);
 void WriteGUI(Stream *out);
 // Converts legacy GUIVisibility into appropriate GUIMain properties
 void ApplyLegacyVisibility(GUIMain &gui, LegacyGUIVisState vis);
+
+// Rebuilds GUIs, connecting them to the child controls in memory.
+// WARNING: the data is processed in the global arrays (guis, guibuts, and so on)
+HError RebuildGUI();
 }
 
 } // namespace Shared


Commit: 47b3cb7de73f1a3ecfcb5d735bd5552903a14e60
    https://github.com/scummvm/scummvm/commit/47b3cb7de73f1a3ecfcb5d735bd5552903a14e60
Author: Walter Agazzi (walter.agazzi at protonmail.com)
Date: 2023-09-16T13:32:58+02:00

Commit Message:
AGS: Engine: rename legacysaves config options, bring to consistency

>From upstream e8d043327f896ce4f10aee04d55a4029ce81d1eb

Changed paths:
    engines/ags/engine/ac/game.cpp
    engines/ags/engine/ac/game_setup.h
    engines/ags/engine/game/savegame.cpp
    engines/ags/engine/game/savegame_v321.cpp
    engines/ags/engine/main/config.cpp


diff --git a/engines/ags/engine/ac/game.cpp b/engines/ags/engine/ac/game.cpp
index 82aa85ce50f..e926ed1699e 100644
--- a/engines/ags/engine/ac/game.cpp
+++ b/engines/ags/engine/ac/game.cpp
@@ -1034,6 +1034,7 @@ bool try_restore_save(int slot) {
 
 bool try_restore_save(const Shared::String &path, int slot) {
 	bool data_overwritten;
+	Debug::Printf(kDbgMsg_Info, "Restoring saved game '%s'", path.GetCStr());
 	HSaveError err = load_game(path, slot, data_overwritten);
 	if (!err) {
 		String error = String::FromFormat("Unable to restore the saved game.\n%s",
diff --git a/engines/ags/engine/ac/game_setup.h b/engines/ags/engine/ac/game_setup.h
index b75f3b45bfb..199bdee9a90 100644
--- a/engines/ags/engine/ac/game_setup.h
+++ b/engines/ags/engine/ac/game_setup.h
@@ -103,9 +103,9 @@ struct GameSetup {
 	char  override_multitasking; // -1 for none, 0 or 1 to lock in the on/off mode
 	bool  override_upscale; // whether upscale old games that supported that
 	// assume game data version when restoring legacy save format
-	GameDataVersion dataver_for_legacysavs = kGameVersion_Undefined;
+	GameDataVersion legacysave_assume_dataver = kGameVersion_Undefined;
 	// allow to read mismatching number of guis from legacy save file
-	bool  legacysaves_let_gui_diff = false;
+	bool legacysave_let_gui_diff = false;
 	// Optional keys for calling built-in save/restore dialogs;
 	// primarily meant for the test runs of the games where save functionality
 	// is not implemented (or does not work correctly).
diff --git a/engines/ags/engine/game/savegame.cpp b/engines/ags/engine/game/savegame.cpp
index c55b35c9e64..f73409eb53a 100644
--- a/engines/ags/engine/game/savegame.cpp
+++ b/engines/ags/engine/game/savegame.cpp
@@ -656,8 +656,8 @@ HSaveError RestoreGameState(Stream *in, SavegameVersion svg_version) {
 	if (svg_version >= kSvgVersion_Components) {
 		err = SavegameComponents::ReadAll(in, svg_version, pp, r_data);
 	} else {
-		GameDataVersion use_dataver = _GP(usetup).dataver_for_legacysavs != kGameVersion_Undefined ? _GP(usetup).dataver_for_legacysavs
-																								   : _G(loaded_game_file_version);
+		GameDataVersion use_dataver = _GP(usetup).legacysave_assume_dataver != kGameVersion_Undefined ? _GP(usetup).legacysave_assume_dataver
+																									  : _G(loaded_game_file_version);
 		err = restore_save_data_v321(in, use_dataver, pp, r_data);
 	}
 	if (!err)
diff --git a/engines/ags/engine/game/savegame_v321.cpp b/engines/ags/engine/game/savegame_v321.cpp
index ee27f690ade..9dc3bca0ebb 100644
--- a/engines/ags/engine/game/savegame_v321.cpp
+++ b/engines/ags/engine/game/savegame_v321.cpp
@@ -267,7 +267,7 @@ static HSaveError restore_game_gui(Stream *in) {
 		return new SavegameError(kSvgErr_GameObjectInitFailed, guierr);
 
 	HSaveError err;
-	const bool warn_only = _GP(usetup).legacysaves_let_gui_diff;
+	const bool warn_only = _GP(usetup).legacysave_let_gui_diff;
 	if (!AssertAndCopyGameContent(res_guis, _GP(guis), err, "GUIs", warn_only) ||
 		!AssertAndCopyGameContent(res_guibuts, _GP(guibuts), err, "GUI Buttons", warn_only) ||
 		!AssertAndCopyGameContent(res_guiinv, _GP(guiinv), err, "GUI InvWindows", warn_only) ||
diff --git a/engines/ags/engine/main/config.cpp b/engines/ags/engine/main/config.cpp
index 9853e206ffb..3d138e8a30d 100644
--- a/engines/ags/engine/main/config.cpp
+++ b/engines/ags/engine/main/config.cpp
@@ -376,8 +376,8 @@ void apply_config(const ConfigTree &cfg) {
 			_GP(usetup).override_script_os = eOS_Mac;
 		}
 		_GP(usetup).override_upscale = CfgReadBoolInt(cfg, "override", "upscale", _GP(usetup).override_upscale);
-		_GP(usetup).dataver_for_legacysavs = static_cast<GameDataVersion>(CfgReadInt(cfg, "override", "dataver_for_legacysaves", kGameVersion_Undefined));
-		_GP(usetup).legacysaves_let_gui_diff = CfgReadBoolInt(cfg, "override", "legacysaves_let_gui_diff");
+		_GP(usetup).legacysave_assume_dataver = static_cast<GameDataVersion>(CfgReadInt(cfg, "override", "legacysave_assume_dataver", kGameVersion_Undefined));
+		_GP(usetup).legacysave_let_gui_diff = CfgReadBoolInt(cfg, "override", "legacysave_let_gui_diff");
 		_GP(usetup).key_save_game = CfgReadInt(cfg, "override", "save_game_key", 0);
 		_GP(usetup).key_restore_game = CfgReadInt(cfg, "override", "restore_game_key", 0);
 	}


Commit: 6166993f425d3bebc9c607244a47f73a7273e7d4
    https://github.com/scummvm/scummvm/commit/6166993f425d3bebc9c607244a47f73a7273e7d4
Author: Walter Agazzi (walter.agazzi at protonmail.com)
Date: 2023-09-16T13:32:59+02:00

Commit Message:
AGS: Engine: fixed WalkStraight() was resetting animation
if called again

This makes Character.WalkStraight() have the same animation
keeping logic as Character.Walk().
Also reduce code duplication by calling walk_or_move_character()
 which handles blocking movement already.
 From upstream c5b04eb0c8991026ebca593d6f3254dfe96fd290

Changed paths:
    engines/ags/engine/ac/character.cpp


diff --git a/engines/ags/engine/ac/character.cpp b/engines/ags/engine/ac/character.cpp
index 27c81a96a9a..40df5f69017 100644
--- a/engines/ags/engine/ac/character.cpp
+++ b/engines/ags/engine/ac/character.cpp
@@ -959,7 +959,6 @@ void Character_WalkStraight(CharacterInfo *chaa, int xx, int yy, int blocking) {
 	if (chaa->room != _G(displayed_room))
 		quit("!MoveCharacterStraight: specified character not in current room");
 
-	Character_StopMoving(chaa);
 	int movetox = xx, movetoy = yy;
 
 	set_wallscreen(prepare_walkable_areas(chaa->index_id));
@@ -976,13 +975,7 @@ void Character_WalkStraight(CharacterInfo *chaa, int xx, int yy, int blocking) {
 		movetoy = mask_to_room_coord(lastcy);
 	}
 
-	walk_character(chaa->index_id, movetox, movetoy, 1, true);
-
-	if ((blocking == BLOCKING) || (blocking == 1))
-		GameLoopUntilNotMoving(&chaa->walking);
-	else if ((blocking != IN_BACKGROUND) && (blocking != 0))
-		quit("!Character.Walk: Blocking must be BLOCKING or IN_BACKGRUOND");
-
+	walk_or_move_character(chaa, movetox, movetoy, blocking, 1 /* use ANYWHERE */, true);
 }
 
 void Character_RunInteraction(CharacterInfo *chaa, int mood) {
@@ -1947,7 +1940,7 @@ void walk_or_move_character(CharacterInfo *chaa, int x, int y, int blocking, int
 	if ((blocking == BLOCKING) || (blocking == 1))
 		GameLoopUntilNotMoving(&chaa->walking);
 	else if ((blocking != IN_BACKGROUND) && (blocking != 0))
-		quit("!Character.Walk: Blocking must be BLOCKING or IN_BACKGRUOND");
+		quit("!Character.Walk: Blocking must be BLOCKING or IN_BACKGROUND");
 
 }
 


Commit: bd41e8272d6ff8e8ae887ecde39ae6e136742399
    https://github.com/scummvm/scummvm/commit/bd41e8272d6ff8e8ae887ecde39ae6e136742399
Author: Walter Agazzi (walter.agazzi at protonmail.com)
Date: 2023-09-16T13:32:59+02:00

Commit Message:
Updated build version (3.6.0.52)

Partially from upstream d64276938a02f52d5a2445cee50794a519c8a340

Changed paths:
    engines/ags/shared/core/def_version.h


diff --git a/engines/ags/shared/core/def_version.h b/engines/ags/shared/core/def_version.h
index 73232b179ac..6f1cc0a1f96 100644
--- a/engines/ags/shared/core/def_version.h
+++ b/engines/ags/shared/core/def_version.h
@@ -22,9 +22,9 @@
 #ifndef AGS_SHARED_CORE_DEFVERSION_H
 #define AGS_SHARED_CORE_DEFVERSION_H
 
-#define ACI_VERSION_STR      "3.6.0.51"
+#define ACI_VERSION_STR      "3.6.0.52"
 #if defined (RC_INVOKED) // for MSVC resource compiler
-#define ACI_VERSION_MSRC_DEF  3.6.0.51
+#define ACI_VERSION_MSRC_DEF  3.6.0.52
 #endif
 
 #define SPECIAL_VERSION ""




More information about the Scummvm-git-logs mailing list