Skip to content

Input

Keyboard, mouse and gamepad state, input actions, and rebinding.

Files: input.odin, input_rebind.odin.

Input: the keyboard, mouse and gamepads as state a script can ask about, and actions: named inputs (“jump”, “move_left”) that any of several keys, mouse buttons, gamepad buttons or stick directions trigger, like Godot’s input map. Scripts ask about actions, so players can remap them and one game runs on a keyboard or a gamepad without code changes:

update = proc(self: ^Player, _: []sdl.Event, dt: f64) {
move := e.Input_GetVector("move_left", "move_right", "move_up", "move_down")
self.node.position += move * 200 * f32(dt)
if e.Input_IsActionJustPressed("jump") do jump(self)
}

Projects define their actions in project.xml (the editor’s Project Settings > Input):

<action name="jump" deadzone="0.5">
<key key="Space"/>
<mouse button="Left"/>
<gamepad button="South"/>
<axis axis="LeftY" direction="-1"/>
</action>
  • Pressed: held down now. JustPressed / JustReleased: this frame only (a key’s repeats don’t count). Strength: 0 to 1 (1 for keys and buttons; how far a stick or trigger is pushed, 0 inside the action’s deadzone).
  • Raw state without actions: Input_IsKeyPressed(.Space), Input_IsMouseButtonJustPressed(.Left), Input_GetMousePosition() (game coordinates), Input_GetGamepadAxis(.LeftX)… The engine’s own Key, MouseButton, GamepadButton and GamepadAxis enums name them; SDL isn’t needed. The SDL events passed to update are still there for code that wants them.
  • Gamepads are numbered from 0 in the order they’re connected; device -1 means any of them.
  • The game’s input is updated at the start of every frame (Game_Update), before globals and scenes. Procedures use the game that’s playing (like Global) unless given one.

Rebinding: letting players change what triggers an action, from the game’s options menu, and keeping their choice. And gamepad rumble.

  1. Input_StartCapture(game), then each frame Input_GetCapturedBinding(game): the next key, mouse button, gamepad button, or stick or trigger pushed past halfway comes back once (Escape too: the game decides whether it cancels). Until then, and on the frame it comes, actions don’t press or release, so the press being bound doesn’t also act.
  2. Input_SetBindings(name, bindings) changes an action’s bindings (Input_GetBindings reads them; Input_ActionsUsing finds actions a binding is already on; Input_ResetBindings puts back the project’s).
  3. Input_SaveBindings() keeps every action’s bindings with the game’s saves (Input_LoadBindings at start, after the project is loaded: actions the save doesn’t have keep the project’s).

Example

// The options menu's "Jump" button
e.Input_StartCapture()
// Its update:
if binding, ok := e.Input_GetCapturedBinding(); ok {
if binding != e.InputBinding(e.KeyBinding{.Escape}) {
e.Input_SetBindings("jump", {binding})
e.Input_SaveBindings()
}
}
Key :: enum i32 {
Unknown = 0,
A = i32(sdl.Scancode.A), B = i32(sdl.Scancode.B), C = i32(sdl.Scancode.C), D = i32(sdl.Scancode.D),
E = i32(sdl.Scancode.E), F = i32(sdl.Scancode.F), G = i32(sdl.Scancode.G), H = i32(sdl.Scancode.H),
I = i32(sdl.Scancode.I), J = i32(sdl.Scancode.J), K = i32(sdl.Scancode.K), L = i32(sdl.Scancode.L),
M = i32(sdl.Scancode.M), N = i32(sdl.Scancode.N), O = i32(sdl.Scancode.O), P = i32(sdl.Scancode.P),
Q = i32(sdl.Scancode.Q), R = i32(sdl.Scancode.R), S = i32(sdl.Scancode.S), T = i32(sdl.Scancode.T),
U = i32(sdl.Scancode.U), V = i32(sdl.Scancode.V), W = i32(sdl.Scancode.W), X = i32(sdl.Scancode.X),
Y = i32(sdl.Scancode.Y), Z = i32(sdl.Scancode.Z),
Num1 = i32(sdl.Scancode._1), Num2 = i32(sdl.Scancode._2), Num3 = i32(sdl.Scancode._3), Num4 = i32(sdl.Scancode._4),
Num5 = i32(sdl.Scancode._5), Num6 = i32(sdl.Scancode._6), Num7 = i32(sdl.Scancode._7), Num8 = i32(sdl.Scancode._8),
Num9 = i32(sdl.Scancode._9), Num0 = i32(sdl.Scancode._0),
Enter = i32(sdl.Scancode.RETURN), Escape = i32(sdl.Scancode.ESCAPE), Backspace = i32(sdl.Scancode.BACKSPACE),
Tab = i32(sdl.Scancode.TAB), Space = i32(sdl.Scancode.SPACE),
Minus = i32(sdl.Scancode.MINUS), Equals = i32(sdl.Scancode.EQUALS), LeftBracket = i32(sdl.Scancode.LEFTBRACKET),
RightBracket = i32(sdl.Scancode.RIGHTBRACKET), Backslash = i32(sdl.Scancode.BACKSLASH), Semicolon = i32(sdl.Scancode.SEMICOLON),
Apostrophe = i32(sdl.Scancode.APOSTROPHE), Grave = i32(sdl.Scancode.GRAVE), Comma = i32(sdl.Scancode.COMMA),
Period = i32(sdl.Scancode.PERIOD), Slash = i32(sdl.Scancode.SLASH), CapsLock = i32(sdl.Scancode.CAPSLOCK),
F1 = i32(sdl.Scancode.F1), F2 = i32(sdl.Scancode.F2), F3 = i32(sdl.Scancode.F3), F4 = i32(sdl.Scancode.F4),
F5 = i32(sdl.Scancode.F5), F6 = i32(sdl.Scancode.F6), F7 = i32(sdl.Scancode.F7), F8 = i32(sdl.Scancode.F8),
F9 = i32(sdl.Scancode.F9), F10 = i32(sdl.Scancode.F10), F11 = i32(sdl.Scancode.F11), F12 = i32(sdl.Scancode.F12),
PrintScreen = i32(sdl.Scancode.PRINTSCREEN), ScrollLock = i32(sdl.Scancode.SCROLLLOCK), Pause = i32(sdl.Scancode.PAUSE),
Insert = i32(sdl.Scancode.INSERT), Home = i32(sdl.Scancode.HOME), PageUp = i32(sdl.Scancode.PAGEUP),
Delete = i32(sdl.Scancode.DELETE), End = i32(sdl.Scancode.END), PageDown = i32(sdl.Scancode.PAGEDOWN),
Right = i32(sdl.Scancode.RIGHT), Left = i32(sdl.Scancode.LEFT), Down = i32(sdl.Scancode.DOWN), Up = i32(sdl.Scancode.UP),
NumLock = i32(sdl.Scancode.NUMLOCKCLEAR), KeypadDivide = i32(sdl.Scancode.KP_DIVIDE), KeypadMultiply = i32(sdl.Scancode.KP_MULTIPLY),
KeypadMinus = i32(sdl.Scancode.KP_MINUS), KeypadPlus = i32(sdl.Scancode.KP_PLUS), KeypadEnter = i32(sdl.Scancode.KP_ENTER),
Keypad1 = i32(sdl.Scancode.KP_1), Keypad2 = i32(sdl.Scancode.KP_2), Keypad3 = i32(sdl.Scancode.KP_3),
Keypad4 = i32(sdl.Scancode.KP_4), Keypad5 = i32(sdl.Scancode.KP_5), Keypad6 = i32(sdl.Scancode.KP_6),
Keypad7 = i32(sdl.Scancode.KP_7), Keypad8 = i32(sdl.Scancode.KP_8), Keypad9 = i32(sdl.Scancode.KP_9),
Keypad0 = i32(sdl.Scancode.KP_0), KeypadPeriod = i32(sdl.Scancode.KP_PERIOD),
LeftCtrl = i32(sdl.Scancode.LCTRL), LeftShift = i32(sdl.Scancode.LSHIFT), LeftAlt = i32(sdl.Scancode.LALT),
LeftSuper = i32(sdl.Scancode.LGUI), RightCtrl = i32(sdl.Scancode.RCTRL), RightShift = i32(sdl.Scancode.RSHIFT),
RightAlt = i32(sdl.Scancode.RALT), RightSuper = i32(sdl.Scancode.RGUI),
}

A keyboard key, by position (a US layout’s names). Values are SDL scancodes

enum. Source: input.odin:44

MouseButton :: enum {
Left,
Middle,
Right,
// The back side button (SDL's X1)
Back,
// The forward side button (SDL's X2)
Forward,
// The wheel turned up (away from the player), for one frame
WheelUp,
WheelDown,
WheelLeft,
WheelRight,
}

A mouse button. The wheel’s four directions count as buttons pressed for the frame it turns

enum. Source: input.odin:81

GamepadButton :: enum i32 {
South = i32(sdl.GamepadButton.SOUTH),
East = i32(sdl.GamepadButton.EAST),
West = i32(sdl.GamepadButton.WEST),
North = i32(sdl.GamepadButton.NORTH),
Back = i32(sdl.GamepadButton.BACK),
Guide = i32(sdl.GamepadButton.GUIDE),
Start = i32(sdl.GamepadButton.START),
LeftStick = i32(sdl.GamepadButton.LEFT_STICK),
RightStick = i32(sdl.GamepadButton.RIGHT_STICK),
LeftShoulder = i32(sdl.GamepadButton.LEFT_SHOULDER),
RightShoulder = i32(sdl.GamepadButton.RIGHT_SHOULDER),
DpadUp = i32(sdl.GamepadButton.DPAD_UP),
DpadDown = i32(sdl.GamepadButton.DPAD_DOWN),
DpadLeft = i32(sdl.GamepadButton.DPAD_LEFT),
DpadRight = i32(sdl.GamepadButton.DPAD_RIGHT),
Misc = i32(sdl.GamepadButton.MISC1),
Touchpad = i32(sdl.GamepadButton.TOUCHPAD),
}

A gamepad button, by position (South is Xbox A, PlayStation Cross, Nintendo B). Values are SDL’s

enum. Source: input.odin:97

GamepadAxis :: enum i32 {
LeftX = i32(sdl.GamepadAxis.LEFTX),
LeftY = i32(sdl.GamepadAxis.LEFTY),
RightX = i32(sdl.GamepadAxis.RIGHTX),
RightY = i32(sdl.GamepadAxis.RIGHTY),
LeftTrigger = i32(sdl.GamepadAxis.LEFT_TRIGGER),
RightTrigger = i32(sdl.GamepadAxis.RIGHT_TRIGGER),
}

A gamepad stick axis (-1 to 1; down and right are positive) or trigger (0 to 1). Values are SDL’s

enum. Source: input.odin:118

InputBinding :: union {
KeyBinding,
MouseBinding,
GamepadButtonBinding,
GamepadAxisBinding,
}

What triggers an action

union. Source: input.odin:128

KeyBinding :: struct {
// The key
key: Key,
}

A keyboard key triggers the action

struct. Source: input.odin:136

MouseBinding :: struct {
// The button
button: MouseButton,
}

A mouse button (or a wheel direction) triggers the action

struct. Source: input.odin:142

GamepadButtonBinding :: struct {
// The button
button: GamepadButton,
// Which gamepad (0 the first connected); -1 any
device: int,
}

A gamepad button triggers the action

struct. Source: input.odin:148

GamepadAxisBinding :: struct {
// The stick axis or trigger
axis: GamepadAxis,
// +1 (right, down, pressed) or -1 (left, up)
direction: f32,
// Which gamepad (0 the first connected); -1 any
device: int,
}

A stick or trigger pushed one way: direction +1 (right, down, pressed) or -1 (left, up)

struct. Source: input.odin:156

InputActionData :: struct {
// The action's name, as scripts ask for it ("jump")
name: string,
// Sticks and triggers below this count as not pressed
deadzone: f32,
// What triggers it: any one of them
bindings: [dynamic]InputBinding,
}

A named input and what triggers it: project.xml’s <action> (format version 8)

struct. Source: input.odin:169

InputState :: struct {
// Keys held, gone down this frame, and let go this frame
keys, keysPressed, keysReleased: #sparse[Key]bool,
// Mouse buttons held, gone down this frame, and let go this frame
mouse, mousePressed, mouseReleased: [MouseButton]bool,
// Where the mouse is, in game coordinates (the app converts window positions)
mousePosition: [2]f32,
// How far it moved this frame, in game coordinates
mouseMotion: [2]f32,
// This frame's wheel turn (y up positive, x right positive)
wheel: [2]f32,
// The connected gamepads, in the order they connected (their index is the device number)
gamepads: [dynamic]GamepadState,
// The actions and their state this frame (`Input_SetActions`, `Input_AddAction`)
actions: [dynamic]ActionState,
// Unknown action names already reported, so a typo warns once (owned keys)
warned: map[string]bool,
// Waiting for the next input to bind (input_rebind.odin)
capture: InputCapture,
// Fingers on the screen, and those lifted this frame (touch.odin)
touches: [dynamic]Touch,
// The screen has been touched (touch controls show)
touched: bool,
// The last mouse press or release came from a finger (SDL's touch mouse): touch controls
// take the finger, not that mouse press
mouseFromTouch: bool,
// Touch controls always show (editors' previews)
showTouchControls: bool,
// The VirtualJoysticks and TouchButtons of the game's scenes (they add and remove themselves)
touchControls: [dynamic]^TouchControl,
// Counts updates (touch controls use the ones that updated last frame)
frame: u64,
// Local players: who plays with which device (players.odin)
players: PlayersState,
}

The game’s input: what’s held, what changed this frame, and the actions (Game.input)

struct. Source: input.odin:198

InputCaptureState :: enum u8 {
// No capture
Off,
// Waiting for the next input
Waiting,
// Got it: Input_GetCapturedBinding hands it out once
Done,
}

Where a capture is (InputState.capture)

enum. Source: input_rebind.odin:40

InputCapture :: struct {
// Where it is
state: InputCaptureState,
// The input captured, once `state` is .Done
binding: InputBinding,
// Gamepad bindings for any gamepad (device -1), or the one used
anyDevice: bool,
// Each gamepad's axes when the capture started: a stick resting off-center isn't a push
baseline: [8][GamepadAxis]f32,
}

A capture of the next input (Input_StartCapture)

struct. Source: input_rebind.odin:50

Input_SetActions :: proc(game: ^Game, actions: []InputActionData)

Sets the game’s actions (replacing any): Game_LoadProject does this with the project’s. Names, bindings and the list are copied into the game’s memory; the bindings also become each action’s defaults (Input_ResetBindings).

Inputs

  • game: The game
  • actions: The actions

procedure. Source: input.odin:243

Input_AddAction :: proc(name: string, bindings: ..InputBinding, deadzone: f32 = DEFAULT_ACTION_DEADZONE, game: ^Game = nil)

Adds an action from code, or more bindings to one that exists (its deadzone then stays). The bindings also become part of its defaults (Input_ResetBindings).

Inputs

  • name: The action’s name (copied)
  • bindings: What triggers it
  • deadzone: How far a stick or trigger must move to count (0 to 1), for a new action
  • game: The game (nil: the one playing)

Example

e.Input_AddAction("dash", e.KeyBinding{.LeftShift}, e.GamepadButtonBinding{.East, -1})

procedure. Source: input.odin:269

Input_HasAction :: proc(name: string, game: ^Game = nil) -> bool

Tells whether the game has an action by that name (without warning when it doesn’t).

Inputs

  • name: The action’s name
  • game: The game (nil: the one playing)

Returns

  • true if it exists

procedure. Source: input.odin:298

Input_IsActionPressed :: proc(name: string, game: ^Game = nil) -> bool

Tells whether an action is held: any of its bindings is down (a stick past its deadzone). An unknown name logs a warning once and counts as not pressed.

Inputs

  • name: The action’s name
  • game: The game (nil: the one playing)

Returns

  • true while it’s held

Example

if e.Input_IsActionPressed("fire") do log.info("firing")

procedure. Source: input.odin:316

Input_IsActionJustPressed :: proc(name: string, game: ^Game = nil) -> bool

Tells whether an action went down this frame. Not while an input is being captured for rebinding (input_rebind.odin).

Inputs

  • name: The action’s name
  • game: The game (nil: the one playing)

Returns

  • true on the frame it was pressed

Example

if e.Input_IsActionJustPressed("jump") do log.info("jump")

procedure. Source: input.odin:335

Input_IsActionJustReleased :: proc(name: string, game: ^Game = nil) -> bool

Tells whether an action was let go this frame. Not while an input is being captured for rebinding (input_rebind.odin).

Inputs

  • name: The action’s name
  • game: The game (nil: the one playing)

Returns

  • true on the frame it was released

procedure. Source: input.odin:351

Input_GetActionStrength :: proc(name: string, game: ^Game = nil) -> f32

How hard an action is pressed: the strongest of its bindings.

Inputs

  • name: The action’s name
  • game: The game (nil: the one playing)

Returns

  • 0 to 1: 1 for keys and buttons, a stick’s or trigger’s travel past the deadzone (rescaled so it starts at 0 there); 0 for an unknown action

procedure. Source: input.odin:366

Input_GetAxis :: proc(negative, positive: string, game: ^Game = nil) -> f32

One axis from two actions: positive’s strength minus negative’s.

Inputs

  • negative: The action for -1 (left, up)
  • positive: The action for +1 (right, down)
  • game: The game (nil: the one playing)

Returns

  • -1 to 1

Example

steer := e.Input_GetAxis("turn_left", "turn_right")

procedure. Source: input.odin:385

Input_GetVector :: proc(negativeX, positiveX, negativeY, positiveY: string, game: ^Game = nil) -> [2]f32

A direction from four actions (x right, y down), at most 1 long: diagonals aren’t faster.

Inputs

  • negativeX: The action for left
  • positiveX: The action for right
  • negativeY: The action for up
  • positiveY: The action for down
  • game: The game (nil: the one playing)

Returns

  • The direction, each axis -1 to 1, length at most 1

Example

// Given: speed: f32
velocity := e.Input_GetVector("move_left", "move_right", "move_up", "move_down") * speed
node.position += velocity * f32(dt)

procedure. Source: input.odin:407

Input_IsKeyPressed :: proc(key: Key, game: ^Game = nil) -> bool

Tells whether a key is held.

Inputs

  • key: The key
  • game: The game (nil: the one playing)

Returns

  • true while it’s down

Example

if e.Input_IsKeyPressed(.LeftShift) do log.info("running")

procedure. Source: input.odin:426

Input_IsKeyJustPressed :: proc(key: Key, game: ^Game = nil) -> bool

Tells whether a key went down this frame (its repeats don’t count).

Inputs

  • key: The key
  • game: The game (nil: the one playing)

Returns

  • true on the frame it was pressed

Example

if e.Input_IsKeyJustPressed(.Escape) do log.info("pause")

procedure. Source: input.odin:444

Input_IsKeyJustReleased :: proc(key: Key, game: ^Game = nil) -> bool

Tells whether a key was let go this frame (or the window lost focus while it was held).

Inputs

  • key: The key
  • game: The game (nil: the one playing)

Returns

  • true on the frame it was released

procedure. Source: input.odin:459

Input_IsMouseButtonPressed :: proc(button: MouseButton, game: ^Game = nil) -> bool

Tells whether a mouse button is held. A wheel direction counts as held on the frame the wheel turns.

Inputs

  • button: The button
  • game: The game (nil: the one playing)

Returns

  • true while it’s down

procedure. Source: input.odin:474

Input_IsMouseButtonJustPressed :: proc(button: MouseButton, game: ^Game = nil) -> bool

Tells whether a mouse button went down this frame (a wheel direction: the wheel turned this frame).

Inputs

  • button: The button
  • game: The game (nil: the one playing)

Returns

  • true on the frame it was pressed

Example

if e.Input_IsMouseButtonJustPressed(.Left) do log.infof("click at %v", e.Input_GetMousePosition())

procedure. Source: input.odin:492

Input_IsMouseButtonJustReleased :: proc(button: MouseButton, game: ^Game = nil) -> bool

Tells whether a mouse button was let go this frame (a wheel direction: the frame after it turned).

Inputs

  • button: The button
  • game: The game (nil: the one playing)

Returns

  • true on the frame it was released

procedure. Source: input.odin:507

Input_GetMousePosition :: proc(game: ^Game = nil) -> [2]f32

Where the mouse is, in game coordinates (Scene_ScreenToWorld gives the world point under it).

Inputs

  • game: The game (nil: the one playing)

Returns

  • The position in game coordinates (zero without a game)

procedure. Source: input.odin:521

Input_GetMouseMotion :: proc(game: ^Game = nil) -> [2]f32

How far the mouse moved this frame.

Inputs

  • game: The game (nil: the one playing)

Returns

  • The movement in game coordinates

procedure. Source: input.odin:535

Input_GetMouseWheel :: proc(game: ^Game = nil) -> [2]f32

How far the wheel turned this frame.

Inputs

  • game: The game (nil: the one playing)

Returns

  • The turn: y positive up, x positive right (SDL’s wheel units)

procedure. Source: input.odin:549

Input_GamepadCount :: proc(game: ^Game = nil) -> int

How many gamepads are connected (devices 0 to the count minus 1).

Inputs

  • game: The game (nil: the one playing)

Returns

  • The count

procedure. Source: input.odin:563

Input_IsGamepadButtonPressed :: proc(button: GamepadButton, device := -1, game: ^Game = nil) -> bool

Tells whether a gamepad button is held.

Inputs

  • button: The button
  • device: Which gamepad (0 the first connected); -1 any
  • game: The game (nil: the one playing)

Returns

  • true while it’s down (false for a device that isn’t connected)

procedure. Source: input.odin:579

Input_IsGamepadButtonJustPressed :: proc(button: GamepadButton, device := -1, game: ^Game = nil) -> bool

Tells whether a gamepad button went down this frame.

Inputs

  • button: The button
  • device: Which gamepad (0 the first connected); -1 any
  • game: The game (nil: the one playing)

Returns

  • true on the frame it was pressed

Example

if e.Input_IsGamepadButtonJustPressed(.Start) do log.info("pause")

procedure. Source: input.odin:598

Input_IsGamepadButtonJustReleased :: proc(button: GamepadButton, device := -1, game: ^Game = nil) -> bool

Tells whether a gamepad button was let go this frame.

Inputs

  • button: The button
  • device: Which gamepad (0 the first connected); -1 any
  • game: The game (nil: the one playing)

Returns

  • true on the frame it was released

procedure. Source: input.odin:614

Input_GetGamepadAxis :: proc(axis: GamepadAxis, device := 0, game: ^Game = nil) -> f32

A gamepad’s stick axis or trigger, raw (no deadzone).

Inputs

  • axis: The stick axis or trigger
  • device: Which gamepad (0 the first connected, the default); -1 the one pushed furthest
  • game: The game (nil: the one playing)

Returns

  • -1 to 1 for a stick (down and right positive), 0 to 1 for a trigger; 0 for a device that isn’t connected

Example

aim := [2]f32{e.Input_GetGamepadAxis(.RightX), e.Input_GetGamepadAxis(.RightY)}
_ = aim

procedure. Source: input.odin:634

Input_Update :: proc(input: ^InputState, events: []sdl.Event)

Starts a frame: forgets last frame’s presses and releases, applies this frame’s events, and works out every action. Game_Update calls it; call it yourself only for input outside a game loop.

Inputs

  • input: The input state (usually &game.input)
  • events: This frame’s SDL events

procedure. Source: input.odin:648

FormatInputBinding :: proc(binding: InputBinding) -> (element: string, attributes: []ScriptPropData)

A binding as project files store it: its element and attributes, e.g. key key="Space", axis axis="LeftX" direction="-1". ParseInputBinding reads it back.

Inputs

  • binding: The binding

Returns

  • element: The element name (“key”, “mouse”, “gamepad”, “axis”)
  • attributes: Its attributes as name / value pairs (temp allocated); device is left out when it is -1

procedure. Source: input.odin:786

ParseInputBinding :: proc(element: string, get: proc(user: rawptr, key: string) -> (string, bool), user: rawptr) -> (InputBinding, bool)

Reads a binding element (FormatInputBinding’s). A missing device is -1 (any gamepad), a missing direction +1.

Inputs

  • element: The element name (“key”, “mouse”, “gamepad”, “axis”)
  • get: Returns an attribute’s value by name, and whether it is there
  • user: Passed to get (e.g. the XML element being read)

Returns

  • The binding, and false for an unknown element or value

procedure. Source: input.odin:822

InputBinding_Describe :: proc(binding: InputBinding) -> string

A binding as a person reads it, for a controls menu: “Space”, “Mouse Left”, “Gamepad South”, “Gamepad LeftX −”, “Gamepad 1 South” (one gamepad, numbered from 1).

Inputs

  • binding: The binding

Returns

  • The text (temp allocated, or a constant)

procedure. Source: input.odin:863

Input_StartCapture :: proc(anyDevice := true, game: ^Game = nil)

Starts waiting for the next input to bind (see above). Replaces a capture already going.

Inputs

  • anyDevice: A gamepad binding works on any gamepad (else only on the one pressed)
  • game: The game (nil: the one playing)

Example

e.Input_StartCapture()

procedure. Source: input_rebind.odin:71

Input_CancelCapture :: proc(game: ^Game = nil)

Stops waiting for an input to bind (a captured one not taken yet is dropped).

Inputs

  • game: The game (nil: the one playing)

procedure. Source: input_rebind.odin:84

Input_IsCapturing :: proc(game: ^Game = nil) -> bool

Tells whether a capture is waiting for its input.

Inputs

  • game: The game (nil: the one playing)

Returns

procedure. Source: input_rebind.odin:97

Input_GetCapturedBinding :: proc(game: ^Game = nil) -> (InputBinding, bool)

The input a capture got, once: from the frame it came (Game_Update’s Input_Update), then the capture is over.

Inputs

  • game: The game (nil: the one playing)

Returns

  • The binding, and whether there is one (false while waiting or with no capture)

Example

if binding, ok := e.Input_GetCapturedBinding(); ok {
e.Input_SetBindings("jump", {binding})
}

procedure. Source: input_rebind.odin:117

Input_GetBindings :: proc(name: string, game: ^Game = nil) -> []InputBinding

An action’s bindings. An unknown name logs a warning once.

Inputs

  • name: The action’s name
  • game: The game (nil: the one playing)

Returns

  • The game’s list (don’t keep it past a change), nil when there’s no such action

procedure. Source: input_rebind.odin:135

Input_SetBindings :: proc(name: string, bindings: []InputBinding, game: ^Game = nil) -> bool

Replaces an action’s bindings (copied). An unknown name logs a warning once.

Inputs

  • name: The action’s name
  • bindings: Its new bindings (an empty slice unbinds it)
  • game: The game (nil: the one playing)

Returns

  • false when there’s no such action

Example

e.Input_SetBindings("jump", {e.KeyBinding{.Space}, e.GamepadButtonBinding{.South, -1}})

procedure. Source: input_rebind.odin:154

Input_ActionsUsing :: proc(binding: InputBinding, game: ^Game = nil) -> []string

The actions a binding triggers (to warn about, or take it off, before binding it to another). Bindings match exactly: a gamepad binding for device -1 doesn’t match one for device 0.

Inputs

  • binding: The binding
  • game: The game (nil: the one playing)

Returns

  • Their names (the game’s strings; the list is temp allocated)

procedure. Source: input_rebind.odin:173

Input_ResetBindings :: proc(game: ^Game = nil)

Puts every action’s bindings back as the project (or Input_AddAction) made them. Doesn’t save: call Input_SaveBindings to keep it.

Inputs

  • game: The game (nil: the one playing)

procedure. Source: input_rebind.odin:193

Input_FormatBindings :: proc(game: ^Game = nil, allocator := context.allocator) -> string

Every action’s bindings as text, one line per action (what Input_SaveBindings writes):

jump = key key=Space | gamepad button=South
move_left = key key=A | axis axis=LeftX direction=-1

Inputs

  • game: The game (nil: the one playing)
  • allocator: Allocates the text

Returns

  • The text, allocated with allocator (“” without a game)

procedure. Source: input_rebind.odin:215

Input_ParseBindings :: proc(text: string, game: ^Game = nil) -> int

Sets actions’ bindings from Input_FormatBindings text. Actions the text doesn’t list keep theirs; lines for actions the game doesn’t have, and bindings that can’t be read, are skipped.

Inputs

  • text: The text
  • game: The game (nil: the one playing)

Returns

  • How many actions it set

procedure. Source: input_rebind.odin:249

Input_SaveBindings :: proc(slot := INPUT_BINDINGS_SLOT, game: ^Game = nil) -> bool

Keeps every action’s bindings with the game’s saves (save.odin’s storage: a file in the player’s data folder, the browser’s localStorage).

Inputs

  • slot: The save slot name
  • game: The game (nil: the one playing)

Returns

  • Whether it was written (failures are logged)

Example

if !e.Input_SaveBindings() do log.warn("bindings not saved")

procedure. Source: input_rebind.odin:296

Input_LoadBindings :: proc(slot := INPUT_BINDINGS_SLOT, game: ^Game = nil) -> bool

Loads bindings Input_SaveBindings kept (call it once the project is loaded), as Input_ParseBindings.

Inputs

  • slot: The save slot name
  • game: The game (nil: the one playing)

Returns

  • false when there’s none

Example

e.Input_LoadBindings()

procedure. Source: input_rebind.odin:321

Input_Rumble :: proc(low, high: f32, seconds: f32, device := -1, game: ^Game = nil) -> bool

Rumbles gamepads (those that can; others ignore it).

Inputs

  • low: The low-frequency motor’s strength, 0 to 1
  • high: The high-frequency motor’s strength, 0 to 1
  • seconds: How long (a new rumble replaces one still going)
  • device: Which gamepad (0 the first connected); -1 all of them
  • game: The game (nil: the one playing)

Returns

  • Whether any gamepad took it

Example

// A hit: a short, strong thump
e.Input_Rumble(0.8, 0.4, 0.15)

procedure. Source: input_rebind.odin:347

DEFAULT_ACTION_DEADZONE :: 0.5

The deadzone actions get unless they set one: how far a stick must move to count

constant. Source: input.odin:166

INPUT_BINDINGS_SLOT :: "bindings"

The save slot bindings are kept in (Input_SaveBindings)

constant. Source: input_rebind.odin:34

INPUT_CAPTURE_AXIS :: 0.5

How far a stick or trigger must move to be captured

constant. Source: input_rebind.odin:37