input: reworked input to make the platform do less work.
authorLukas Krickl <lukas@krickl.dev>
Mon, 2 Mar 2026 04:00:47 +0000 (05:00 +0100)
committerLukas Krickl <lukas@krickl.dev>
Mon, 2 Mar 2026 04:00:47 +0000 (05:00 +0100)
Inputs are now polled based on action entries and the platform simply
has to accept a call of the core code for each action.
Actions now contain a generic scan code and device id to allow the
backend to decide which device to poll.
The device id is opaque. The platform may decide what it means.

src/i_input.c
src/i_input.h
src/p_platform.h
src/p_r_sdl/p_window.c

index d50cc487bcdff99284c70068ad72cc5af2650dfc..a8c16cec520af434088bb4e18b209938ded1b28b 100644 (file)
@@ -1,58 +1,38 @@
 #include "i_input.h"
 
-/* TODO: change api so that this calls the platform backend
- * with specific actions that are expected */
-
 struct i_input_map i_input_map;
 
 void i_input_init(void) {
+       p_input_init();
        p_input_set_default_map();
 
 
        /* TODO read key map from config file */
 }
 
-struct i_input_map_ent* i_input_find_ent(u16 scan_code, lrts_bool mod_shift, 
-               lrts_bool mod_alt, lrts_bool mod_ctrl, lrts_bool mod_super) {
-       u32 i = 0;
-       struct i_input_map_ent *ent = LRTS_NULL;
-       for (i = 0; i < I_INPUT_ACTION_LEN; i++) {
-               ent = &i_input_map.inputs[i];
-
-               if (ent->scan_code == scan_code 
-                               && ent->mod_shift == mod_shift
-                               && ent->mod_alt == mod_alt
-                               && ent->mod_ctrl == mod_ctrl
-                               && ent->mod_super == mod_super) {
-                       return ent;
-               }
-       }
-
-       return LRTS_NULL;
-}
-
-void i_input_set(u16 scan_code, lrts_bool mod_shift, lrts_bool mod_alt, lrts_bool mod_ctrl, lrts_bool mod_super) {
-       struct i_input_map_ent *ent = i_input_find_ent(scan_code, mod_shift, mod_alt, mod_ctrl, mod_super);
-       if (ent == LRTS_NULL) {
-               return;
-       }
-       ent->held = 1;
+void i_input_map_init_default(enum i_input_actions action, 
+               u16 scan_code, 
+               u16 device_id,
+               lrts_bool mod_shift,
+               lrts_bool mod_alt,
+               lrts_bool mod_ctrl,
+               lrts_bool mod_super) {
+       struct i_input_map_ent *e = &i_input_map.inputs[action];
+       e->scan_code = scan_code;
+       e->device_id = device_id;
+       e->mod_shift = mod_shift;
+       e->mod_alt = mod_alt;
+       e->mod_ctrl = mod_ctrl;
+               e->mod_super = mod_super;
 }
 
-void i_input_unset(u16 scan_code, lrts_bool mod_shift, lrts_bool mod_alt, lrts_bool mod_ctrl, lrts_bool mod_super) {
-       struct i_input_map_ent *ent = i_input_find_ent(scan_code, mod_shift, mod_alt, mod_ctrl, mod_super);
-       if (ent == LRTS_NULL) {
-               return;
-       }
-       ent->held = 0;
-}
 
 void i_input_update(void) {
        u32 i = 0;
        /* move all pressed events over one position */ 
        for (i = 0; i < I_INPUT_ACTION_LEN; i++) {
                i_input_map.inputs[i].pressed <<= 1;
-               i_input_map.inputs[i].pressed |= i_input_map.inputs[i].held;
+               i_input_map.inputs[i].pressed |= p_input_poll_action(&i_input_map.inputs[i]);
        }
 }
 
@@ -61,31 +41,6 @@ void i_input_cursor_set(i32 x, i32 y) {
        i_input_map.cursor_y = y;
 }
 
-void i_input_cursor_click_set(void) {
-       i_input_map.inputs[I_INPUT_ACTION_CURSOR_CLICK].held = 1;
-}
-
-void i_input_cursor_drag_set(void) {
-       i_input_map.inputs[I_INPUT_ACTION_CURSOR_DRAG].held = 1;
-}
-
-void i_input_cursor_action_set(void) {
-       i_input_map.inputs[I_INPUT_ACTION_CURSOR_ACTION].held = 1;
-}
-
-void i_input_cursor_click_unset(void) {
-       i_input_map.inputs[I_INPUT_ACTION_CURSOR_CLICK].held = 0;
-}
-
-void i_input_cursor_drag_unset(void) {
-       i_input_map.inputs[I_INPUT_ACTION_CURSOR_DRAG].held = 0;
-}
-
-void i_input_cursor_action_unset(void) {
-       i_input_map.inputs[I_INPUT_ACTION_CURSOR_ACTION].held = 0;
-}
-
-
 lrts_bool i_input_just_pressed(enum i_input_actions action) {
        LRTS_UNUSED(action);
        return LRTS_FALSE;
index 3669ddd05dd009f268dea6c9b5e3d4d6ed827f69..90d68b9481761b02c45938403a1646a41238de17 100644 (file)
@@ -30,6 +30,10 @@ enum i_input_actions {
 
 /* input entry */
 struct i_input_map_ent {
+       /* can be used by the platform module to poll
+        * a specfici device */
+       u16 device_id;
+
        /* this is a platform specific button
         * code to this input action
         */
@@ -46,7 +50,6 @@ struct i_input_map_ent {
         * the most recent state is in the rightmost bit
         */
        u16 pressed;
-       u16 held;
 };
 
 /* map of all input actions to scanscodes */
@@ -70,11 +73,9 @@ void i_input_init(void);
  * to pass events as inputs to the engine
  * should be called by p_poll_events
  */
-void i_input_set(u16 scan_code, lrts_bool mod_shift, lrts_bool mod_alt, lrts_bool mod_ctrl, lrts_bool mod_super);
+void i_input_set(u16 scan_code, lrts_bool mod_shift, lrts_bool mod_alt, 
+               lrts_bool mod_ctrl, lrts_bool mod_super, lrts_bool key_state);
 
-/* unsets held state
- */
-void i_input_unset(u16 scan_code, lrts_bool mod_shift, lrts_bool mod_alt, lrts_bool mod_ctrl, lrts_bool mod_super);
 
 /* updates input history by shifting pressed bitfield over by 1 and oring it with the held state */
 void i_input_update(void);
@@ -84,14 +85,6 @@ void i_input_update(void);
  */
 void i_input_cursor_set(i32 x, i32 y);
 
-void i_input_cursor_click_set(void);
-void i_input_cursor_drag_set(void);
-void i_input_cursor_action_set(void);
-
-void i_input_cursor_click_unset(void);
-void i_input_cursor_drag_unset(void);
-void i_input_cursor_action_unset(void);
-
 /* returns true if this action was just performed this frame */
 lrts_bool i_input_just_pressed(enum i_input_actions action);
 
@@ -107,4 +100,15 @@ lrts_bool i_input_double_press(enum i_input_actions action);
  */
 void i_input_poll(void);
 
+
+/* inits the default for a keybind */
+void i_input_map_init_default(enum i_input_actions action, 
+               u16 scan_code, 
+               u16 device_id,
+               lrts_bool mod_shift,
+               lrts_bool mod_alt,
+               lrts_bool mod_ctrl,
+               lrts_bool mod_super);
+
+
 #endif
index 2817e0f846b010aded82fe2d48bde88112aba92d..4495d9d15a3109a685c100e6a7b2448ac1446f57 100644 (file)
@@ -1,6 +1,8 @@
 #ifndef P_PLATFORM_H__
 #define P_PLATFORM_H__
 
+#include "i_input.h"
+
 /**
  * This module contains init code for platforms
  */
@@ -75,4 +77,12 @@ int p_poll_events();
  */ 
 void p_input_set_default_map();
 
+/**
+ * Inits input platform
+ */
+void p_input_init(void);
+
+/* polls a single key action. returns current buttin state */
+lrts_bool p_input_poll_action(struct i_input_map_ent *ent);
+
 #endif
index ecc1d2bcf072f780e6c254eede93d898275f261c..27e0ab912f3ab5b06b056d7204d49a23ae87ba62 100644 (file)
@@ -5,11 +5,101 @@ SDL_Window *p_main_window;
 
 SDL_Surface *r_target;
 
-void p_input_set_default_map() {
-       i_input_map.inputs[I_INPUT_ACTION_CAMERA_UP].scan_code = SDL_SCANCODE_UP;
-       i_input_map.inputs[I_INPUT_ACTION_CAMERA_DOWN].scan_code = SDL_SCANCODE_DOWN;
-       i_input_map.inputs[I_INPUT_ACTION_CAMERA_LEFT].scan_code = SDL_SCANCODE_LEFT;
-       i_input_map.inputs[I_INPUT_ACTION_CAMERA_RIGHT].scan_code = SDL_SCANCODE_RIGHT;
+const bool *key_map;
+SDL_MouseButtonFlags mouse_state;
+
+enum p_input_devices {
+       P_INPUT_DEV_MOUSE,
+       P_INPUT_DEV_KEYBOARD
+};
+
+void p_input_init(void) {
+       key_map = SDL_GetKeyboardState(LRTS_NULL);
+}
+
+void p_input_set_default_map(void) {
+       i_input_map_init_default(I_INPUT_ACTION_CAMERA_UP, 
+                       SDL_SCANCODE_UP, 
+                       P_INPUT_DEV_KEYBOARD,
+                       LRTS_FALSE,
+                       LRTS_FALSE,
+                       LRTS_FALSE,
+                       LRTS_FALSE);
+       i_input_map_init_default(I_INPUT_ACTION_CAMERA_DOWN, 
+                       SDL_SCANCODE_DOWN, 
+                       P_INPUT_DEV_KEYBOARD,
+                       LRTS_FALSE,
+                       LRTS_FALSE,
+                       LRTS_FALSE,
+                       LRTS_FALSE);
+       i_input_map_init_default(I_INPUT_ACTION_CAMERA_LEFT, 
+                       SDL_SCANCODE_LEFT, 
+                       P_INPUT_DEV_KEYBOARD,
+                       LRTS_FALSE,
+                       LRTS_FALSE,
+                       LRTS_FALSE,
+                       LRTS_FALSE);
+       i_input_map_init_default(I_INPUT_ACTION_CAMERA_RIGHT, 
+                       SDL_SCANCODE_RIGHT, 
+                       P_INPUT_DEV_KEYBOARD,
+                       LRTS_FALSE,
+                       LRTS_FALSE,
+                       LRTS_FALSE,
+                       LRTS_FALSE);
+
+       i_input_map_init_default(I_INPUT_ACTION_CURSOR_CLICK, 
+                       SDL_BUTTON_LMASK, 
+                       P_INPUT_DEV_MOUSE,
+                       LRTS_FALSE,
+                       LRTS_FALSE,
+                       LRTS_FALSE,
+                       LRTS_FALSE);
+
+       i_input_map_init_default(I_INPUT_ACTION_CURSOR_ACTION, 
+                       SDL_BUTTON_RMASK, 
+                       P_INPUT_DEV_MOUSE,
+                       LRTS_FALSE,
+                       LRTS_FALSE,
+                       LRTS_FALSE,
+                       LRTS_FALSE);
+
+       i_input_map_init_default(I_INPUT_ACTION_CURSOR_DRAG, 
+                       SDL_BUTTON_MMASK, 
+                       P_INPUT_DEV_MOUSE,
+                       LRTS_FALSE,
+                       LRTS_FALSE,
+                       LRTS_FALSE,
+                       LRTS_FALSE);
+}
+
+lrts_bool p_input_poll_action(struct i_input_map_ent *ent) {
+       lrts_bool mod_shift, mod_alt, mod_ctrl, mod_super, pressed;
+       if (ent == LRTS_NULL) {
+               return LRTS_FALSE;
+       }
+
+       mod_shift = key_map[SDL_SCANCODE_LSHIFT] | key_map[SDL_SCANCODE_RSHIFT];
+       mod_alt = key_map[SDL_SCANCODE_LALT] | key_map[SDL_SCANCODE_RALT];
+       mod_ctrl = key_map[SDL_SCANCODE_LCTRL] | key_map[SDL_SCANCODE_RCTRL];
+       mod_super = key_map[SDL_SCANCODE_LGUI] | key_map[SDL_SCANCODE_RGUI];
+
+       if (ent->device_id == P_INPUT_DEV_KEYBOARD) {
+               pressed = key_map[ent->scan_code];
+       } else if (ent->device_id == P_INPUT_DEV_MOUSE) {
+               pressed = (mouse_state & ent->scan_code) != 0;
+       } else {
+               pressed = LRTS_FALSE;
+       }
+
+       
+       if (ent->mod_shift == mod_shift
+                       && ent->mod_alt == mod_alt
+                       && ent->mod_ctrl == mod_ctrl
+                       && ent->mod_super == mod_super) {
+               return pressed;
+       }
+
+       return LRTS_FALSE;
 }
 
 int p_poll_events() {
@@ -21,45 +111,12 @@ int p_poll_events() {
                        case SDL_EVENT_QUIT:
                                lrts_cfg()->exit = LRTS_TRUE;
                                break;
-                       case SDL_EVENT_KEY_DOWN:
-                               i_input_set(e.key.scancode, 
-                                               (e.key.mod & (SDL_KMOD_LSHIFT | SDL_KMOD_RSHIFT)) != 0,
-                                               (e.key.mod & (SDL_KMOD_LALT | SDL_KMOD_RALT)) != 0,
-                                               (e.key.mod & (SDL_KMOD_LCTRL | SDL_KMOD_RCTRL)) != 0,
-                                               (e.key.mod & (SDL_KMOD_LGUI | SDL_KMOD_RGUI)) != 0
-                               );
-                               break;
-                       case SDL_EVENT_KEY_UP:
-                               i_input_unset(e.key.scancode, 
-                                               (e.key.mod & (SDL_KMOD_LSHIFT | SDL_KMOD_RSHIFT)) != 0,
-                                               (e.key.mod & (SDL_KMOD_LALT | SDL_KMOD_RALT)) != 0,
-                                               (e.key.mod & (SDL_KMOD_LCTRL | SDL_KMOD_RCTRL)) != 0,
-                                               (e.key.mod & (SDL_KMOD_LGUI | SDL_KMOD_RGUI)) != 0
-                               );
-                               break;
-                       case SDL_EVENT_MOUSE_BUTTON_DOWN:
-                               if (e.button.button == SDL_BUTTON_LEFT) {
-                                       i_input_cursor_click_set();
-                               } else if (e.button.button == SDL_BUTTON_MIDDLE) {
-                                       i_input_cursor_drag_set();
-                               } else if (e.button.button == SDL_BUTTON_RIGHT) {
-                                       i_input_cursor_action_set();
-                               }
-                               break;
-                       case SDL_EVENT_MOUSE_BUTTON_UP:
-                               if (e.button.button == SDL_BUTTON_LEFT) {
-                                       i_input_cursor_click_unset();
-                               } else if (e.button.button == SDL_BUTTON_MIDDLE) {
-                                       i_input_cursor_drag_unset();
-                               } else if (e.button.button == SDL_BUTTON_RIGHT) {
-                                       i_input_cursor_action_unset();
-                               }
-                               break;
                }
 
        }
+
        
-       SDL_GetMouseState(&x, &y);
+       mouse_state = SDL_GetMouseState(&x, &y);
        i_input_cursor_set(x, y);
 
        return 0;