simvx.core.input.gamepad

The engine’s gamepad convention, and the mapping every backend feeds.

A window backend reports whatever its own library reports. GLFW hands back a resting trigger as -1.0, SDL3 hands back a 0..32767 integer, and a browser hands back 0.0. This module is the single place those conventions become the engine’s, so the same physical trigger reads the same number whichever backend the game booted with.

The convention, and it is what Input.get_gamepad_axis documents:

  • Sticks run -1.0 to 1.0 per axis, centred at 0.0, with +y pointing down the screen.

  • Triggers run 0.0 when released to 1.0 when fully pulled.

  • A pad reports exactly :data:BUTTON_NAMES and :data:AXIS_NAMES: no more, so a backend cannot smuggle in a name nothing else has; no fewer, so a name a game polls is never quietly absent on one backend.

A backend declares its source ranges and calls :func:normalise_axes; it does not do the arithmetic itself. That is what stops a fourth backend re-deriving the divergence this module exists to remove.

Module Contents

Functions

normalise_buttons

Coerce one pad’s raw button readings to the engine’s set of booleans.

normalise_axes

Map one pad’s raw axis readings onto the engine’s convention.

out_of_range_axes

Names whose value breaks the convention, for a caller that wants to warn.

Data

API

simvx.core.input.gamepad.__all__

[‘AXIS_NAMES’, ‘BUTTON_NAMES’, ‘STICK_NAMES’, ‘TRIGGER_NAMES’, ‘normalise_axes’, ‘normalise_buttons’…

simvx.core.input.gamepad.BUTTON_NAMES: tuple[str, ...]

(‘a’, ‘b’, ‘x’, ‘y’, ‘lb’, ‘rb’, ‘back’, ‘start’, ‘guide’, ‘l3’, ‘r3’, ‘dpad_up’, ‘dpad_right’, ‘dpa…

simvx.core.input.gamepad.STICK_NAMES: tuple[str, ...]

(‘left_x’, ‘left_y’, ‘right_x’, ‘right_y’)

simvx.core.input.gamepad.TRIGGER_NAMES: tuple[str, ...]

(‘lt’, ‘rt’)

simvx.core.input.gamepad.AXIS_NAMES: tuple[str, ...]

None

simvx.core.input.gamepad.normalise_buttons(raw: collections.abc.Mapping[str, object]) dict[str, bool][source]

Coerce one pad’s raw button readings to the engine’s set of booleans.

Args: raw: The backend’s readings, keyed by :data:BUTTON_NAMES. Values may be anything truthy (SDL3 returns ints, GLFW returns bytes).

Raises: ValueError: If a name is missing or is not one the engine knows.

simvx.core.input.gamepad.normalise_axes(raw: collections.abc.Mapping[str, float], *, stick_scale: float, trigger_range: tuple[float, float]) dict[str, float][source]

Map one pad’s raw axis readings onto the engine’s convention.

Args: raw: The backend’s readings, keyed by :data:AXIS_NAMES. stick_scale: The magnitude a fully deflected stick reports. 1.0 for a library that already reports floats, 32767.0 for one that reports signed 16-bit. A stick divides by this and is clamped, so a library whose negative extreme is -32768 cannot overshoot the documented [-1, 1], and centre stays exactly 0.0. trigger_range: (released, fully_pulled) in the backend’s own units: (-1.0, 1.0) for GLFW, (0.0, 32767.0) for SDL3, (0.0,         1.0) for a browser. A trigger maps linearly from this onto [0, 1].

Raises: ValueError: If a name is missing or unknown, or if either range is degenerate.

simvx.core.input.gamepad.out_of_range_axes(axes: collections.abc.Mapping[str, float]) list[str][source]

Names whose value breaks the convention, for a caller that wants to warn.

This is the guard on the seam rather than the fix: a value that arrives here already out of range has lost the provenance needed to correct it, so the caller can only report which backend is lying.