From 64115186036eac93d145a20bce13b3db3231d06c Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Tue, 21 Dec 2021 17:45:48 +0900 Subject: [PATCH] [ruamoko] Make some progress on the input bindings --- libs/ruamoko/rua_input.c | 269 +++++++++++++++++++++++++++++++++- ruamoko/include/Makemodule.am | 5 +- ruamoko/include/input.h | 39 +++++ ruamoko/lib/Makemodule.am | 6 +- ruamoko/lib/input.r | 37 +++++ 5 files changed, 346 insertions(+), 10 deletions(-) create mode 100644 ruamoko/include/input.h create mode 100644 ruamoko/lib/input.r diff --git a/libs/ruamoko/rua_input.c b/libs/ruamoko/rua_input.c index 8d89948bf..e53f6b0db 100644 --- a/libs/ruamoko/rua_input.c +++ b/libs/ruamoko/rua_input.c @@ -36,13 +36,25 @@ # include #endif +#include "QF/cmem.h" +#include "QF/hash.h" #include "QF/input.h" #include "QF/progs.h" #include "rua_internal.h" -//typedef struct input_resources_s { -//} input_resources_t; +typedef struct rua_in_cookie_s { + size_t users; + progs_t *pr; + func_t func; + pointer_t data; +} rua_in_cookie_t; + +typedef struct input_resources_s { + hashlink_t *hash_links; + hashtab_t *cookies; + memsuper_t *cookie_super; +} input_resources_t; static void bi_IN_FindDeviceId (progs_t *pr) @@ -150,6 +162,199 @@ bi_IN_CreateAxis (progs_t *pr) RETURN_POINTER (pr, axis); } +static void +bi_IN_GetAxisInfo (progs_t *pr) +{ + int devid = P_INT (pr, 0); + int axis = P_INT (pr, 1); + + R_INT (pr) = 0; + + in_axisinfo_t info; + if (IN_GetAxisInfo (devid, axis, &info)) { + P_STRUCT (pr, in_axisinfo_t, 2) = info; + R_INT (pr) = 1; + } +} + +static void +bi_IN_GetButtonInfo (progs_t *pr) +{ + int devid = P_INT (pr, 0); + int button = P_INT (pr, 1); + + R_INT (pr) = 0; + + in_buttoninfo_t info; + if (IN_GetButtonInfo (devid, button, &info)) { + P_STRUCT (pr, in_buttoninfo_t, 2) = info; + R_INT (pr) = 1; + } +} + +static void +rua_add_axis_listener (progs_t *pr, axis_listener_t listener) +{ + input_resources_t *res = PR_Resources_Find (pr, "input"); + in_axis_t *axis = &P_STRUCT (pr, in_axis_t, 0); + rua_in_cookie_t search = { + .func = P_FUNCTION (pr, 1), + .data = P_POINTER (pr, 2), + }; + rua_in_cookie_t *cookie = Hash_FindElement (res->cookies, &search); + if (cookie) { + cookie = cmemalloc (res->cookie_super, sizeof (rua_in_cookie_t)); + *cookie = search; + } + cookie->users++; + IN_AxisAddListener (axis, listener, cookie); +} + +static void +rua_remove_axis_listener (progs_t *pr, axis_listener_t listener) +{ + input_resources_t *res = PR_Resources_Find (pr, "input"); + in_axis_t *axis = &P_STRUCT (pr, in_axis_t, 0); + rua_in_cookie_t search = { + .func = P_FUNCTION (pr, 1), + .data = P_POINTER (pr, 2), + }; + rua_in_cookie_t *cookie = Hash_FindElement (res->cookies, &search); + if (cookie) { + IN_AxisRemoveListener (axis, listener, cookie); + } +} + +static void +rua_add_button_listener (progs_t *pr, button_listener_t listener) +{ + input_resources_t *res = PR_Resources_Find (pr, "input"); + in_button_t *button = &P_STRUCT (pr, in_button_t, 0); + rua_in_cookie_t search = { + .func = P_FUNCTION (pr, 1), + .data = P_POINTER (pr, 2), + }; + rua_in_cookie_t *cookie = Hash_FindElement (res->cookies, &search); + if (cookie) { + cookie = cmemalloc (res->cookie_super, sizeof (rua_in_cookie_t)); + *cookie = search; + } + cookie->users++; + IN_ButtonAddListener (button, listener, cookie); +} + +static void +rua_remove_button_listener (progs_t *pr, button_listener_t listener) +{ + input_resources_t *res = PR_Resources_Find (pr, "input"); + in_button_t *button = &P_STRUCT (pr, in_button_t, 0); + rua_in_cookie_t search = { + .func = P_FUNCTION (pr, 1), + .data = P_POINTER (pr, 2), + }; + rua_in_cookie_t *cookie = Hash_FindElement (res->cookies, &search); + if (cookie) { + IN_ButtonRemoveListener (button, listener, cookie); + } +} + +static void +rua_listener_func (rua_in_cookie_t *cookie, const void *input) +{ + progs_t *pr = cookie->pr; + PR_PushFrame (pr); + P_POINTER (pr, 0) = cookie->data; + P_POINTER (pr, 1) = PR_SetPointer (pr, input);//FIXME check input + pr->pr_argc = 2; + PR_ExecuteProgram (pr, cookie->func); + PR_PopFrame (pr); +} + +static void +rua_listener_method (rua_in_cookie_t *cookie, const void *input) +{ + progs_t *pr = cookie->pr; + PR_PushFrame (pr); + P_POINTER (pr, 0) = cookie->data; + P_POINTER (pr, 1) = 0; // don't know the method name (selector) + P_POINTER (pr, 2) = PR_SetPointer (pr, input);//FIXME check input + pr->pr_argc = 3; + PR_ExecuteProgram (pr, cookie->func); + PR_PopFrame (pr); +} + +static void +rua_axis_listener_func (void *data, const in_axis_t *axis) +{ + rua_listener_func (data, axis); +} + +static void +rua_axis_listener_method (void *data, const in_axis_t *axis) +{ + rua_listener_method (data, axis); +} + +static void +rua_button_listener_func (void *data, const in_button_t *button) +{ + rua_listener_func (data, button); +} + +static void +rua_button_listener_method (void *data, const in_button_t *button) +{ + rua_listener_method (data, button); +} + +static void +rua_IN_ButtonAddListener_func (progs_t *pr) +{ + rua_add_button_listener (pr, rua_button_listener_func); +} + +static void +rua_IN_ButtonRemoveListener_func (progs_t *pr) +{ + rua_remove_button_listener (pr, rua_button_listener_func); +} + +static void +rua_IN_AxisAddListener_func (progs_t *pr) +{ + rua_add_axis_listener (pr, rua_axis_listener_func); +} + +static void +rua_IN_AxisRemoveListener_func (progs_t *pr) +{ + rua_remove_axis_listener (pr, rua_axis_listener_func); +} + +static void +rua_IN_ButtonAddListener_method (progs_t *pr) +{ + rua_add_button_listener (pr, rua_button_listener_method); +} + +static void +rua_IN_ButtonRemoveListener_method (progs_t *pr) +{ + rua_remove_button_listener (pr, rua_button_listener_method); +} + +static void +rua_IN_AxisAddListener_method (progs_t *pr) +{ + rua_add_axis_listener (pr, rua_axis_listener_method); +} + +static void +rua_IN_AxisRemoveListener_method (progs_t *pr) +{ + rua_remove_axis_listener (pr, rua_axis_listener_method); +} + static void secured (progs_t *pr) { @@ -182,19 +387,67 @@ static builtin_t builtins[] = { bi(IN_GetButtonNumber), bi(IN_ProcessEvents), bi(IN_ClearStates), + bi(IN_GetAxisInfo), + bi(IN_GetButtonInfo), + {"IN_ButtonAddListener|^{tag in_button_s=}^(v^v^{tag in_button_s=})^v", + rua_IN_ButtonAddListener_func, -1}, + {"IN_ButtonRemoveListener|^{tag in_button_s=}^(v^v^{tag in_button_s=})^v", + rua_IN_ButtonRemoveListener_func, -1}, + {"IN_AxisAddListener|^{tag in_axis_s=}^(v^v^{tag in_axis_s=})^v", + rua_IN_AxisAddListener_func, -1}, + {"IN_AxisRemoveListener|^{tag in_axis_s=}^(v^v^{tag in_axis_s=})^v", + rua_IN_AxisRemoveListener_func, -1}, + {"IN_ButtonAddListener|^{tag in_button_s=}(@@:.)@", + rua_IN_ButtonAddListener_method, -1}, + {"IN_ButtonRemoveListener|^{tag in_button_s=}(@@:.)@", + rua_IN_ButtonRemoveListener_method, -1}, + {"IN_AxisAddListener|^{tag in_axis_s=}(@@:.)@", + rua_IN_AxisAddListener_method, -1}, + {"IN_AxisRemoveListener|^{tag in_axis_s=}(@@:.)@", + rua_IN_AxisRemoveListener_method, -1}, {0} }; -//static void -//bi_input_clear (progs_t *pr, void *_res) -//{ -//} +static void +bi_input_clear (progs_t *pr, void *_res) +{ + input_resources_t *res = _res; + Hash_FlushTable (res->cookies); +} + +static uintptr_t +rua_in_hash_cookie (const void *_cookie, void *_res) +{ + const rua_in_cookie_t *cookie = _cookie; + return cookie->func + cookie->data; +} + +static int +rua_in_cmp_cookies (const void *_a, const void *_b, void *_res) +{ + const rua_in_cookie_t *a = _a; + const rua_in_cookie_t *b = _b; + return a->func == b->func && a->data == b->data; +} + +static void +rua_in_free_cookie (void *_cookie, void *_res) +{ + input_resources_t *res = _res; + rua_in_cookie_t *cookie = _cookie; + cmemfree (res->cookie_super, cookie); +} void RUA_Input_Init (progs_t *pr, int secure) { - //input_resources_t *res = calloc (sizeof (input_resources_t), 1); - //PR_Resources_Register (pr, "input", res, bi_input_clear); + input_resources_t *res = calloc (sizeof (input_resources_t), 1); + PR_Resources_Register (pr, "input", res, bi_input_clear); + + res->cookie_super = new_memsuper (); + res->cookies = Hash_NewTable (251, 0, rua_in_free_cookie, res, + &res->hash_links); + Hash_SetHashCompare (res->cookies, rua_in_hash_cookie, rua_in_cmp_cookies); if (secure & 2) { PR_RegisterBuiltins (pr, secure_builtins); diff --git a/ruamoko/include/Makemodule.am b/ruamoko/include/Makemodule.am index 8324491d3..2920ed408 100644 --- a/ruamoko/include/Makemodule.am +++ b/ruamoko/include/Makemodule.am @@ -3,6 +3,7 @@ ruamoko_include = \ ruamoko/include/debug.h \ ruamoko/include/entities.h \ ruamoko/include/infokey.h \ + ruamoko/include/input.h \ ruamoko/include/math.h \ ruamoko/include/message.h \ ruamoko/include/nq_message.h \ @@ -23,7 +24,6 @@ ruamoko_include = \ ruamoko/include/types.h \ ruamoko/include/legacy_string.h \ ruamoko/include/draw.h \ - ruamoko/include/key.h \ ruamoko/include/cbuf.h \ ruamoko/include/cmd.h \ ruamoko/include/cvar.h \ @@ -55,3 +55,6 @@ ruamoko_gui_includedir = $(datarootdir)/qfcc/include/gui ruamoko_include_HEADERS = $(ruamoko_include) ruamoko_gui_include_HEADERS = $(ruamoko_gui_include) + +EXTRA_DIST += \ + ruamoko/include/key.h diff --git a/ruamoko/include/input.h b/ruamoko/include/input.h new file mode 100644 index 000000000..ebbb970d6 --- /dev/null +++ b/ruamoko/include/input.h @@ -0,0 +1,39 @@ +#ifndef __ruamoko_input_h +#define __ruamoko_input_h + +#include + +in_button_t *IN_CreateButton (string name, string description); +in_axis_t *IN_CreateAxis (string name, string description); +int IN_FindDeviceId (string _id); +string IN_GetDeviceName (int devid); +string IN_GetDeviceId (int devid); +//IN_AxisInfo (); +//IN_ButtonInfo (); +string IN_GetAxisName (int devid, int axis); +string IN_GetButtonName (int devid, int axis); +int IN_GetAxisNumber (int devid, string axis); +int IN_GetButtonNumber (int devid, string axis); +void IN_ProcessEvents (void); +void IN_ClearStates (void); +int IN_GetAxisInfo (int devid, int axis, in_axisinfo_t *info); +int IN_GetButtonInfo (int devid, int button, in_buttoninfo_t *info); +typedef void (*button_listener_t) (void *data, in_button_t *button);//FIXME const +@overload void IN_ButtonAddListener (in_button_t *button, + button_listener_t listener, void *data); +@overload void IN_ButtonRemoveListener (in_button_t *button, + button_listener_t listener, + void *data); +typedef void (*axis_listener_t) (void *data, in_axis_t *axis);//FIXME const +@overload void IN_AxisAddListener (in_axis_t *axis, axis_listener_t listener, + void *data); +@overload void IN_AxisRemoveListener (in_axis_t *axis, + axis_listener_t listener, void *data); +@overload void IN_ButtonAddListener (in_button_t *button, IMP listener, + id obj); +@overload void IN_ButtonRemoveListener (in_button_t *button, IMP listener, + id obj); +@overload void IN_AxisAddListener (in_axis_t *axis, IMP listener, id obj); +@overload void IN_AxisRemoveListener (in_axis_t *axis, IMP listener, id obj); + +#endif//__ruamoko_input_h diff --git a/ruamoko/lib/Makemodule.am b/ruamoko/lib/Makemodule.am index 5711a0b24..e5218d298 100644 --- a/ruamoko/lib/Makemodule.am +++ b/ruamoko/lib/Makemodule.am @@ -45,7 +45,11 @@ ruamoko_lib_libqw_a_src= \ ruamoko/lib/qw_message.r ruamoko/lib/qw_physics.r ruamoko/lib/qw_sys.r ruamoko_lib_libnq_a_src= \ ruamoko/lib/nq_message.r -ruamoko_lib_libcsqc_a_src= ruamoko/lib/draw.r ruamoko/lib/gib.r ruamoko/lib/key.r +ruamoko_lib_libcsqc_a_src= \ + ruamoko/lib/draw.r \ + ruamoko/lib/gib.r \ + ruamoko/lib/input.r \ + ruamoko/lib/key.r ruamoko_lib_common_dep=$(call qcautodep,$(ruamoko_lib_common_src)) include $(ruamoko_lib_common_dep) # am--include-marker diff --git a/ruamoko/lib/input.r b/ruamoko/lib/input.r new file mode 100644 index 000000000..74ee30e89 --- /dev/null +++ b/ruamoko/lib/input.r @@ -0,0 +1,37 @@ +#include "input.h" + +in_button_t *IN_CreateButton (string name, string description) = #0; +in_axis_t *IN_CreateAxis (string name, string description) = #0; +int IN_FindDeviceId (string _id) = #0; +string IN_GetDeviceName (int devid) = #0; +string IN_GetDeviceId (int devid) = #0; +//IN_AxisInfo () = #0; +//IN_ButtonInfo () = #0; +string IN_GetAxisName (int devid, int axis) = #0; +string IN_GetButtonName (int devid, int axis) = #0; +int IN_GetAxisNumber (int devid, string axis) = #0; +int IN_GetButtonNumber (int devid, string axis) = #0; +void IN_ProcessEvents (void) = #0; +void IN_ClearStates (void) = #0; +int IN_GetAxisInfo (int devid, int axis, in_axisinfo_t *info) = #0; +int IN_GetButtonInfo (int devid, int button, in_buttoninfo_t *info) = #0; +@overload +void IN_ButtonAddListener (in_button_t *button, button_listener_t listener, + void *data) = #0; +@overload +void IN_ButtonRemoveListener (in_button_t *button, button_listener_t listener, + void *data) = #0; +@overload +void IN_AxisAddListener (in_axis_t *axis, axis_listener_t listener, + void *data) = #0; +@overload +void IN_AxisRemoveListener (in_axis_t *axis, axis_listener_t listener, + void *data) = #0; +@overload +void IN_ButtonAddListener (in_button_t *button, IMP listener, id obj) = #0; +@overload +void IN_ButtonRemoveListener (in_button_t *button, IMP listener, id obj) = #0; +@overload +void IN_AxisAddListener (in_axis_t *axis, IMP listener, id obj) = #0; +@overload +void IN_AxisRemoveListener (in_axis_t *axis, IMP listener, id obj) = #0;