[Scummvm-git-logs] scummvm master -> bf5e0b2d083ded5bfb9b8bad5af26c15373de707
dreammaster
noreply at scummvm.org
Fri Apr 22 05:20:15 UTC 2022
This automated email contains information about 10 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
b4b4110db6 AGS: Implement play_flc_video
e736059bbe AGS: pass key modifiers as an extra arg to `on_key_press`
e0282d5064 AGS: Implemented key handling switch (old/new mode)
5060848b48 AGS: Support requesting particular audio driver
7fb5f6d21a AGS: Support option for software renderer's output driver
cc9bda9251 AGS: Added NumLock and CapsLock key mods
4057fa05b9 AGS: Updated build version (3.6.0.20)
06880291b2 AGS: Refactor restrict_until and ShouldStayInWaitMode()
415235b74e AGS: expanded Button.Animate to feature all common params
bf5e0b2d08 AGS: Updated AnimatingButton save format
Commit: b4b4110db69c0903fdf47bb90a744b82ae04a881
https://github.com/scummvm/scummvm/commit/b4b4110db69c0903fdf47bb90a744b82ae04a881
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2022-04-21T19:29:53-07:00
Commit Message:
AGS: Implement play_flc_video
Changed paths:
engines/ags/engine/media/video/video.cpp
diff --git a/engines/ags/engine/media/video/video.cpp b/engines/ags/engine/media/video/video.cpp
index 026f07b6c07..ebe07db2680 100644
--- a/engines/ags/engine/media/video/video.cpp
+++ b/engines/ags/engine/media/video/video.cpp
@@ -20,6 +20,7 @@
*/
#include "video/avi_decoder.h"
+#include "video/flic_decoder.h"
#include "video/mpegps_decoder.h"
#include "video/theora_decoder.h"
#include "ags/shared/core/platform.h"
@@ -151,9 +152,10 @@ bool play_theora_video(const char *name, int flags, VideoSkipType skip, bool sho
}
bool play_flc_video(int numb, int flags, VideoSkipType skip) {
- // TODO: play_flc_file
- Display("This games uses Flic videos that ScummVM doesn't yet support");
- return false;
+ Video::FlicDecoder decoder;
+ String flicName = String::FromFormat("flic%d.flc", numb);
+
+ return play_video(&decoder, flicName, flags, skip, false);
}
void video_pause() {
Commit: e736059bbea024839a68dc78d7c5f57d7af05d66
https://github.com/scummvm/scummvm/commit/e736059bbea024839a68dc78d7c5f57d7af05d66
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2022-04-21T20:23:53-07:00
Commit Message:
AGS: pass key modifiers as an extra arg to `on_key_press`
>From upstream b00b82220cbabf44185e042ef33b543fe2ad3543
Changed paths:
engines/ags/engine/ac/dialog.cpp
engines/ags/engine/ac/event.cpp
engines/ags/engine/ac/event.h
engines/ags/engine/ac/sys_events.cpp
engines/ags/engine/main/game_run.cpp
engines/ags/engine/script/non_blocking_script_function.h
engines/ags/events.cpp
engines/ags/events.h
engines/ags/shared/ac/keycode.h
diff --git a/engines/ags/engine/ac/dialog.cpp b/engines/ags/engine/ac/dialog.cpp
index bf0f18ebd52..1601e08573c 100644
--- a/engines/ags/engine/ac/dialog.cpp
+++ b/engines/ags/engine/ac/dialog.cpp
@@ -850,6 +850,7 @@ bool DialogOptions::Run() {
} else if (new_custom_render) {
_GP(runDialogOptionKeyPressHandlerFunc).params[0].SetDynamicObject(&_GP(ccDialogOptionsRendering), &_GP(ccDialogOptionsRendering));
_GP(runDialogOptionKeyPressHandlerFunc).params[1].SetInt32(AGSKeyToScriptKey(gkey));
+ _GP(runDialogOptionKeyPressHandlerFunc).params[2].SetInt32(ki.Mod);
run_function_on_non_blocking_thread(&_GP(runDialogOptionKeyPressHandlerFunc));
_GP(runDialogOptionTextInputHandlerFunc).params[0].SetDynamicObject(&_GP(ccDialogOptionsRendering), &_GP(ccDialogOptionsRendering));
_GP(runDialogOptionTextInputHandlerFunc).params[1].SetInt32(ki.UChar);
diff --git a/engines/ags/engine/ac/event.cpp b/engines/ags/engine/ac/event.cpp
index 75a8e7e15aa..9252e5e5bb3 100644
--- a/engines/ags/engine/ac/event.cpp
+++ b/engines/ags/engine/ac/event.cpp
@@ -134,13 +134,14 @@ void process_event(const EventHappened *evp) {
RuntimeScriptValue rval_null;
if (evp->type == EV_TEXTSCRIPT) {
_G(ccError) = 0;
- if (evp->data2 > -1000) {
- RuntimeScriptValue params[]{ evp->data2 };
+ RuntimeScriptValue params[2]{ evp->data2, evp->data3 };
+ if (evp->data3 > -1000)
+ QueueScriptFunction(kScInstGame, _G(tsnames)[evp->data1], 2, params);
+ else if (evp->data2 > -1000)
QueueScriptFunction(kScInstGame, _G(tsnames)[evp->data1], 1, params);
- } else {
+ else
QueueScriptFunction(kScInstGame, _G(tsnames)[evp->data1]);
- }
- } else if (evp->type == EV_NEWROOM) {
+ } else if (evp->type == EV_NEWROOM) {
NewRoom(evp->data1);
} else if (evp->type == EV_RUNEVBLOCK) {
Interaction *evpt = nullptr;
diff --git a/engines/ags/engine/ac/event.h b/engines/ags/engine/ac/event.h
index a795c7a88de..7187fb42e9c 100644
--- a/engines/ags/engine/ac/event.h
+++ b/engines/ags/engine/ac/event.h
@@ -63,8 +63,8 @@ void run_on_event(int evtype, RuntimeScriptValue &wparam);
void run_room_event(int id);
void run_event_block_inv(int invNum, int event);
// event list functions
-void setevent(int evtyp, int ev1 = 0, int ev2 = -1000, int ev3 = 0);
-void force_event(int evtyp, int ev1 = 0, int ev2 = -1000, int ev3 = 0);
+void setevent(int evtyp, int ev1 = 0, int ev2 = -1000, int ev3 = -1000);
+void force_event(int evtyp, int ev1 = 0, int ev2 = -1000, int ev3 = -1000);
void process_event(const EventHappened *evp);
void runevent_now(int evtyp, int ev1, int ev2, int ev3);
void processallevents();
diff --git a/engines/ags/engine/ac/sys_events.cpp b/engines/ags/engine/ac/sys_events.cpp
index 8d9bed8072b..0cbf9feec97 100644
--- a/engines/ags/engine/ac/sys_events.cpp
+++ b/engines/ags/engine/ac/sys_events.cpp
@@ -65,7 +65,7 @@ static void(*_on_switchout_callback)(void) = nullptr;
KeyInput ags_keycode_from_scummvm(const Common::Event &event) {
KeyInput ki;
- ki.Key = ::AGS::g_events->scummvm_key_to_ags_key(event);
+ ki.Key = ::AGS::g_events->scummvm_key_to_ags_key(event, ki.Mod);
return ki;
}
diff --git a/engines/ags/engine/main/game_run.cpp b/engines/ags/engine/main/game_run.cpp
index 0981fb9e672..3a3dde4529b 100644
--- a/engines/ags/engine/main/game_run.cpp
+++ b/engines/ags/engine/main/game_run.cpp
@@ -499,8 +499,9 @@ static void check_keyboard_controls() {
if (!keywasprocessed) {
int sckey = AGSKeyToScriptKey(kgn);
- debug_script_log("Running on_key_press keycode %d", sckey);
- setevent(EV_TEXTSCRIPT, TS_KEYPRESS, sckey);
+ int sckeymod = ki.Mod;
+ debug_script_log("Running on_key_press keycode %d, mod %d", sckey, sckeymod);
+ setevent(EV_TEXTSCRIPT, TS_KEYPRESS, sckey, sckeymod);
if (ki.UChar > 0) {
debug_script_log("Running on_text_input char %s (%d)", ki.Text, ki.UChar);
setevent(EV_TEXTSCRIPT, TS_TEXTINPUT, ki.UChar);
diff --git a/engines/ags/engine/script/non_blocking_script_function.h b/engines/ags/engine/script/non_blocking_script_function.h
index 3b7de5646fb..ed553bbd58b 100644
--- a/engines/ags/engine/script/non_blocking_script_function.h
+++ b/engines/ags/engine/script/non_blocking_script_function.h
@@ -31,9 +31,7 @@ namespace AGS3 {
struct NonBlockingScriptFunction {
const char *functionName;
int numParameters;
- //void* param1;
- //void* param2;
- RuntimeScriptValue params[2];
+ RuntimeScriptValue params[3];
bool roomHasFunction;
bool globalScriptHasFunction;
std::vector<bool> moduleHasFunction;
diff --git a/engines/ags/events.cpp b/engines/ags/events.cpp
index 735eac250c4..8981ed26cf3 100644
--- a/engines/ags/events.cpp
+++ b/engines/ags/events.cpp
@@ -22,6 +22,7 @@
#include "common/system.h"
#include "ags/events.h"
#include "ags/globals.h"
+#include "ags/shared/ac/keycode.h"
namespace AGS {
@@ -310,13 +311,19 @@ bool EventsManager::ags_key_to_scancode(AGS3::eAGSKeyCode key, Common::KeyCode(&
return false;
}
-AGS3::eAGSKeyCode EventsManager::scummvm_key_to_ags_key(const Common::Event &event) {
+AGS3::eAGSKeyCode EventsManager::scummvm_key_to_ags_key(const Common::Event &event, int &ags_mod) {
if (event.type != Common::EVENT_KEYDOWN)
return AGS3::eAGSKeyCodeNone;
const Common::KeyCode sym = event.kbd.keycode;
const uint16 mod = event.kbd.flags;
+ // First handle the mods, - these are straightforward
+ ags_mod = 0;
+ if (mod & Common::KBD_SHIFT) ags_mod |= AGS3::eAGSModLShift;
+ if (mod & Common::KBD_CTRL) ags_mod |= AGS3::eAGSModLCtrl;
+ if (mod & Common::KBD_ALT) ags_mod |= AGS3::eAGSModLAlt;
+
// Ctrl and Alt combinations realign the letter code to certain offset
if (sym >= Common::KEYCODE_a && sym <= Common::KEYCODE_z) {
if ((mod & Common::KBD_CTRL) != 0) // align letters to code 1
diff --git a/engines/ags/events.h b/engines/ags/events.h
index e2c42595a08..9c902e43156 100644
--- a/engines/ags/events.h
+++ b/engines/ags/events.h
@@ -52,7 +52,7 @@ public:
/*
* Converts a ScummVM event to the ags keycode
*/
- static AGS3::eAGSKeyCode scummvm_key_to_ags_key(const Common::Event &event);
+ static AGS3::eAGSKeyCode scummvm_key_to_ags_key(const Common::Event &event, int &ags_mod);
public:
EventsManager();
diff --git a/engines/ags/shared/ac/keycode.h b/engines/ags/shared/ac/keycode.h
index d14e6b6fabb..63cfb97a06e 100644
--- a/engines/ags/shared/ac/keycode.h
+++ b/engines/ags/shared/ac/keycode.h
@@ -251,11 +251,22 @@ enum eAGSKeyCode {
*/
};
+// AGS key modifiers
+enum eAGSKeyMod {
+ eAGSModLShift = 0x0001,
+ eAGSModRShift = 0x0002,
+ eAGSModLCtrl = 0x0004,
+ eAGSModRCtrl = 0x0008,
+ eAGSModLAlt = 0x0010,
+ eAGSModRAlt = 0x0020
+};
+
// Combined key code and a textual representation in UTF-8
struct KeyInput {
const static size_t UTF8_ARR_SIZE = 5;
eAGSKeyCode Key = eAGSKeyCodeNone; // actual key code
+ int Mod = 0; // key modifiers
int UChar = 0; // full character value (supports unicode)
char Text[UTF8_ARR_SIZE]{}; // character in a string format
Commit: e0282d506447f490c61b1e37f3462e48f8c2a096
https://github.com/scummvm/scummvm/commit/e0282d506447f490c61b1e37f3462e48f8c2a096
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2022-04-21T20:55:38-07:00
Commit Message:
AGS: Implemented key handling switch (old/new mode)
>From upstream b9e23731d0d792d095c1d4e83fa1797a1afeee46
Changed paths:
engines/ags/engine/ac/dialog.cpp
engines/ags/engine/ac/sys_events.cpp
engines/ags/engine/ac/sys_events.h
engines/ags/engine/main/game_run.cpp
engines/ags/engine/main/game_run.h
engines/ags/events.cpp
engines/ags/events.h
engines/ags/globals.cpp
engines/ags/shared/ac/game_struct_defines.h
diff --git a/engines/ags/engine/ac/dialog.cpp b/engines/ags/engine/ac/dialog.cpp
index 1601e08573c..a55597b528b 100644
--- a/engines/ags/engine/ac/dialog.cpp
+++ b/engines/ags/engine/ac/dialog.cpp
@@ -801,6 +801,7 @@ bool DialogOptions::Run() {
sys_evt_process_pending();
const bool new_custom_render = usingCustomRendering && _GP(game).options[OPT_DIALOGOPTIONSAPI] >= 0;
+ const bool old_keyhandle = _GP(game).options[OPT_KEYHANDLEAPI] == 0;
if (runGameLoopsInBackground) {
_GP(play).disabled_user_interface++;
@@ -848,13 +849,19 @@ bool DialogOptions::Run() {
}
}
} else if (new_custom_render) {
- _GP(runDialogOptionKeyPressHandlerFunc).params[0].SetDynamicObject(&_GP(ccDialogOptionsRendering), &_GP(ccDialogOptionsRendering));
- _GP(runDialogOptionKeyPressHandlerFunc).params[1].SetInt32(AGSKeyToScriptKey(gkey));
- _GP(runDialogOptionKeyPressHandlerFunc).params[2].SetInt32(ki.Mod);
- run_function_on_non_blocking_thread(&_GP(runDialogOptionKeyPressHandlerFunc));
- _GP(runDialogOptionTextInputHandlerFunc).params[0].SetDynamicObject(&_GP(ccDialogOptionsRendering), &_GP(ccDialogOptionsRendering));
- _GP(runDialogOptionTextInputHandlerFunc).params[1].SetInt32(ki.UChar);
- run_function_on_non_blocking_thread(&_GP(runDialogOptionKeyPressHandlerFunc));
+ 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[2].SetInt32(ki.Mod);
+ run_function_on_non_blocking_thread(&_GP(runDialogOptionKeyPressHandlerFunc));
+ }
+ if (!old_keyhandle && (ki.UChar > 0)) {
+ // "dialog_options_text_input"
+ _GP(runDialogOptionTextInputHandlerFunc).params[0].SetDynamicObject(&_GP(ccDialogOptionsRendering), &_GP(ccDialogOptionsRendering));
+ _GP(runDialogOptionTextInputHandlerFunc).params[1].SetInt32(ki.UChar);
+ run_function_on_non_blocking_thread(&_GP(runDialogOptionKeyPressHandlerFunc));
+ }
}
// Allow selection of options by keyboard shortcuts
else if (_GP(game).options[OPT_DIALOGNUMBERED] >= kDlgOptKeysOnly &&
diff --git a/engines/ags/engine/ac/sys_events.cpp b/engines/ags/engine/ac/sys_events.cpp
index 0cbf9feec97..c0e2522b1d1 100644
--- a/engines/ags/engine/ac/sys_events.cpp
+++ b/engines/ags/engine/ac/sys_events.cpp
@@ -62,10 +62,10 @@ static void(*_on_switchout_callback)(void) = nullptr;
// KEYBOARD INPUT
// ----------------------------------------------------------------------------
-KeyInput ags_keycode_from_scummvm(const Common::Event &event) {
+KeyInput ags_keycode_from_scummvm(const Common::Event &event, bool old_keyhandle) {
KeyInput ki;
- ki.Key = ::AGS::g_events->scummvm_key_to_ags_key(event, ki.Mod);
+ ki.Key = ::AGS::g_events->scummvm_key_to_ags_key(event, ki.Mod, old_keyhandle);
return ki;
}
diff --git a/engines/ags/engine/ac/sys_events.h b/engines/ags/engine/ac/sys_events.h
index 88e64d70d13..7313b641bf9 100644
--- a/engines/ags/engine/ac/sys_events.h
+++ b/engines/ags/engine/ac/sys_events.h
@@ -65,7 +65,10 @@ inline int make_merged_mod(int mod) {
return m_mod;
}
-extern KeyInput ags_keycode_from_scummvm(const Common::Event &event);
+// Converts ScummVM key event to eAGSKeyCode if it is in proper range,
+// see comments to eAGSKeyCode for details.
+// Optionally works in bacward compatible mode (old_keyhandle)
+extern KeyInput ags_keycode_from_scummvm(const Common::Event &event, bool old_keyhandle);
// Tells if there are any buffered key events
extern bool ags_keyevent_ready();
diff --git a/engines/ags/engine/main/game_run.cpp b/engines/ags/engine/main/game_run.cpp
index 3a3dde4529b..623da50799e 100644
--- a/engines/ags/engine/main/game_run.cpp
+++ b/engines/ags/engine/main/game_run.cpp
@@ -243,7 +243,12 @@ int old_key_mod = 0; // for saving previous key mods
// Runs service key controls, returns false if service key combinations were handled
// and no more processing required, otherwise returns true and provides current keycode and key shifts.
+//
+// * old_keyhandle mode is a backward compatible input handling mode, where
+// - lone mod keys are not passed further into the engine;
+// - key + mod combos are merged into one key code for the script callback.
bool run_service_key_controls(KeyInput &out_key) {
+ const bool old_keyhandle = (_GP(game).options[OPT_KEYHANDLEAPI] == 0);
bool handled = false;
const bool key_valid = ags_keyevent_ready();
const Common::Event key_evt = key_valid ? ags_get_next_keyevent() : Common::Event();
@@ -299,11 +304,10 @@ bool run_service_key_controls(KeyInput &out_key) {
if (!key_valid)
return false; // if there was no key press, finish after handling current mod state
- if (is_only_mod_key || handled)
- return false; // rest of engine currently does not use pressed mod keys
- // change this when it's no longer true (but be mindful about key-skipping!)
+ if (handled || (old_keyhandle && is_only_mod_key))
+ return false; // in backward mode the engine does not react to single mod keys
- KeyInput ki = ags_keycode_from_scummvm(key_evt);
+ KeyInput ki = ags_keycode_from_scummvm(key_evt, old_keyhandle);
eAGSKeyCode agskey = ki.Key;
if (agskey == eAGSKeyCodeNone)
return false; // should skip this key event
@@ -405,6 +409,7 @@ bool run_service_mb_controls(int &mbut, int &mwheelz) {
// Runs default keyboard handling
static void check_keyboard_controls() {
+ const bool old_keyhandle = _GP(game).options[OPT_KEYHANDLEAPI] == 0;
// First check for service engine's combinations (mouse lock, display mode switch, and so forth)
KeyInput ki;
if (!run_service_key_controls(ki)) {
@@ -500,9 +505,11 @@ static void check_keyboard_controls() {
if (!keywasprocessed) {
int sckey = AGSKeyToScriptKey(kgn);
int sckeymod = ki.Mod;
- debug_script_log("Running on_key_press keycode %d, mod %d", sckey, sckeymod);
- setevent(EV_TEXTSCRIPT, TS_KEYPRESS, sckey, sckeymod);
- if (ki.UChar > 0) {
+ 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);
+ }
+ if (!old_keyhandle && (ki.UChar > 0)) {
debug_script_log("Running on_text_input char %s (%d)", ki.Text, ki.UChar);
setevent(EV_TEXTSCRIPT, TS_TEXTINPUT, ki.UChar);
}
diff --git a/engines/ags/engine/main/game_run.h b/engines/ags/engine/main/game_run.h
index 102134d22dc..340d70d9635 100644
--- a/engines/ags/engine/main/game_run.h
+++ b/engines/ags/engine/main/game_run.h
@@ -50,9 +50,9 @@ 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.
-struct KeyInput;
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.
diff --git a/engines/ags/events.cpp b/engines/ags/events.cpp
index 8981ed26cf3..42054e9ebe3 100644
--- a/engines/ags/events.cpp
+++ b/engines/ags/events.cpp
@@ -311,7 +311,7 @@ bool EventsManager::ags_key_to_scancode(AGS3::eAGSKeyCode key, Common::KeyCode(&
return false;
}
-AGS3::eAGSKeyCode EventsManager::scummvm_key_to_ags_key(const Common::Event &event, int &ags_mod) {
+AGS3::eAGSKeyCode EventsManager::scummvm_key_to_ags_key(const Common::Event &event, int &ags_mod, bool old_keyhandle) {
if (event.type != Common::EVENT_KEYDOWN)
return AGS3::eAGSKeyCodeNone;
@@ -324,13 +324,17 @@ AGS3::eAGSKeyCode EventsManager::scummvm_key_to_ags_key(const Common::Event &eve
if (mod & Common::KBD_CTRL) ags_mod |= AGS3::eAGSModLCtrl;
if (mod & Common::KBD_ALT) ags_mod |= AGS3::eAGSModLAlt;
- // Ctrl and Alt combinations realign the letter code to certain offset
- if (sym >= Common::KEYCODE_a && sym <= Common::KEYCODE_z) {
+ // Old mode: Ctrl and Alt combinations realign the letter code to certain offset
+ if (old_keyhandle && (sym >= Common::KEYCODE_a && sym <= Common::KEYCODE_z)) {
if ((mod & Common::KBD_CTRL) != 0) // align letters to code 1
return static_cast<AGS3::eAGSKeyCode>(0 + (sym - Common::KEYCODE_a) + 1);
else if ((mod & Common::KBD_ALT) != 0) // align letters to code 301
return static_cast<AGS3::eAGSKeyCode>(AGS_EXT_KEY_SHIFT + (sym - Common::KEYCODE_a) + 1);
}
+ // New mode: also handle common key range
+ else if (!old_keyhandle && (sym >= Common::KEYCODE_SPACE && sym <= Common::KEYCODE_z)) {
+ return static_cast<AGS3::eAGSKeyCode>(sym);
+ }
if (event.kbd.ascii >= 32 && event.kbd.ascii <= 127)
return static_cast<AGS3::eAGSKeyCode>(event.kbd.ascii);
@@ -406,6 +410,18 @@ AGS3::eAGSKeyCode EventsManager::scummvm_key_to_ags_key(const Common::Event &eve
case Common::KEYCODE_KP_PERIOD:
case Common::KEYCODE_DELETE:
return AGS3::eAGSKeyCodeDelete;
+ case Common::KEYCODE_LSHIFT:
+ return AGS3::eAGSKeyCodeLShift;
+ case Common::KEYCODE_RSHIFT:
+ return AGS3::eAGSKeyCodeRShift;
+ case Common::KEYCODE_LCTRL:
+ return AGS3::eAGSKeyCodeLCtrl;
+ case Common::KEYCODE_RCTRL:
+ return AGS3::eAGSKeyCodeRCtrl;
+ case Common::KEYCODE_LALT:
+ return AGS3::eAGSKeyCodeLAlt;
+ case Common::KEYCODE_RALT:
+ return AGS3::eAGSKeyCodeRAlt;
default:
return AGS3::eAGSKeyCodeNone;
diff --git a/engines/ags/events.h b/engines/ags/events.h
index 9c902e43156..c1de5f2a1e9 100644
--- a/engines/ags/events.h
+++ b/engines/ags/events.h
@@ -52,7 +52,7 @@ public:
/*
* Converts a ScummVM event to the ags keycode
*/
- static AGS3::eAGSKeyCode scummvm_key_to_ags_key(const Common::Event &event, int &ags_mod);
+ static AGS3::eAGSKeyCode scummvm_key_to_ags_key(const Common::Event &event, int &ags_mod, bool old_keyhandle);
public:
EventsManager();
diff --git a/engines/ags/globals.cpp b/engines/ags/globals.cpp
index 9a7902cffff..35e7c677a21 100644
--- a/engines/ags/globals.cpp
+++ b/engines/ags/globals.cpp
@@ -333,7 +333,7 @@ Globals::Globals() {
_renderDialogOptionsFunc = new NonBlockingScriptFunction("dialog_options_render", 1);
_getDialogOptionUnderCursorFunc = new NonBlockingScriptFunction("dialog_options_get_active", 1);
_runDialogOptionMouseClickHandlerFunc = new NonBlockingScriptFunction("dialog_options_mouse_click", 2);
- _runDialogOptionKeyPressHandlerFunc = new NonBlockingScriptFunction("dialog_options_key_press", 2);
+ _runDialogOptionKeyPressHandlerFunc = new NonBlockingScriptFunction("dialog_options_key_press", 3);
_runDialogOptionTextInputHandlerFunc = new NonBlockingScriptFunction("dialog_options_text_input", 2);
_runDialogOptionRepExecFunc = new NonBlockingScriptFunction("dialog_options_repexec", 1);
_scsystem = new ScriptSystem();
diff --git a/engines/ags/shared/ac/game_struct_defines.h b/engines/ags/shared/ac/game_struct_defines.h
index 5bde0137f7f..fdf37ddb78c 100644
--- a/engines/ags/shared/ac/game_struct_defines.h
+++ b/engines/ags/shared/ac/game_struct_defines.h
@@ -85,7 +85,8 @@ namespace AGS3 {
#define OPT_WALKSPEEDABSOLUTE 47 // if movement speeds are independent of walkable mask resolution
#define OPT_CLIPGUICONTROLS 48 // clip drawn gui control contents to the control's rectangle
#define OPT_GAMETEXTENCODING 49 // how the text in the game data should be interpreted
-#define OPT_HIGHESTOPTION OPT_GAMETEXTENCODING
+#define OPT_KEYHANDLEAPI 50 // key handling mode (old/new)
+#define OPT_HIGHESTOPTION OPT_KEYHANDLEAPI
#define OPT_NOMODMUSIC 98
#define OPT_LIPSYNCTEXT 99
#define PORTRAIT_LEFT 0
Commit: 5060848b483613163a58c7d2466d371607a8c96f
https://github.com/scummvm/scummvm/commit/5060848b483613163a58c7d2466d371607a8c96f
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2022-04-21T21:20:58-07:00
Commit Message:
AGS: Support requesting particular audio driver
>From upstream 076e675a3d031cd0a9d162f914e6d94c93a10d71
Changed paths:
engines/ags/engine/ac/game_setup.cpp
engines/ags/engine/ac/game_setup.h
engines/ags/engine/ac/global_video.cpp
engines/ags/engine/main/config.cpp
engines/ags/engine/main/engine.cpp
engines/ags/engine/media/audio/audio.cpp
engines/ags/engine/platform/base/sys_main.cpp
engines/ags/engine/platform/base/sys_main.h
engines/ags/plugins/ags_plugin.cpp
diff --git a/engines/ags/engine/ac/game_setup.cpp b/engines/ags/engine/ac/game_setup.cpp
index a32820938f5..9af8dfbdc20 100644
--- a/engines/ags/engine/ac/game_setup.cpp
+++ b/engines/ags/engine/ac/game_setup.cpp
@@ -25,7 +25,7 @@ namespace AGS3 {
GameSetup::GameSetup() {
local_user_conf = false;
- audio_backend = 1;
+ audio_enabled = true;
no_speech_pack = false;
textheight = 0;
enable_antialiasing = false;
diff --git a/engines/ags/engine/ac/game_setup.h b/engines/ags/engine/ac/game_setup.h
index 393929e7af7..e91d0244e9e 100644
--- a/engines/ags/engine/ac/game_setup.h
+++ b/engines/ags/engine/ac/game_setup.h
@@ -60,8 +60,9 @@ using AGS::Shared::String;
// that engine may use a "config" object or combo of objects to store
// current user config, which may also be changed from script, and saved.
struct GameSetup {
- int audio_backend; // abstract option, currently only works as on/off
- int textheight; // text height used on the certain built-in GUI // TODO: move out to game class?
+ bool audio_enabled;
+ String audio_driver;
+ int textheight; // text height used on the certain built-in GUI // TODO: move out to game class?
bool no_speech_pack;
bool enable_antialiasing;
bool disable_exception_handling;
diff --git a/engines/ags/engine/ac/global_video.cpp b/engines/ags/engine/ac/global_video.cpp
index 320ac267186..253c2507d48 100644
--- a/engines/ags/engine/ac/global_video.cpp
+++ b/engines/ags/engine/ac/global_video.cpp
@@ -101,7 +101,7 @@ void PlayVideo(const char *name, int skip, int scr_flags) {
flags |= kVideo_EnableAudio;
// if game audio is disabled, then don't play any sound on the video either
- if (_GP(usetup).audio_backend == 0)
+ if (!_GP(usetup).audio_enabled)
flags &= ~kVideo_EnableAudio;
if (_G(loaded_game_file_version) < kGameVersion_360_16)
diff --git a/engines/ags/engine/main/config.cpp b/engines/ags/engine/main/config.cpp
index 633d276bc49..e2d6565a2e3 100644
--- a/engines/ags/engine/main/config.cpp
+++ b/engines/ags/engine/main/config.cpp
@@ -227,8 +227,6 @@ void config_defaults() {
// Defaults for the window style are max resizing window and "fullscreen desktop"
_GP(usetup).Screen.FsSetup = WindowSetup(kWnd_FullDesktop);
_GP(usetup).Screen.WinSetup = WindowSetup(kWnd_Windowed);
- _GP(usetup).audio_backend = 1;
- _GP(usetup).translation = "";
}
static void read_legacy_graphics_config(const ConfigTree &cfg) {
@@ -372,7 +370,8 @@ void override_config_ext(ConfigTree &cfg) {
void apply_config(const ConfigTree &cfg) {
{
- _GP(usetup).audio_backend = INIreadint(cfg, "sound", "enabled", _GP(usetup).audio_backend);
+ _GP(usetup).audio_enabled = INIreadint(cfg, "sound", "enabled", _GP(usetup).audio_enabled);
+ _GP(usetup).audio_driver = INIreadstring(cfg, "sound", "driver");
// Legacy graphics settings has to be translated into new options;
// they must be read first, to let newer options override them, if ones are present
diff --git a/engines/ags/engine/main/engine.cpp b/engines/ags/engine/main/engine.cpp
index a9760d20a05..3087a9a83a2 100644
--- a/engines/ags/engine/main/engine.cpp
+++ b/engines/ags/engine/main/engine.cpp
@@ -326,24 +326,22 @@ void engine_init_timer() {
void engine_init_audio() {
#if !AGS_PLATFORM_SCUMMVM
- if (usetup.audio_backend != 0)
- {
- Debug::Printf("Initializing audio");
- try {
- audio_core_init(); // audio core system
- } catch(std::runtime_error) {
- Debug::Printf("Failed to initialize audio, disabling.");
- usetup.audio_backend = 0;
- }
- }
+ if (usetup.audio_backend != 0) {
+ Debug::Printf("Initializing audio");
+ try {
+ audio_core_init(); // audio core system
+ } catch (std::runtime_error ex) {
+ Debug::Printf(kDbgMsg_Error, "Failed to initialize audio: %s", ex.what());
+ usetup.audio_backend = 0;
+ }
+ }
#endif
- _G(our_eip) = -181;
-
- if (_GP(usetup).audio_backend == 0) {
+ if (!_GP(usetup).audio_enabled) {
// all audio is disabled
_GP(play).voice_avail = false;
_GP(play).separate_music_lib = false;
+ Debug::Printf(kDbgMsg_Info, "Audio is disabled");
}
}
diff --git a/engines/ags/engine/media/audio/audio.cpp b/engines/ags/engine/media/audio/audio.cpp
index aa99c4c9976..ebaae24baa1 100644
--- a/engines/ags/engine/media/audio/audio.cpp
+++ b/engines/ags/engine/media/audio/audio.cpp
@@ -34,6 +34,7 @@
#include "ags/engine/media/audio/sound.h"
#include "ags/engine/debugging/debug_log.h"
#include "ags/engine/debugging/debugger.h"
+#include "ags/engine/platform/base/sys_main.h"
#include "ags/shared/ac/common.h"
#include "ags/engine/ac/file.h"
#include "ags/engine/ac/global_audio.h"
@@ -189,7 +190,7 @@ static int find_free_audio_channel(ScriptAudioClip *clip, int priority, bool int
}
bool is_audiotype_allowed_to_play(AudioFileType type) {
- return _GP(usetup).audio_backend != 0;
+ return _GP(usetup).audio_enabled;
}
SOUNDCLIP *load_sound_clip(ScriptAudioClip *audioClip, bool repeat) {
@@ -592,6 +593,8 @@ void shutdown_sound() {
#if !AGS_PLATFORM_SCUMMVM
audio_core_shutdown(); // audio core system
#endif
+ sys_audio_shutdown(); // backend
+ _GP(usetup).audio_enabled = false;
}
// the sound will only be played if there is a free channel or
diff --git a/engines/ags/engine/platform/base/sys_main.cpp b/engines/ags/engine/platform/base/sys_main.cpp
index 79dfb565513..19f8114e490 100644
--- a/engines/ags/engine/platform/base/sys_main.cpp
+++ b/engines/ags/engine/platform/base/sys_main.cpp
@@ -82,6 +82,37 @@ void sys_get_desktop_modes(std::vector<AGS::Engine::DisplayMode> &dms) {
#endif
}
+// ----------------------------------------------------------------------------
+// AUDIO UTILS
+// ----------------------------------------------------------------------------
+
+bool sys_audio_init(const AGS::Shared::String &driver_name) {
+#ifdef AGS_PLATFORM_SCUMMVM
+ return true;
+#else
+ bool res = false;
+ if (!driver_name.IsEmpty()) {
+ res = SDL_AudioInit(driver_name.GetCStr()) == 0;
+ if (!res)
+ Debug::Printf(kDbgMsg_Error, "Failed to initialize audio driver %s; error: %s",
+ driver_name.GetCStr(), SDL_GetError());
+ }
+ if (!res) {
+ res = SDL_InitSubSystem(SDL_INIT_AUDIO) == 0;
+ if (!res)
+ Debug::Printf(kDbgMsg_Error, "Failed to initialize audio backend: %s", SDL_GetError());
+ }
+ if (res)
+ Debug::Printf(kDbgMsg_Info, "Audio driver: %s", SDL_GetCurrentAudioDriver());
+ return res;
+#endif
+}
+
+void sys_audio_shutdown() {
+#ifndef AGS_PLATFORM_SCUMMVM
+ SDL_QuitSubSystem(SDL_INIT_AUDIO);
+#endif
+}
// ----------------------------------------------------------------------------
// WINDOW UTILS
diff --git a/engines/ags/engine/platform/base/sys_main.h b/engines/ags/engine/platform/base/sys_main.h
index c248010818e..aa08868acfe 100644
--- a/engines/ags/engine/platform/base/sys_main.h
+++ b/engines/ags/engine/platform/base/sys_main.h
@@ -28,6 +28,7 @@
//=============================================================================
#include "ags/shared/core/platform.h"
+#include "ags/shared/util/string.h"
#include "ags/lib/std/vector.h"
#include "ags/engine/gfx/gfx_defines.h"
@@ -51,6 +52,13 @@ int sys_get_desktop_resolution(int &width, int &height);
// Queries supported desktop modes.
void sys_get_desktop_modes(std::vector<AGS::Engine::DisplayMode> &dms);
+// Audio utilities.
+//
+// Tries to init the audio backend; optionally requests particular driver
+bool sys_audio_init(const AGS::Shared::String &driver_name = "");
+// Shutdown audio backend
+void sys_audio_shutdown();
+
// Window utilities.
//
struct SDL_Window;
diff --git a/engines/ags/plugins/ags_plugin.cpp b/engines/ags/plugins/ags_plugin.cpp
index c2f52d20124..f1d8bced28e 100644
--- a/engines/ags/plugins/ags_plugin.cpp
+++ b/engines/ags/plugins/ags_plugin.cpp
@@ -599,7 +599,6 @@ int IAGSEngine::IsSpriteAlphaBlended(int32 slot) {
// disable AGS's sound engine
void IAGSEngine::DisableSound() {
shutdown_sound();
- _GP(usetup).audio_backend = 0;
}
int IAGSEngine::CanRunScriptFunctionNow() {
if (_G(inside_script))
Commit: 7fb5f6d21a605d42024cdda4a130a88f68cc46f0
https://github.com/scummvm/scummvm/commit/7fb5f6d21a605d42024cdda4a130a88f68cc46f0
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2022-04-21T21:31:00-07:00
Commit Message:
AGS: Support option for software renderer's output driver
>From upstream d45f77548675f06056143d6989929870338b34a1
Changed paths:
engines/ags/engine/ac/game_setup.h
engines/ags/engine/main/config.cpp
engines/ags/engine/main/engine.cpp
engines/ags/engine/platform/base/sys_main.cpp
engines/ags/engine/platform/base/sys_main.h
diff --git a/engines/ags/engine/ac/game_setup.h b/engines/ags/engine/ac/game_setup.h
index e91d0244e9e..ccef879bbad 100644
--- a/engines/ags/engine/ac/game_setup.h
+++ b/engines/ags/engine/ac/game_setup.h
@@ -96,6 +96,7 @@ struct GameSetup {
ScreenRotation rotation;
DisplayModeSetup Screen;
+ String software_render_driver;
GameSetup();
};
diff --git a/engines/ags/engine/main/config.cpp b/engines/ags/engine/main/config.cpp
index e2d6565a2e3..a95d9b9d2b6 100644
--- a/engines/ags/engine/main/config.cpp
+++ b/engines/ags/engine/main/config.cpp
@@ -400,6 +400,8 @@ void apply_config(const ConfigTree &cfg) {
_GP(usetup).Screen.Params.VSync = INIreadint(cfg, "graphics", "vsync") > 0;
_GP(usetup).RenderAtScreenRes = INIreadint(cfg, "graphics", "render_at_screenres") > 0;
_GP(usetup).Supersampling = INIreadint(cfg, "graphics", "supersampling", 1);
+ _GP(usetup).software_render_driver = INIreadstring(cfg, "graphics", "software_driver");
+
#ifdef TODO
_GP(usetup).rotation = (ScreenRotation)INIreadint(cfg, "graphics", "rotation", _GP(usetup).rotation);
String rotation_str = INIreadstring(cfg, "graphics", "rotation", "unlocked");
diff --git a/engines/ags/engine/main/engine.cpp b/engines/ags/engine/main/engine.cpp
index 3087a9a83a2..0941335660e 100644
--- a/engines/ags/engine/main/engine.cpp
+++ b/engines/ags/engine/main/engine.cpp
@@ -1216,6 +1216,8 @@ int initialize_engine(const ConfigTree &startup_opts) {
bool engine_try_set_gfxmode_any(const DisplayModeSetup &setup) {
engine_shutdown_gfxmode();
+ sys_renderer_set_output(_GP(usetup).software_render_driver);
+
const Size init_desktop = get_desktop_size();
bool res = graphics_mode_init_any(GraphicResolution(_GP(game).GetGameRes(), _GP(game).color_depth * 8),
setup, ColorDepthOption(_GP(game).GetColorDepth()));
diff --git a/engines/ags/engine/platform/base/sys_main.cpp b/engines/ags/engine/platform/base/sys_main.cpp
index 19f8114e490..71d22db0b2d 100644
--- a/engines/ags/engine/platform/base/sys_main.cpp
+++ b/engines/ags/engine/platform/base/sys_main.cpp
@@ -82,6 +82,12 @@ void sys_get_desktop_modes(std::vector<AGS::Engine::DisplayMode> &dms) {
#endif
}
+void sys_renderer_set_output(const AGS::Shared::String &name) {
+#ifndef AGS_PLATFORM_SCUMMVM
+ SDL_SetHint(SDL_HINT_RENDER_DRIVER, name.GetCStr());
+#endif
+}
+
// ----------------------------------------------------------------------------
// AUDIO UTILS
// ----------------------------------------------------------------------------
diff --git a/engines/ags/engine/platform/base/sys_main.h b/engines/ags/engine/platform/base/sys_main.h
index aa08868acfe..5436adb5a51 100644
--- a/engines/ags/engine/platform/base/sys_main.h
+++ b/engines/ags/engine/platform/base/sys_main.h
@@ -51,6 +51,8 @@ void sys_set_background_mode(bool on);
int sys_get_desktop_resolution(int &width, int &height);
// Queries supported desktop modes.
void sys_get_desktop_modes(std::vector<AGS::Engine::DisplayMode> &dms);
+// Sets output driver for the backend's renderer
+void sys_renderer_set_output(const AGS::Shared::String &name);
// Audio utilities.
//
Commit: cc9bda925140d1a45f257ba2a3cd92aa5a128a05
https://github.com/scummvm/scummvm/commit/cc9bda925140d1a45f257ba2a3cd92aa5a128a05
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2022-04-21T21:35:00-07:00
Commit Message:
AGS: Added NumLock and CapsLock key mods
>From upstream c845ac3450159fd54fec91e19dc857860fc8ac38
Changed paths:
engines/ags/events.cpp
engines/ags/shared/ac/keycode.h
diff --git a/engines/ags/events.cpp b/engines/ags/events.cpp
index 42054e9ebe3..c76b4d5b582 100644
--- a/engines/ags/events.cpp
+++ b/engines/ags/events.cpp
@@ -323,6 +323,8 @@ AGS3::eAGSKeyCode EventsManager::scummvm_key_to_ags_key(const Common::Event &eve
if (mod & Common::KBD_SHIFT) ags_mod |= AGS3::eAGSModLShift;
if (mod & Common::KBD_CTRL) ags_mod |= AGS3::eAGSModLCtrl;
if (mod & Common::KBD_ALT) ags_mod |= AGS3::eAGSModLAlt;
+ if (mod & Common::KBD_NUM) ags_mod |= AGS3::eAGSModNum;
+ if (mod & Common::KBD_CAPS) ags_mod |= AGS3::eAGSModCaps;
// Old mode: Ctrl and Alt combinations realign the letter code to certain offset
if (old_keyhandle && (sym >= Common::KEYCODE_a && sym <= Common::KEYCODE_z)) {
diff --git a/engines/ags/shared/ac/keycode.h b/engines/ags/shared/ac/keycode.h
index 63cfb97a06e..f0198ac2a1e 100644
--- a/engines/ags/shared/ac/keycode.h
+++ b/engines/ags/shared/ac/keycode.h
@@ -258,7 +258,9 @@ enum eAGSKeyMod {
eAGSModLCtrl = 0x0004,
eAGSModRCtrl = 0x0008,
eAGSModLAlt = 0x0010,
- eAGSModRAlt = 0x0020
+ eAGSModRAlt = 0x0020,
+ eAGSModNum = 0x0040,
+ eAGSModCaps = 0x0080
};
// Combined key code and a textual representation in UTF-8
Commit: 4057fa05b99f02d68aec675bc91d8b7af5ca51d4
https://github.com/scummvm/scummvm/commit/4057fa05b99f02d68aec675bc91d8b7af5ca51d4
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2022-04-21T21:36:00-07:00
Commit Message:
AGS: Updated build version (3.6.0.20)
>From upstream ca98a8705ce101212cc8385ffcee7934340a36b0
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 a47916eb3d3..765bd984d7b 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.19"
+#define ACI_VERSION_STR "3.6.0.20"
#if defined (RC_INVOKED) // for MSVC resource compiler
-#define ACI_VERSION_MSRC_DEF 3.6.0.19
+#define ACI_VERSION_MSRC_DEF 3.6.020
#endif
#define SPECIAL_VERSION ""
Commit: 06880291b28e5a9b0648bab069101fd8e454a1c9
https://github.com/scummvm/scummvm/commit/06880291b28e5a9b0648bab069101fd8e454a1c9
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2022-04-21T21:49:13-07:00
Commit Message:
AGS: Refactor restrict_until and ShouldStayInWaitMode()
>From upstream 434dd136b4e6628545677a17fc17c847efff1c71
Changed paths:
engines/ags/engine/ac/runtime_defines.h
engines/ags/engine/main/game_run.cpp
engines/ags/globals.h
diff --git a/engines/ags/engine/ac/runtime_defines.h b/engines/ags/engine/ac/runtime_defines.h
index 1e27e341e36..cc127f5fed6 100644
--- a/engines/ags/engine/ac/runtime_defines.h
+++ b/engines/ags/engine/ac/runtime_defines.h
@@ -118,7 +118,6 @@ const int LegacyRoomVolumeFactor = 30;
#define FOR_SCRIPT 2
#define FOR_EXITLOOP 3
#define CHMLSOFFS (MAX_ROOM_OBJECTS+1) // reserve this many movelists for objects & stuff
-#define abort_all_conditions _G(restrict_until)
#define MAX_SCRIPT_AT_ONCE 10
#define EVENT_NONE 0
#define EVENT_INPROGRESS 1
diff --git a/engines/ags/engine/main/game_run.cpp b/engines/ags/engine/main/game_run.cpp
index 623da50799e..e98e7f79fcb 100644
--- a/engines/ags/engine/main/game_run.cpp
+++ b/engines/ags/engine/main/game_run.cpp
@@ -72,7 +72,7 @@ namespace AGS3 {
using namespace AGS::Shared;
-static int ShouldStayInWaitMode();
+static bool ShouldStayInWaitMode();
#define UNTIL_ANIMEND 1
#define UNTIL_MOVEEND 2
@@ -155,7 +155,7 @@ static int game_loop_check_ground_level_interactions() {
// if in a Wait loop which is no longer valid (probably
// because the Region interaction did a NewRoom), abort
// the rest of the loop
- if ((_G(restrict_until)) && (!ShouldStayInWaitMode())) {
+ if ((_G(restrict_until).type > 0) && (!ShouldStayInWaitMode())) {
// cancel the Rep Exec and Stands on Hotspot events that
// we just added -- otherwise the event queue gets huge
_GP(events).resize(_G(numEventsAtStartOfFunction));
@@ -382,7 +382,7 @@ bool run_service_key_controls(KeyInput &out_key) {
}
if (((agskey == eAGSKeyCodeCtrlV) && (cur_key_mods & Common::KBD_ALT) != 0)
- && (_GP(play).wait_counter < 1) && (_GP(play).text_overlay_on == 0) && (_G(restrict_until) == 0)) {
+ && (_GP(play).wait_counter < 1) && (_GP(play).text_overlay_on == 0) && (_G(restrict_until).type == 0)) {
// make sure we can't interrupt a Wait()
// and desync the music to cutscene
_GP(play).debug_mode++;
@@ -832,56 +832,67 @@ static void UpdateMouseOverLocation() {
}
// Checks if user interface should remain disabled for now
-static int ShouldStayInWaitMode() {
- if (_G(restrict_until) == 0)
+// Checks if user interface should remain disabled for now
+static bool ShouldStayInWaitMode() {
+ if (_G(restrict_until).type == 0)
quit("end_wait_loop called but game not in loop_until state");
- int retval = _G(restrict_until);
-
- if (_G(restrict_until) == UNTIL_MOVEEND) {
- const int16 *wkptr = (const int16 *)_G(user_disabled_data);
- if (wkptr[0] < 1) retval = 0;
- } else if (_G(restrict_until) == UNTIL_CHARIS0) {
- const char *chptr = (const char *)_G(user_disabled_data);
- if (chptr[0] == 0) retval = 0;
- } else if (_G(restrict_until) == UNTIL_NEGATIVE) {
- const int16 *wkptr = (const int16 *)_G(user_disabled_data);
- if (wkptr[0] < 0) retval = 0;
- } else if (_G(restrict_until) == UNTIL_INTISNEG) {
- const int *wkptr = (const int *)_G(user_disabled_data);
- if (wkptr[0] < 0) retval = 0;
- } else if (_G(restrict_until) == UNTIL_NOOVERLAY) {
- if (_GP(play).text_overlay_on == 0) retval = 0;
- } else if (_G(restrict_until) == UNTIL_INTIS0) {
- const int *wkptr = (const int *)_G(user_disabled_data);
- if (wkptr[0] == 0) retval = 0;
- } else if (_G(restrict_until) == UNTIL_SHORTIS0) {
- const int16 *wkptr = (const int16 *)_G(user_disabled_data);
- if (wkptr[0] == 0) retval = 0;
- } else quit("loop_until: unknown until event");
-
- return retval;
+
+ switch (_G(restrict_until).type) {
+ case UNTIL_MOVEEND: {
+ short *wkptr = (short *)_G(restrict_until).data_ptr;
+ return !(wkptr[0] < 1);
+ }
+ case UNTIL_CHARIS0: {
+ char *chptr = (char *)_G(restrict_until).data_ptr;
+ return !(chptr[0] == 0);
+ }
+ case UNTIL_NEGATIVE: {
+ short *wkptr = (short *)_G(restrict_until).data_ptr;
+ return !(wkptr[0] < 0);
+ }
+ case UNTIL_INTISNEG: {
+ int *wkptr = (int *)_G(restrict_until).data_ptr;
+ return !(wkptr[0] < 0);
+ }
+ case UNTIL_NOOVERLAY: {
+ return !(_GP(play).text_overlay_on == 0);
+ }
+ case UNTIL_INTIS0: {
+ int *wkptr = (int *)_G(restrict_until).data_ptr;
+ return !(wkptr[0] == 0);
+ }
+ case UNTIL_SHORTIS0: {
+ short *wkptr = (short *)_G(restrict_until).data_ptr;
+ return !(wkptr[0] == 0);
+ }
+ default:
+ quit("loop_until: unknown until event");
+ }
+
+ return true; // should stay in wait
}
static int UpdateWaitMode() {
- if (_G(restrict_until) == 0) {
+ if (_G(restrict_until).type == 0) {
return RETURN_CONTINUE;
}
- _G(restrict_until) = ShouldStayInWaitMode();
+ if (!ShouldStayInWaitMode())
+ _G(restrict_until).type = 0;
_G(our_eip) = 77;
- if (_G(restrict_until) != 0) {
+ if (_G(restrict_until).type > 0) {
return RETURN_CONTINUE;
}
- auto was_disabled_for = _G(user_disabled_for);
+ auto was_disabled_for = _G(restrict_until).disabled_for;
set_default_cursor();
if (GUI::Options.DisabledStyle != kGuiDis_Unchanged) { // If GUI looks change when disabled, then update them all
GUI::MarkAllGUIForUpdate();
}
_GP(play).disabled_user_interface--;
- _G(user_disabled_for) = 0;
+ _G(restrict_until).disabled_for = 0;
switch (was_disabled_for) {
// case FOR_ANIMATION:
@@ -893,7 +904,7 @@ static int UpdateWaitMode() {
quit("err: for_script obsolete (v2.1 and earlier only)");
break;
default:
- quit("Unknown _G(user_disabled_for) in end _G(restrict_until)");
+ quit("Unknown user_disabled_for in end _G(restrict_until)");
}
// we shouldn't get here.
@@ -932,9 +943,9 @@ static void SetupLoopParameters(int untilwhat, const void *udata) {
(_G(cur_mode) != CURS_WAIT))
set_mouse_cursor(CURS_WAIT);
- _G(restrict_until) = untilwhat;
- _G(user_disabled_data) = udata;
- _G(user_disabled_for) = FOR_EXITLOOP;
+ _G(restrict_until).type = untilwhat;
+ _G(restrict_until).data_ptr = udata;
+ _G(restrict_until).disabled_for = FOR_EXITLOOP;
}
// This function is called from lot of various functions
@@ -947,8 +958,6 @@ static void GameLoopUntilEvent(int untilwhat, const void *daaa) {
// remember the state of these vars in case a higher level
// call needs them
auto cached_restrict_until = _G(restrict_until);
- auto cached_user_disabled_data = _G(user_disabled_data);
- auto cached_user_disabled_for = _G(user_disabled_for);
SetupLoopParameters(untilwhat, daaa);
while (GameTick() == 0 && !_G(abort_engine)) {}
@@ -956,8 +965,6 @@ static void GameLoopUntilEvent(int untilwhat, const void *daaa) {
_G(our_eip) = 78;
_G(restrict_until) = cached_restrict_until;
- _G(user_disabled_data) = cached_user_disabled_data;
- _G(user_disabled_for) = cached_user_disabled_for;
}
void GameLoopUntilValueIsZero(const int8 *value) {
diff --git a/engines/ags/globals.h b/engines/ags/globals.h
index 65ef6b648aa..b6fa0207f88 100644
--- a/engines/ags/globals.h
+++ b/engines/ags/globals.h
@@ -812,11 +812,14 @@ public:
* @{
*/
- // Following 3 parameters instruct the engine to run game loops until
- // certain condition is not fullfilled.
- int _restrict_until = 0;
- int _user_disabled_for = 0;
- const void *_user_disabled_data = nullptr;
+ // Following struct instructs the engine to run game loops until
+ // certain condition is not fullfilled.
+ struct RestrictUntil {
+ int type = 0; // type of condition, UNTIL_* constant
+ int disabled_for = 0; // FOR_* constant
+ // pointer to the test variable
+ const void *data_ptr = nullptr;
+ } _restrict_until;
unsigned int _loopcounter = 0;
unsigned int _lastcounter = 0;
Commit: 415235b74e304520e4466ed969b24163a9ce1d66
https://github.com/scummvm/scummvm/commit/415235b74e304520e4466ed969b24163a9ce1d66
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2022-04-21T22:07:41-07:00
Commit Message:
AGS: expanded Button.Animate to feature all common params
>From upstream 0853d4146276f86c7418dc02360deb49a0ef324a
Changed paths:
engines/ags/engine/ac/button.cpp
engines/ags/engine/ac/button.h
engines/ags/engine/gui/animating_gui_button.h
engines/ags/engine/main/game_run.cpp
engines/ags/engine/main/game_run.h
engines/ags/engine/script/script_api.h
engines/ags/globals.h
diff --git a/engines/ags/engine/ac/button.cpp b/engines/ags/engine/ac/button.cpp
index 937138758df..f8e09f35dbb 100644
--- a/engines/ags/engine/ac/button.cpp
+++ b/engines/ags/engine/ac/button.cpp
@@ -34,6 +34,7 @@
#include "ags/engine/script/script_api.h"
#include "ags/engine/script/script_runtime.h"
#include "ags/engine/ac/dynobj/script_string.h"
+#include "ags/engine/main/game_run.h"
#include "ags/globals.h"
namespace AGS3 {
@@ -42,25 +43,50 @@ using namespace AGS::Shared;
// *** BUTTON FUNCTIONS
-void Button_Animate(GUIButton *butt, int view, int loop, int speed, int repeat) {
+void Button_AnimateEx(GUIButton *butt, int view, int loop, int speed, int repeat, int blocking, int direction, int sframe) {
int guin = butt->ParentId;
int objn = butt->Id;
+ if (direction == FORWARDS)
+ direction = 0;
+ else if (direction == BACKWARDS)
+ direction = 1;
+ if (blocking == BLOCKING)
+ blocking = 1;
+ else if (blocking == IN_BACKGROUND)
+ blocking = 0;
+
if ((view < 1) || (view > _GP(game).numviews))
quit("!AnimateButton: invalid view specified");
view--;
-
if ((loop < 0) || (loop >= _GP(views)[view].numLoops))
quit("!AnimateButton: invalid loop specified for view");
+ if (sframe < 0 || sframe >= _GP(views)[view].loops[loop].numFrames)
+ quit("!AnimateButton: invalid starting frame number specified");
+ if ((repeat < 0) || (repeat > 1))
+ quit("!AnimateButton: invalid repeat value");
+ if ((blocking < 0) || (blocking > 1))
+ quit("!AnimateButton: invalid blocking value");
+ if ((direction < 0) || (direction > 1))
+ quit("!AnimateButton: invalid direction");
// if it's already animating, stop it
FindAndRemoveButtonAnimation(guin, objn);
+ // Prepare button
int buttonId = _GP(guis)[guin].GetControlID(objn);
-
_GP(guibuts)[buttonId].PushedImage = 0;
_GP(guibuts)[buttonId].MouseOverImage = 0;
+ // reverse animation starts at the *previous frame*
+ if (direction) {
+ if (--sframe < 0)
+ sframe = _GP(views)[view].loops[loop].numFrames - (-sframe);
+ sframe++; // set on next frame, first call to Update will decrement
+ } else {
+ sframe--; // set on prev frame, first call to Update will increment
+ }
+
AnimatingGUIButton abtn;
abtn.ongui = guin;
abtn.onguibut = objn;
@@ -69,7 +95,9 @@ void Button_Animate(GUIButton *butt, int view, int loop, int speed, int repeat)
abtn.loop = loop;
abtn.speed = speed;
abtn.repeat = repeat;
- abtn.frame = -1;
+ abtn.blocking = blocking;
+ abtn.direction = direction;
+ abtn.frame = sframe;
abtn.wait = 0;
_GP(animbuts).push_back(abtn);
// launch into the first frame
@@ -78,6 +106,14 @@ void Button_Animate(GUIButton *butt, int view, int loop, int speed, int repeat)
butt->GetScriptName().GetCStr(), view, loop);
StopButtonAnimation(_GP(animbuts).size() - 1);
}
+
+ // Blocking animate
+ if (blocking)
+ GameLoopUntilButAnimEnd(guin, objn);
+}
+
+void Button_Animate(GUIButton *butt, int view, int loop, int speed, int repeat) {
+ Button_AnimateEx(butt, view, loop, speed, repeat, IN_BACKGROUND, FORWARDS, 0);
}
const char *Button_GetText_New(GUIButton *butt) {
@@ -216,21 +252,37 @@ int UpdateAnimatingButton(int bu) {
}
ViewStruct *tview = &_GP(views)[abtn.view];
- abtn.frame++;
-
- if (abtn.frame >= tview->loops[abtn.loop].numFrames) {
- if (tview->loops[abtn.loop].RunNextLoop()) {
- // go to next loop
- abtn.loop++;
- abtn.frame = 0;
- } else if (abtn.repeat) {
- abtn.frame = 0;
- // multi-loop anim, go back
- while ((abtn.loop > 0) &&
- (tview->loops[abtn.loop - 1].RunNextLoop()))
+ if (abtn.direction) { // backwards
+ abtn.frame--;
+ if (abtn.frame < 0) {
+ if ((abtn.loop > 0) && tview->loops[abtn.loop - 1].RunNextLoop()) {
+ // go to next loop
abtn.loop--;
- } else
- return 1;
+ abtn.frame = tview->loops[abtn.loop].numFrames - 1;
+ } else if (abtn.repeat) {
+ // multi-loop anim, go back
+ while (tview->loops[abtn.loop].RunNextLoop())
+ abtn.loop++;
+ abtn.frame = tview->loops[abtn.loop].numFrames - 1;
+ } else
+ return 1;
+ }
+ } else { // forwards
+ abtn.frame++;
+ if (abtn.frame >= tview->loops[abtn.loop].numFrames) {
+ if (tview->loops[abtn.loop].RunNextLoop()) {
+ // go to next loop
+ abtn.loop++;
+ abtn.frame = 0;
+ } else if (abtn.repeat) {
+ abtn.frame = 0;
+ // multi-loop anim, go back
+ while ((abtn.loop > 0) &&
+ (tview->loops[abtn.loop - 1].RunNextLoop()))
+ abtn.loop--;
+ } else
+ return 1;
+ }
}
CheckViewFrame(abtn.view, abtn.loop, abtn.frame);
@@ -256,7 +308,7 @@ void RemoveAllButtonAnimations() {
// Returns the index of the AnimatingGUIButton object corresponding to the
// given button ID; returns -1 if no such animation exists
-int FindAnimatedButton(int guin, int objn) {
+int FindButtonAnimation(int guin, int objn) {
for (size_t i = 0; i < _GP(animbuts).size(); ++i) {
if (_GP(animbuts)[i].ongui == guin && _GP(animbuts)[i].onguibut == objn)
return i;
@@ -265,7 +317,7 @@ int FindAnimatedButton(int guin, int objn) {
}
void FindAndRemoveButtonAnimation(int guin, int objn) {
- int idx = FindAnimatedButton(guin, objn);
+ int idx = FindButtonAnimation(guin, objn);
if (idx >= 0)
StopButtonAnimation(idx);
}
@@ -277,24 +329,24 @@ void Button_Click(GUIButton *butt, int mbut) {
}
bool Button_IsAnimating(GUIButton *butt) {
- return FindAnimatedButton(butt->ParentId, butt->Id) >= 0;
+ return FindButtonAnimation(butt->ParentId, butt->Id) >= 0;
}
// NOTE: in correspondance to similar functions for Character & Object,
// GetView returns (view index + 1), while GetLoop and GetFrame return
// zero-based index and 0 in case of no animation.
int Button_GetAnimView(GUIButton *butt) {
- int idx = FindAnimatedButton(butt->ParentId, butt->Id);
+ int idx = FindButtonAnimation(butt->ParentId, butt->Id);
return idx >= 0 ? _GP(animbuts)[idx].view + 1 : 0;
}
int Button_GetAnimLoop(GUIButton *butt) {
- int idx = FindAnimatedButton(butt->ParentId, butt->Id);
+ int idx = FindButtonAnimation(butt->ParentId, butt->Id);
return idx >= 0 ? _GP(animbuts)[idx].loop : 0;
}
int Button_GetAnimFrame(GUIButton *butt) {
- int idx = FindAnimatedButton(butt->ParentId, butt->Id);
+ int idx = FindButtonAnimation(butt->ParentId, butt->Id);
return idx >= 0 ? _GP(animbuts)[idx].frame : 0;
}
@@ -320,6 +372,10 @@ RuntimeScriptValue Sc_Button_Animate(void *self, const RuntimeScriptValue *param
API_OBJCALL_VOID_PINT4(GUIButton, Button_Animate);
}
+RuntimeScriptValue Sc_Button_AnimateEx(void *self, const RuntimeScriptValue *params, int32_t param_count) {
+ API_OBJCALL_VOID_PINT7(GUIButton, Button_AnimateEx);
+}
+
// const char* | GUIButton *butt
RuntimeScriptValue Sc_Button_GetText_New(void *self, const RuntimeScriptValue *params, int32_t param_count) {
API_CONST_OBJCALL_OBJ(GUIButton, const char, _GP(myScriptStringImpl), Button_GetText_New);
@@ -430,6 +486,7 @@ RuntimeScriptValue Sc_Button_GetView(void *self, const RuntimeScriptValue *param
void RegisterButtonAPI() {
ccAddExternalObjectFunction("Button::Animate^4", Sc_Button_Animate);
+ ccAddExternalObjectFunction("Button::Animate^7", Sc_Button_AnimateEx);
ccAddExternalObjectFunction("Button::Click^1", Sc_Button_Click);
ccAddExternalObjectFunction("Button::GetText^1", Sc_Button_GetText);
ccAddExternalObjectFunction("Button::SetText^1", Sc_Button_SetText);
diff --git a/engines/ags/engine/ac/button.h b/engines/ags/engine/ac/button.h
index b0ecbcc652b..733d0769f34 100644
--- a/engines/ags/engine/ac/button.h
+++ b/engines/ags/engine/ac/button.h
@@ -53,6 +53,7 @@ size_t GetAnimatingButtonCount();
AnimatingGUIButton *GetAnimatingButtonByIndex(int idxn);
void AddButtonAnimation(const AnimatingGUIButton &abtn);
void StopButtonAnimation(int idxn);
+int FindButtonAnimation(int guin, int objn);
void FindAndRemoveButtonAnimation(int guin, int objn);
void RemoveAllButtonAnimations();
diff --git a/engines/ags/engine/gui/animating_gui_button.h b/engines/ags/engine/gui/animating_gui_button.h
index 48242d27d5f..e63d0c9a7f2 100644
--- a/engines/ags/engine/gui/animating_gui_button.h
+++ b/engines/ags/engine/gui/animating_gui_button.h
@@ -39,7 +39,8 @@ struct AnimatingGUIButton {
short buttonid = 0, ongui = 0, onguibut = 0;
// current animation status
short view = 0, loop = 0, frame = 0;
- short speed = 0, repeat = 0, wait = 0;
+ short speed = 0, repeat = 0, blocking = 0,
+ direction = 0, wait = 0;
void ReadFromFile(Shared::Stream *in);
void WriteToFile(Shared::Stream *out);
diff --git a/engines/ags/engine/main/game_run.cpp b/engines/ags/engine/main/game_run.cpp
index e98e7f79fcb..55168765ea5 100644
--- a/engines/ags/engine/main/game_run.cpp
+++ b/engines/ags/engine/main/game_run.cpp
@@ -82,6 +82,7 @@ static bool ShouldStayInWaitMode();
#define UNTIL_INTIS0 6
#define UNTIL_SHORTIS0 7
#define UNTIL_INTISNEG 8
+#define UNTIL_ANIMBTNEND 9
static void ProperExit() {
_G(want_exit) = 0;
@@ -865,6 +866,10 @@ static bool ShouldStayInWaitMode() {
short *wkptr = (short *)_G(restrict_until).data_ptr;
return !(wkptr[0] == 0);
}
+ case UNTIL_ANIMBTNEND: {
+ // still animating?
+ return FindButtonAnimation(_G(restrict_until).data1, _G(restrict_until).data2) >= 0;
+ }
default:
quit("loop_until: unknown until event");
}
@@ -932,7 +937,7 @@ static int GameTick() {
return res;
}
-static void SetupLoopParameters(int untilwhat, const void *udata) {
+static void SetupLoopParameters(int untilwhat, const void *data_ptr = nullptr, int data1 = 0, int data2 = 0) {
_GP(play).disabled_user_interface++;
if (GUI::Options.DisabledStyle != kGuiDis_Unchanged) { // If GUI looks change when disabled, then update them all
GUI::MarkAllGUIForUpdate();
@@ -940,17 +945,19 @@ static void SetupLoopParameters(int untilwhat, const void *udata) {
// Only change the mouse cursor if it hasn't been specifically changed first
// (or if it's speech, always change it)
if (((_G(cur_cursor) == _G(cur_mode)) || (untilwhat == UNTIL_NOOVERLAY)) &&
- (_G(cur_mode) != CURS_WAIT))
+ (_G(cur_mode) != CURS_WAIT))
set_mouse_cursor(CURS_WAIT);
_G(restrict_until).type = untilwhat;
- _G(restrict_until).data_ptr = udata;
+ _G(restrict_until).data_ptr = data_ptr;
+ _G(restrict_until).data1 = data1;
+ _G(restrict_until).data2 = data2;
_G(restrict_until).disabled_for = FOR_EXITLOOP;
}
// This function is called from lot of various functions
// in the game core, character, room object etc
-static void GameLoopUntilEvent(int untilwhat, const void *daaa) {
+static void GameLoopUntilEvent(int untilwhat, const void *data_ptr = nullptr, int data1 = 0, int data2 = 0) {
// blocking cutscene - end skipping
EndSkippingUntilCharStops();
@@ -959,8 +966,8 @@ static void GameLoopUntilEvent(int untilwhat, const void *daaa) {
// call needs them
auto cached_restrict_until = _G(restrict_until);
- SetupLoopParameters(untilwhat, daaa);
- while (GameTick() == 0 && !_G(abort_engine)) {}
+ SetupLoopParameters(untilwhat, data_ptr, data1, data2);
+ while (GameTick() == 0);
_G(our_eip) = 78;
@@ -996,10 +1003,12 @@ void GameLoopUntilNotMoving(const short *move) {
}
void GameLoopUntilNoOverlay() {
- GameLoopUntilEvent(UNTIL_NOOVERLAY, nullptr);
+ GameLoopUntilEvent(UNTIL_NOOVERLAY);
}
-
+void GameLoopUntilButAnimEnd(int guin, int objn) {
+ GameLoopUntilEvent(UNTIL_ANIMBTNEND, nullptr, guin, objn);
+}
void RunGameUntilAborted() {
// skip ticks to account for time spent starting _GP(game).
diff --git a/engines/ags/engine/main/game_run.h b/engines/ags/engine/main/game_run.h
index 340d70d9635..0928801a596 100644
--- a/engines/ags/engine/main/game_run.h
+++ b/engines/ags/engine/main/game_run.h
@@ -19,8 +19,8 @@
*
*/
-#ifndef AGS_ENGINE_MAIN__GAMERUN_H
-#define AGS_ENGINE_MAIN__GAMERUN_H
+#ifndef AGS_ENGINE_MAIN_GAME_RUN_H
+#define AGS_ENGINE_MAIN_GAME_RUN_H
namespace AGS3 {
@@ -40,6 +40,7 @@ void GameLoopUntilValueIsNegative(const short *value);
void GameLoopUntilValueIsNegative(const int *value);
void GameLoopUntilNotMoving(const short *move);
void GameLoopUntilNoOverlay();
+void GameLoopUntilButAnimEnd(int guin, int objn);
// Run the actual game until it ends, or aborted by player/error; loops GameTick() internally
void RunGameUntilAborted();
diff --git a/engines/ags/engine/script/script_api.h b/engines/ags/engine/script/script_api.h
index 8f4887e7f95..0c49950028f 100644
--- a/engines/ags/engine/script/script_api.h
+++ b/engines/ags/engine/script/script_api.h
@@ -427,6 +427,11 @@ inline const char *ScriptVSprintf(char *buffer, size_t buf_length, const char *f
METHOD((CLASS*)self, params[0].IValue, params[1].IValue, params[2].IValue, params[3].IValue, params[4].IValue, params[5].IValue); \
return RuntimeScriptValue((int32_t)0)
+#define API_OBJCALL_VOID_PINT7(CLASS, METHOD) \
+ ASSERT_OBJ_PARAM_COUNT(METHOD, 7); \
+ METHOD((CLASS*)self, params[0].IValue, params[1].IValue, params[2].IValue, params[3].IValue, params[4].IValue, params[5].IValue, params[6].IValue); \
+ return RuntimeScriptValue((int32_t)0)
+
#define API_OBJCALL_VOID_PFLOAT(CLASS, METHOD) \
ASSERT_OBJ_PARAM_COUNT(METHOD, 1); \
METHOD((CLASS*)self, params[0].FValue); \
diff --git a/engines/ags/globals.h b/engines/ags/globals.h
index b6fa0207f88..53319d6df42 100644
--- a/engines/ags/globals.h
+++ b/engines/ags/globals.h
@@ -819,6 +819,9 @@ public:
int disabled_for = 0; // FOR_* constant
// pointer to the test variable
const void *data_ptr = nullptr;
+ // other values used for a test, depend on type
+ int data1 = 0;
+ int data2 = 0;
} _restrict_until;
unsigned int _loopcounter = 0;
Commit: bf5e0b2d083ded5bfb9b8bad5af26c15373de707
https://github.com/scummvm/scummvm/commit/bf5e0b2d083ded5bfb9b8bad5af26c15373de707
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2022-04-21T22:18:33-07:00
Commit Message:
AGS: Updated AnimatingButton save format
>From upstream 7920a8719db3bc39b1187a076184d9a6d66b1310
Changed paths:
engines/ags/engine/game/savegame_components.cpp
engines/ags/engine/game/savegame_v321.cpp
engines/ags/engine/gui/animating_gui_button.cpp
engines/ags/engine/gui/animating_gui_button.h
engines/ags/shared/gui/gui_defines.h
diff --git a/engines/ags/engine/game/savegame_components.cpp b/engines/ags/engine/game/savegame_components.cpp
index 8111b8fbede..fb8f2f66648 100644
--- a/engines/ags/engine/game/savegame_components.cpp
+++ b/engines/ags/engine/game/savegame_components.cpp
@@ -635,9 +635,10 @@ HSaveError ReadGUI(Stream *in, int32_t cmp_ver, const PreservedParams &pp, Resto
int anim_count = in->ReadInt32();
for (int i = 0; i < anim_count; ++i) {
AnimatingGUIButton abut;
- abut.ReadFromFile(in);
+ abut.ReadFromFile(in, cmp_ver);
AddButtonAnimation(abut);
- } return err;
+ }
+ return err;
}
HSaveError WriteInventory(Stream *out) {
@@ -1047,7 +1048,7 @@ ComponentHandler ComponentHandlers[] = {
},
{
"GUI",
- kGuiSvgVersion_350,
+ kGuiSvgVersion_36020,
kGuiSvgVersion_Initial,
WriteGUI,
ReadGUI
diff --git a/engines/ags/engine/game/savegame_v321.cpp b/engines/ags/engine/game/savegame_v321.cpp
index a5e0792cd15..6631ca7264d 100644
--- a/engines/ags/engine/game/savegame_v321.cpp
+++ b/engines/ags/engine/game/savegame_v321.cpp
@@ -216,7 +216,7 @@ void ReadAnimatedButtons_Aligned(Stream *in, int num_abuts) {
AlignedStream align_s(in, Shared::kAligned_Read);
for (int i = 0; i < num_abuts; ++i) {
AnimatingGUIButton abtn;
- abtn.ReadFromFile(&align_s);
+ abtn.ReadFromFile(&align_s, 0);
AddButtonAnimation(abtn);
align_s.Reset();
}
diff --git a/engines/ags/engine/gui/animating_gui_button.cpp b/engines/ags/engine/gui/animating_gui_button.cpp
index 9f3cdfb1508..ded337e5c37 100644
--- a/engines/ags/engine/gui/animating_gui_button.cpp
+++ b/engines/ags/engine/gui/animating_gui_button.cpp
@@ -26,7 +26,7 @@ namespace AGS3 {
using AGS::Shared::Stream;
-void AnimatingGUIButton::ReadFromFile(Stream *in) {
+void AnimatingGUIButton::ReadFromFile(Stream *in, int cmp_ver) {
buttonid = in->ReadInt16();
ongui = in->ReadInt16();
onguibut = in->ReadInt16();
@@ -34,11 +34,21 @@ void AnimatingGUIButton::ReadFromFile(Stream *in) {
loop = in->ReadInt16();
frame = in->ReadInt16();
speed = in->ReadInt16();
- repeat = in->ReadInt16();
+ uint16_t anim_flags = in->ReadInt16(); // was repeat (0,1)
wait = in->ReadInt16();
+
+ if (cmp_ver < 2) anim_flags &= 0x1; // restrict to repeat only
+ repeat = anim_flags & 0x1;
+ blocking = (anim_flags >> 1) & 0x1;
+ direction = (anim_flags >> 2) & 0x1;
}
void AnimatingGUIButton::WriteToFile(Stream *out) {
+ uint16_t anim_flags =
+ (repeat & 0x1) |
+ (blocking & 0x1) << 1 |
+ (direction & 0x1) << 2;
+
out->WriteInt16(buttonid);
out->WriteInt16(ongui);
out->WriteInt16(onguibut);
@@ -46,7 +56,7 @@ void AnimatingGUIButton::WriteToFile(Stream *out) {
out->WriteInt16(loop);
out->WriteInt16(frame);
out->WriteInt16(speed);
- out->WriteInt16(repeat);
+ out->WriteInt16(anim_flags); // was repeat (0,1)
out->WriteInt16(wait);
}
diff --git a/engines/ags/engine/gui/animating_gui_button.h b/engines/ags/engine/gui/animating_gui_button.h
index e63d0c9a7f2..c6290318a57 100644
--- a/engines/ags/engine/gui/animating_gui_button.h
+++ b/engines/ags/engine/gui/animating_gui_button.h
@@ -42,7 +42,7 @@ struct AnimatingGUIButton {
short speed = 0, repeat = 0, blocking = 0,
direction = 0, wait = 0;
- void ReadFromFile(Shared::Stream *in);
+ void ReadFromFile(Shared::Stream *in, int cmp_ver);
void WriteToFile(Shared::Stream *out);
};
diff --git a/engines/ags/shared/gui/gui_defines.h b/engines/ags/shared/gui/gui_defines.h
index d88a61c29f4..10621fbaee2 100644
--- a/engines/ags/shared/gui/gui_defines.h
+++ b/engines/ags/shared/gui/gui_defines.h
@@ -184,7 +184,8 @@ enum GUITextBoxFlags {
// TODO: move to the engine code
enum GuiSvgVersion {
kGuiSvgVersion_Initial = 0,
- kGuiSvgVersion_350 = 1
+ kGuiSvgVersion_350,
+ kGuiSvgVersion_36020
};
enum GuiDisableStyle {
More information about the Scummvm-git-logs
mailing list