aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkdx <kikoodx@paranoici.org>2024-04-12 00:19:25 +0200
committerkdx <kikoodx@paranoici.org>2024-04-12 00:19:25 +0200
commitca7deb67edcdd946173e63bfb89e04b33eb2eb64 (patch)
treee7f70a001ac19036060d9987afe7d8660df22b2b
parenta1d6b52259ccc2eb96883a7af39fdda60bcf8462 (diff)
downloadinput-ca7deb67edcdd946173e63bfb89e04b33eb2eb64.tar.gz
prevent duplicate binding
-rw-r--r--input.c50
1 files changed, 47 insertions, 3 deletions
diff --git a/input.c b/input.c
index a1914ff..4f22530 100644
--- a/input.c
+++ b/input.c
@@ -26,6 +26,35 @@ _input_get_action(const char *tag)
return NULL;
}
+static bool
+_input_is_new(const char *tag, InputBind bind)
+{
+ InputAction *action = _input_get_action(tag);
+ if (action == NULL)
+ panic("_input_get_action failed");
+ foreach (e, action->binds.next) {
+ if (e->type != bind.type)
+ continue;
+ switch (bind.type) {
+ case IBT_SCANCODE:
+ if (e->sc == bind.sc)
+ return false;
+ break;
+ case IBT_MOUSEBUTTON:
+ if (e->mb == bind.mb)
+ return false;
+ break;
+ case IBT_CONBUTTON:
+ if (e->cb == bind.cb)
+ return false;
+ break;
+ default:
+ break;
+ }
+ }
+ return true;
+}
+
static InputBind *
_input_new_bind(const char *tag, InputBindType ibt)
{
@@ -41,8 +70,11 @@ _input_new_bind(const char *tag, InputBindType ibt)
memset(bind, 0, sizeof(*bind));
bind->type = ibt;
- bind->next = action->binds.next;
- action->binds.next = bind;
+
+ InputBind *tail = &action->binds;
+ while (tail->next)
+ tail = tail->next;
+ tail->next = bind;
return bind;
}
@@ -106,7 +138,7 @@ input_clear_action(const char *tag)
{
InputAction *action = _input_get_action(tag);
if (action == NULL)
- panic("_input_new_bind failed");
+ panic("_input_get_action failed");
InputBind *prev = &action->binds;
InputBind *bind = action->binds.next;
while (bind) {
@@ -124,6 +156,9 @@ input_clear_action(const char *tag)
void
input_bind_action_sc(const char *tag, SDL_Scancode sc)
{
+ const InputBind test = { .type = IBT_SCANCODE, .sc = sc };
+ if (!_input_is_new(tag, test))
+ return;
InputBind *bind = _input_new_bind(tag, IBT_SCANCODE);
if (bind == NULL)
panic("_input_new_bind failed");
@@ -133,6 +168,9 @@ input_bind_action_sc(const char *tag, SDL_Scancode sc)
void
input_bind_action_sc_locked(const char *tag, SDL_Scancode sc)
{
+ const InputBind test = { .type = IBT_SCANCODE, .sc = sc };
+ if (!_input_is_new(tag, test))
+ panic("locked input slot in use");
InputBind *bind = _input_new_bind(tag, IBT_SCANCODE);
if (bind == NULL)
panic("_input_new_bind failed");
@@ -143,6 +181,9 @@ input_bind_action_sc_locked(const char *tag, SDL_Scancode sc)
void
input_bind_action_cb(const char *tag, uint8_t cb)
{
+ const InputBind test = { .type = IBT_CONBUTTON, .cb = cb };
+ if (!_input_is_new(tag, test))
+ return;
InputBind *bind = _input_new_bind(tag, IBT_CONBUTTON);
if (bind == NULL)
panic("_input_new_bind failed");
@@ -152,6 +193,9 @@ input_bind_action_cb(const char *tag, uint8_t cb)
void
input_bind_action_mb(const char *tag, uint8_t mb)
{
+ const InputBind test = { .type = IBT_MOUSEBUTTON, .mb = mb };
+ if (!_input_is_new(tag, test))
+ return;
InputBind *bind = _input_new_bind(tag, IBT_MOUSEBUTTON);
if (bind == NULL)
panic("_input_new_bind failed");