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) characterQueue: [dynamic]rune, // for text input isInputCaptured: bool, // if true, something (e.g. a text box) is consuming the input mousePosition: gmath.Vector2, previousMousePosition: gmath.Vector2, mouseDelta: 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 :: falseConfiguration 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.
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.
getCharacterQueue
Section titled “getCharacterQueue”getCharacterQueue :: proc () -> []runeReturns a queue of characters triggered this frame. Useful for text input boxes.
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).
getMouseDelta
Section titled “getMouseDelta”getMouseDelta :: proc () -> gmath.Vector2Returns the vector by which the mouse moved in the last frame.
getMousePosition
Section titled “getMousePosition”getMousePosition :: proc (space: Maybe(InputSpace) = nil) -> gmath.Vector2Converts the raw screen mouse coordinates into World/UI space coordinates
by un-projecting them using the current renderer’s projection matrix.
Accepts optional space argument. If set, returns the mouse position in
selected space. Otherwise returns the mouse position in currently set space.
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.
setCaptured
Section titled “setCaptured”setCaptured :: proc (captured: bool)Sets whether input is currently captured.
If true, isKeyDown/isKeyPressed/isKeyReleased
will return false.
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.