94 lines
3.2 KiB
Markdown
94 lines
3.2 KiB
Markdown
# Input System
|
|
|
|
Source: `src/dusk/input/`
|
|
|
|
The input system decouples physical hardware buttons from logical game actions via a binding layer. Actions are defined in `src/dusk/input/input.csv` and code-generated into `inputaction_t` enum values — see [architecture.md](architecture.md#code-generation-from-csv).
|
|
|
|
---
|
|
|
|
## Concepts
|
|
|
|
**Button** (`inputbutton_t`) — a physical input source: a keyboard scancode, gamepad button, gamepad axis, or pointer axis. The available button types depend on which `DUSK_INPUT_*` defines are active for the target platform.
|
|
|
|
**Action** (`inputaction_t`) — a logical game input (e.g. `INPUT_ACTION_UP`, `INPUT_ACTION_CONFIRM`, `INPUT_ACTION_RAGEQUIT`). Each action accumulates a float value `[0.0, 1.0]` from all buttons bound to it.
|
|
|
|
**Binding** — a many-to-one mapping from buttons to actions. Bindings are registered at runtime with `inputBind(button, action)`.
|
|
|
|
---
|
|
|
|
## Querying actions
|
|
|
|
```c
|
|
// Boolean helpers (current frame):
|
|
inputIsDown(action) // value > 0 this frame
|
|
inputPressed(action) // down this frame but not last
|
|
inputReleased(action) // down last frame but not this
|
|
|
|
// Last frame state:
|
|
inputWasDown(action)
|
|
|
|
// Raw float value:
|
|
inputGetCurrentValue(action) // [0.0, 1.0]
|
|
inputGetLastValue(action)
|
|
|
|
// Axis helpers — combine two opposing actions into a signed float:
|
|
float_t h = inputAxis(INPUT_ACTION_LEFT, INPUT_ACTION_RIGHT); // -1.0 to 1.0
|
|
inputAxis2D(negX, posX, negY, posY, result); // fills vec2
|
|
inputAngle2D(negX, posX, negY, posY, result); // atan2-based normalized direction
|
|
|
|
// Deadzone:
|
|
float_t clean = inputDeadzone(rawValue, 0.1f);
|
|
```
|
|
|
|
---
|
|
|
|
## Dynamic values (`DUSK_TIME_DYNAMIC`)
|
|
|
|
On platforms with variable frame rates, each action also tracks `dynamicDelta`-scaled values:
|
|
|
|
```c
|
|
inputGetCurrentValueDynamic(action)
|
|
inputGetLastValueDynamic(action)
|
|
```
|
|
|
|
These account for the actual time elapsed since the last frame, so movement calculated from them is frame-rate independent.
|
|
|
|
---
|
|
|
|
## Events on actions
|
|
|
|
Each `inputactiondata_t` exposes `onPressed` and `onReleased` events:
|
|
|
|
```c
|
|
eventSubscribe(&INPUT.actions[INPUT_ACTION_CONFIRM].onPressed, myCallback, myUser);
|
|
```
|
|
|
|
The callback signature is `void cb(void *params, void *user)`. `params` is always `NULL` for input events.
|
|
|
|
---
|
|
|
|
## Buttons and bindings
|
|
|
|
Physical buttons are typed via `inputbuttontype_t`:
|
|
|
|
| Constant | When available | Payload |
|
|
|---|---|---|
|
|
| `INPUT_BUTTON_TYPE_KEYBOARD` | `DUSK_INPUT_KEYBOARD` | `inputscancode_t` |
|
|
| `INPUT_BUTTON_TYPE_GAMEPAD` | `DUSK_INPUT_GAMEPAD` | `inputgamepadbutton_t` |
|
|
| `INPUT_BUTTON_TYPE_GAMEPAD_AXIS` | `DUSK_INPUT_GAMEPAD` | axis + positive direction flag |
|
|
| `INPUT_BUTTON_TYPE_POINTER` | `DUSK_INPUT_POINTER` | `inputpointeraxis_t` |
|
|
|
|
Button names and default bindings are defined in `input.csv`. Look up a button by name:
|
|
```c
|
|
inputbutton_t btn = inputButtonGetByName("keyboard_w");
|
|
inputBind(btn, INPUT_ACTION_UP);
|
|
```
|
|
|
|
`INPUT_BUTTON_DATA[]` holds runtime state (current/last raw values) for every physical button.
|
|
|
|
---
|
|
|
|
## Platform platform-specific reads
|
|
|
|
`inputButtonGetValuePlatform(button)` is the one required platform function — it returns the current raw `[0.0, 1.0]` value for a button. The platform implementations live in `src/dusk{platform}/input/`.
|