[Scummvm-git-logs] scummvm master -> 99cc27e840b59a84e1804dda2619ecd67891cdfb
dreammaster
noreply at scummvm.org
Tue Apr 19 02:31:45 UTC 2022
This automated email contains information about 8 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
8be58d3de2 AGS: Store game events in std::vector, remove event cap
af079a9c45 AGS: Handle all the buffered key events in one game frame
2e24e08d5b AGS: Brought few "run script" functions to similar arg list
b2d8bcad75 AGS: Refactor RunTextScript* functions for the purpose of clarity
c0010986ac AGS: Implemented `on_text_input(int chr)` callback
09da0fbf5d AGS: Implemented `dialog_options_text_input(int chr)` callback
dec92f05ea AGS: Support passing partial argument list to a script callback
99cc27e840 AGS: Fixed few comments in ccInstance::Run()
Commit: 8be58d3de20ab96c300fcfcaa94546fee15bf5fe
https://github.com/scummvm/scummvm/commit/8be58d3de20ab96c300fcfcaa94546fee15bf5fe
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2022-04-18T19:10:29-07:00
Commit Message:
AGS: Store game events in std::vector, remove event cap
>From upstream a2f9a5ba94377686762b2828df4fccbe661d2b03
Changed paths:
engines/ags/engine/ac/event.cpp
engines/ags/engine/ac/event.h
engines/ags/engine/ac/room.cpp
engines/ags/engine/main/game_run.cpp
engines/ags/globals.cpp
engines/ags/globals.h
engines/ags/lib/std/utility.h
diff --git a/engines/ags/engine/ac/event.cpp b/engines/ags/engine/ac/event.cpp
index 0f0e64942b8..f6dc82c3a3b 100644
--- a/engines/ags/engine/ac/event.cpp
+++ b/engines/ags/engine/ac/event.cpp
@@ -110,13 +110,13 @@ void run_event_block_inv(int invNum, int event) {
// event list functions
void setevent(int evtyp, int ev1, int ev2, int ev3) {
- _G(event)[_G(numevents)].type = evtyp;
- _G(event)[_G(numevents)].data1 = ev1;
- _G(event)[_G(numevents)].data2 = ev2;
- _G(event)[_G(numevents)].data3 = ev3;
- _G(event)[_G(numevents)].player = _GP(game).playercharacter;
- _G(numevents)++;
- if (_G(numevents) >= MAXEVENTS) quit("too many events posted");
+ EventHappened evt;
+ evt.type = evtyp;
+ evt.data1 = ev1;
+ evt.data2 = ev2;
+ evt.data3 = ev3;
+ evt.player = _GP(game).playercharacter;
+ _GP(events).push_back(evt);
}
// TODO: this is kind of a hack, which forces event to be processed even if
@@ -129,7 +129,7 @@ void force_event(int evtyp, int ev1, int ev2, int ev3) {
setevent(evtyp, ev1, ev2, ev3);
}
-void process_event(EventHappened *evp) {
+void process_event(const EventHappened *evp) {
RuntimeScriptValue rval_null;
if (evp->type == EV_TEXTSCRIPT) {
_G(ccError) = 0;
@@ -340,41 +340,34 @@ void runevent_now(int evtyp, int ev1, int ev2, int ev3) {
process_event(&evh);
}
-void processallevents(int numev, EventHappened *evlist) {
- int dd;
-
+void processallevents() {
if (_G(inside_processevent))
return;
- // make a copy of the events - if processing an event includes
- // a blocking function it will continue to the next game loop
- // and wipe out the event pointer we were passed
- EventHappened copyOfList[MAXEVENTS];
- memcpy(©OfList[0], &evlist[0], sizeof(EventHappened) * numev);
+ // Take ownership of the pending events
+ // Note: upstream AGS used std::move, which I haven't been able
+ // to properly implement in ScummVM. Luckily, our events are
+ // a pointer, so I could get the same result swapping them
+ std::vector<EventHappened> *evtCopy = new std::vector<EventHappened>();
+ SWAP(evtCopy, _G(events));
int room_was = _GP(play).room_changes;
_G(inside_processevent)++;
- for (dd = 0; dd < numev; dd++) {
-
- process_event(©OfList[dd]);
+ for (size_t i = 0; i < evtCopy->size(); ++i) {
+ process_event(&(*evtCopy)[i]);
- if (room_was != _GP(play).room_changes || _G(abort_engine))
+ if (room_was != _GP(play).room_changes)
break; // changed room, so discard other events
}
+ delete evtCopy;
_G(inside_processevent)--;
}
-void update_events() {
- processallevents(_G(numevents), &_G(event)[0]);
- _G(numevents) = 0;
-}
-
// end event list functions
-
void ClaimEvent() {
if (_G(eventClaimed) == EVENT_NONE)
quit("!ClaimEvent: no event to claim");
diff --git a/engines/ags/engine/ac/event.h b/engines/ags/engine/ac/event.h
index ed361b15e54..2596054cc35 100644
--- a/engines/ags/engine/ac/event.h
+++ b/engines/ags/engine/ac/event.h
@@ -38,8 +38,6 @@ namespace AGS3 {
#define GE_LOSE_INV 8
#define GE_RESTORE_GAME 9
-#define MAXEVENTS 15
-
#define EV_TEXTSCRIPT 1
#define EV_RUNEVBLOCK 2
#define EV_FADEIN 3
@@ -52,9 +50,9 @@ namespace AGS3 {
#define EVB_ROOM 2
struct EventHappened {
- int type;
- int data1, data2, data3;
- int player;
+ int type = 0;
+ int data1 = 0, data2 = 0, data3 = 0;
+ int player = -1;
};
int run_claimable_event(const char *tsname, bool includeRoom, int numParams, const RuntimeScriptValue *params, bool *eventWasClaimed);
@@ -65,10 +63,9 @@ 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 process_event(EventHappened *evp);
+void process_event(const EventHappened *evp);
void runevent_now(int evtyp, int ev1, int ev2, int ev3);
-void processallevents(int numev, EventHappened *evlist);
-void update_events();
+void processallevents();
// end event list functions
void ClaimEvent();
diff --git a/engines/ags/engine/ac/room.cpp b/engines/ags/engine/ac/room.cpp
index ec9e464c5e8..6a60c83ee5a 100644
--- a/engines/ags/engine/ac/room.cpp
+++ b/engines/ags/engine/ac/room.cpp
@@ -245,7 +245,7 @@ void unload_old_room() {
}
cancel_all_scripts();
- _G(numevents) = 0; // cancel any pending room events
+ _GP(events).clear(); // cancel any pending room events
if (_G(roomBackgroundBmp) != nullptr) {
_G(gfxDriver)->DestroyDDB(_G(roomBackgroundBmp));
diff --git a/engines/ags/engine/main/game_run.cpp b/engines/ags/engine/main/game_run.cpp
index 6957ad27aef..07f26a1862d 100644
--- a/engines/ags/engine/main/game_run.cpp
+++ b/engines/ags/engine/main/game_run.cpp
@@ -158,7 +158,7 @@ static int game_loop_check_ground_level_interactions() {
if ((_G(restrict_until)) && (!ShouldStayInWaitMode())) {
// cancel the Rep Exec and Stands on Hotspot events that
// we just added -- otherwise the event queue gets huge
- _G(numevents) = _G(numEventsAtStartOfFunction);
+ _GP(events).resize(_G(numEventsAtStartOfFunction));
return 0;
}
} // end if checking ground level interactions
@@ -516,14 +516,14 @@ static void check_controls() {
check_keyboard_controls();
}
-static void check_room_edges(int numevents_was) {
+static void check_room_edges(size_t numevents_was) {
if ((IsInterfaceEnabled()) && (IsGamePaused() == 0) &&
(_G(in_new_room) == 0) && (_G(new_room_was) == 0)) {
// Only allow walking off edges if not in wait mode, and
// if not in Player Enters Screen (allow walking in from off-screen)
int edgesActivated[4] = { 0, 0, 0, 0 };
// Only do it if nothing else has happened (eg. mouseclick)
- if ((_G(numevents) == numevents_was) &&
+ if ((_GP(events).size() == numevents_was) &&
((_GP(play).ground_level_areas_disabled & GLED_INTERACTION) == 0)) {
if (_G(playerchar)->x <= _GP(thisroom).Edges.Left)
@@ -558,7 +558,7 @@ static void game_loop_check_controls(bool checkControls) {
// don't let the player do anything before the screen fades in
if ((_G(in_new_room) == 0) && (checkControls)) {
int inRoom = _G(displayed_room);
- int numevents_was = _G(numevents);
+ size_t numevents_was = _GP(events).size();
check_controls();
check_room_edges(numevents_was);
@@ -631,7 +631,7 @@ static void game_loop_update_events() {
if (_G(in_new_room) > 0)
setevent(EV_FADEIN, 0, 0, 0);
_G(in_new_room) = 0;
- update_events();
+ processallevents();
if (!_G(abort_engine) && (_G(new_room_was) > 0) && (_G(in_new_room) == 0)) {
// if in a new room, and the room wasn't just changed again in update_events,
// then queue the Enters Screen scripts
@@ -704,7 +704,7 @@ void UpdateGameOnce(bool checkControls, IDriverDependantBitmap *extraBitmap, int
sys_evt_process_pending();
- _G(numEventsAtStartOfFunction) = _G(numevents);
+ _G(numEventsAtStartOfFunction) = _GP(events).size();
if (_G(want_exit)) {
ProperExit();
diff --git a/engines/ags/globals.cpp b/engines/ags/globals.cpp
index bc226ee9b56..73dab86f469 100644
--- a/engines/ags/globals.cpp
+++ b/engines/ags/globals.cpp
@@ -196,7 +196,7 @@ Globals::Globals() {
_ResPaths = new ResourcePaths();
// event.cpp globals
- _event = new EventHappened[MAXEVENTS + 1];
+ _events = new std::vector<EventHappened>();
// fonts.cpp globals
_fonts = new std::vector<AGS::Shared::Font>();
@@ -443,7 +443,7 @@ Globals::~Globals() {
delete _ResPaths;
// event.cpp globals
- delete[] _event;
+ delete _events;
// fonts.cpp globals
delete _fonts;
diff --git a/engines/ags/globals.h b/engines/ags/globals.h
index c656b992117..f5ad1ec7fbe 100644
--- a/engines/ags/globals.h
+++ b/engines/ags/globals.h
@@ -667,8 +667,7 @@ public:
int _in_enters_screen = 0, _done_es_error = 0;
int _in_leaves_screen = -1;
- EventHappened *_event;
- int _numevents = 0;
+ std::vector<EventHappened> *_events;
const char *_evblockbasename = nullptr;
int _evblocknum = 0;
diff --git a/engines/ags/lib/std/utility.h b/engines/ags/lib/std/utility.h
index 7fe1f595467..d701a3c3dd5 100644
--- a/engines/ags/lib/std/utility.h
+++ b/engines/ags/lib/std/utility.h
@@ -22,6 +22,8 @@
#ifndef AGS_STD_UTILITY_H
#define AGS_STD_UTILITY_H
+#include "common/textconsole.h"
+
namespace AGS3 {
namespace std {
@@ -41,9 +43,21 @@ pair<T1, T2> make_pair(T1 first, T2 second) {
return pair<T1, T2>(first, second);
}
-template<class T>
-T move(const T &v) {
- return v;
+// STRUCT TEMPLATE remove_reference
+template <class _Ty>
+struct remove_reference {
+ using type = _Ty;
+};
+
+template <class _Ty>
+using remove_reference_t = typename remove_reference<_Ty>::type;
+
+// FUNCTION TEMPLATE move
+// TODO: Haven't been able to get this to properly work to reset
+// the source when moving the contents of std::vector arrays
+template <class _Ty>
+constexpr remove_reference_t<_Ty> &&move(_Ty &&_Arg) noexcept {
+ return static_cast<remove_reference_t<_Ty> &&>(_Arg);
}
} // namespace std
Commit: af079a9c452b0e537eac1c7a781640d74c89e4cb
https://github.com/scummvm/scummvm/commit/af079a9c452b0e537eac1c7a781640d74c89e4cb
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2022-04-18T19:10:38-07:00
Commit Message:
AGS: Handle all the buffered key events in one game frame
>From upstream e489e187e88071c15fa64351852b8ede45f9f7ac
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 07f26a1862d..7190f51ff06 100644
--- a/engines/ags/engine/main/game_run.cpp
+++ b/engines/ags/engine/main/game_run.cpp
@@ -502,8 +502,6 @@ static void check_keyboard_controls() {
debug_script_log("Running on_key_press keycode %d", sckey);
setevent(EV_TEXTSCRIPT, TS_KEYPRESS, sckey);
}
-
- // RunTextScriptIParam(_G(gameinst),"on_key_press",kgn);
}
// check_controls: checks mouse & keyboard interface
@@ -513,7 +511,9 @@ static void check_controls() {
sys_evt_process_pending();
check_mouse_controls();
- check_keyboard_controls();
+ // Handle all the buffered key events
+ while (ags_keyevent_ready())
+ check_keyboard_controls();
}
static void check_room_edges(size_t numevents_was) {
Commit: 2e24e08d5ba87ef5ecfa3ff1e4e4389176ad44d3
https://github.com/scummvm/scummvm/commit/2e24e08d5ba87ef5ecfa3ff1e4e4389176ad44d3
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2022-04-18T19:10:39-07:00
Commit Message:
AGS: Brought few "run script" functions to similar arg list
>From upstream 78163a07400353013dd939ca86f5513f3196394a
Changed paths:
engines/ags/engine/ac/event.cpp
engines/ags/engine/ac/global_room.cpp
engines/ags/engine/ac/gui.cpp
engines/ags/engine/script/executing_script.cpp
engines/ags/engine/script/executing_script.h
engines/ags/engine/script/script.cpp
engines/ags/engine/script/script.h
engines/ags/plugins/ags_plugin.cpp
diff --git a/engines/ags/engine/ac/event.cpp b/engines/ags/engine/ac/event.cpp
index f6dc82c3a3b..ddcc7ab3ee4 100644
--- a/engines/ags/engine/ac/event.cpp
+++ b/engines/ags/engine/ac/event.cpp
@@ -85,7 +85,8 @@ int run_claimable_event(const char *tsname, bool includeRoom, int numParams, con
// runs the global script on_event function
void run_on_event(int evtype, RuntimeScriptValue &wparam) {
- QueueScriptFunction(kScInstGame, "on_event", 2, RuntimeScriptValue().SetInt32(evtype), wparam);
+ RuntimeScriptValue params[]{ evtype , wparam };
+ QueueScriptFunction(kScInstGame, "on_event", 2, params);
}
void run_room_event(int id) {
@@ -134,7 +135,8 @@ void process_event(const EventHappened *evp) {
if (evp->type == EV_TEXTSCRIPT) {
_G(ccError) = 0;
if (evp->data2 > -1000) {
- QueueScriptFunction(kScInstGame, _G(tsnames)[evp->data1], 1, RuntimeScriptValue().SetInt32(evp->data2));
+ RuntimeScriptValue params[]{ evp->data2 };
+ QueueScriptFunction(kScInstGame, _G(tsnames)[evp->data1], 1, params);
} else {
QueueScriptFunction(kScInstGame, _G(tsnames)[evp->data1]);
}
diff --git a/engines/ags/engine/ac/global_room.cpp b/engines/ags/engine/ac/global_room.cpp
index fd1a7b15366..121962c9733 100644
--- a/engines/ags/engine/ac/global_room.cpp
+++ b/engines/ags/engine/ac/global_room.cpp
@@ -177,8 +177,8 @@ void CallRoomScript(int value) {
quit("!CallRoomScript: not inside a script???");
_GP(play).roomscript_finished = 0;
- RuntimeScriptValue rval_null;
- _G(curscript)->run_another("on_call", kScInstRoom, 1, RuntimeScriptValue().SetInt32(value), rval_null);
+ RuntimeScriptValue params[]{ value , RuntimeScriptValue() };
+ _G(curscript)->run_another("on_call", kScInstRoom, 1, params);
}
int HasBeenToRoom(int roomnum) {
diff --git a/engines/ags/engine/ac/gui.cpp b/engines/ags/engine/ac/gui.cpp
index d3908450c68..0506dc9f356 100644
--- a/engines/ags/engine/ac/gui.cpp
+++ b/engines/ags/engine/ac/gui.cpp
@@ -311,9 +311,9 @@ void remove_popup_interface(int ifacenum) {
void process_interface_click(int ifce, int btn, int mbut) {
if (btn < 0) {
// click on GUI background
- QueueScriptFunction(kScInstGame, _GP(guis)[ifce].OnClickHandler.GetCStr(), 2,
- RuntimeScriptValue().SetDynamicObject(&_G(scrGui)[ifce], &_GP(ccDynamicGUI)),
- RuntimeScriptValue().SetInt32(mbut));
+ RuntimeScriptValue params[]{ RuntimeScriptValue().SetDynamicObject(&_G(scrGui)[ifce], &_GP(ccDynamicGUI)),
+ RuntimeScriptValue().SetInt32(mbut) };
+ QueueScriptFunction(kScInstGame, _GP(guis)[ifce].OnClickHandler.GetCStr(), 2, params);
return;
}
@@ -335,24 +335,24 @@ void process_interface_click(int ifce, int btn, int mbut) {
// if the object has a special handler script then run it;
// otherwise, run interface_click
if ((theObj->GetEventCount() > 0) &&
- (!theObj->EventHandlers[0].IsEmpty()) &&
- (!_G(gameinst)->GetSymbolAddress(theObj->EventHandlers[0].GetCStr()).IsNull())) {
+ (!theObj->EventHandlers[0].IsEmpty()) &&
+ (!_G(gameinst)->GetSymbolAddress(theObj->EventHandlers[0].GetCStr()).IsNull())) {
// control-specific event handler
- if (strchr(theObj->GetEventArgs(0).GetCStr(), ',') != nullptr)
- QueueScriptFunction(kScInstGame, theObj->EventHandlers[0].GetCStr(), 2,
- RuntimeScriptValue().SetDynamicObject(theObj, &_GP(ccDynamicGUIObject)),
- RuntimeScriptValue().SetInt32(mbut));
- else
- QueueScriptFunction(kScInstGame, theObj->EventHandlers[0].GetCStr(), 1,
- RuntimeScriptValue().SetDynamicObject(theObj, &_GP(ccDynamicGUIObject)));
- } else
- QueueScriptFunction(kScInstGame, "interface_click", 2,
- RuntimeScriptValue().SetInt32(ifce),
- RuntimeScriptValue().SetInt32(btn));
+ if (theObj->GetEventArgs(0).FindChar(',') != -1) {
+ RuntimeScriptValue params[]{ RuntimeScriptValue().SetDynamicObject(theObj, &_GP(ccDynamicGUIObject)),
+ RuntimeScriptValue().SetInt32(mbut) };
+ QueueScriptFunction(kScInstGame, theObj->EventHandlers[0].GetCStr(), 2, params);
+ } else {
+ RuntimeScriptValue params[]{ RuntimeScriptValue().SetDynamicObject(theObj, &_GP(ccDynamicGUIObject)) };
+ QueueScriptFunction(kScInstGame, theObj->EventHandlers[0].GetCStr(), 1, params);
+ }
+ } else {
+ RuntimeScriptValue params[]{ ifce , btn };
+ QueueScriptFunction(kScInstGame, "interface_click", 2, params);
+ }
}
}
-
void replace_macro_tokens(const char *text, String &fixed_text) {
const char *curptr = &text[0];
char tmpm[3];
diff --git a/engines/ags/engine/script/executing_script.cpp b/engines/ags/engine/script/executing_script.cpp
index 2a1b3a597bb..0222546c91f 100644
--- a/engines/ags/engine/script/executing_script.cpp
+++ b/engines/ags/engine/script/executing_script.cpp
@@ -60,7 +60,7 @@ int ExecutingScript::queue_action(PostScriptAction act, int data, const char *an
return numPostScriptActions - 1;
}
-void ExecutingScript::run_another(const char *namm, ScriptInstType scinst, size_t param_count, const RuntimeScriptValue &p1, const RuntimeScriptValue &p2) {
+void ExecutingScript::run_another(const char *namm, ScriptInstType scinst, size_t param_count, const RuntimeScriptValue *params) {
if (numanother < MAX_QUEUED_SCRIPTS)
numanother++;
else {
@@ -73,8 +73,8 @@ void ExecutingScript::run_another(const char *namm, ScriptInstType scinst, size_
script.FnName.SetString(namm, MAX_FUNCTION_NAME_LEN);
script.Instance = scinst;
script.ParamCount = param_count;
- script.Param1 = p1;
- script.Param2 = p2;
+ for (size_t p = 0; p < MAX_QUEUED_PARAMS && p < param_count; ++p)
+ script.Params[p] = params[p];
}
void ExecutingScript::init() {
diff --git a/engines/ags/engine/script/executing_script.h b/engines/ags/engine/script/executing_script.h
index 36363b6a747..938d0213108 100644
--- a/engines/ags/engine/script/executing_script.h
+++ b/engines/ags/engine/script/executing_script.h
@@ -41,6 +41,7 @@ enum PostScriptAction {
#define MAX_QUEUED_SCRIPTS 4
#define MAX_QUEUED_ACTIONS 5
#define MAX_FUNCTION_NAME_LEN 60
+#define MAX_QUEUED_PARAMS 4
enum ScriptInstType {
kScInstGame,
@@ -51,8 +52,7 @@ struct QueuedScript {
Shared::String FnName;
ScriptInstType Instance;
size_t ParamCount;
- RuntimeScriptValue Param1;
- RuntimeScriptValue Param2;
+ RuntimeScriptValue Params[MAX_QUEUED_PARAMS];
QueuedScript();
};
@@ -70,7 +70,7 @@ struct ExecutingScript {
int8 forked;
int queue_action(PostScriptAction act, int data, const char *aname);
- void run_another(const char *namm, ScriptInstType scinst, size_t param_count, const RuntimeScriptValue &p1, const RuntimeScriptValue &p2);
+ void run_another(const char *namm, ScriptInstType scinst, size_t param_count, const RuntimeScriptValue *params);
void init();
ExecutingScript();
};
diff --git a/engines/ags/engine/script/script.cpp b/engines/ags/engine/script/script.cpp
index e458ab3a1fa..5f1190fb8f7 100644
--- a/engines/ags/engine/script/script.cpp
+++ b/engines/ags/engine/script/script.cpp
@@ -271,22 +271,22 @@ ccInstance *GetScriptInstanceByType(ScriptInstType sc_inst) {
return nullptr;
}
-void QueueScriptFunction(ScriptInstType sc_inst, const char *fn_name, size_t param_count, const RuntimeScriptValue &p1, const RuntimeScriptValue &p2) {
+void QueueScriptFunction(ScriptInstType sc_inst, const char *fn_name, size_t param_count, const RuntimeScriptValue *params) {
if (_G(inside_script))
// queue the script for the run after current script is finished
- _G(curscript)->run_another(fn_name, sc_inst, param_count, p1, p2);
+ _G(curscript)->run_another(fn_name, sc_inst, param_count, params);
else
// if no script is currently running, run the requested script right away
- RunScriptFunction(sc_inst, fn_name, param_count, p1, p2);
+ RunScriptFunction(sc_inst, fn_name, param_count, params);
}
-void RunScriptFunction(ScriptInstType sc_inst, const char *fn_name, size_t param_count, const RuntimeScriptValue &p1, const RuntimeScriptValue &p2) {
+void RunScriptFunction(ScriptInstType sc_inst, const char *fn_name, size_t param_count, const RuntimeScriptValue *params) {
ccInstance *sci = GetScriptInstanceByType(sc_inst);
if (sci) {
if (param_count == 2)
- RunTextScript2IParam(sci, fn_name, p1, p2);
+ RunTextScript2IParam(sci, fn_name, params[0], params[1]);
else if (param_count == 1)
- RunTextScriptIParam(sci, fn_name, p1);
+ RunTextScriptIParam(sci, fn_name, params[0]);
else if (param_count == 0)
RunTextScript(sci, fn_name);
}
@@ -361,7 +361,7 @@ int PrepareTextScript(ccInstance *sci, const char **tsname) {
return 0;
}
-int RunScriptFunctionIfExists(ccInstance *sci, const char *tsname, int numParam, const RuntimeScriptValue *params) {
+int RunScriptFunctionIfExists(ccInstance *sci, const char *tsname, size_t numParam, const RuntimeScriptValue *params) {
int oldRestoreCount = _G(gameHasBeenRestored);
// First, save the current ccError state
// This is necessary because we might be attempting
@@ -573,7 +573,7 @@ void post_script_cleanup() {
for (jj = 0; jj < copyof.numanother; jj++) {
old_room_number = _G(displayed_room);
QueuedScript &script = copyof.ScFnQueue[jj];
- RunScriptFunction(script.Instance, script.FnName.GetCStr(), script.ParamCount, script.Param1, script.Param2);
+ RunScriptFunction(script.Instance, script.FnName.GetCStr(), script.ParamCount, script.Params);
if (script.Instance == kScInstRoom && script.ParamCount == 1) {
// some bogus hack for "on_call" event handler
_GP(play).roomscript_finished = 1;
@@ -899,8 +899,8 @@ void run_unhandled_event(int evnt) {
else if ((evtype == 3) & (evnt == 4)); // any click on character
else if (evtype > 0) {
can_run_delayed_command();
-
- QueueScriptFunction(kScInstGame, "unhandled_event", 2, RuntimeScriptValue().SetInt32(evtype), RuntimeScriptValue().SetInt32(evnt));
+ RuntimeScriptValue params[] = { evtype, evnt };
+ QueueScriptFunction(kScInstGame, "unhandled_event", 2, params);
}
}
diff --git a/engines/ags/engine/script/script.h b/engines/ags/engine/script/script.h
index 3dcd52bf355..a81aead095d 100644
--- a/engines/ags/engine/script/script.h
+++ b/engines/ags/engine/script/script.h
@@ -53,12 +53,12 @@ void cancel_all_scripts();
ccInstance *GetScriptInstanceByType(ScriptInstType sc_inst);
// Queues a script function to be run either called by the engine or from another script
void QueueScriptFunction(ScriptInstType sc_inst, const char *fn_name, size_t param_count = 0,
- const RuntimeScriptValue &p1 = RuntimeScriptValue(), const RuntimeScriptValue &p2 = RuntimeScriptValue());
+ const RuntimeScriptValue *params = nullptr);
// Try to run a script function right away
void RunScriptFunction(ScriptInstType sc_inst, const char *fn_name, size_t param_count = 0,
- const RuntimeScriptValue &p1 = RuntimeScriptValue(), const RuntimeScriptValue &p2 = RuntimeScriptValue());
+ const RuntimeScriptValue *params = nullptr);
-int RunScriptFunctionIfExists(ccInstance *sci, const char *tsname, int numParam, const RuntimeScriptValue *params);
+int RunScriptFunctionIfExists(ccInstance *sci, const char *tsname, size_t param_count, const RuntimeScriptValue *params);
int RunTextScript(ccInstance *sci, const char *tsname);
int RunTextScriptIParam(ccInstance *sci, const char *tsname, const RuntimeScriptValue &iparam);
int RunTextScript2IParam(ccInstance *sci, const char *tsname, const RuntimeScriptValue &iparam, const RuntimeScriptValue ¶m2);
diff --git a/engines/ags/plugins/ags_plugin.cpp b/engines/ags/plugins/ags_plugin.cpp
index 9b497229820..4991f168e9a 100644
--- a/engines/ags/plugins/ags_plugin.cpp
+++ b/engines/ags/plugins/ags_plugin.cpp
@@ -612,11 +612,12 @@ int IAGSEngine::CallGameScriptFunction(const char *name, int32 globalScript, int
ccInstance *toRun = GetScriptInstanceByType(globalScript ? kScInstGame : kScInstRoom);
- RuntimeScriptValue params[3];
- params[0].SetPluginArgument(arg1);
- params[1].SetPluginArgument(arg2);
- params[2].SetPluginArgument(arg3);
- int toret = RunScriptFunctionIfExists(toRun, name, numArgs, params);
+ RuntimeScriptValue params[]{
+ RuntimeScriptValue().SetPluginArgument(arg1),
+ RuntimeScriptValue().SetPluginArgument(arg2),
+ RuntimeScriptValue().SetPluginArgument(arg3),
+ };
+ int toret = RunScriptFunctionIfExists(toRun, (char *)name, numArgs, params);
return toret;
}
@@ -641,8 +642,9 @@ void IAGSEngine::QueueGameScriptFunction(const char *name, int32 globalScript, i
if (numArgs < 0 || numArgs > 2)
quit("IAGSEngine::QueueGameScriptFunction: invalid number of arguments");
- _G(curscript)->run_another(name, globalScript ? kScInstGame : kScInstRoom, numArgs,
- RuntimeScriptValue().SetPluginArgument(arg1), RuntimeScriptValue().SetPluginArgument(arg2));
+ RuntimeScriptValue params[]{ RuntimeScriptValue().SetPluginArgument(arg1),
+ RuntimeScriptValue().SetPluginArgument(arg2) };
+ _G(curscript)->run_another(name, globalScript ? kScInstGame : kScInstRoom, numArgs, params);
}
int IAGSEngine::RegisterManagedObject(const void *object, IAGSScriptManagedObject *callback) {
Commit: b2d8bcad753468e53e74823292a73c5b60d44031
https://github.com/scummvm/scummvm/commit/b2d8bcad753468e53e74823292a73c5b60d44031
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2022-04-18T19:10:39-07:00
Commit Message:
AGS: Refactor RunTextScript* functions for the purpose of clarity
>From upstream 17af6ca2cb1fba310900f5189da788fa52ef7dab
Changed paths:
engines/ags/engine/ac/dialog.cpp
engines/ags/engine/ac/event.cpp
engines/ags/engine/ac/event.h
engines/ags/engine/main/game_run.cpp
engines/ags/engine/main/game_start.cpp
engines/ags/engine/script/script.cpp
engines/ags/engine/script/script.h
engines/ags/globals.h
engines/ags/plugins/ags_plugin.cpp
diff --git a/engines/ags/engine/ac/dialog.cpp b/engines/ags/engine/ac/dialog.cpp
index 2d5725974d2..9720c213bdb 100644
--- a/engines/ags/engine/ac/dialog.cpp
+++ b/engines/ags/engine/ac/dialog.cpp
@@ -173,7 +173,8 @@ int run_dialog_script(DialogTopic *dtpp, int dialogID, int offse, int optionInde
if (_G(dialogScriptsInst)) {
char funcName[100];
sprintf(funcName, "_run_dialog%d", dialogID);
- RunTextScriptIParam(_G(dialogScriptsInst), funcName, RuntimeScriptValue().SetInt32(optionIndex));
+ RuntimeScriptValue params[]{ optionIndex };
+ RunScriptFunction(_G(dialogScriptsInst), funcName, 1, params);
result = _G(dialogScriptsInst)->returnValue;
} else {
// old dialog format
diff --git a/engines/ags/engine/ac/event.cpp b/engines/ags/engine/ac/event.cpp
index ddcc7ab3ee4..75a8e7e15aa 100644
--- a/engines/ags/engine/ac/event.cpp
+++ b/engines/ags/engine/ac/event.cpp
@@ -58,7 +58,7 @@ int run_claimable_event(const char *tsname, bool includeRoom, int numParams, con
int toret;
if (includeRoom && _G(roominst)) {
- toret = RunScriptFunctionIfExists(_G(roominst), tsname, numParams, params);
+ toret = RunScriptFunction(_G(roominst), tsname, numParams, params);
if (_G(abort_engine))
return -1;
@@ -70,7 +70,7 @@ int run_claimable_event(const char *tsname, bool includeRoom, int numParams, con
// run script modules
for (int kk = 0; kk < _G(numScriptModules); kk++) {
- toret = RunScriptFunctionIfExists(_GP(moduleInst)[kk], tsname, numParams, params);
+ toret = RunScriptFunction(_GP(moduleInst)[kk], tsname, numParams, params);
if (_G(eventClaimed) == EVENT_CLAIMED) {
_G(eventClaimed) = eventClaimedOldValue;
diff --git a/engines/ags/engine/ac/event.h b/engines/ags/engine/ac/event.h
index 2596054cc35..7df4f619c06 100644
--- a/engines/ags/engine/ac/event.h
+++ b/engines/ags/engine/ac/event.h
@@ -46,6 +46,7 @@ namespace AGS3 {
#define TS_REPEAT 1
#define TS_KEYPRESS 2
#define TS_MCLICK 3
+#define TS_NUM 4
#define EVB_HOTSPOT 1
#define EVB_ROOM 2
diff --git a/engines/ags/engine/main/game_run.cpp b/engines/ags/engine/main/game_run.cpp
index 7190f51ff06..0e2dd3fe3a0 100644
--- a/engines/ags/engine/main/game_run.cpp
+++ b/engines/ags/engine/main/game_run.cpp
@@ -222,8 +222,8 @@ static void check_mouse_controls() {
}
_G(wasongui) = mongu;
_G(wasbutdown) = mbut + 1;
- } else setevent(EV_TEXTSCRIPT, TS_MCLICK, mbut + 1);
- // else RunTextScriptIParam(_G(gameinst),"on_mouse_click",aa+1);
+ } else
+ setevent(EV_TEXTSCRIPT, TS_MCLICK, mbut + 1);
}
if (mwheelz < 0)
diff --git a/engines/ags/engine/main/game_start.cpp b/engines/ags/engine/main/game_start.cpp
index 00c2f3014fa..a8f6aa28a7b 100644
--- a/engines/ags/engine/main/game_start.cpp
+++ b/engines/ags/engine/main/game_start.cpp
@@ -83,10 +83,7 @@ void start_game() {
// skip ticks to account for initialisation or a restored _GP(game).
skipMissedTicks();
- for (int kk = 0; kk < _G(numScriptModules); kk++)
- RunTextScript(_GP(moduleInst)[kk], "game_start");
-
- RunTextScript(_G(gameinst), "game_start");
+ RunScriptFunctionInModules("game_start");
_G(our_eip) = -43;
diff --git a/engines/ags/engine/script/script.cpp b/engines/ags/engine/script/script.cpp
index 5f1190fb8f7..3cebf13b503 100644
--- a/engines/ags/engine/script/script.cpp
+++ b/engines/ags/engine/script/script.cpp
@@ -19,7 +19,6 @@
*
*/
-//include <string.h>
#include "ags/engine/script/script.h"
#include "ags/shared/ac/common.h"
#include "ags/engine/ac/character.h"
@@ -55,9 +54,13 @@
namespace AGS3 {
+static bool DoRunScriptFuncCantBlock(ccInstance *sci, NonBlockingScriptFunction *funcToRun, bool hasTheFunc);
+static char scfunctionname[MAX_FUNCTION_NAME_LEN + 1];
+
int run_dialog_request(int parmtr) {
_GP(play).stop_dialog_at_end = DIALOG_RUNNING;
- RunTextScriptIParam(_G(gameinst), "dialog_request", RuntimeScriptValue().SetInt32(parmtr));
+ RuntimeScriptValue params[]{ parmtr };
+ RunScriptFunction(_G(gameinst), "dialog_request", 1, params);
if (_GP(play).stop_dialog_at_end == DIALOG_STOP) {
_GP(play).stop_dialog_at_end = DIALOG_NONE;
@@ -277,22 +280,10 @@ void QueueScriptFunction(ScriptInstType sc_inst, const char *fn_name, size_t par
_G(curscript)->run_another(fn_name, sc_inst, param_count, params);
else
// if no script is currently running, run the requested script right away
- RunScriptFunction(sc_inst, fn_name, param_count, params);
-}
-
-void RunScriptFunction(ScriptInstType sc_inst, const char *fn_name, size_t param_count, const RuntimeScriptValue *params) {
- ccInstance *sci = GetScriptInstanceByType(sc_inst);
- if (sci) {
- if (param_count == 2)
- RunTextScript2IParam(sci, fn_name, params[0], params[1]);
- else if (param_count == 1)
- RunTextScriptIParam(sci, fn_name, params[0]);
- else if (param_count == 0)
- RunTextScript(sci, fn_name);
- }
+ RunScriptFunctionAuto(sc_inst, fn_name, param_count, params);
}
-bool DoRunScriptFuncCantBlock(ccInstance *sci, NonBlockingScriptFunction *funcToRun, bool hasTheFunc) {
+static bool DoRunScriptFuncCantBlock(ccInstance *sci, NonBlockingScriptFunction *funcToRun, bool hasTheFunc) {
if (!hasTheFunc)
return (false);
@@ -324,8 +315,7 @@ bool DoRunScriptFuncCantBlock(ccInstance *sci, NonBlockingScriptFunction *funcTo
return (hasTheFunc);
}
-char scfunctionname[MAX_FUNCTION_NAME_LEN + 1];
-int PrepareTextScript(ccInstance *sci, const char **tsname) {
+static int PrepareTextScript(ccInstance *sci, const char **tsname) {
_G(ccError) = 0;
// FIXME: try to make it so this function is not called with NULL sci
if (sci == nullptr) return -1;
@@ -361,7 +351,7 @@ int PrepareTextScript(ccInstance *sci, const char **tsname) {
return 0;
}
-int RunScriptFunctionIfExists(ccInstance *sci, const char *tsname, size_t numParam, const RuntimeScriptValue *params) {
+int RunScriptFunction(ccInstance *sci, const char *tsname, size_t numParam, const RuntimeScriptValue *params) {
int oldRestoreCount = _G(gameHasBeenRestored);
// First, save the current ccError state
// This is necessary because we might be attempting
@@ -381,10 +371,7 @@ int RunScriptFunctionIfExists(ccInstance *sci, const char *tsname, size_t numPar
// Clear the error message
_G(ccErrorString) = "";
- if (numParam < 3) {
- toret = _G(curscript)->inst->CallScriptFunction(tsname, numParam, params);
- } else
- quit("Too many parameters to RunScriptFunctionIfExists");
+ toret = _G(curscript)->inst->CallScriptFunction(tsname, numParam, params);
if (_G(abort_engine))
return -1;
@@ -413,64 +400,70 @@ int RunScriptFunctionIfExists(ccInstance *sci, const char *tsname, size_t numPar
return toret;
}
-int RunTextScript(ccInstance *sci, const char *tsname) {
- if (strcmp(tsname, REP_EXEC_NAME) == 0) {
- // run module rep_execs
- // FIXME: in theory the function may be already called for _GP(moduleInst)[i],
- // in which case this should not be executed; need to rearrange the code somehow
- int room_changes_was = _GP(play).room_changes;
- int restore_game_count_was = _G(gameHasBeenRestored);
-
- for (int kk = 0; kk < _G(numScriptModules); kk++) {
- if (!_GP(moduleRepExecAddr)[kk].IsNull())
- RunScriptFunctionIfExists(_GP(moduleInst)[kk], tsname, 0, nullptr);
-
- if ((room_changes_was != _GP(play).room_changes) ||
- (restore_game_count_was != _G(gameHasBeenRestored)))
- return 0;
- }
- }
+void RunScriptFunctionInModules(const char *tsname, size_t param_count, const RuntimeScriptValue *params) {
+ for (int i = 0; i < _G(numScriptModules); ++i)
+ RunScriptFunction(_GP(moduleInst)[i], tsname, param_count, params);
+ RunScriptFunction(_G(gameinst), tsname, param_count, params);
+}
- int toret = RunScriptFunctionIfExists(sci, tsname, 0, nullptr);
- if ((toret == -18) && (sci == _G(roominst))) {
- // functions in room script must exist
- quitprintf("prepare_script: error %d (%s) trying to run '%s' (Room %d)", toret, _G(ccErrorString).GetCStr(), tsname, _G(displayed_room));
- }
+int RunScriptFunctionInRoom(const char *tsname, size_t param_count, const RuntimeScriptValue *params) {
+ // Some room callbacks are considered to be obligatory; for historical reasons these are
+ // identified by having no parameters;
+ // TODO: this is a hack, this should be defined either by function type, or as an arg
+ const bool strict_room_event = (param_count == 0);
+ int toret = RunScriptFunction(_G(roominst), tsname, param_count, params);
+ // If it's a obligatory room event, and return code means missing function - error
+ if (strict_room_event && (toret == -18))
+ quitprintf("RunScriptFunction: error %d (%s) trying to run '%s' (Room %d)",
+ toret, _G(ccErrorString).GetCStr(), tsname, _G(displayed_room));
return toret;
}
-int RunTextScriptIParam(ccInstance *sci, const char *tsname, const RuntimeScriptValue &iparam) {
- if ((strcmp(tsname, "on_key_press") == 0) || (strcmp(tsname, "on_mouse_click") == 0)) {
- bool eventWasClaimed;
- int toret = run_claimable_event(tsname, true, 1, &iparam, &eventWasClaimed);
-
- if (eventWasClaimed)
- return toret;
+// Run non-claimable event in all script modules, except room, break if certain events occured
+static int RunUnclaimableEvent(const char *tsname) {
+ const int room_changes_was = _GP(play).room_changes;
+ const int restore_game_count_was = _G(gameHasBeenRestored);
+ for (int i = 0; i < _G(numScriptModules); ++i) {
+ if (!_GP(moduleRepExecAddr)[i].IsNull())
+ RunScriptFunction(_GP(moduleInst)[i], tsname);
+ // Break on room change or save restoration
+ if ((room_changes_was != _GP(play).room_changes) ||
+ (restore_game_count_was != _G(gameHasBeenRestored)))
+ return 0;
}
-
- return RunScriptFunctionIfExists(sci, tsname, 1, &iparam);
+ return RunScriptFunction(_G(gameinst), tsname);
}
-int RunTextScript2IParam(ccInstance *sci, const char *tsname, const RuntimeScriptValue &iparam, const RuntimeScriptValue ¶m2) {
- RuntimeScriptValue params[2];
- params[0] = iparam;
- params[1] = param2;
-
- if (strcmp(tsname, "on_event") == 0) {
- bool eventWasClaimed;
- int toret = run_claimable_event(tsname, true, 2, params, &eventWasClaimed);
+static int RunClaimableEvent(const char *tsname, size_t param_count, const RuntimeScriptValue *params) {
+ // Run claimable event chain in script modules and room script
+ bool eventWasClaimed;
+ int toret = run_claimable_event(tsname, true, param_count, params, &eventWasClaimed);
+ // Break on event claim
+ if (eventWasClaimed)
+ return toret;
+ return RunScriptFunction(_G(gameinst), tsname, param_count, params);
+}
- if (eventWasClaimed || _G(abort_engine))
- return toret;
+int RunScriptFunctionAuto(ScriptInstType sc_inst, const char *tsname, size_t param_count, const RuntimeScriptValue *params) {
+ // If told to use a room instance, then run only there
+ if (sc_inst == kScInstRoom)
+ return RunScriptFunctionInRoom(tsname, param_count, params);
+ // Rep-exec is only run in script modules, but not room script
+ // (because room script has its own callback, attached to event slot)
+ if (strcmp(tsname, REP_EXEC_NAME) == 0) {
+ return RunUnclaimableEvent(REP_EXEC_NAME);
}
-
- // response to a button click, better update guis
- if (ags_strnicmp(tsname, "interface_click", 15) == 0) {
- // interface_click(int interface, int button)
- _GP(guis)[iparam.IValue].MarkChanged();
+ // Claimable event is run in all the script modules and room script,
+ // before running in the globalscript instance
+ if ((strcmp(tsname, _G(tsnames)[TS_KEYPRESS]) == 0) || (strcmp(tsname, _G(tsnames)[TS_MCLICK]) == 0) ||
+ (strcmp(tsname, "on_event") == 0)) {
+ return RunClaimableEvent(tsname, param_count, params);
}
-
- return RunScriptFunctionIfExists(sci, tsname, 2, params);
+ // Else run on the single chosen script instance
+ ccInstance *sci = GetScriptInstanceByType(sc_inst);
+ if (!sci)
+ return 0;
+ return RunScriptFunction(sci, tsname, param_count, params);
}
String GetScriptName(ccInstance *sci) {
@@ -573,7 +566,7 @@ void post_script_cleanup() {
for (jj = 0; jj < copyof.numanother; jj++) {
old_room_number = _G(displayed_room);
QueuedScript &script = copyof.ScFnQueue[jj];
- RunScriptFunction(script.Instance, script.FnName.GetCStr(), script.ParamCount, script.Params);
+ RunScriptFunctionAuto(script.Instance, script.FnName.GetCStr(), script.ParamCount, script.Params);
if (script.Instance == kScInstRoom && script.ParamCount == 1) {
// some bogus hack for "on_call" event handler
_GP(play).roomscript_finished = 1;
diff --git a/engines/ags/engine/script/script.h b/engines/ags/engine/script/script.h
index a81aead095d..e0b0f3af4eb 100644
--- a/engines/ags/engine/script/script.h
+++ b/engines/ags/engine/script/script.h
@@ -54,17 +54,20 @@ ccInstance *GetScriptInstanceByType(ScriptInstType sc_inst);
// Queues a script function to be run either called by the engine or from another script
void QueueScriptFunction(ScriptInstType sc_inst, const char *fn_name, size_t param_count = 0,
const RuntimeScriptValue *params = nullptr);
-// Try to run a script function right away
-void RunScriptFunction(ScriptInstType sc_inst, const char *fn_name, size_t param_count = 0,
+// Try to run a script function on a given script instance
+int RunScriptFunction(ccInstance *sci, const char *tsname, size_t param_count = 0,
+ const RuntimeScriptValue *params = nullptr);
+// Run a script function in all the regular script modules, in order, where available
+// includes globalscript, but not the current room script.
+void RunScriptFunctionInModules(const char *tsname, size_t param_count = 0,
+ const RuntimeScriptValue *params = nullptr);
+// Run an obligatory script function in the current room script
+int RunScriptFunctionInRoom(const char *tsname, size_t param_count = 0,
+ const RuntimeScriptValue *params = nullptr);
+// Try to run a script function, guessing the behavior by its name and script instance type;
+// depending on the type may run a claimable callback chain
+int RunScriptFunctionAuto(ScriptInstType sc_inst, const char *fn_name, size_t param_count = 0,
const RuntimeScriptValue *params = nullptr);
-
-int RunScriptFunctionIfExists(ccInstance *sci, const char *tsname, size_t param_count, const RuntimeScriptValue *params);
-int RunTextScript(ccInstance *sci, const char *tsname);
-int RunTextScriptIParam(ccInstance *sci, const char *tsname, const RuntimeScriptValue &iparam);
-int RunTextScript2IParam(ccInstance *sci, const char *tsname, const RuntimeScriptValue &iparam, const RuntimeScriptValue ¶m2);
-
-int PrepareTextScript(ccInstance *sci, const char **tsname);
-bool DoRunScriptFuncCantBlock(ccInstance *sci, NonBlockingScriptFunction *funcToRun, bool hasTheFunc);
AGS::Shared::String GetScriptName(ccInstance *sci);
diff --git a/engines/ags/globals.h b/engines/ags/globals.h
index f5ad1ec7fbe..3a41fc21223 100644
--- a/engines/ags/globals.h
+++ b/engines/ags/globals.h
@@ -32,6 +32,7 @@
#include "ags/shared/util/version.h"
#include "ags/shared/gui/gui_main.h"
#include "ags/shared/script/cc_script.h"
+#include "ags/engine/ac/event.h"
#include "ags/engine/ac/runtime_defines.h"
#include "ags/engine/ac/walk_behind.h"
#include "ags/engine/main/engine.h"
@@ -675,7 +676,7 @@ public:
int _inside_processevent = 0;
int _eventClaimed = 0;
- const char *_tsnames[4] = { nullptr, REP_EXEC_NAME, "on_key_press", "on_mouse_click" };
+ const char *_tsnames[TS_NUM] = { nullptr, REP_EXEC_NAME, "on_key_press", "on_mouse_click" };
/**@}*/
diff --git a/engines/ags/plugins/ags_plugin.cpp b/engines/ags/plugins/ags_plugin.cpp
index 4991f168e9a..8276c8d87ce 100644
--- a/engines/ags/plugins/ags_plugin.cpp
+++ b/engines/ags/plugins/ags_plugin.cpp
@@ -617,7 +617,7 @@ int IAGSEngine::CallGameScriptFunction(const char *name, int32 globalScript, int
RuntimeScriptValue().SetPluginArgument(arg2),
RuntimeScriptValue().SetPluginArgument(arg3),
};
- int toret = RunScriptFunctionIfExists(toRun, (char *)name, numArgs, params);
+ int toret = RunScriptFunction(toRun, (char *)name, numArgs, params);
return toret;
}
Commit: c0010986ac6bb709285ada648aec8d55ff39d098
https://github.com/scummvm/scummvm/commit/c0010986ac6bb709285ada648aec8d55ff39d098
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2022-04-18T19:10:39-07:00
Commit Message:
AGS: Implemented `on_text_input(int chr)` callback
>From upstream ba866abab0ba5a48b8577c4a01f0533a2d7e68de
Changed paths:
engines/ags/engine/ac/event.h
engines/ags/engine/main/game_run.cpp
engines/ags/engine/script/script.cpp
engines/ags/globals.h
engines/ags/shared/ac/keycode.h
diff --git a/engines/ags/engine/ac/event.h b/engines/ags/engine/ac/event.h
index 7df4f619c06..a795c7a88de 100644
--- a/engines/ags/engine/ac/event.h
+++ b/engines/ags/engine/ac/event.h
@@ -43,12 +43,13 @@ namespace AGS3 {
#define EV_FADEIN 3
#define EV_IFACECLICK 4
#define EV_NEWROOM 5
-#define TS_REPEAT 1
-#define TS_KEYPRESS 2
-#define TS_MCLICK 3
-#define TS_NUM 4
-#define EVB_HOTSPOT 1
-#define EVB_ROOM 2
+#define TS_REPEAT 1
+#define TS_KEYPRESS 2
+#define TS_MCLICK 3
+#define TS_TEXTINPUT 4
+#define TS_NUM 5
+#define EVB_HOTSPOT 1
+#define EVB_ROOM 2
struct EventHappened {
int type = 0;
diff --git a/engines/ags/engine/main/game_run.cpp b/engines/ags/engine/main/game_run.cpp
index 0e2dd3fe3a0..0981fb9e672 100644
--- a/engines/ags/engine/main/game_run.cpp
+++ b/engines/ags/engine/main/game_run.cpp
@@ -501,6 +501,10 @@ static void check_keyboard_controls() {
int sckey = AGSKeyToScriptKey(kgn);
debug_script_log("Running on_key_press keycode %d", sckey);
setevent(EV_TEXTSCRIPT, TS_KEYPRESS, sckey);
+ 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/script.cpp b/engines/ags/engine/script/script.cpp
index 3cebf13b503..e995563ac9f 100644
--- a/engines/ags/engine/script/script.cpp
+++ b/engines/ags/engine/script/script.cpp
@@ -456,7 +456,7 @@ int RunScriptFunctionAuto(ScriptInstType sc_inst, const char *tsname, size_t par
// Claimable event is run in all the script modules and room script,
// before running in the globalscript instance
if ((strcmp(tsname, _G(tsnames)[TS_KEYPRESS]) == 0) || (strcmp(tsname, _G(tsnames)[TS_MCLICK]) == 0) ||
- (strcmp(tsname, "on_event") == 0)) {
+ (strcmp(tsname, _G(tsnames)[TS_TEXTINPUT]) == 0) || (strcmp(tsname, "on_event") == 0)) {
return RunClaimableEvent(tsname, param_count, params);
}
// Else run on the single chosen script instance
diff --git a/engines/ags/globals.h b/engines/ags/globals.h
index 3a41fc21223..c8327d7049a 100644
--- a/engines/ags/globals.h
+++ b/engines/ags/globals.h
@@ -676,7 +676,7 @@ public:
int _inside_processevent = 0;
int _eventClaimed = 0;
- const char *_tsnames[TS_NUM] = { nullptr, REP_EXEC_NAME, "on_key_press", "on_mouse_click" };
+ const char *_tsnames[TS_NUM] = { nullptr, REP_EXEC_NAME, "on_key_press", "on_mouse_click", "on_text_input" };
/**@}*/
diff --git a/engines/ags/shared/ac/keycode.h b/engines/ags/shared/ac/keycode.h
index cdfd97fa80d..d14e6b6fabb 100644
--- a/engines/ags/shared/ac/keycode.h
+++ b/engines/ags/shared/ac/keycode.h
@@ -255,8 +255,9 @@ enum eAGSKeyCode {
struct KeyInput {
const static size_t UTF8_ARR_SIZE = 5;
- eAGSKeyCode Key = eAGSKeyCodeNone;
- char Text[UTF8_ARR_SIZE] = { 0 };
+ eAGSKeyCode Key = eAGSKeyCodeNone; // actual key code
+ int UChar = 0; // full character value (supports unicode)
+ char Text[UTF8_ARR_SIZE]{}; // character in a string format
KeyInput() = default;
};
Commit: 09da0fbf5db836d94a95ecaae844eb19449ec58e
https://github.com/scummvm/scummvm/commit/09da0fbf5db836d94a95ecaae844eb19449ec58e
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2022-04-18T19:10:39-07:00
Commit Message:
AGS: Implemented `dialog_options_text_input(int chr)` callback
>From upstream 76db49c6189810faa467b00c1aef9e78c526876d
Changed paths:
engines/ags/engine/ac/dialog.cpp
engines/ags/engine/ac/game.cpp
engines/ags/engine/game/game_init.cpp
engines/ags/globals.cpp
engines/ags/globals.h
diff --git a/engines/ags/engine/ac/dialog.cpp b/engines/ags/engine/ac/dialog.cpp
index 9720c213bdb..bf0f18ebd52 100644
--- a/engines/ags/engine/ac/dialog.cpp
+++ b/engines/ags/engine/ac/dialog.cpp
@@ -851,6 +851,9 @@ bool DialogOptions::Run() {
_GP(runDialogOptionKeyPressHandlerFunc).params[0].SetDynamicObject(&_GP(ccDialogOptionsRendering), &_GP(ccDialogOptionsRendering));
_GP(runDialogOptionKeyPressHandlerFunc).params[1].SetInt32(AGSKeyToScriptKey(gkey));
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));
}
// Allow selection of options by keyboard shortcuts
else if (_GP(game).options[OPT_DIALOGNUMBERED] >= kDlgOptKeysOnly &&
diff --git a/engines/ags/engine/ac/game.cpp b/engines/ags/engine/ac/game.cpp
index 124331b6e0d..f94b2a25e32 100644
--- a/engines/ags/engine/ac/game.cpp
+++ b/engines/ags/engine/ac/game.cpp
@@ -409,6 +409,7 @@ void unload_game_file() {
_GP(getDialogOptionUnderCursorFunc).moduleHasFunction.resize(0);
_GP(runDialogOptionMouseClickHandlerFunc).moduleHasFunction.resize(0);
_GP(runDialogOptionKeyPressHandlerFunc).moduleHasFunction.resize(0);
+ _GP(runDialogOptionTextInputHandlerFunc).moduleHasFunction.resize(0);
_GP(runDialogOptionRepExecFunc).moduleHasFunction.resize(0);
_G(numScriptModules) = 0;
diff --git a/engines/ags/engine/game/game_init.cpp b/engines/ags/engine/game/game_init.cpp
index d899185258e..7670891971f 100644
--- a/engines/ags/engine/game/game_init.cpp
+++ b/engines/ags/engine/game/game_init.cpp
@@ -327,6 +327,7 @@ void AllocScriptModules() {
_GP(getDialogOptionUnderCursorFunc).moduleHasFunction.resize(_G(numScriptModules), true);
_GP(runDialogOptionMouseClickHandlerFunc).moduleHasFunction.resize(_G(numScriptModules), true);
_GP(runDialogOptionKeyPressHandlerFunc).moduleHasFunction.resize(_G(numScriptModules), true);
+ _GP(runDialogOptionTextInputHandlerFunc).moduleHasFunction.resize(_G(numScriptModules), true);
_GP(runDialogOptionRepExecFunc).moduleHasFunction.resize(_G(numScriptModules), true);
for (int i = 0; i < _G(numScriptModules); ++i) {
_GP(moduleRepExecAddr)[i].Invalidate();
diff --git a/engines/ags/globals.cpp b/engines/ags/globals.cpp
index 73dab86f469..9a7902cffff 100644
--- a/engines/ags/globals.cpp
+++ b/engines/ags/globals.cpp
@@ -334,6 +334,7 @@ Globals::Globals() {
_getDialogOptionUnderCursorFunc = new NonBlockingScriptFunction("dialog_options_get_active", 1);
_runDialogOptionMouseClickHandlerFunc = new NonBlockingScriptFunction("dialog_options_mouse_click", 2);
_runDialogOptionKeyPressHandlerFunc = new NonBlockingScriptFunction("dialog_options_key_press", 2);
+ _runDialogOptionTextInputHandlerFunc = new NonBlockingScriptFunction("dialog_options_text_input", 2);
_runDialogOptionRepExecFunc = new NonBlockingScriptFunction("dialog_options_repexec", 1);
_scsystem = new ScriptSystem();
_scriptModules = new std::vector<PScript>();
@@ -570,6 +571,7 @@ Globals::~Globals() {
delete _getDialogOptionUnderCursorFunc;
delete _runDialogOptionMouseClickHandlerFunc;
delete _runDialogOptionKeyPressHandlerFunc;
+ delete _runDialogOptionTextInputHandlerFunc;
delete _runDialogOptionRepExecFunc;
delete _scsystem;
delete _scriptModules;
diff --git a/engines/ags/globals.h b/engines/ags/globals.h
index c8327d7049a..65ef6b648aa 100644
--- a/engines/ags/globals.h
+++ b/engines/ags/globals.h
@@ -1256,6 +1256,7 @@ public:
NonBlockingScriptFunction *_getDialogOptionUnderCursorFunc;
NonBlockingScriptFunction *_runDialogOptionMouseClickHandlerFunc;
NonBlockingScriptFunction *_runDialogOptionKeyPressHandlerFunc;
+ NonBlockingScriptFunction *_runDialogOptionTextInputHandlerFunc;
NonBlockingScriptFunction *_runDialogOptionRepExecFunc;
ScriptSystem *_scsystem;
Commit: dec92f05ea9156961d17d9a7f62f11d73b8dba07
https://github.com/scummvm/scummvm/commit/dec92f05ea9156961d17d9a7f62f11d73b8dba07
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2022-04-18T19:10:40-07:00
Commit Message:
AGS: Support passing partial argument list to a script callback
>From upstream e38df03c5d1658a2c44a26ba4ee6f22663c1e701
Changed paths:
engines/ags/engine/script/cc_instance.cpp
diff --git a/engines/ags/engine/script/cc_instance.cpp b/engines/ags/engine/script/cc_instance.cpp
index 29aab984b13..19eca09f2a7 100644
--- a/engines/ags/engine/script/cc_instance.cpp
+++ b/engines/ags/engine/script/cc_instance.cpp
@@ -284,22 +284,25 @@ int ccInstance::CallScriptFunction(const char *funcname, int32_t numargs, const
int32_t startat = -1;
int k;
char mangledName[200];
- sprintf(mangledName, "%s$", funcname);
+ size_t mangled_len = snprintf(mangledName, sizeof(mangledName), "%s$", funcname);
+ int export_args = 0;
for (k = 0; k < instanceof->numexports; k++) {
char *thisExportName = instanceof->exports[k];
int match = 0;
// check for a mangled name match
- if (strncmp(thisExportName, mangledName, strlen(mangledName)) == 0) {
+ if (strncmp(thisExportName, mangledName, mangled_len) == 0) {
// found, compare the number of parameters
- char *numParams = thisExportName + strlen(mangledName);
- if (atoi(numParams) != numargs) {
- cc_error("wrong number of parameters to exported function '%s' (expected %d, supplied %d)", funcname, atoi(numParams), numargs);
+ export_args = atoi(thisExportName + mangled_len);
+ if (export_args > numargs) {
+ cc_error("wrong number of parameters to exported function '%s' (expected %d, supplied %d)",
+ funcname, export_args, numargs);
return -1;
}
match = 1;
}
+
// check for an exact match (if the script was compiled with
// an older version)
if ((match == 1) || (strcmp(thisExportName, funcname) == 0)) {
@@ -318,6 +321,9 @@ int ccInstance::CallScriptFunction(const char *funcname, int32_t numargs, const
return -2;
}
+ // Allow to pass less parameters if script callback has less declared args
+ numargs = std::min(numargs, export_args);
+
//numargs++; // account for return address
flags &= ~INSTF_ABORTED;
Commit: 99cc27e840b59a84e1804dda2619ecd67891cdfb
https://github.com/scummvm/scummvm/commit/99cc27e840b59a84e1804dda2619ecd67891cdfb
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2022-04-18T19:10:40-07:00
Commit Message:
AGS: Fixed few comments in ccInstance::Run()
>From upstream 109346cf4cc747c9a3bef72c234a18a5f63d30fe
Changed paths:
engines/ags/engine/script/cc_instance.cpp
diff --git a/engines/ags/engine/script/cc_instance.cpp b/engines/ags/engine/script/cc_instance.cpp
index 19eca09f2a7..23766968dd7 100644
--- a/engines/ags/engine/script/cc_instance.cpp
+++ b/engines/ags/engine/script/cc_instance.cpp
@@ -694,7 +694,7 @@ int ccInstance::Run(int32_t curpc) {
reg1 = !(reg1);
break;
case SCMD_CALL:
- // CallScriptFunction another function within same script, just save PC
+ // Call another function within same script, just save PC
// and continue from there
if (curnest >= MAXNEST - 1) {
cc_error("!call stack overflow, recursive call problem?");
@@ -920,7 +920,7 @@ int ccInstance::Run(int32_t curpc) {
case SCMD_CALLAS: {
PUSH_CALL_STACK;
- // CallScriptFunction to a function in another script
+ // Call to a function in another script
// If there are nested CALLAS calls, the stack might
// contain 2 calls worth of parameters, so only
@@ -977,7 +977,7 @@ int ccInstance::Run(int32_t curpc) {
break;
}
case SCMD_CALLEXT: {
- // CallScriptFunction to a real 'C' code function
+ // Call to a real 'C' code function
was_just_callas = -1;
if (num_args_to_func < 0) {
num_args_to_func = func_callstack.Count;
More information about the Scummvm-git-logs
mailing list