# Input System Source: `src/dusk/input/`, platform layers in `src/dusk/input/` ## Architecture The input system has two layers: 1. **Action layer** (`inputaction_t`) -- named gameplay inputs, e.g. UP, DOWN, ACCEPT, CANCEL. This is what game code reads. 2. **Button layer** (`inputbutton_t`) -- physical hardware inputs, e.g. keyboard key, gamepad button, analog axis, mouse axis. Multiple buttons can bind to the same action (the highest value wins). The platform layer implements two hooks: - `inputUpdatePlatform()` -- read hardware state once per frame - `inputButtonGetValuePlatform()` -- return the analog value [0.0, 1.0] for a given button ## Global state ```c extern input_t INPUT; // INPUT.actions[INPUT_ACTION_COUNT] -- all action states // INPUT.platform -- platform-specific data ``` ## Reading actions (game code) ```c // Analog value this frame (0.0 - 1.0) float_t inputGetCurrentValue(inputaction_t action); // Analog value last frame float_t inputGetLastValue(inputaction_t action); // Boolean helpers (built on current/last values) bool_t inputIsDown(inputaction_t action); bool_t inputWasDown(inputaction_t action); bool_t inputPressed(inputaction_t action); // was up, now down bool_t inputReleased(inputaction_t action); // was down, now up // 2D axis helpers void inputAxis2D( inputaction_t horiz, inputaction_t vert, vec2 out ); float_t inputAngle2D(inputaction_t horiz, inputaction_t vert); void inputAxis(inputaction_t action, float_t *out); // Deadzone filter (applied to raw axis values) float_t inputDeadzone(float_t value, float_t deadzone); ``` ## Binding buttons to actions ```c void inputBind(inputaction_t action, inputbutton_t button); ``` Each platform's init function calls `inputBind` to wire its hardware buttons to the standard action IDs. Game code should never need to call `inputBind` -- it is set up once during platform init. ## Button types ```c INPUT_BUTTON_TYPE_KEYBOARD // SDL scancode (SDL2 targets only) INPUT_BUTTON_TYPE_POINTER // Mouse axes: X, Y, Z, WHEEL_X, WHEEL_Y INPUT_BUTTON_TYPE_TOUCH // Touch (defined, not fully implemented) INPUT_BUTTON_TYPE_GAMEPAD // Digital gamepad buttons INPUT_BUTTON_TYPE_GAMEPAD_AXIS // Analog axes (-1.0 to 1.0 internally) ``` ## Events Each action has `onPressed` and `onReleased` event callbacks. Subscribe via the event system (see `.claude/events.md`): ```c eventSubscribe(&INPUT.actions[ACTION_ACCEPT].onPressed, myCallback, NULL); ``` ## Platform implementations ### SDL2 (`src/dusksdl2/input/`) Handles Linux, Knulli, and PSP (PSP adds its own button mapping layer on top of SDL2). - Keyboard: SDL scancode array from `SDL_GetKeyboardState()` - Pointer: normalized mouse position (0.0-1.0), scroll axes - Gamepad: first available `SDL_GameController`; axis values normalized to [-1.0, 1.0] with deadzone (default 0.2f via `inputGetDeadzoneSDL2`) ### Dolphin -- GameCube / Wii (`src/duskdolphin/input/`) Uses `libogc` PAD API. No keyboard or pointer input -- trying to use those button types is a compile-time `#error`. - Gamepad: `PAD_ScanPads()` + `PAD_ButtonsHeld()` for pad 0 - Axes: left stick X/Y, C-stick X/Y, L/R triggers (6 total) - Deadzone: hardcoded 0.2f - Default bindings set at init: D-pad/L-stick = directional actions, A = ACCEPT, B = CANCEL, X = CONSOLE, Start = RAGEQUIT ### PSP (`src/duskpsp/input/`) Layered on top of SDL2. `inputInitPSP()` remaps SDL2 controller button constants to PSP button names, then calls `inputBind` to wire them: | PSP button | SDL2 constant | |------------|---------------| | Cross | `SDL_CONTROLLER_BUTTON_A` | | Circle | `SDL_CONTROLLER_BUTTON_B` | | Triangle | `SDL_CONTROLLER_BUTTON_Y` | | Square | `SDL_CONTROLLER_BUTTON_X` | | L / R | `SDL_CONTROLLER_BUTTON_LEFTSHOULDER` / `RIGHTSHOULDER` | | L-Stick | `SDL_CONTROLLER_AXIS_LEFTX/Y` | ## Platform capability notes | Feature | Linux/Knulli | PSP | GameCube/Wii | |---------|-------------|-----|--------------| | Keyboard | Yes (SDL2) | No | No | | Pointer/Mouse | Yes (SDL2) | No | No | | Gamepad | Yes (SDL2) | Yes (SDL2) | Yes (PAD) | | Analog axes | Yes | L-Stick only | L-Stick, C-Stick, Triggers | | Touch | Defined, not implemented | -- | -- |