Turns game-controller events into the set of actions a player is holding.
A game declares a padmap from action to controls, in the Xbox layout whatever the
hardware, as Gamepad.Wire names them:
padmap = %{left: [:dpad_left, {:axis, :left_x, :neg}], fire: [:a, :right_bumper]}
pad = Cauldron2D.Input.Pad.new(padmap, deadzone: 0.3)Feed it every {:controller, event} map with handle/2; held/1 is the set of
actions held and strength/1 how hard each axis-driven one is pushed. Hand both to
Cauldron2D.Input.merge/3.
A control is a button name (:a, :b, :x, :y, :left_bumper, :right_bumper,
:back, :start, :guide, :left_stick, :right_stick, :dpad_up, :dpad_down,
:dpad_left, :dpad_right) or {:axis, name, :neg | :pos} for one direction of
:left_x, :left_y, :right_x, :right_y, :left_trigger or :right_trigger.
Axis values run -1.0..1.0, up and left negative; a trigger runs 0.0..1.0.
A button holds its action in full. An axis holds it at its magnitude once past
:deadzone. An action held by both is held in full. Every controller's controls
count, and a controller that goes away releases what it held.
A stick may aim instead of holding actions: the padmap's :aim bound to
{:stick, :left} or {:stick, :right} makes aim/1 the direction that stick is
pushed in, {dx, dy} of length one (up and left negative), or nil inside the
deadzone, measured radially; a client turns it into an aim point a fixed way from
the focus, as an on-screen thumbstick does. :aim holds no action of its own, but
the stick may push one: {:stick, :left, push: [action: :thrust, beyond: 0.6, least: 0.3, gain: 1.4]} holds :thrust while the stick is past beyond of its
travel, at a strength that starts at least and grows by gain over the rest of the
travel to 1.0 — the rule an on-screen thumbstick's push follows. Defaults:
beyond: 0.5, least: 0.25, gain: 1.6.
Summary
Functions
Where the aim stick points: a direction of length one, or nil with no aim stick or inside the deadzone.
The stick bound to :aim, or nil.
Where axis stands now, -1.0..1.0 (0.0..1.0 for a trigger): the reading furthest
from centre over every controller, or 0.0 while none is past the deadzone.
Whether the padmap binds either direction of axis to an action.
The padmap for actions that steers with the d-pad and the left stick.
Apply one controller event.
The actions held by any controller.
A pad reading padmap.
What the aim stick pushes when pushed far, or nil.
How hard each action held only through an axis is pushed, 0.0..1.0.
Types
@type padmap() :: %{required(Cauldron2D.Input.action()) => [control()]}
@type push() :: %{ action: Cauldron2D.Input.action(), beyond: float(), least: float(), gain: float() }
@type t() :: %Cauldron2D.Input.Pad{ aim_stick: :left | :right | nil, axes: %{required({non_neg_integer(), atom()}) => float()}, bindings: %{required(control()) => [Cauldron2D.Input.action()]}, buttons: %{required({non_neg_integer(), atom()}) => true}, deadzone: float(), push: push() | nil, sticks: %{required({non_neg_integer(), atom()}) => float()} }
Functions
Where the aim stick points: a direction of length one, or nil with no aim stick or inside the deadzone.
@spec aim_stick(t()) :: :left | :right | nil
The stick bound to :aim, or nil.
Where axis stands now, -1.0..1.0 (0.0..1.0 for a trigger): the reading furthest
from centre over every controller, or 0.0 while none is past the deadzone.
Whether the padmap binds either direction of axis to an action.
@spec default_map([Cauldron2D.Input.action()]) :: padmap()
The padmap for actions that steers with the d-pad and the left stick.
Of the actions given, :left, :right, :up and :down are bound to the matching
d-pad button and direction of the left stick; the rest are left unbound.
Apply one controller event.
@spec held(t()) :: MapSet.t(Cauldron2D.Input.action())
The actions held by any controller.
A pad reading padmap.
Options
:deadzone— the axis magnitude below which an axis holds nothing. Default0.3
What the aim stick pushes when pushed far, or nil.
@spec strength(t()) :: %{required(Cauldron2D.Input.action()) => float()}
How hard each action held only through an axis is pushed, 0.0..1.0.
An action a button holds is held in full and has no entry.