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

criezy noreply at scummvm.org
Sun Oct 9 23:16:30 UTC 2022


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

Summary:
06620b6e9f AGS: renamed Button's MouseButton enum to avoid name confusion
5987bc5e6e AGS: rewrote eAGSMouseButton enum to sync with the script API
250e32f9a1 AGS: adjusted InputType and KeyMod for easier packing in int32
e2497cff42 AGS: include KeyMods flags in the WaitSkipResult
0927821afd AGS: small refactor of key code variables (stricter names, types)
bcb854370d AGS: key plugin callback and game. vars must use "CompatKey"
9f24f6eda4 AGS: fixed ags_misbuttondown()
a06124e572 AGS: Updated build version (3.6.0.31)
6163d4880a AGS: fixed CompatKey may be "none" in some cases for valid key press
483ff1bc30 AGS: fixed object cache may sometimes keep an old dynsprite ref
2f8d4cb072 AGS: PlayVideo supports playing game and video sound together
6bae4af005 AGS: rename "multitasking" option to "background" and added cmd arg
c7f44082b8 AGS: more explicit code for the video flag parsing (PlayVideo/Flic)
58212aeebd AGS: added render callback AGSE_POSTROOMDRAW
b13b408972 AGS: renamed IAGSFontRenderer2 to IAGSFontRendererInternal


Commit: 06620b6e9f3d0be05047a617ccee528bbb4dff8a
    https://github.com/scummvm/scummvm/commit/06620b6e9f3d0be05047a617ccee528bbb4dff8a
Author: Thierry Crozat (criezy at scummvm.org)
Date: 2022-10-10T00:16:16+01:00

Commit Message:
AGS: renamed Button's MouseButton enum to avoid name confusion

Was conflicting with the internal engine's eAGSMouseButton constants.

>From upstream a5cfccee2d3681b55dafb8cfb9e0f38f84124855

Changed paths:
    engines/ags/engine/ac/gui.cpp
    engines/ags/engine/ac/mouse.cpp
    engines/ags/shared/gui/gui_button.cpp
    engines/ags/shared/gui/gui_button.h


diff --git a/engines/ags/engine/ac/gui.cpp b/engines/ags/engine/ac/gui.cpp
index a227f4b6564..370aff5ad4c 100644
--- a/engines/ags/engine/ac/gui.cpp
+++ b/engines/ags/engine/ac/gui.cpp
@@ -316,8 +316,8 @@ void process_interface_click(int ifce, int btn, int mbut) {
 	int rtype = kGUIAction_None, rdata = 0;
 	if (btype == kGUIButton) {
 		GUIButton *gbuto = (GUIButton *)_GP(guis)[ifce].GetControl(btn);
-		rtype = gbuto->ClickAction[kMouseLeft];
-		rdata = gbuto->ClickData[kMouseLeft];
+		rtype = gbuto->ClickAction[kGUIClickLeft];
+		rdata = gbuto->ClickData[kGUIClickLeft];
 	} else if ((btype == kGUISlider) || (btype == kGUITextBox) || (btype == kGUIListBox))
 		rtype = kGUIAction_RunScript;
 	else quit("unknown GUI object triggered process_interface");
diff --git a/engines/ags/engine/ac/mouse.cpp b/engines/ags/engine/ac/mouse.cpp
index b1c47310938..c1a4d98d3d5 100644
--- a/engines/ags/engine/ac/mouse.cpp
+++ b/engines/ags/engine/ac/mouse.cpp
@@ -245,8 +245,8 @@ void enable_cursor_mode(int modd) {
 		for (ww = 0; ww < _GP(guis)[uu].GetControlCount(); ww++) {
 			if (_GP(guis)[uu].GetControlType(ww) != kGUIButton) continue;
 			GUIButton *gbpt = (GUIButton *)_GP(guis)[uu].GetControl(ww);
-			if (gbpt->ClickAction[kMouseLeft] != kGUIAction_SetMode) continue;
-			if (gbpt->ClickData[kMouseLeft] != modd) continue;
+			if (gbpt->ClickAction[kGUIClickLeft] != kGUIAction_SetMode) continue;
+			if (gbpt->ClickData[kGUIClickLeft] != modd) continue;
 			gbpt->SetEnabled(true);
 		}
 	}
@@ -261,8 +261,8 @@ void disable_cursor_mode(int modd) {
 		for (ww = 0; ww < _GP(guis)[uu].GetControlCount(); ww++) {
 			if (_GP(guis)[uu].GetControlType(ww) != kGUIButton) continue;
 			GUIButton *gbpt = (GUIButton *)_GP(guis)[uu].GetControl(ww);
-			if (gbpt->ClickAction[kMouseLeft] != kGUIAction_SetMode) continue;
-			if (gbpt->ClickData[kMouseLeft] != modd) continue;
+			if (gbpt->ClickAction[kGUIClickLeft] != kGUIAction_SetMode) continue;
+			if (gbpt->ClickData[kGUIClickLeft] != modd) continue;
 			gbpt->SetEnabled(false);
 		}
 	}
diff --git a/engines/ags/shared/gui/gui_button.cpp b/engines/ags/shared/gui/gui_button.cpp
index a35dddac415..c8a77e5ca56 100644
--- a/engines/ags/shared/gui/gui_button.cpp
+++ b/engines/ags/shared/gui/gui_button.cpp
@@ -67,10 +67,10 @@ GUIButton::GUIButton() {
 	Font = 0;
 	TextColor = 0;
 	TextAlignment = kAlignTopCenter;
-	ClickAction[kMouseLeft] = kGUIAction_RunScript;
-	ClickAction[kMouseRight] = kGUIAction_RunScript;
-	ClickData[kMouseLeft] = 0;
-	ClickData[kMouseRight] = 0;
+	ClickAction[kGUIClickLeft] = kGUIAction_RunScript;
+	ClickAction[kGUIClickRight] = kGUIAction_RunScript;
+	ClickData[kGUIClickLeft] = 0;
+	ClickData[kGUIClickRight] = 0;
 
 	IsPushed = false;
 	IsMouseOver = false;
@@ -248,10 +248,10 @@ void GUIButton::WriteToFile(Stream *out) const {
 	out->WriteInt32(PushedImage);
 	out->WriteInt32(Font);
 	out->WriteInt32(TextColor);
-	out->WriteInt32(ClickAction[kMouseLeft]);
-	out->WriteInt32(ClickAction[kMouseRight]);
-	out->WriteInt32(ClickData[kMouseLeft]);
-	out->WriteInt32(ClickData[kMouseRight]);
+	out->WriteInt32(ClickAction[kGUIClickLeft]);
+	out->WriteInt32(ClickAction[kGUIClickRight]);
+	out->WriteInt32(ClickData[kGUIClickLeft]);
+	out->WriteInt32(ClickData[kGUIClickRight]);
 
 	StrUtil::WriteString(_text, out);
 	out->WriteInt32(TextAlignment);
@@ -270,10 +270,10 @@ void GUIButton::ReadFromFile(Stream *in, GuiVersion gui_version) {
 	}
 	Font = in->ReadInt32();
 	TextColor = in->ReadInt32();
-	ClickAction[kMouseLeft] = (GUIClickAction)in->ReadInt32();
-	ClickAction[kMouseRight] = (GUIClickAction)in->ReadInt32();
-	ClickData[kMouseLeft] = in->ReadInt32();
-	ClickData[kMouseRight] = in->ReadInt32();
+	ClickAction[kGUIClickLeft] = (GUIClickAction)in->ReadInt32();
+	ClickAction[kGUIClickRight] = (GUIClickAction)in->ReadInt32();
+	ClickData[kGUIClickLeft] = in->ReadInt32();
+	ClickData[kGUIClickRight] = in->ReadInt32();
 	if (gui_version < kGuiVersion_350)
 		SetText(String::FromStreamCount(in, GUIBUTTON_LEGACY_TEXTLENGTH));
 	else
diff --git a/engines/ags/shared/gui/gui_button.h b/engines/ags/shared/gui/gui_button.h
index 2fe0ae77bd3..390c7e45ed1 100644
--- a/engines/ags/shared/gui/gui_button.h
+++ b/engines/ags/shared/gui/gui_button.h
@@ -34,10 +34,10 @@ namespace AGS3 {
 namespace AGS {
 namespace Shared {
 
-enum MouseButton {
-	kMouseNone = -1,
-	kMouseLeft = 0,
-	kMouseRight = 1,
+enum GUIClickMouseButton {
+	kGUIClickLeft  = 0,
+	kGUIClickRight = 1,
+	kNumGUIClicks
 };
 
 enum GUIClickAction {
@@ -96,9 +96,8 @@ public:
 	FrameAlignment TextAlignment;
 	// Click actions for left and right mouse buttons
 	// NOTE: only left click is currently in use
-	static const int ClickCount = kMouseRight + 1;
-	GUIClickAction ClickAction[ClickCount];
-	int32_t        ClickData[ClickCount];
+	GUIClickAction ClickAction[kNumGUIClicks];
+	int32_t        ClickData[kNumGUIClicks];
 
 	bool        IsPushed;
 	bool        IsMouseOver;


Commit: 5987bc5e6e01c22ee2bd1c1d86fa32e28230de78
    https://github.com/scummvm/scummvm/commit/5987bc5e6e01c22ee2bd1c1d86fa32e28230de78
Author: Thierry Crozat (criezy at scummvm.org)
Date: 2022-10-10T00:16:16+01:00

Commit Message:
AGS: rewrote eAGSMouseButton enum to sync with the script API

* Changed from -1 - based constants to 0 - based constants;
* These were purely internal values, therefore no API would be harmed;
* Removed necessity of converting from internal mouse button code to script and back all the time;
* On a side note, this fixes a bug where WaitMouse etc were returning incorrect values on mouse skip, because we forgot to convert from internal to script code.

>From upstream 471098d239b076c494beb2d554572ccb69372667

Changed paths:
    engines/ags/engine/ac/dialog.cpp
    engines/ags/engine/ac/display.cpp
    engines/ags/engine/ac/game.cpp
    engines/ags/engine/ac/inv_window.cpp
    engines/ags/engine/ac/mouse.cpp
    engines/ags/engine/ac/sys_events.cpp
    engines/ags/engine/ac/sys_events.h
    engines/ags/engine/gui/csci_dialog.cpp
    engines/ags/engine/gui/gui_dialog_internal_defs.h
    engines/ags/engine/gui/my_push_button.cpp
    engines/ags/engine/main/game_run.cpp
    engines/ags/engine/main/game_run.h
    engines/ags/engine/media/video/video.cpp
    engines/ags/globals.h
    engines/ags/plugins/ags_plugin.cpp
    engines/ags/shared/ac/keycode.h


diff --git a/engines/ags/engine/ac/dialog.cpp b/engines/ags/engine/ac/dialog.cpp
index 01e9b542e9a..84f61d1e8b7 100644
--- a/engines/ags/engine/ac/dialog.cpp
+++ b/engines/ags/engine/ac/dialog.cpp
@@ -915,14 +915,14 @@ bool DialogOptions::Run() {
 			parserActivated = 1;
 	}
 
-	int mouseButtonPressed = MouseNone;
-	int mouseWheelTurn = 0;
-	if (run_service_mb_controls(mouseButtonPressed, mouseWheelTurn) && mouseButtonPressed >= 0 &&
+	eAGSMouseButton mbut;
+	int mwheelz;
+	if (run_service_mb_controls(mbut, mwheelz) && mbut > kMouseNone &&
 		!_GP(play).IsIgnoringInput()) {
 		if (mouseison < 0 && !new_custom_render) {
 			if (usingCustomRendering) {
 				_GP(runDialogOptionMouseClickHandlerFunc).params[0].SetDynamicObject(&_GP(ccDialogOptionsRendering), &_GP(ccDialogOptionsRendering));
-				_GP(runDialogOptionMouseClickHandlerFunc).params[1].SetInt32(mouseButtonPressed + 1);
+				_GP(runDialogOptionMouseClickHandlerFunc).params[1].SetInt32(mbut);
 				run_function_on_non_blocking_thread(&_GP(runDialogOptionMouseClickHandlerFunc));
 
 				if (_GP(runDialogOptionMouseClickHandlerFunc).atLeastOneImplementationExists) {
@@ -937,7 +937,7 @@ bool DialogOptions::Run() {
 			parserActivated = 1;
 		} else if (new_custom_render) {
 			_GP(runDialogOptionMouseClickHandlerFunc).params[0].SetDynamicObject(&_GP(ccDialogOptionsRendering), &_GP(ccDialogOptionsRendering));
-			_GP(runDialogOptionMouseClickHandlerFunc).params[1].SetInt32(mouseButtonPressed + 1);
+			_GP(runDialogOptionMouseClickHandlerFunc).params[1].SetInt32(mbut);
 			run_function_on_non_blocking_thread(&_GP(runDialogOptionMouseClickHandlerFunc));
 		} else if (usingCustomRendering) {
 			chose = mouseison;
@@ -949,9 +949,9 @@ bool DialogOptions::Run() {
 	}
 
 	if (usingCustomRendering) {
-		if (mouseWheelTurn != 0) {
+		if (mwheelz != 0) {
 			_GP(runDialogOptionMouseClickHandlerFunc).params[0].SetDynamicObject(&_GP(ccDialogOptionsRendering), &_GP(ccDialogOptionsRendering));
-			_GP(runDialogOptionMouseClickHandlerFunc).params[1].SetInt32((mouseWheelTurn < 0) ? 9 : 8);
+			_GP(runDialogOptionMouseClickHandlerFunc).params[1].SetInt32((mwheelz < 0) ? 9 : 8);
 			run_function_on_non_blocking_thread(&_GP(runDialogOptionMouseClickHandlerFunc));
 
 			if (!new_custom_render) {
diff --git a/engines/ags/engine/ac/display.cpp b/engines/ags/engine/ac/display.cpp
index e7ccd9b10b8..c147be48278 100644
--- a/engines/ags/engine/ac/display.cpp
+++ b/engines/ags/engine/ac/display.cpp
@@ -283,8 +283,9 @@ ScreenOverlay *_display_main(int xx, int yy, int wii, const char *text, int disp
 
 			update_audio_system_on_game_loop();
 			render_graphics();
-			int mbut, mwheelz;
-			if (run_service_mb_controls(mbut, mwheelz) && mbut >= 0) {
+			eAGSMouseButton mbut;
+			int mwheelz;
+			if (run_service_mb_controls(mbut, mwheelz) && mbut > kMouseNone) {
 				check_skip_cutscene_mclick(mbut);
 				if (_GP(play).fast_forward)
 					break;
diff --git a/engines/ags/engine/ac/game.cpp b/engines/ags/engine/ac/game.cpp
index 2ff30a57090..d3b29f8552e 100644
--- a/engines/ags/engine/ac/game.cpp
+++ b/engines/ags/engine/ac/game.cpp
@@ -1081,7 +1081,7 @@ bool check_skip_cutscene_keypress(int kgn) {
 bool check_skip_cutscene_mclick(int mbut) {
 	CutsceneSkipStyle skip = get_cutscene_skipstyle();
 	if (skip == eSkipSceneMouse || skip == eSkipSceneKeyMouse ||
-	        (mbut == MouseRight && skip == eSkipSceneEscOrRMB)) {
+	        (mbut == kMouseRight && skip == eSkipSceneEscOrRMB)) {
 		start_skipping_cutscene();
 		return true;
 	}
diff --git a/engines/ags/engine/ac/inv_window.cpp b/engines/ags/engine/ac/inv_window.cpp
index 442faf5ca0f..d8874e14b57 100644
--- a/engines/ags/engine/ac/inv_window.cpp
+++ b/engines/ags/engine/ac/inv_window.cpp
@@ -364,12 +364,13 @@ bool InventoryScreen::Run() {
 	if ((isonitem < 0) | (isonitem >= numitems) | (isonitem >= top_item + num_visible_items))
 		isonitem = -1;
 
-	int mclick, mwheelz;
-	if (!run_service_mb_controls(mclick, mwheelz) || _GP(play).IsIgnoringInput()) {
-		mclick = MouseNone;
+	eAGSMouseButton mbut;
+	int mwheelz;
+	if (!run_service_mb_controls(mbut, mwheelz) || _GP(play).IsIgnoringInput()) {
+		mbut = kMouseNone;
 	}
 
-	if (mclick == MouseLeft) {
+	if (mbut == kMouseLeft) {
 		if ((my < 0) | (my > windowhit) | (mx < 0) | (mx > windowwid))
 			return true; // continue inventory screen loop
 		if (my < buttonyp) {
@@ -455,7 +456,7 @@ bool InventoryScreen::Run() {
 			}
 			set_mouse_cursor(cmode);
 		}
-	} else if (mclick == MouseRight) {
+	} else if (mbut == kMouseRight) {
 		if (cmode == CURS_ARROW)
 			cmode = MODE_LOOK;
 		else
diff --git a/engines/ags/engine/ac/mouse.cpp b/engines/ags/engine/ac/mouse.cpp
index c1a4d98d3d5..fb67fb96cc2 100644
--- a/engines/ags/engine/ac/mouse.cpp
+++ b/engines/ags/engine/ac/mouse.cpp
@@ -297,11 +297,9 @@ int GetCursorMode() {
 }
 
 int IsButtonDown(int which) {
-	if ((which < 1) || (which > 3))
+	if ((which < kMouseLeft) || (which > kMouseMiddle))
 		quit("!IsButtonDown: only works with eMouseLeft, eMouseRight, eMouseMiddle");
-	if (ags_misbuttondown(which - 1))
-		return 1;
-	return 0;
+	return ags_misbuttondown(static_cast<eAGSMouseButton>(which)) ? 1 : 0;
 }
 
 int IsModeEnabled(int which) {
diff --git a/engines/ags/engine/ac/sys_events.cpp b/engines/ags/engine/ac/sys_events.cpp
index 182efc6e5f3..c5080ce153a 100644
--- a/engines/ags/engine/ac/sys_events.cpp
+++ b/engines/ags/engine/ac/sys_events.cpp
@@ -53,7 +53,9 @@ using namespace AGS::Shared;
 using namespace AGS::Engine;
 
 extern void domouse(int str);
-const int MB_ARRAY[3] = { MouseBitLeft, MouseBitRight, MouseBitMiddle };
+// Convert mouse button id to flags
+const int MouseButton2Bits[kNumMouseButtons] =
+	{ MouseBitLeft, MouseBitRight, MouseBitMiddle };
 static void(*_on_quit_callback)(void) = nullptr;
 static void(*_on_switchin_callback)(void) = nullptr;
 static void(*_on_switchout_callback)(void) = nullptr;
@@ -157,22 +159,19 @@ static void on_mouse_wheel(const Common::Event &event) {
 		_G(sys_mouse_z)--;
 }
 
-int mgetbutton() {
-	int toret = MouseNone;
-	int butis = mouse_button_poll();
+static eAGSMouseButton mgetbutton() {
+	const int butis = mouse_button_poll();
 
 	if ((butis > 0) & (_G(butwas) > 0))
-		return MouseNone;  // don't allow holding button down
+		return kMouseNone;  // don't allow holding button down
 
 	if (butis & MouseBitLeft)
-		toret = MouseLeft;
+		return kMouseLeft;
 	else if (butis & MouseBitRight)
-		toret = MouseRight;
+		return kMouseRight;
 	else if (butis & MouseBitMiddle)
-		toret = MouseMiddle;
-
-	_G(butwas) = butis;
-	return toret;
+		return kMouseMiddle;
+	return kMouseNone;
 
 	// TODO: presumably this was a hack for 1-button Mac mouse;
 	// is this still necessary?
@@ -184,23 +183,19 @@ int mgetbutton() {
 		toret = RIGHT;
 	}
 #endif
-	return 0;
 }
 
-bool ags_misbuttondown(int but) {
-	return (mouse_button_poll() & MB_ARRAY[but]) != 0;
+bool ags_misbuttondown(eAGSMouseButton but) {
+	return (mouse_button_poll() & MouseButton2Bits[but]) != 0;
 }
 
-int ags_mgetbutton() {
-	int result;
-
-	if (_G(pluginSimulatedClick) > MouseNone) {
-		result = _G(pluginSimulatedClick);
-		_G(pluginSimulatedClick) = MouseNone;
-	} else {
-		result = mgetbutton();
+eAGSMouseButton ags_mgetbutton() {
+	if (_G(pluginSimulatedClick) > kMouseNone) {
+		eAGSMouseButton mbut = _G(pluginSimulatedClick);
+		_G(pluginSimulatedClick) = kMouseNone;
+		return mbut;
 	}
-	return result;
+	return mgetbutton();;
 }
 
 void ags_mouse_get_relxy(int &x, int &y) {
diff --git a/engines/ags/engine/ac/sys_events.h b/engines/ags/engine/ac/sys_events.h
index e1fb98bc3c6..2e16181ef7b 100644
--- a/engines/ags/engine/ac/sys_events.h
+++ b/engines/ags/engine/ac/sys_events.h
@@ -27,21 +27,6 @@
 
 namespace AGS3 {
 
-// AGS own mouse button codes
-// TODO: these were internal button codes, but AGS script uses different ones,
-// which start with Left=1, and make more sense (0 is easier to use as "no value").
-// Must research if there are any dependencies to these internal values, and if not,
-// then just replace these matching script ones!
-// UPD: even plugin API seem to match script codes and require remap to internals.
-// UPD: or use SDL constants in the engine, but make conversion more visible by using a function.
-enum eAGSMouseButton {
-	MouseNone = -1,
-	MouseLeft = 0,
-	MouseRight = 1,
-	MouseMiddle = 2
-};
-
-
 // Keyboard input handling
 //
 // avoid including SDL.h here, at least for now, because that leads to conflicts with allegro
@@ -85,9 +70,9 @@ extern void ags_simulate_keypress(eAGSKeyCode ags_key);
 // Mouse input handling
 //
 // Tells if the mouse button is currently down
-extern bool ags_misbuttondown(int but);
+extern bool ags_misbuttondown(eAGSMouseButton but);
 // Returns mouse button code
-extern int  ags_mgetbutton();
+extern eAGSMouseButton ags_mgetbutton();
 // Returns recent relative mouse movement
 extern void ags_mouse_get_relxy(int &x, int &y);
 // Updates mouse cursor position in game
diff --git a/engines/ags/engine/gui/csci_dialog.cpp b/engines/ags/engine/gui/csci_dialog.cpp
index 089992feddd..7962e3abebe 100644
--- a/engines/ags/engine/gui/csci_dialog.cpp
+++ b/engines/ags/engine/gui/csci_dialog.cpp
@@ -156,8 +156,9 @@ int CSCIWaitMessage(CSCIMessage *cscim) {
 			}
 		}
 
-		int mbut, mwheelz;
-		if (run_service_mb_controls(mbut, mwheelz) && mbut >= 0 && !_GP(play).IsIgnoringInput()) {
+		eAGSMouseButton mbut;
+		int mwheelz;
+		if (run_service_mb_controls(mbut, mwheelz) && (mbut > kMouseNone) && !_GP(play).IsIgnoringInput()) {
 			if (checkcontrols()) {
 				cscim->id = _G(controlid);
 				cscim->code = CM_COMMAND;
diff --git a/engines/ags/engine/gui/gui_dialog_internal_defs.h b/engines/ags/engine/gui/gui_dialog_internal_defs.h
index a2290d0a5d2..8735012db9b 100644
--- a/engines/ags/engine/gui/gui_dialog_internal_defs.h
+++ b/engines/ags/engine/gui/gui_dialog_internal_defs.h
@@ -30,7 +30,6 @@
 #undef WINAPI
 #endif
 #define WINAPI
-#define mbutrelease(X) (!ags_misbuttondown(X))
 #define TEXT_HT _GP(usetup).textheight
 
 #endif
diff --git a/engines/ags/engine/gui/my_push_button.cpp b/engines/ags/engine/gui/my_push_button.cpp
index 4f3f8a03e37..34503ec4b77 100644
--- a/engines/ags/engine/gui/my_push_button.cpp
+++ b/engines/ags/engine/gui/my_push_button.cpp
@@ -72,7 +72,7 @@ void MyPushButton::draw(Bitmap *ds) {
 
 int MyPushButton::pressedon(int mx, int my) {
 	int wasstat;
-	while (mbutrelease(MouseLeft) == 0) {
+	while (!ags_misbuttondown(kMouseLeft) == 0) {
 
 		wasstat = state;
 		state = mouseisinarea(mx, my);
diff --git a/engines/ags/engine/main/game_run.cpp b/engines/ags/engine/main/game_run.cpp
index 91bc2adc8bd..9ddea6eef4d 100644
--- a/engines/ags/engine/main/game_run.cpp
+++ b/engines/ags/engine/main/game_run.cpp
@@ -192,16 +192,16 @@ static void check_mouse_controls() {
 		remove_popup_interface(_G(ifacepopped));
 
 	// check mouse clicks on GUIs
-	if ((_G(wasbutdown) > 0) && (ags_misbuttondown(_G(wasbutdown) - 1))) {
+	if ((_G(wasbutdown) > kMouseNone) && (ags_misbuttondown(_G(wasbutdown)))) {
 		gui_on_mouse_hold(_G(wasongui), _G(wasbutdown));
-	} else if ((_G(wasbutdown) > 0) && (!ags_misbuttondown(_G(wasbutdown) - 1))) {
+	} else if ((_G(wasbutdown) > kMouseNone) && (!ags_misbuttondown(_G(wasbutdown)))) {
 		gui_on_mouse_up(_G(wasongui), _G(wasbutdown));
-		_G(wasbutdown) = 0;
+		_G(wasbutdown) = kMouseNone;
 	}
 
-	int mbut = MouseNone;
-	int mwheelz = 0;
-	if (run_service_mb_controls(mbut, mwheelz) && mbut >= 0) {
+	eAGSMouseButton mbut;
+	int mwheelz;
+	if (run_service_mb_controls(mbut, mwheelz) && mbut > kMouseNone) {
 
 		check_skip_cutscene_mclick(mbut);
 
@@ -214,17 +214,17 @@ static void check_mouse_controls() {
 				_GP(play).SetWaitSkipResult(SKIP_MOUSECLICK, mbut);
 			}
 		} else if (!IsInterfaceEnabled());  // blocking cutscene, ignore mouse
-		else if (pl_run_plugin_hooks(AGSE_MOUSECLICK, mbut + 1)) {
+		else if (pl_run_plugin_hooks(AGSE_MOUSECLICK, mbut)) {
 			// plugin took the click
-			debug_script_log("Plugin handled mouse button %d", mbut + 1);
+			debug_script_log("Plugin handled mouse button %d", mbut);
 		} else if (mongu >= 0) {
-			if (_G(wasbutdown) == 0) {
-				gui_on_mouse_down(mongu, mbut + 1);
+			if (_G(wasbutdown) == kMouseNone) {
+				gui_on_mouse_down(mongu, mbut);
 			}
 			_G(wasongui) = mongu;
-			_G(wasbutdown) = mbut + 1;
+			_G(wasbutdown) = mbut;
 		} else
-			setevent(EV_TEXTSCRIPT, TS_MCLICK, mbut + 1);
+			setevent(EV_TEXTSCRIPT, TS_MCLICK, mbut);
 	}
 
 	if (mwheelz < 0)
@@ -256,6 +256,8 @@ bool run_service_key_controls(KeyInput &out_key) {
 	const bool is_only_mod_key = key_evt.type == Common::EVENT_KEYDOWN ?
 		is_mod_key(key_evt.kbd.keycode) : false;
 
+	out_key = KeyInput(); // reset to default
+
 	// Following section is for testing for pushed and released mod-keys.
 	// A bit of explanation: some service actions may require combination of
 	// mod-keys, for example [Ctrl + Alt] toggles mouse lock in window.
@@ -398,14 +400,12 @@ bool run_service_key_controls(KeyInput &out_key) {
 	return true;
 }
 
-bool run_service_mb_controls(int &mbut, int &mwheelz) {
-	int mb = ags_mgetbutton();
-	int mz = ags_check_mouse_wheel();
-	if (mb == MouseNone && mz == 0)
+bool run_service_mb_controls(eAGSMouseButton &mbut, int &mwheelz) {
+	mbut = ags_mgetbutton();
+	mwheelz = ags_check_mouse_wheel();
+	if (mbut == kMouseNone && mwheelz == 0)
 		return false;
-	lock_mouse_on_click(); // do not claim
-	mbut = mb;
-	mwheelz = mz;
+	lock_mouse_on_click();
 	return true;
 }
 
diff --git a/engines/ags/engine/main/game_run.h b/engines/ags/engine/main/game_run.h
index 0928801a596..9645123d334 100644
--- a/engines/ags/engine/main/game_run.h
+++ b/engines/ags/engine/main/game_run.h
@@ -22,6 +22,8 @@
 #ifndef AGS_ENGINE_MAIN_GAME_RUN_H
 #define AGS_ENGINE_MAIN_GAME_RUN_H
 
+#include "ags/shared/ac/keycode.h"
+
 namespace AGS3 {
 
 namespace AGS {
@@ -51,13 +53,12 @@ void UpdateGameAudioOnly();
 // Gets current logical game FPS, this is normally a fixed number set in script;
 // in case of "maxed fps" mode this function returns real measured FPS.
 float get_current_fps();
-struct KeyInput;
 // Runs service key controls, returns false if no key was pressed or key input was claimed by the engine,
 // otherwise returns true and provides a keycode.
 bool run_service_key_controls(KeyInput &kgn);
 // Runs service mouse controls, returns false if mouse input was claimed by the engine,
 // otherwise returns true and provides mouse button code.
-bool run_service_mb_controls(int &mbut, int &mwheelz);
+bool run_service_mb_controls(eAGSMouseButton &mbut, int &mwheelz);
 
 } // namespace AGS3
 
diff --git a/engines/ags/engine/media/video/video.cpp b/engines/ags/engine/media/video/video.cpp
index ebe07db2680..cea58c64d8a 100644
--- a/engines/ags/engine/media/video/video.cpp
+++ b/engines/ags/engine/media/video/video.cpp
@@ -111,7 +111,8 @@ static bool play_video(Video::VideoDecoder *decoder, const char *name, int flags
 		if (skip != VideoSkipNone) {
 			// Check for whether user aborted video
 			KeyInput key;
-			int mbut, mwheelz;
+			eAGSMouseButton mbut;
+			int mwheelz;
 			if (run_service_key_controls(key)) {
 				if (key.Key == 27 && skip >= VideoSkipEscape)
 					return true;
@@ -119,7 +120,7 @@ static bool play_video(Video::VideoDecoder *decoder, const char *name, int flags
 					return true;  // skip on any key
 			}
 
-			if (run_service_mb_controls(mbut, mwheelz) && mbut >= 0 && skip == VideoSkipKeyOrMouse) {
+			if (run_service_mb_controls(mbut, mwheelz) && mbut >= kMouseNone && skip == VideoSkipKeyOrMouse) {
 				return true; // skip on mouse click
 			}
 		}
diff --git a/engines/ags/globals.h b/engines/ags/globals.h
index 903e916c5cb..80498217e70 100644
--- a/engines/ags/globals.h
+++ b/engines/ags/globals.h
@@ -27,6 +27,7 @@
 
 #include "ags/lib/std/queue.h"
 #include "ags/shared/ac/game_version.h"
+#include "ags/shared/ac/keycode.h"
 #include "ags/shared/util/stdio_compat.h"
 #include "ags/shared/util/string.h"
 #include "ags/shared/util/string_types.h"
@@ -242,7 +243,8 @@ public:
 	int _mouse_accum_button_state = 0;
 	uint32 _mouse_clear_at_time = 0;
 	int _mouse_accum_relx = 0, _mouse_accum_rely = 0;
-	int _wasbutdown = 0, _wasongui = 0;
+	eAGSMouseButton _wasbutdown = kMouseNone;
+	int _wasongui = 0;
 
 	/**@}*/
 
@@ -1324,7 +1326,7 @@ public:
 	long _pl_file_handle = -1;
 	AGS::Shared::Stream *_pl_file_stream = nullptr;
 
-	int _pluginSimulatedClick = -1;
+	eAGSMouseButton _pluginSimulatedClick = kMouseNone;
 	int _mouse_z_was = 0;
 
 	/**@}*/
diff --git a/engines/ags/plugins/ags_plugin.cpp b/engines/ags/plugins/ags_plugin.cpp
index eb7d5b06327..19afd4a8f0b 100644
--- a/engines/ags/plugins/ags_plugin.cpp
+++ b/engines/ags/plugins/ags_plugin.cpp
@@ -86,7 +86,7 @@ const int PLUGIN_API_VERSION = 25;
 // we can reuse the same handle.
 
 void PluginSimulateMouseClick(int pluginButtonID) {
-	_G(pluginSimulatedClick) = pluginButtonID - 1;
+	_G(pluginSimulatedClick) = static_cast<eAGSMouseButton>(pluginButtonID);
 }
 
 void IAGSEngine::AbortGame(const char *reason) {
@@ -342,8 +342,9 @@ void IAGSEngine::BlitSpriteRotated(int32 x, int32 y, BITMAP *bmp, int32 angle) {
 void IAGSEngine::PollSystem() {
 	ags_domouse();
 	update_polled_stuff_if_runtime();
-	int mbut, mwheelz;
-	if (run_service_mb_controls(mbut, mwheelz) && mbut >= 0 && !_GP(play).IsIgnoringInput())
+	eAGSMouseButton mbut;
+	int mwheelz;
+	if (run_service_mb_controls(mbut, mwheelz) && mbut > kMouseNone && !_GP(play).IsIgnoringInput())
 		pl_run_plugin_hooks(AGSE_MOUSECLICK, mbut);
 	KeyInput kp;
 	if (run_service_key_controls(kp) && !_GP(play).IsIgnoringInput()) {
diff --git a/engines/ags/shared/ac/keycode.h b/engines/ags/shared/ac/keycode.h
index 97b2a8b137b..985da59eb07 100644
--- a/engines/ags/shared/ac/keycode.h
+++ b/engines/ags/shared/ac/keycode.h
@@ -276,6 +276,17 @@ struct KeyInput {
 	KeyInput() = default;
 };
 
+// AGS own mouse button codes;
+// These correspond to MouseButton enum in script API (sans special values)
+enum eAGSMouseButton
+{
+	kMouseNone = 0,
+	kMouseLeft = 1,
+	kMouseRight = 2,
+	kMouseMiddle = 3,
+	kNumMouseButtons
+};
+
 // Converts eAGSKeyCode to script API code, for "on_key_press" and similar callbacks
 int AGSKeyToScriptKey(int keycode);
 // Converts eAGSKeyCode to ASCII text representation with the range check; returns 0 on failure


Commit: 250e32f9a1b5fe43e5056a99c71a1118bff430c3
    https://github.com/scummvm/scummvm/commit/250e32f9a1b5fe43e5056a99c71a1118bff430c3
Author: Thierry Crozat (criezy at scummvm.org)
Date: 2022-10-10T00:16:16+01:00

Commit Message:
AGS: adjusted InputType and KeyMod for easier packing in int32

This allows to fully pack InputType, KeyMod and KeyCode/MouseButton/etc in a int32:

- 8 bits (0xFF) - input type
- 8 bits (0xFF) - key mod flags
- 4 bits (0xF) - reserved (potentially for expanding mod flags, if that will be necessary)
- 12 bits (0xFFF) - KeyCode, mouse codes, gamepad buttons, etc.

Purpose:
1. Potentially allow to set keycodes + mods in an integer and assign to an integer variable/property, such as "skip key", instead of using existing "combo keys"
2. In fact, with InputType flags, this makes it possible to assign a mouse or gamepad button to the same variables.
3. Potentially allow to return keycode + mods from Wait* (currently returns only single key).

>From upstream 0203e8feb73b96c501ac2439aa3fe3d6c182c8f4

Changed paths:
    engines/ags/engine/ac/game_state.cpp
    engines/ags/engine/ac/runtime_defines.h
    engines/ags/shared/ac/keycode.h


diff --git a/engines/ags/engine/ac/game_state.cpp b/engines/ags/engine/ac/game_state.cpp
index e675b6d2314..cffeed10286 100644
--- a/engines/ags/engine/ac/game_state.cpp
+++ b/engines/ags/engine/ac/game_state.cpp
@@ -387,8 +387,8 @@ void GameState::SetWaitSkipResult(int how, int data) {
 
 int GameState::GetWaitSkipResult() const {
 	// NOTE: we remove timer flag to make timeout reason = 0
-	return ((wait_skipped_by & ~SKIP_AUTOTIMER) << 16)
-		| (wait_skipped_by_data & 0x0000FFFF);
+	return ((wait_skipped_by & ~SKIP_AUTOTIMER) << SKIP_RESULT_TYPE_SHIFT)
+		| (wait_skipped_by_data & SKIP_RESULT_DATA_MASK);
 }
 
 bool GameState::IsBlockingVoiceSpeech() const {
diff --git a/engines/ags/engine/ac/runtime_defines.h b/engines/ags/engine/ac/runtime_defines.h
index b638ea44cb8..c43430952a3 100644
--- a/engines/ags/engine/ac/runtime_defines.h
+++ b/engines/ags/engine/ac/runtime_defines.h
@@ -134,11 +134,16 @@ const int LegacyRoomVolumeFactor = 30;
 #define EVENT_INPROGRESS 1
 #define EVENT_CLAIMED    2
 
-// Internal skip style flags, for speech/display, wait
+// Internal skip style flags, for speech/display, wait;
+ // theoretically correspond to InputType in script (with a 24-bit shift)
 #define SKIP_NONE       0x00
 #define SKIP_AUTOTIMER  0x01
 #define SKIP_KEYPRESS   0x02
 #define SKIP_MOUSECLICK 0x04
+// Bit shift for packing skip type into result
+#define SKIP_RESULT_TYPE_SHIFT 24
+// Bit mask for packing skip key/button data into result
+#define SKIP_RESULT_DATA_MASK  0x00FFFFFF
 
 #define MANOBJNUM 99
 
diff --git a/engines/ags/shared/ac/keycode.h b/engines/ags/shared/ac/keycode.h
index 985da59eb07..57e76e8b55c 100644
--- a/engines/ags/shared/ac/keycode.h
+++ b/engines/ags/shared/ac/keycode.h
@@ -249,18 +249,27 @@ enum eAGSKeyCode {
 	case 425: __allegro_KEY_NUMLOCK
 	case 426: __allegro_KEY_CAPSLOCK
 	*/
+
+	// Mask defines the key code position if packed in the int32;
+	// takes only 12 bits, as minimal necessary to accomodate historical codes.
+	eAGSKeyMask = 0x0FFF
 };
 
 // AGS key modifiers
 enum eAGSKeyMod {
-	eAGSModLShift = 0x0001,
-	eAGSModRShift = 0x0002,
-	eAGSModLCtrl = 0x0004,
-	eAGSModRCtrl = 0x0008,
-	eAGSModLAlt = 0x0010,
-	eAGSModRAlt = 0x0020,
-	eAGSModNum = 0x0040,
-	eAGSModCaps = 0x0080
+	eAGSModLShift = 0x00010000,
+	eAGSModRShift = 0x00020000,
+	eAGSModLCtrl  = 0x00040000,
+	eAGSModRCtrl  = 0x00080000,
+	eAGSModLAlt   = 0x00100000,
+	eAGSModRAlt   = 0x00200000,
+	eAGSModNum    = 0x00400000,
+	eAGSModCaps   = 0x00800000,
+
+	// Mask defines the key mod position if packed in the int32;
+	// the upper 8 bits are reserved for "input type" codes;
+	// potentially may take 4 bits below (4th pos), as KeyMask takes only 12.
+	eAGSModMask   = 0x00FF0000
 };
 
 // Combined key code and a textual representation in UTF-8


Commit: e2497cff428e3d496e5b59b2d6dfe2f0ea5f4b12
    https://github.com/scummvm/scummvm/commit/e2497cff428e3d496e5b59b2d6dfe2f0ea5f4b12
Author: Thierry Crozat (criezy at scummvm.org)
Date: 2022-10-10T00:16:16+01:00

Commit Message:
AGS: include KeyMods flags in the WaitSkipResult

>From upstream 65bfbb9bde733457b8ab958bb3cd273f7fadcb25

Changed paths:
    engines/ags/engine/ac/display.cpp
    engines/ags/engine/ac/game_state.h
    engines/ags/engine/main/game_run.cpp


diff --git a/engines/ags/engine/ac/display.cpp b/engines/ags/engine/ac/display.cpp
index c147be48278..3a4e2925535 100644
--- a/engines/ags/engine/ac/display.cpp
+++ b/engines/ags/engine/ac/display.cpp
@@ -294,13 +294,13 @@ ScreenOverlay *_display_main(int xx, int yy, int wii, const char *text, int disp
 					break;
 				}
 			}
-			KeyInput kp;
-			if (run_service_key_controls(kp)) {
-				check_skip_cutscene_keypress(kp.Key);
+			KeyInput ki;
+			if (run_service_key_controls(ki)) {
+				check_skip_cutscene_keypress(ki.Key);
 				if (_GP(play).fast_forward)
 					break;
 				if ((skip_setting & SKIP_KEYPRESS) && !_GP(play).IsIgnoringInput()) {
-					_GP(play).SetWaitSkipResult(SKIP_KEYPRESS, kp.Key);
+					_GP(play).SetWaitKeySkip(ki);
 					break;
 				}
 			}
diff --git a/engines/ags/engine/ac/game_state.h b/engines/ags/engine/ac/game_state.h
index 1cefd30ef6d..2a9c239c5be 100644
--- a/engines/ags/engine/ac/game_state.h
+++ b/engines/ags/engine/ac/game_state.h
@@ -25,6 +25,7 @@
 #include "ags/lib/std/memory.h"
 #include "ags/lib/std/vector.h"
 #include "ags/shared/ac/character_info.h"
+#include "ags/shared/ac/keycode.h"
 #include "ags/engine/ac/runtime_defines.h"
 #include "ags/engine/ac/speech.h"
 #include "ags/engine/ac/timer.h"
@@ -67,7 +68,6 @@ enum GameStateSvgVersion {
 };
 
 
-
 // Adding to this might need to modify AGSDEFNS.SH and AGSPLUGIN.H
 struct GameState {
 	int  score = 0;      // player's current score
@@ -359,10 +359,13 @@ struct GameState {
 
 	// Set how the last blocking wait was skipped
 	void SetWaitSkipResult(int how, int data = 0);
-	// Returns the code of the latest blocking wait skip method.
-	// * positive value means a key code;
-	// * negative value means a -(mouse code + 1);
-	// * 0 means timeout.
+	void SetWaitKeySkip(const KeyInput &kp) {
+		SetWaitSkipResult(SKIP_KEYPRESS, AGSKeyToScriptKey(kp.Key) | kp.Mod);
+	}
+	// Returns the information about how the latest blocking wait was skipped.
+	// The information is packed into int32 value like this:
+	// | 0xFF       | 0xFF    | 0xF      | 0xFFF                     |
+	// | eInputType | eKeyMod | reserved | eKeyCode, MouseButton etc |
 	int GetWaitSkipResult() const;
 
 	//
diff --git a/engines/ags/engine/main/game_run.cpp b/engines/ags/engine/main/game_run.cpp
index 9ddea6eef4d..cbaac2cd38a 100644
--- a/engines/ags/engine/main/game_run.cpp
+++ b/engines/ags/engine/main/game_run.cpp
@@ -442,7 +442,7 @@ static void check_keyboard_controls() {
 				(kgn != _GP(play).skip_speech_specific_key)) {
 			} else {
 				remove_screen_overlay(_GP(play).text_overlay_on);
-				_GP(play).SetWaitSkipResult(SKIP_KEYPRESS, kgn);
+				_GP(play).SetWaitKeySkip(ki);
 			}
 		}
 
@@ -450,7 +450,7 @@ static void check_keyboard_controls() {
 	}
 
 	if ((_GP(play).wait_counter != 0) && (_GP(play).key_skip_wait & SKIP_KEYPRESS) != 0) {
-		_GP(play).SetWaitSkipResult(SKIP_KEYPRESS, kgn);
+		_GP(play).SetWaitKeySkip(ki);
 		return;
 	}
 


Commit: 0927821afdbf7c12fb7fc9765bdaf13c2e65f9a7
    https://github.com/scummvm/scummvm/commit/0927821afdbf7c12fb7fc9765bdaf13c2e65f9a7
Author: Thierry Crozat (criezy at scummvm.org)
Date: 2022-10-10T00:16:16+01:00

Commit Message:
AGS: small refactor of key code variables (stricter names, types)

>From upstream e04c8ff1fe77e4462babd21d2a103a12e68b4b84

Changed paths:
    engines/ags/engine/ac/dialog.cpp
    engines/ags/engine/ac/inv_window.cpp
    engines/ags/engine/main/game_run.cpp
    engines/ags/shared/ac/keycode.cpp
    engines/ags/shared/ac/keycode.h


diff --git a/engines/ags/engine/ac/dialog.cpp b/engines/ags/engine/ac/dialog.cpp
index 84f61d1e8b7..c707a908593 100644
--- a/engines/ags/engine/ac/dialog.cpp
+++ b/engines/ags/engine/ac/dialog.cpp
@@ -820,12 +820,12 @@ bool DialogOptions::Run() {
 
 	KeyInput ki;
 	if (run_service_key_controls(ki) && !_GP(play).IsIgnoringInput()) {
-		eAGSKeyCode gkey = ki.Key;
+		const eAGSKeyCode agskey = ki.Key;
 		if (parserInput) {
 			wantRefresh = true;
 			// type into the parser 
 			// TODO: find out what are these key commands, and are these documented?
-			if ((gkey == eAGSKeyCodeF3) || ((gkey == eAGSKeyCodeSpace) && (parserInput->Text.GetLength() == 0))) {
+			if ((agskey == eAGSKeyCodeF3) || ((agskey == eAGSKeyCodeSpace) && (parserInput->Text.GetLength() == 0))) {
 				// write previous contents into textbox (F3 or Space when box is empty)
 				size_t last_len = ustrlen(_GP(play).lastParserEntry);
 				size_t cur_len = ustrlen(parserInput->Text.GetCStr());
@@ -841,7 +841,7 @@ bool DialogOptions::Run() {
 				//ags_domouse(DOMOUSE_DISABLE);
 				Redraw();
 				return true; // continue running loop
-			} else if ((gkey >= eAGSKeyCodeSpace) || (gkey == eAGSKeyCodeReturn) || (gkey == eAGSKeyCodeBackspace)) {
+			} else if ((agskey >= eAGSKeyCodeSpace) || (agskey == eAGSKeyCodeReturn) || (agskey == eAGSKeyCodeBackspace)) {
 				parserInput->OnKeyPress(ki);
 				if (!parserInput->IsActivated) {
 					//ags_domouse(DOMOUSE_DISABLE);
@@ -853,7 +853,7 @@ bool DialogOptions::Run() {
 			if (old_keyhandle || (ki.UChar == 0)) {
 				// "dialog_options_key_press"
 				_GP(runDialogOptionKeyPressHandlerFunc).params[0].SetDynamicObject(&_GP(ccDialogOptionsRendering), &_GP(ccDialogOptionsRendering));
-				_GP(runDialogOptionKeyPressHandlerFunc).params[1].SetInt32(AGSKeyToScriptKey(gkey));
+				_GP(runDialogOptionKeyPressHandlerFunc).params[1].SetInt32(AGSKeyToScriptKey(ki.Key));
 				_GP(runDialogOptionKeyPressHandlerFunc).params[2].SetInt32(ki.Mod);
 				run_function_on_non_blocking_thread(&_GP(runDialogOptionKeyPressHandlerFunc));
 			}
@@ -866,8 +866,8 @@ bool DialogOptions::Run() {
 		}
 		// Allow selection of options by keyboard shortcuts
 		else if (_GP(game).options[OPT_DIALOGNUMBERED] >= kDlgOptKeysOnly &&
-			gkey >= '1' && gkey <= '9') {
-			int numkey = gkey - '1';
+			agskey >= '1' && agskey <= '9') {
+			int numkey = agskey - '1';
 			if (numkey < numdisp) {
 				chose = disporder[numkey];
 				return false; // end dialog options running loop
diff --git a/engines/ags/engine/ac/inv_window.cpp b/engines/ags/engine/ac/inv_window.cpp
index d8874e14b57..204edfd1d12 100644
--- a/engines/ags/engine/ac/inv_window.cpp
+++ b/engines/ags/engine/ac/inv_window.cpp
@@ -346,8 +346,8 @@ bool InventoryScreen::Run() {
 	// Run() can be called in a loop, so keep events going.
 	sys_evt_process_pending();
 
-	KeyInput kgn;
-	if (run_service_key_controls(kgn) && !_GP(play).IsIgnoringInput()) {
+	KeyInput ki;
+	if (run_service_key_controls(ki) && !_GP(play).IsIgnoringInput()) {
 		return false; // end inventory screen loop
 	}
 
diff --git a/engines/ags/engine/main/game_run.cpp b/engines/ags/engine/main/game_run.cpp
index cbaac2cd38a..85f6429a3c3 100644
--- a/engines/ags/engine/main/game_run.cpp
+++ b/engines/ags/engine/main/game_run.cpp
@@ -323,7 +323,7 @@ bool run_service_key_controls(KeyInput &out_key) {
 	}
 
 	// Alt+X, abort (but only once game is loaded)
-	if ((_G(displayed_room) >= 0) && (_GP(play).abort_key > 0 && agskey == _GP(play).abort_key)) {
+	if ((_G(displayed_room) >= 0) && (agskey == _GP(play).abort_key)) {
 		Debug::Printf("Abort key pressed");
 		_G(check_dynamic_sprites_at_exit) = 0;
 		quit("!|");
@@ -417,9 +417,9 @@ static void check_keyboard_controls() {
 	if (!run_service_key_controls(ki)) {
 		return;
 	}
-	eAGSKeyCode kgn = ki.Key;
+	const eAGSKeyCode agskey = ki.Key;
 	// Then, check cutscene skip
-	check_skip_cutscene_keypress(kgn);
+	check_skip_cutscene_keypress(agskey);
 	if (_GP(play).fast_forward) {
 		return;
 	}
@@ -427,9 +427,9 @@ static void check_keyboard_controls() {
 		return;
 	}
 	// Now check for in-game controls
-	if (pl_run_plugin_hooks(AGSE_KEYPRESS, kgn)) {
+	if (pl_run_plugin_hooks(AGSE_KEYPRESS, agskey)) {
 		// plugin took the keypress
-		debug_script_log("Keypress code %d taken by plugin", kgn);
+		debug_script_log("Keypress code %d taken by plugin", agskey);
 		return;
 	}
 
@@ -438,9 +438,8 @@ static void check_keyboard_controls() {
 		// only allow a key to remove the overlay if the icon bar isn't up
 		if (IsGamePaused() == 0) {
 			// check if it requires a specific keypress
-			if ((_GP(play).skip_speech_specific_key > 0) &&
-				(kgn != _GP(play).skip_speech_specific_key)) {
-			} else {
+			if ((_GP(play).skip_speech_specific_key == 0) ||
+				(agskey == _GP(play).skip_speech_specific_key)) {
 				remove_screen_overlay(_GP(play).text_overlay_on);
 				_GP(play).SetWaitKeySkip(ki);
 			}
@@ -456,7 +455,7 @@ static void check_keyboard_controls() {
 
 	if (_G(inside_script)) {
 		// Don't queue up another keypress if it can't be run instantly
-		debug_script_log("Keypress %d ignored (game blocked)", kgn);
+		debug_script_log("Keypress %d ignored (game blocked)", agskey);
 		return;
 	}
 
@@ -466,8 +465,9 @@ static void check_keyboard_controls() {
 	// it should do if a displayable character (32-255) is
 	// pressed, but exclude control characters (<32) and
 	// extended keys (eg. up/down arrow; 256+)
-	if ((((kgn >= 32) && (kgn <= 255) && (kgn != '[')) || (kgn == eAGSKeyCodeReturn) || (kgn == eAGSKeyCodeBackspace))
-			&& (_G(all_buttons_disabled) < 0)) {
+	if ( (((agskey >= 32) && (agskey <= 255) && (agskey != '[')) ||
+			(agskey == eAGSKeyCodeReturn) || (agskey == eAGSKeyCodeBackspace))
+		&& (_G(all_buttons_disabled) < 0)) {
 		for (int guiIndex = 0; guiIndex < _GP(game).numgui; guiIndex++) {
 			auto &gui = _GP(guis)[guiIndex];
 
@@ -505,17 +505,17 @@ static void check_keyboard_controls() {
 	}
 
 	// Built-in key-presses
-	if (kgn == _GP(usetup).key_save_game) {
+	if (agskey == _GP(usetup).key_save_game) {
 		do_save_game_dialog();
 		return;
-	} else if (kgn == _GP(usetup).key_restore_game) {
+	} else if (agskey == _GP(usetup).key_restore_game) {
 		do_restore_game_dialog();
 		return;
 	}
 
 	if (!keywasprocessed) {
-		int sckey = AGSKeyToScriptKey(kgn);
-		int sckeymod = ki.Mod;
+		const int sckey = AGSKeyToScriptKey(ki.Key);
+		const int sckeymod = ki.Mod;
 		if (old_keyhandle || (ki.UChar == 0)) {
 			debug_script_log("Running on_key_press keycode %d, mod %d", sckey, sckeymod);
 			setevent(EV_TEXTSCRIPT, TS_KEYPRESS, sckey, sckeymod);
diff --git a/engines/ags/shared/ac/keycode.cpp b/engines/ags/shared/ac/keycode.cpp
index 7b256f55810..7c689b64e10 100644
--- a/engines/ags/shared/ac/keycode.cpp
+++ b/engines/ags/shared/ac/keycode.cpp
@@ -23,12 +23,13 @@
 
 namespace AGS3 {
 
-int AGSKeyToScriptKey(int keycode) {
+eAGSKeyCode AGSKeyToScriptKey(eAGSKeyCode keycode) {
 	// Script API requires strictly capital letters, if this is a small letter - capitalize it
-	return (keycode >= 'a' && keycode <= 'z') ? keycode - 'a' + 'A' : keycode;
+	return (keycode >= 'a' && keycode <= 'z') ?
+			static_cast<eAGSKeyCode>(keycode - 'a' + 'A') : keycode;
 }
 
-char AGSKeyToText(int keycode) {
+char AGSKeyToText(eAGSKeyCode keycode) {
 	// support only printable characters (128-255 are chars from extended fonts)
 	if (keycode >= 32 && keycode < 256)
 		return static_cast<char>(keycode);
diff --git a/engines/ags/shared/ac/keycode.h b/engines/ags/shared/ac/keycode.h
index 57e76e8b55c..5f9c84335ef 100644
--- a/engines/ags/shared/ac/keycode.h
+++ b/engines/ags/shared/ac/keycode.h
@@ -297,10 +297,10 @@ enum eAGSMouseButton
 };
 
 // Converts eAGSKeyCode to script API code, for "on_key_press" and similar callbacks
-int AGSKeyToScriptKey(int keycode);
+eAGSKeyCode AGSKeyToScriptKey(eAGSKeyCode keycode);
 // Converts eAGSKeyCode to ASCII text representation with the range check; returns 0 on failure
 // Not unicode compatible.
-char AGSKeyToText(int keycode);
+char AGSKeyToText(eAGSKeyCode keycode);
 
 } // namespace AGS3
 


Commit: bcb854370dd848152526295b3c3f8406cef040bd
    https://github.com/scummvm/scummvm/commit/bcb854370dd848152526295b3c3f8406cef040bd
Author: Thierry Crozat (criezy at scummvm.org)
Date: 2022-10-10T00:16:16+01:00

Commit Message:
AGS: key plugin callback and game. vars must use "CompatKey"

>From upstream 555a3060491523d2c236f0bbb77b981eab2d4359

Changed paths:
    engines/ags/engine/main/game_run.cpp


diff --git a/engines/ags/engine/main/game_run.cpp b/engines/ags/engine/main/game_run.cpp
index 85f6429a3c3..fb77bff51de 100644
--- a/engines/ags/engine/main/game_run.cpp
+++ b/engines/ags/engine/main/game_run.cpp
@@ -314,7 +314,7 @@ bool run_service_key_controls(KeyInput &out_key) {
 	if (ki.Key == eAGSKeyCodeNone)
 		return false; // should skip this key event
 
-	// Use backward-compatible combined key for service checks
+	// Use backward-compatible combined key (comparable with script variables)
 	eAGSKeyCode agskey = ki.CompatKey;
 	// LAlt or RAlt + Enter/Return
 	if ((cur_mod == Common::KBD_ALT) && agskey == eAGSKeyCodeReturn) {
@@ -417,7 +417,8 @@ static void check_keyboard_controls() {
 	if (!run_service_key_controls(ki)) {
 		return;
 	}
-	const eAGSKeyCode agskey = ki.Key;
+	// Use backward-compatible combined key (comparable with script variables)
+	const eAGSKeyCode agskey = ki.CompatKey;
 	// Then, check cutscene skip
 	check_skip_cutscene_keypress(agskey);
 	if (_GP(play).fast_forward) {


Commit: 9f24f6eda4a883544921315bd1cfc7820b8f014d
    https://github.com/scummvm/scummvm/commit/9f24f6eda4a883544921315bd1cfc7820b8f014d
Author: Thierry Crozat (criezy at scummvm.org)
Date: 2022-10-10T00:16:16+01:00

Commit Message:
AGS: fixed ags_misbuttondown()

Complementing afdccb3d3 (upstream 471098d)

>From upstream f6e23781c4895ab79b42f97324743356aa401eec

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


diff --git a/engines/ags/engine/ac/sys_events.cpp b/engines/ags/engine/ac/sys_events.cpp
index c5080ce153a..c0309ad87e4 100644
--- a/engines/ags/engine/ac/sys_events.cpp
+++ b/engines/ags/engine/ac/sys_events.cpp
@@ -55,7 +55,7 @@ using namespace AGS::Engine;
 extern void domouse(int str);
 // Convert mouse button id to flags
 const int MouseButton2Bits[kNumMouseButtons] =
-	{ MouseBitLeft, MouseBitRight, MouseBitMiddle };
+	{ 0, MouseBitLeft, MouseBitRight, MouseBitMiddle };
 static void(*_on_quit_callback)(void) = nullptr;
 static void(*_on_switchin_callback)(void) = nullptr;
 static void(*_on_switchout_callback)(void) = nullptr;


Commit: a06124e572d6b9f7eeec03803f250689b666a9eb
    https://github.com/scummvm/scummvm/commit/a06124e572d6b9f7eeec03803f250689b666a9eb
Author: Thierry Crozat (criezy at scummvm.org)
Date: 2022-10-10T00:16:16+01:00

Commit Message:
AGS: Updated build version (3.6.0.31)

>From upstream ecaf7c59bb5cf7901d1429f2145954c665c85629

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 4f2d45b5c9d..70eab91245d 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.30"
+#define ACI_VERSION_STR      "3.6.0.31"
 #if defined (RC_INVOKED) // for MSVC resource compiler
-#define ACI_VERSION_MSRC_DEF  3.6.0.30
+#define ACI_VERSION_MSRC_DEF  3.6.0.31
 #endif
 
 #define SPECIAL_VERSION ""


Commit: 6163d4880a0ca2848fe28a4aa031c4f3ef9bc5ff
    https://github.com/scummvm/scummvm/commit/6163d4880a0ca2848fe28a4aa031c4f3ef9bc5ff
Author: Thierry Crozat (criezy at scummvm.org)
Date: 2022-10-10T00:16:16+01:00

Commit Message:
AGS: fixed CompatKey may be "none" in some cases for valid key press

>From upstream f0e699392866b1b737a6b5be08790cbddbc6767d

Changed paths:
    engines/ags/engine/ac/sys_events.cpp
    engines/ags/engine/main/game_run.cpp


diff --git a/engines/ags/engine/ac/sys_events.cpp b/engines/ags/engine/ac/sys_events.cpp
index c0309ad87e4..9c691138f6b 100644
--- a/engines/ags/engine/ac/sys_events.cpp
+++ b/engines/ags/engine/ac/sys_events.cpp
@@ -70,7 +70,8 @@ KeyInput ags_keycode_from_scummvm(const Common::Event &event, bool old_keyhandle
 	ki.UChar = event.kbd.ascii;
 	ki.Key = ::AGS::g_events->scummvm_key_to_ags_key(event, ki.Mod, old_keyhandle);
 	ki.CompatKey = ::AGS::g_events->scummvm_key_to_ags_key(event, ki.Mod, true);
-
+	if (ki.CompatKey == eAGSKeyCodeNone)
+		ki.CompatKey = ki.Key;
 	return ki;
 }
 
diff --git a/engines/ags/engine/main/game_run.cpp b/engines/ags/engine/main/game_run.cpp
index fb77bff51de..9f5a5b9340e 100644
--- a/engines/ags/engine/main/game_run.cpp
+++ b/engines/ags/engine/main/game_run.cpp
@@ -314,7 +314,7 @@ bool run_service_key_controls(KeyInput &out_key) {
 	if (ki.Key == eAGSKeyCodeNone)
 		return false; // should skip this key event
 
-	// Use backward-compatible combined key (comparable with script variables)
+	// Use backward-compatible combined key for special controls
 	eAGSKeyCode agskey = ki.CompatKey;
 	// LAlt or RAlt + Enter/Return
 	if ((cur_mod == Common::KBD_ALT) && agskey == eAGSKeyCodeReturn) {
@@ -417,7 +417,7 @@ static void check_keyboard_controls() {
 	if (!run_service_key_controls(ki)) {
 		return;
 	}
-	// Use backward-compatible combined key (comparable with script variables)
+	// Use backward-compatible combined key for special controls
 	const eAGSKeyCode agskey = ki.CompatKey;
 	// Then, check cutscene skip
 	check_skip_cutscene_keypress(agskey);


Commit: 483ff1bc309b92c564bd9e6527b2b5ee075ee4eb
    https://github.com/scummvm/scummvm/commit/483ff1bc309b92c564bd9e6527b2b5ee075ee4eb
Author: Thierry Crozat (criezy at scummvm.org)
Date: 2022-10-10T00:16:16+01:00

Commit Message:
AGS: fixed object cache may sometimes keep an old dynsprite ref

This may result in object texture not updating if the old sprite was deleted but a new dynamic sprite was created right after having same ID.

Was broken by upstream 9dffb04 in 3.5.1, and also some later changes in 3.6.0.

>From upstream 7ed51861898d864902b0f61b0cb7d0acadef1fe3

Changed paths:
    engines/ags/engine/ac/draw.cpp
    engines/ags/engine/ac/draw.h
    engines/ags/engine/ac/game.cpp


diff --git a/engines/ags/engine/ac/draw.cpp b/engines/ags/engine/ac/draw.cpp
index c1525ae1ace..1204386ab7e 100644
--- a/engines/ags/engine/ac/draw.cpp
+++ b/engines/ags/engine/ac/draw.cpp
@@ -603,19 +603,24 @@ void mark_object_changed(int objid) {
 	_G(objcache)[objid].y = -9999;
 }
 
-void reset_objcache_for_sprite(int sprnum) {
-	// Check if this sprite is assigned to any game object, and update them if necessary
+void reset_objcache_for_sprite(int sprnum, bool deleted) {
+	// Check if this sprite is assigned to any game object, and mark these for update;
+	// if the sprite was deleted, also dispose shared textures
 	// room objects cache
 	if (_G(croom) != nullptr) {
 		for (size_t i = 0; i < (size_t)_G(croom)->numobj; ++i) {
-			if (_G(objs)[i].num == sprnum)
+			if (_G(objcache)[i].sppic == sprnum)
 				_G(objcache)[i].sppic = -1;
+			if (deleted && (_GP(actsps)[i].SpriteID == sprnum))
+				_GP(actsps)[i] = ObjTexture();
 		}
 	}
 	// character cache
 	for (size_t i = 0; i < (size_t)_GP(game).numcharacters; ++i) {
 		if (_GP(charcache)[i].sppic == sprnum)
 			_GP(charcache)[i].sppic = -1;
+		if (deleted && (_GP(actsps)[ACTSP_OBJSOFF + i].SpriteID == sprnum))
+			_GP(actsps)[i] = ObjTexture();
 	}
 }
 
diff --git a/engines/ags/engine/ac/draw.h b/engines/ags/engine/ac/draw.h
index e6f1b9a7cfe..ab457390151 100644
--- a/engines/ags/engine/ac/draw.h
+++ b/engines/ags/engine/ac/draw.h
@@ -132,7 +132,7 @@ void on_roomcamera_changed(Camera *cam);
 // Marks particular object as need to update the texture
 void mark_object_changed(int objid);
 // Resets all object caches which reference this sprite
-void reset_objcache_for_sprite(int sprnum);
+void reset_objcache_for_sprite(int sprnum, bool deleted);
 
 // whether there are currently remnants of a DisplaySpeech
 void mark_screen_dirty();
diff --git a/engines/ags/engine/ac/game.cpp b/engines/ags/engine/ac/game.cpp
index d3b29f8552e..57ae9da485b 100644
--- a/engines/ags/engine/ac/game.cpp
+++ b/engines/ags/engine/ac/game.cpp
@@ -1347,7 +1347,7 @@ void game_sprite_updated(int sprnum) {
 	_G(gfxDriver)->UpdateSharedDDB(sprnum, _GP(spriteset)[sprnum], (_GP(game).SpriteInfos[sprnum].Flags & SPF_ALPHACHANNEL) != 0, false);
 
 	// character and object draw caches
-	reset_objcache_for_sprite(sprnum);
+	reset_objcache_for_sprite(sprnum, false);
 
 	// gui backgrounds
 	for (auto &gui : _GP(guis)) {
@@ -1378,7 +1378,7 @@ void game_sprite_deleted(int sprnum) {
 	// clear from texture cache
 	_G(gfxDriver)->ClearSharedDDB(sprnum);
 	// character and object draw caches
-	reset_objcache_for_sprite(sprnum);
+	reset_objcache_for_sprite(sprnum, true);
 	// room object graphics
 	if (_G(croom) != nullptr) {
 		for (size_t i = 0; i < (size_t)_G(croom)->numobj; ++i) {


Commit: 2f8d4cb072ce82c30711e457e52f481a13b50769
    https://github.com/scummvm/scummvm/commit/2f8d4cb072ce82c30711e457e52f481a13b50769
Author: Thierry Crozat (criezy at scummvm.org)
Date: 2022-10-10T00:16:16+01:00

Commit Message:
AGS: PlayVideo supports playing game and video sound together

>From commit f2a9f3043aac24b0e70b48602a664541ec12df8d

Changed paths:
    engines/ags/engine/ac/global_video.cpp
    engines/ags/engine/media/video/video.cpp
    engines/ags/engine/media/video/video.h


diff --git a/engines/ags/engine/ac/global_video.cpp b/engines/ags/engine/ac/global_video.cpp
index 253c2507d48..79a934d0c77 100644
--- a/engines/ags/engine/ac/global_video.cpp
+++ b/engines/ags/engine/ac/global_video.cpp
@@ -87,18 +87,21 @@ void PlayVideo(const char *name, int skip, int scr_flags) {
 		return;
 
 	// Convert PlayVideo flags to common video flags
-	/*
-	0: the video will be played at original size, with AVI audio
-	1: the video will be stretched to full screen, with appropriate
-	   black borders to maintain its aspect ratio and AVI audio.
-	10: original size, with game audio continuing (AVI audio muted)
-	11: stretched to full screen, with game audio continuing (AVI audio muted)
+	/* NOTE: historically using decimal "flags"
+	default (0): the video will be played at original size,
+				video's own audio is playing, game sounds muted;
+	1: the video will be stretched to full screen;
+	10: keep game audio only, video's own audio muted;
+	-- since 3.6.0:
+	20: play both game audio and video's own audio
 	*/
 	int flags = kVideo_EnableVideo;
 	if ((scr_flags % 10) == 1)
 		flags |= kVideo_Stretch;
-	if (scr_flags < 10)
+	if ((scr_flags / 10) == 0 || (scr_flags / 10) == 2)
 		flags |= kVideo_EnableAudio;
+	if ((scr_flags / 10) > 0)
+		flags |= kVideo_KeepGameAudio;
 
 	// if game audio is disabled, then don't play any sound on the video either
 	if (!_GP(usetup).audio_enabled)
@@ -113,11 +116,17 @@ void PlayVideo(const char *name, int skip, int scr_flags) {
 #ifndef AGS_NO_VIDEO_PLAYER
 
 void pause_sound_if_necessary_and_play_video(const char *name, int flags, VideoSkipType skip) {
+	// Save the game audio parameters, in case we stop these
 	int musplaying = _GP(play).cur_music_number, i;
 	int ambientWas[MAX_GAME_CHANNELS]{ 0 };
 	for (i = NUM_SPEECH_CHANS; i < _GP(game).numGameChannels; i++)
 		ambientWas[i] = _GP(ambient)[i].channel;
 
+	// Optionally stop the game audio
+	if ((flags & kVideo_KeepGameAudio) == 0) {
+		stop_all_sound_and_music();
+	}
+
 	if ((strlen(name) > 3) && (ags_stricmp(&name[strlen(name) - 3], "ogv") == 0)) {
 		play_theora_video(name, flags, skip, true);
 	} else if ((strlen(name) > 3) && (ags_stricmp(&name[strlen(name) - 3], "mpg") == 0)) {
@@ -132,9 +141,9 @@ void pause_sound_if_necessary_and_play_video(const char *name, int flags, VideoS
 			Display("Unsupported video '%s'", name);
 	}
 
-	if ((flags & kVideo_EnableAudio) != 0) {
+	// Restore the game audio if we stopped them before the video playback
+	if ((flags & kVideo_KeepGameAudio) == 0) {
 		update_music_volume();
-		// restart the music
 		if (musplaying >= 0)
 			newmusic(musplaying);
 		for (i = NUM_SPEECH_CHANS; i < _GP(game).numGameChannels; i++) {
diff --git a/engines/ags/engine/media/video/video.cpp b/engines/ags/engine/media/video/video.cpp
index cea58c64d8a..8c2e8c70cc4 100644
--- a/engines/ags/engine/media/video/video.cpp
+++ b/engines/ags/engine/media/video/video.cpp
@@ -75,10 +75,8 @@ static bool play_video(Video::VideoDecoder *decoder, const char *name, int flags
 	bool enableVideo = (flags & kVideo_EnableVideo) != 0;
 	bool enableAudio = (flags & kVideo_EnableAudio) != 0;
 
-	// TODO: This seems back to front
-	if (enableAudio) {
-		stop_all_sound_and_music();
-	}
+	if (!enableAudio)
+		decoder->setVolume(0);
 
 	update_polled_stuff_if_runtime();
 	 
diff --git a/engines/ags/engine/media/video/video.h b/engines/ags/engine/media/video/video.h
index 8d3acd297eb..2ae9e1858d0 100644
--- a/engines/ags/engine/media/video/video.h
+++ b/engines/ags/engine/media/video/video.h
@@ -42,6 +42,7 @@ enum VideoFlags {
 	kVideo_ClearScreen = 0x0004,
 	kVideo_LegacyFrameSize = 0x0008,
 	kVideo_EnableAudio = 0x0010,
+	kVideo_KeepGameAudio  = 0x0020
 };
 
 enum VideoSkipType {


Commit: 6bae4af00517dd7ec339f4c8bbd0c56933998711
    https://github.com/scummvm/scummvm/commit/6bae4af00517dd7ec339f4c8bbd0c56933998711
Author: Thierry Crozat (criezy at scummvm.org)
Date: 2022-10-10T00:16:16+01:00

Commit Message:
AGS: rename "multitasking" option to "background" and added cmd arg

>From upstream cb83231c03764c74b8f8f09f8c876207a475f7b9

Changed paths:
    engines/ags/engine/main/config.cpp
    engines/ags/engine/main/main.cpp


diff --git a/engines/ags/engine/main/config.cpp b/engines/ags/engine/main/config.cpp
index 9e3ad21d84e..6dfd83a1267 100644
--- a/engines/ags/engine/main/config.cpp
+++ b/engines/ags/engine/main/config.cpp
@@ -350,7 +350,7 @@ void apply_config(const ConfigTree &cfg) {
 		}
 
 		// Various system options
-		_GP(usetup).multitasking = CfgReadInt(cfg, "misc", "multitasking", 0) != 0;
+		_GP(usetup).multitasking = CfgReadInt(cfg, "misc", "background", 0) != 0;
 
 		// User's overrides and hacks
 		_GP(usetup).override_multitasking = CfgReadInt(cfg, "override", "multitasking", -1);
diff --git a/engines/ags/engine/main/main.cpp b/engines/ags/engine/main/main.cpp
index 9372b788b89..42a42f31ab2 100644
--- a/engines/ags/engine/main/main.cpp
+++ b/engines/ags/engine/main/main.cpp
@@ -96,6 +96,8 @@ void main_print_help() {
 	                          "Usage: ags [OPTIONS] [GAMEFILE or DIRECTORY]\n\n"
 	                          //--------------------------------------------------------------------------------|
 	                          "Options:\n"
+                              "  --background                 Keeps game running in background\n"
+                              "                               (this does not work in exclusive fullscreen)\n"
                               "  --clear-cache-on-room-change Clears sprite cache on every room change\n"
 	                          "  --conf FILEPATH              Specify explicit config file to read on startup\n"
 #if AGS_PLATFORM_OS_WINDOWS
@@ -261,6 +263,8 @@ int main_process_cmdline(ConfigTree &cfg, int argc, const char *argv[]) {
 			cfg["language"]["translation"] = argv[++ee];
 		} else if (ags_stricmp(arg, "--no-translation") == 0) {
 			cfg["language"]["translation"] = "";
+		} else if (ags_stricmp(arg, "--background") == 0) {
+			cfg["override"]["multitasking"] = "1";
 		} else if (ags_stricmp(arg, "--fps") == 0)
 			cfg["misc"]["show_fps"] = "1";
 		else if (ags_stricmp(arg, "--test") == 0) _G(debug_flags) |= DBG_DEBUGMODE;


Commit: c7f44082b8bdcfb4ae16eca5a8c744f64371630b
    https://github.com/scummvm/scummvm/commit/c7f44082b8bdcfb4ae16eca5a8c744f64371630b
Author: Thierry Crozat (criezy at scummvm.org)
Date: 2022-10-10T00:16:16+01:00

Commit Message:
AGS: more explicit code for the video flag parsing (PlayVideo/Flic)

This is just for easier to maintain / safer code.

>From upstream ee2f91560969d22bd92a5e75af5a447937afb5c5

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


diff --git a/engines/ags/engine/ac/global_video.cpp b/engines/ags/engine/ac/global_video.cpp
index 79a934d0c77..059eda6ee13 100644
--- a/engines/ags/engine/ac/global_video.cpp
+++ b/engines/ags/engine/ac/global_video.cpp
@@ -56,24 +56,32 @@ void PlayFlic(int numb, int scr_flags) {
 		_GP(play).screen_is_faded_out = 0;
 
 	// Convert PlayFlic flags to common video flags
-	/*
-	0  player can't skip animation
-	1  player can press ESC to skip animation
-	2  player can press any key or click mouse to skip animation
-	+10 (i.e.10,11,12) do not stretch to full-screen, just play at flc size
-	+100 do not clear the screen before starting playback
+	/* NOTE: historically using decimal "flags"
+	default (0): the video will be played stretched to screen;
+		player cannot skip animation; screen will be cleared
+	1: player can press ESC to skip animation
+	2: player can press any key or click mouse to skip animation
+	10: play the video at original size
+	100: do not clear the screen before starting playback
 	*/
 	int flags = kVideo_EnableVideo;
 	VideoSkipType skip = VideoSkipNone;
+	// skip type
 	switch (scr_flags % 10) {
 	case 1: skip = VideoSkipEscape; break;
 	case 2: skip = VideoSkipKeyOrMouse; break;
-	default: break;
+	default: skip = VideoSkipNone; break;
+	}
+	// video size
+	switch ((scr_flags % 100) / 10) {
+	case 1: /* play original size, no flag */ break;
+	default: flags |= kVideo_Stretch;
+	}
+	// clear screen
+	switch ((scr_flags % 1000) / 100) {
+	case 1: /* don't clear screen, no flag */ break;
+	default: flags |= kVideo_ClearScreen;
 	}
-	if ((scr_flags % 100) < 10)
-		flags |= kVideo_Stretch;
-	if (scr_flags < 100)
-		flags |= kVideo_ClearScreen;
 
 	play_flc_video(numb, flags, skip);
 }
@@ -89,19 +97,24 @@ void PlayVideo(const char *name, int skip, int scr_flags) {
 	// Convert PlayVideo flags to common video flags
 	/* NOTE: historically using decimal "flags"
 	default (0): the video will be played at original size,
-				video's own audio is playing, game sounds muted;
+		video's own audio is playing, game sounds muted;
 	1: the video will be stretched to full screen;
 	10: keep game audio only, video's own audio muted;
 	-- since 3.6.0:
 	20: play both game audio and video's own audio
 	*/
 	int flags = kVideo_EnableVideo;
-	if ((scr_flags % 10) == 1)
-		flags |= kVideo_Stretch;
-	if ((scr_flags / 10) == 0 || (scr_flags / 10) == 2)
-		flags |= kVideo_EnableAudio;
-	if ((scr_flags / 10) > 0)
-		flags |= kVideo_KeepGameAudio;
+	// video size
+	switch (scr_flags % 10) {
+	case 1: flags |= kVideo_Stretch; break;
+	default: break;
+	}
+	// audio option
+	switch ((scr_flags % 100) / 10) {
+	case 1: flags |= kVideo_KeepGameAudio; break;
+	case 2: flags |= kVideo_EnableAudio | kVideo_KeepGameAudio; break;
+	default: flags |= kVideo_EnableAudio; break;
+	}
 
 	// if game audio is disabled, then don't play any sound on the video either
 	if (!_GP(usetup).audio_enabled)


Commit: 58212aeebd2037b889abde52f8cacaa6eef98b2f
    https://github.com/scummvm/scummvm/commit/58212aeebd2037b889abde52f8cacaa6eef98b2f
Author: Thierry Crozat (criezy at scummvm.org)
Date: 2022-10-10T00:16:16+01:00

Commit Message:
AGS: added render callback AGSE_POSTROOMDRAW

This render stage overlays the room with objects and characters, but
stays within room transform, therefore will work with non-standard
viewport positions and multiple cameras.
The next closest stage is AGSE_PREGUIDRAW, which is rendered outside
room viewport. The new one fills the missing stage, lacking after the
viewport/camera update in 3.5.0.

>From upstream 4ff7e14400ab81693fb64195d9ada70e979647ac

Changed paths:
    engines/ags/engine/ac/draw.cpp
    engines/ags/plugins/ags_plugin.h


diff --git a/engines/ags/engine/ac/draw.cpp b/engines/ags/engine/ac/draw.cpp
index 1204386ab7e..d416ccc979d 100644
--- a/engines/ags/engine/ac/draw.cpp
+++ b/engines/ags/engine/ac/draw.cpp
@@ -1756,6 +1756,9 @@ void prepare_room_sprites() {
 		add_thing_to_draw(_GP(debugRoomMaskObj).Ddb, 0, 0);
 	if ((_G(debugMoveListChar) >= 0) && _GP(debugMoveListObj).Ddb)
 		add_thing_to_draw(_GP(debugMoveListObj).Ddb, 0, 0);
+
+	if (pl_any_want_hook(AGSE_POSTROOMDRAW))
+		add_render_stage(AGSE_POSTROOMDRAW);
 }
 
 // Draws the black surface behind (or rather between) the room viewports
diff --git a/engines/ags/plugins/ags_plugin.h b/engines/ags/plugins/ags_plugin.h
index 752e8fec427..a71b473649e 100644
--- a/engines/ags/plugins/ags_plugin.h
+++ b/engines/ags/plugins/ags_plugin.h
@@ -239,18 +239,20 @@ public:
 #define AGSE_TRANSITIONOUT   0x400
 // Below are interface 12 and later
 #define AGSE_FINALSCREENDRAW 0x800
-#define AGSE_TRANSLATETEXT  0x1000
+#define AGSE_TRANSLATETEXT   0x1000
 // Below are interface 13 and later
-#define AGSE_SCRIPTDEBUG    0x2000
-#define AGSE_AUDIODECODE    0x4000 // obsolete, no longer supported
+#define AGSE_SCRIPTDEBUG     0x2000
+#define AGSE_AUDIODECODE     0x4000 // obsolete, no longer supported
 // Below are interface 18 and later
-#define AGSE_SPRITELOAD     0x8000
+#define AGSE_SPRITELOAD      0x8000
 // Below are interface 21 and later
-#define AGSE_PRERENDER     0x10000
+#define AGSE_PRERENDER       0x10000
 // Below are interface 24 and later
 #define AGSE_PRESAVEGAME     0x20000
 #define AGSE_POSTRESTOREGAME 0x40000
-#define AGSE_TOOHIGH         0x80000
+// Below are interface 26 and later
+#define AGSE_POSTROOMDRAW    0x80000
+#define AGSE_TOOHIGH         0x100000
 
 // GetFontType font types
 #define FNT_INVALID 0


Commit: b13b408972d9ce5f190ed2d3a985c6ac1347c2c9
    https://github.com/scummvm/scummvm/commit/b13b408972d9ce5f190ed2d3a985c6ac1347c2c9
Author: Thierry Crozat (criezy at scummvm.org)
Date: 2022-10-10T00:16:16+01:00

Commit Message:
AGS: renamed IAGSFontRenderer2 to IAGSFontRendererInternal

>From upstream 6fc7c295728bf4d6815596f12a8587c80dbe4a5e

Changed paths:
    engines/ags/shared/font/ags_font_renderer.h
    engines/ags/shared/font/fonts.cpp
    engines/ags/shared/font/fonts.h
    engines/ags/shared/font/ttf_font_renderer.h
    engines/ags/shared/font/wfn_font_renderer.h


diff --git a/engines/ags/shared/font/ags_font_renderer.h b/engines/ags/shared/font/ags_font_renderer.h
index 42de9c296f4..5c6eb06c85f 100644
--- a/engines/ags/shared/font/ags_font_renderer.h
+++ b/engines/ags/shared/font/ags_font_renderer.h
@@ -56,8 +56,9 @@ struct FontMetrics {
 	int CompatHeight = 0; // either formal or real height, depending on compat settings
 };
 
-// NOTE: this extending interface is not yet exposed to plugins
-class IAGSFontRenderer2 {
+// The strictly internal font renderer interface, not to use in plugin API.
+ // Contains methods necessary for built-in font renderers.
+class IAGSFontRendererInternal {
 public:
 	// Tells if this is a bitmap font (otherwise it's a vector font)
 	virtual bool IsBitmapFont() = 0;
@@ -69,8 +70,8 @@ public:
 	// Perform any necessary adjustments when the AA mode is toggled
 	virtual void AdjustFontForAntiAlias(int fontNumber, bool aa_mode) = 0;
 protected:
-	IAGSFontRenderer2() {}
-	~IAGSFontRenderer2() {}
+	IAGSFontRendererInternal() {}
+	~IAGSFontRendererInternal() {}
 };
 
 } // namespace AGS3
diff --git a/engines/ags/shared/font/fonts.cpp b/engines/ags/shared/font/fonts.cpp
index cd8e9b3fef6..e86e065b85b 100644
--- a/engines/ags/shared/font/fonts.cpp
+++ b/engines/ags/shared/font/fonts.cpp
@@ -107,15 +107,15 @@ IAGSFontRenderer *font_replace_renderer(size_t fontNumber, IAGSFontRenderer *ren
 		return nullptr;
 	IAGSFontRenderer *oldRender = _GP(fonts)[fontNumber].Renderer;
 	_GP(fonts)[fontNumber].Renderer = renderer;
-	_GP(fonts)[fontNumber].Renderer2 = nullptr;
+	_GP(fonts)[fontNumber].RendererInt = nullptr;
 	font_post_init(fontNumber);
 	return oldRender;
 }
 
 bool is_bitmap_font(size_t fontNumber) {
-	if (fontNumber >= _GP(fonts).size() || !_GP(fonts)[fontNumber].Renderer2)
+	if (fontNumber >= _GP(fonts).size() || !_GP(fonts)[fontNumber].RendererInt)
 		return false;
-	return _GP(fonts)[fontNumber].Renderer2->IsBitmapFont();
+	return _GP(fonts)[fontNumber].RendererInt->IsBitmapFont();
 }
 
 bool font_supports_extended_characters(size_t fontNumber) {
@@ -125,9 +125,9 @@ bool font_supports_extended_characters(size_t fontNumber) {
 }
 
 const char *get_font_name(size_t fontNumber) {
-	if (fontNumber >= _GP(fonts).size() || !_GP(fonts)[fontNumber].Renderer2)
+	if (fontNumber >= _GP(fonts).size() || !_GP(fonts)[fontNumber].RendererInt)
 		return "";
-	const char *name = _GP(fonts)[fontNumber].Renderer2->GetName(fontNumber);
+	const char *name = _GP(fonts)[fontNumber].RendererInt->GetName(fontNumber);
 	return name ? name : "";
 }
 
@@ -404,10 +404,10 @@ bool load_font_size(size_t fontNumber, const FontInfo &font_info) {
 
 	if (_GP(ttfRenderer).LoadFromDiskEx(fontNumber, font_info.Size, &params, &metrics)) {
 		_GP(fonts)[fontNumber].Renderer = &_GP(ttfRenderer);
-		_GP(fonts)[fontNumber].Renderer2 = &_GP(ttfRenderer);
+		_GP(fonts)[fontNumber].RendererInt = &_GP(ttfRenderer);
 	} else if (_GP(wfnRenderer).LoadFromDiskEx(fontNumber, font_info.Size, &params, &metrics)) {
 		_GP(fonts)[fontNumber].Renderer = &_GP(wfnRenderer);
-		_GP(fonts)[fontNumber].Renderer2 = &_GP(wfnRenderer);
+		_GP(fonts)[fontNumber].RendererInt = &_GP(wfnRenderer);
 	}
 
 	if (!_GP(fonts)[fontNumber].Renderer)
@@ -459,8 +459,8 @@ void alloc_font_outline_buffers(size_t font_number,
 
 void adjust_fonts_for_render_mode(bool aa_mode) {
 	for (size_t i = 0; i < _GP(fonts).size(); ++i) {
-		if (_GP(fonts)[i].Renderer2 != nullptr)
-			_GP(fonts)[i].Renderer2->AdjustFontForAntiAlias(i, aa_mode);
+		if (_GP(fonts)[i].RendererInt != nullptr)
+			_GP(fonts)[i].RendererInt->AdjustFontForAntiAlias(i, aa_mode);
 	}
 }
 
diff --git a/engines/ags/shared/font/fonts.h b/engines/ags/shared/font/fonts.h
index 0643e6eb441..51163b51888 100644
--- a/engines/ags/shared/font/fonts.h
+++ b/engines/ags/shared/font/fonts.h
@@ -32,7 +32,7 @@
 namespace AGS3 {
 
 class IAGSFontRenderer;
-class IAGSFontRenderer2;
+class IAGSFontRendererInternal;
 struct FontInfo;
 struct FontRenderParams;
 
@@ -41,7 +41,7 @@ namespace Shared {
 
 struct Font {
 	IAGSFontRenderer *Renderer = nullptr;
-	IAGSFontRenderer2 *Renderer2 = nullptr;
+	IAGSFontRendererInternal *RendererInt = nullptr;
 	FontInfo            Info;
 	// Values received from the renderer and saved for the reference
 	FontMetrics       Metrics;
@@ -61,7 +61,7 @@ struct Font {
 using namespace AGS;
 
 class IAGSFontRenderer;
-class IAGSFontRenderer2;
+class IAGSFontRendererInternal;
 struct FontInfo;
 struct FontRenderParams;
 
diff --git a/engines/ags/shared/font/ttf_font_renderer.h b/engines/ags/shared/font/ttf_font_renderer.h
index 6e76189a91f..8f01ecdb198 100644
--- a/engines/ags/shared/font/ttf_font_renderer.h
+++ b/engines/ags/shared/font/ttf_font_renderer.h
@@ -30,7 +30,7 @@ namespace AGS3 {
 
 struct ALFONT_FONT;
 
-class TTFFontRenderer : public IAGSFontRenderer, public IAGSFontRenderer2 {
+class TTFFontRenderer : public IAGSFontRenderer, public IAGSFontRendererInternal {
 public:
 	virtual ~TTFFontRenderer() {}
 
@@ -46,7 +46,7 @@ public:
 	void AdjustYCoordinateForFont(int *ycoord, int fontNumber) override;
 	void EnsureTextValidForFont(char *text, int fontNumber) override;
 
-	// IAGSFontRenderer2 implementation
+	// IAGSFontRendererInternal implementation
 	bool IsBitmapFont() override;
 	bool LoadFromDiskEx(int fontNumber, int fontSize, const FontRenderParams *params,
 		FontMetrics *metrics) override;
diff --git a/engines/ags/shared/font/wfn_font_renderer.h b/engines/ags/shared/font/wfn_font_renderer.h
index aabbf302a28..d944284d0cd 100644
--- a/engines/ags/shared/font/wfn_font_renderer.h
+++ b/engines/ags/shared/font/wfn_font_renderer.h
@@ -29,7 +29,7 @@ namespace AGS3 {
 
 class WFNFont;
 
-class WFNFontRenderer : public IAGSFontRenderer, public IAGSFontRenderer2 {
+class WFNFontRenderer : public IAGSFontRenderer, public IAGSFontRendererInternal {
 public:
 	// IAGSFontRenderer implementation
 	virtual ~WFNFontRenderer() {}
@@ -43,7 +43,7 @@ public:
 	void AdjustYCoordinateForFont(int *ycoord, int fontNumber) override;
 	void EnsureTextValidForFont(char *text, int fontNumber) override;
 
-	// IAGSFontRenderer2 implementation
+	// IAGSFontRendererInternal implementation
 	bool IsBitmapFont() override;
 	bool LoadFromDiskEx(int fontNumber, int fontSize,
 		const FontRenderParams *params, FontMetrics *metrics) override;




More information about the Scummvm-git-logs mailing list