input
This package manages user input across keyboard, mouse and gamepad devices. It supports both raw key polling and an abstract, player-centric binding system that decouples physical inputs from logical game actions.
Features:
- Action system: Maps physical keys to logical
Actionenums (digital). - Axis system: Maps keys and sticks to logical
Axisenums (analog). - Multi-User: Supports separate bindings for multiple (default: 5) players via
PlayerProfile. - Hybrid input: Automatically handles switching between keyboard and gamepad, as well as multiplayer input.
- Mouse utilities: Helpers for easy usage of the mouse inputs (
getMousePosition,getScrollY) - Key reading: Direct access to key states via
isKeyDown,isKeyPressedandisKeyReleased. - Cursor control: Functions to lock or hide the system cursor (
setCursorLocked,setCursorVisible) (Desktop only)
Action
Section titled “Action”Action :: enum u8 { MenuLeft, MenuRight, MenuUp, MenuDown, // Add more if needed!}Abstract digital actions (on/off) that decouple game logic from specific physical keys.
Axis :: enum u8 { MoveX, MoveY, LookX, LookY,}Abstract analog axes (Float -1.0 to 1.0). Used e.g. for movement.
AxisBind
Section titled “AxisBind”AxisBind :: struct { source: BindingSource, scale: f32, deadzone: f32,}Configuration for a single axis binding (e.g., ‘W’ key contributes -1.0 to MoveY).
BindingSource
Section titled “BindingSource”BindingSource :: union { KeyCode, GamepadButton, GamepadAxis,}Represents a single physical input source.
ButtonPressed
Section titled “ButtonPressed”ButtonPressed :: struct { index: GamepadIndex, button: GamepadButton,}Event payload when a button is pressed down.
ButtonReleased
Section titled “ButtonReleased”ButtonReleased :: struct { index: GamepadIndex, button: GamepadButton,}Event payload when a button is released.
DPAD_DOWN
Section titled “DPAD_DOWN”DPAD_DOWN :: GamepadButton.LeftFaceDownAlias for LeftFaceDown gamepad button.
DPAD_LEFT
Section titled “DPAD_LEFT”DPAD_LEFT :: GamepadButton.LeftFaceLeftAlias for LeftFaceLeft gamepad button.
DPAD_RIGHT
Section titled “DPAD_RIGHT”DPAD_RIGHT :: GamepadButton.LeftFaceRightAlias for LeftFaceRight gamepad button.
DPAD_UP
Section titled “DPAD_UP”DPAD_UP :: GamepadButton.LeftFaceUpAlias for LeftFaceUp gamepad button.
FACE_DOWN
Section titled “FACE_DOWN”FACE_DOWN :: GamepadButton.RightFaceDownAlias for RightFaceDown gamepad button (equivalent of “A” on XBOX controllers and “X” on PS controllers).
FACE_LEFT
Section titled “FACE_LEFT”FACE_LEFT :: GamepadButton.RightFaceLeftAlias for RightFaceLeft gamepad button (equivalent of “X” on XBOX controllers and ”□” on PS controllers).
FACE_RIGHT
Section titled “FACE_RIGHT”FACE_RIGHT :: GamepadButton.RightFaceRightAlias for RightFaceRight gamepad button (equivalent of “B” on XBOX controllers and ”○” on PS controllers).
FACE_UP
Section titled “FACE_UP”FACE_UP :: GamepadButton.RightFaceUpAlias for RightFaceUp gamepad button (equivalent of “Y” on XBOX controllers and ”∆” on PS controllers).
GamepadAxis
Section titled “GamepadAxis”GamepadAxis :: enum { None, LeftStickX, LeftStickY, RightStickX, RightStickY, LeftTrigger, RightTrigger,}Standard analog axes for a dual-stick controller.
GamepadButton
Section titled “GamepadButton”GamepadButton :: enum { None, LeftFaceUp, LeftFaceDown, LeftFaceLeft, LeftFaceRight, RightFaceUp, RightFaceDown, RightFaceLeft, RightFaceRight, LeftShoulder, LeftTrigger, RightShoulder, RightTrigger, LeftStickPress, RightStickPress, MiddleFaceLeft, MiddleFaceMiddle, MiddleFaceRight,}Standard physical buttons for a modern controller.
GamepadEvent
Section titled “GamepadEvent”GamepadEvent :: union { ButtonPressed, ButtonReleased,}Union representing a state change event for a gamepad.
GamepadIndex
Section titled “GamepadIndex”GamepadIndex :: intUnique identifier for a connected gamepad.
Input :: struct { keys: [_KEY_CODE_CAPACITY]bit_set[InputFlag], //bitset of 4 bits (down, pressed, released, repeat) mousePosition: gmath.Vector2, mouseScroll: gmath.Vector2, gamepadKeys: [MAX_GAMEPADS][GamepadButton]bit_set[InputFlag], touches: [MAX_TOUCHES]Touch, virtualAxisValues: [MAX_GAMEPADS][GamepadAxis]f32,}Main container for the current frame’s input state.
InputFlag
Section titled “InputFlag”InputFlag :: enum u8 { down, // Key is currently held down pressed, // Key was pressed this frame released, // Key was released this frame}Bit flags representing the state of a specific key or button in the current frame.
KeyCode
Section titled “KeyCode”KeyCode :: enum { INVALID = 0, SPACE = 32, APOSTROPHE = 39, COMMA = 44, MINUS = 45, PERIOD = 46, SLASH = 47, _0 = 48, _1 = 49, _2 = 50, _3 = 51, _4 = 52, _5 = 53, _6 = 54, _7 = 55, _8 = 56, _9 = 57, SEMICOLON = 59, EQUAL = 61, A = 65, B = 66, C = 67, D = 68, E = 69, F = 70, G = 71, H = 72, I = 73, J = 74, K = 75, L = 76, M = 77, N = 78, O = 79, P = 80, Q = 81, R = 82, S = 83, T = 84, U = 85, V = 86, W = 87, X = 88, Y = 89, Z = 90, LEFT_BRACKET = 91, BACKSLASH = 92, RIGHT_BRACKET = 93, GRAVE_ACCENT = 96, WORLD_1 = 161, WORLD_2 = 162, ESC = 256, ENTER = 257, TAB = 258, BACKSPACE = 259, INSERT = 260, DELETE = 261, RIGHT = 262, LEFT = 263, DOWN = 264, UP = 265, PAGE_UP = 266, PAGE_DOWN = 267, HOME = 268, END = 269, CAPS_LOCK = 280, SCROLL_LOCK = 281, NUM_LOCK = 282, PRINT_SCREEN = 283, PAUSE = 284, F1 = 290, F2 = 291, F3 = 292, F4 = 293, F5 = 294, F6 = 295, F7 = 296, F8 = 297, F9 = 298, F10 = 299, F11 = 300, F12 = 301, F13 = 302, F14 = 303, F15 = 304, F16 = 305, F17 = 306, F18 = 307, F19 = 308, F20 = 309, F21 = 310, F22 = 311, F23 = 312, F24 = 313, F25 = 314, KP_0 = 320, KP_1 = 321, KP_2 = 322, KP_3 = 323, KP_4 = 324, KP_5 = 325, KP_6 = 326, KP_7 = 327, KP_8 = 328, KP_9 = 329, KP_DECIMAL = 330, KP_DIVIDE = 331, KP_MULTIPLY = 332, KP_SUBTRACT = 333, KP_ADD = 334, KP_ENTER = 335, KP_EQUAL = 336, LEFT_SHIFT = 340, LEFT_CONTROL = 341, LEFT_ALT = 342, LEFT_SUPER = 343, RIGHT_SHIFT = 344, RIGHT_CONTROL = 345, RIGHT_ALT = 346, RIGHT_SUPER = 347, MENU = 348, LEFT_MOUSE = 400, RIGHT_MOUSE = 401, MIDDLE_MOUSE = 402,}Physical key codes (Stripped from Sokol), but with included mouse buttons.
MAX_GAMEPADS
Section titled “MAX_GAMEPADS”MAX_GAMEPADS :: 4The maximum number of supported concurrent gamepads. Default is 4, being in line with the maximum limit for Windows and Web.
MAX_PLAYERS
Section titled “MAX_PLAYERS”MAX_PLAYERS :: MAX_GAMEPADS + 1Maximum count of logical players that will have their inputs separated.
MOUSE_EMULATE_TOUCH
Section titled “MOUSE_EMULATE_TOUCH”MOUSE_EMULATE_TOUCH :: trueConfiguration constant for touch emulation. If set to true,
makes each mouse click emulate a 0-index touch.
PlayerProfile
Section titled “PlayerProfile”PlayerProfile :: struct { gamepadIndex: GamepadIndex, // -1 for no gamepad useKeyboard: bool, bindings: [Action][dynamic]BindingSource, axes: [Axis][dynamic]AxisBind,}Configuration state for a logical player. Contains their assigned device ID and input mappings.
SELECT
Section titled “SELECT”SELECT :: GamepadButton.MiddleFaceLeftAlias for MiddleFaceLeft gamepad button.
START :: GamepadButton.MiddleFaceRightAlias for MiddleFaceRight gamepad button.
TOUCH_EMULATE_MOUSE
Section titled “TOUCH_EMULATE_MOUSE”TOUCH_EMULATE_MOUSE :: trueConfiguration constant for touch support. If set to true,
makes each touch (0-index) emulate a mouse click.
TouchPhase
Section titled “TouchPhase”TouchPhase :: enum { None, // Slot is empty Began, // On finger touch Moved, // Finger is moving Stationary, // Finger is holding still Ended, // On finger lift Cancelled, // System interrupt}Defines the lifecycle of a finger.
addVirtualStick
Section titled “addVirtualStick”addVirtualStick :: proc ( position: gmath.Vector2, radius: f32, axisX: GamepadAxis, axisY: GamepadAxis, playerIndex: uint = 0,)Adds a virtual joystick to the touch overlay for a specified player.
Default playerIndex is 0.
position is the middle point of the thumbstick.
:::note(Example)
input.addVirtualStick(pos, 20.0, playerIndex = 1) // adds the thumbstick for player 2
:::
assignGamepad
Section titled “assignGamepad”assignGamepad :: proc (playerIndex: uint, gamepadIndex: GamepadIndex)Helper to assign a specific gamepad of index gamepadIndex to a player slot of index playerIndex.
bindAction
Section titled “bindAction”bindAction :: proc (action: Action, source: BindingSource, playerIndex: uint = 0)Binds a physical input to a logical Action.
Default playerIndex is 0.
bindAxis
Section titled “bindAxis”bindAxis :: proc ( axis: Axis, source: BindingSource, scale: f32, deadzone: f32 = 0.1, playerIndex: uint = 0,)Binds a physical input to an Axis with a specific scale.
Default playerIndex is 0.
:::note(Example)
bindAxis(.MoveY, .W, 1.0)bindAxis(.MoveY, .S, -1.0)bindAxis(.MoveX, .A, -1.0)bindAxis(.MoveX, .D, 1.0):::
consumeActionPressed
Section titled “consumeActionPressed”consumeActionPressed :: proc (action: Action, playerIndex: uint = 0) -> boolConsumes the press event for a specific action.
Returns true if the Action state was changed.
consumeActionReleased
Section titled “consumeActionReleased”consumeActionReleased :: proc (action: Action, playerIndex: uint = 0) -> boolConsumes the release event for a specific action.
Returns true if the Action state was changed.
Default playerIndex is 0.
consumeAnyGamepadPress
Section titled “consumeAnyGamepadPress”consumeAnyGamepadPress :: proc (index: GamepadIndex = -1) -> boolChecks if any button on a specific gamepad (or all gamepads if the argument isn’t provided) was pressed.
consumeAnyKeyPress
Section titled “consumeAnyKeyPress”consumeAnyKeyPress :: proc () -> boolChecks if any key is pressed this frame. If found, it consumes that press and returns true.
consumeGamepadPressed
Section titled “consumeGamepadPressed”consumeGamepadPressed :: proc (index: GamepadIndex, button: GamepadButton) -> boolManually consumes a pressed event.
Returns true if the state was successfully changed.
consumeGamepadReleased
Section titled “consumeGamepadReleased”consumeGamepadReleased :: proc (index: GamepadIndex, button: GamepadButton) -> boolManually consumes a released event.
Returns true if the state was successfully changed.
consumeKeyPressed
Section titled “consumeKeyPressed”consumeKeyPressed :: proc (code: KeyCode) -> boolManually consumes a pressed event for a key.
Returns true if the state was changed.
consumeKeyReleased
Section titled “consumeKeyReleased”consumeKeyReleased :: proc (code: KeyCode) -> boolManually consumes a released event for a key.
Returns true if the state was changed.
getAxis
Section titled “getAxis”getAxis :: proc (axis: Axis, playerIndex: uint = 0) -> f32Returns clamped float (-1.0 to 1.0) combining all bound inputs.
Default playerIndex is 0.
getInputState
Section titled “getInputState”getInputState :: proc () -> ^InputReturns the input state for current frame.
getInputVector
Section titled “getInputVector”getInputVector :: proc (playerIndex: uint = 0) -> gmath.Vector2Helper to construct a normalized directional vector from the standard
up/down/left/right actions.
Default playerIndex is 0.
Returns a zero vector if no input, or a normalized vector (length equal to 1.0).
getMousePosition
Section titled “getMousePosition”getMousePosition :: proc () -> gmath.Vector2Converts the raw screen mouse coordinates into World/UI space coordinates by un-projecting them using the current renderer’s projection matrix.
getScrollY
Section titled “getScrollY”getScrollY :: proc () -> f32Returns the current vertical scroll delta (mouse wheel).
isActionDown
Section titled “isActionDown”isActionDown :: proc (action: Action, playerIndex: uint = 0) -> boolChecks if a mapped action is currently held down.
Default playerIndex is 0.
isActionPressed
Section titled “isActionPressed”isActionPressed :: proc (action: Action, playerIndex: uint = 0) -> boolChecks if a mapped action (e.g. .MenuLeft, .MenuRight) was pressed this frame.
Default playerIndex is 0.
isActionReleased
Section titled “isActionReleased”isActionReleased :: proc (action: Action, playerIndex: uint = 0) -> boolChecks if a mapped action was released this frame.
Default playerIndex is 0.
isGamepadDown
Section titled “isGamepadDown”isGamepadDown :: proc (index: GamepadIndex, button: GamepadButton) -> boolChecks if a GamepadButton is currently held down.
isGamepadPressed
Section titled “isGamepadPressed”isGamepadPressed :: proc (index: GamepadIndex, button: GamepadButton) -> boolChecks if a GamepadButton was pressed this frame.
isGamepadReleased
Section titled “isGamepadReleased”isGamepadReleased :: proc (index: GamepadIndex, button: GamepadButton) -> boolChecks if a GamepadButton was released this frame.
isKeyDown
Section titled “isKeyDown”isKeyDown :: proc (code: KeyCode) -> boolChecks if a physical key is currently held down. Returns true as long as the key is held.
isKeyPressed
Section titled “isKeyPressed”isKeyPressed :: proc (code: KeyCode) -> boolChecks if a physical key was pressed this frame. Returns true only on the frame the key went down.
isKeyReleased
Section titled “isKeyReleased”isKeyReleased :: proc (code: KeyCode) -> boolChecks if a physical key was released this frame. Returns true only on the frame the key went up.
setCursorLocked
Section titled “setCursorLocked”setCursorLocked :: proc (isLocked: bool)Locks the cursor to the window.
setCursorVisible
Section titled “setCursorVisible”setCursorVisible :: proc (isVisible: bool)Controls the visibility of the system (hardware) cursor. Set to false if you intend to render your own custom cursor sprite.