gamepad
gamepad · utilityConnected USB / Bluetooth game controller as CV (stick axes + triggers) and gate (face / bumper / dpad / menu buttons). Reads navigator.getGamepads() at requestAnimationFrame rate. Browser security requires the user to press a button on the gamepad once before the browser exposes it. Outputs: lx / ly / rx / ry (cv ±1, Y inverted so +1 = up, 0.08 deadzone), ax / ay (cv ±1 — the AUX stick, a third X/Y pair that ships bound to NOTHING and reads a hard 0 until you bind it, for the axes a flight stick has and a gamepad does not: a twist/rudder, a throttle lever, a slider), lt / rt (cv 0..1), lb / rb / a / b / x / y / du / dd / dl / dr / start / back (gate). Standard mapping = Xbox layout; PlayStation + generic HID controllers that report 'standard' mapping also work. SLOT param picks which of up to 4 simultaneous controllers to read; it is the module's only param, and it is the one ranked cell on the faceplate — everything else a player configures lives on the dock's MAPPING BOARD. REMAP: right-click ANY cell on the board — a button LED, a trigger row, or an X / Y button under a stick — to arm a listener, then move the physical control you want bound to that output; alt-click resets a cell. (The axis buttons used to arm on LEFT-click and RESET on right-click, the inverse of every other cell, so right-clicking the one you wanted to bind silently cleared it instead of listening.) The Gamepad API has no events, so the armed listener diffs each poll against the reading captured when you armed it and takes the first control past a 0.5 threshold; Escape cancels. STICK CALIBRATION, on BOTH sticks independently: "calibrate left/right" arms a sweep mode — move that stick through its full range several times (the board draws the swept extent as a box inside the stick pad, which fills as you go), then "complete" locks the swept range in so observed-min→full-min and observed-max→full-max per axis, with a captured true rest centre mapped to 0 and a radial deadzone around it (no snap-back drift). A separate per-stick "set center" captures that rest centre on its own, for a stick that physically rests off-centre. INVERT: a per-axis sign flip on every stick axis (lx / ly / rx / ry / ax / ay) that composes on top of any remap. Each of these is persisted once to the patch (rides collab + undo); "clear" reverts a stick to the fixed-deadzone path. SAVE / LOAD MAPPING bundles every binding, both calibrations and every invert into a .json you can reload or share, and built-in presets ship for the NXT Gladiator and for the Gladiator EVO R (whose TWIST is physical axis 5, a full-range bipolar axis, routed to the AUX X output). Presets are OFFERED in the picker and never auto-applied on a device-id match. This is what makes worn pads and non-Xbox-layout sticks (e.g. VKB Gladiator NXT flight sticks, which report a non-standard mapping with a reduced raw range) reach the full ±1 output range.
the faceplate
outputs
| id | cable | what it does |
|---|---|---|
lx | cv | Left stick X as bipolar CV, −1 (left) through 0 (center) to +1 (right), after a small deadzone and re-normalization (and the left-stick calibration if you've run it). control voltage (CV) |
ly | cv | Left stick Y as bipolar CV, −1 (down) through 0 to +1 (up) — the axis is flipped so pushing up reads positive — with the same deadzone/calibration treatment as LX. control voltage (CV) |
rx | cv | Right stick X as bipolar CV, −1 (left) to +1 (right), with the stick deadzone applied. control voltage (CV) |
ry | cv | Right stick Y as bipolar CV, −1 (down) to +1 (up), Y flipped, with the stick deadzone applied. control voltage (CV) |
ax | cv | Aux stick X as bipolar CV, −1 to +1, with the stick deadzone applied. The aux pair is the THIRD X/Y set, and unlike every other output it starts life bound to NOTHING — a flight stick's twist, rudder or throttle lever has no standard-mapping index to default to, so until you bind it (from the mapping board, or by loading a preset) this jack reads exactly 0 rather than guessing at a physical axis. Load the 'Gladiator EVO R (twist → AUX X)' preset and this becomes the stick's twist. control voltage (CV) |
ay | cv | Aux stick Y as bipolar CV, −1 to +1, with the stick deadzone applied — the aux pair's second axis, for a second unmapped control such as a throttle lever or a slider. Like AX it is unbound by default and reads exactly 0 until you bind something to it; an unbound jack is silent, never the resting value of some default axis. control voltage (CV) |
lt | cv | Left trigger as unipolar CV, 0 fully released to +1 fully pressed — its analog travel, useful as a swell or VCA ride. control voltage (CV) |
rt | cv | Right trigger as unipolar CV, 0 released to +1 pressed. control voltage (CV) |
lb | gate | Left bumper as a gate: 1 while the button is held, 0 when released. gate / trigger; gate — acts while the level is high (reacts to both edges) |
rb | gate | Right bumper as a gate: 1 while held, 0 when released. gate / trigger; gate — acts while the level is high (reacts to both edges) |
a | gate | The A face button as a gate: 1 while held, 0 when released — patch it into a strike or scene trigger. gate / trigger; gate — acts while the level is high (reacts to both edges) |
b | gate | The B face button as a gate: 1 while held, 0 when released. gate / trigger; gate — acts while the level is high (reacts to both edges) |
x | gate | The X face button as a gate: 1 while held, 0 when released. gate / trigger; gate — acts while the level is high (reacts to both edges) |
y | gate | The Y face button as a gate: 1 while held, 0 when released. gate / trigger; gate — acts while the level is high (reacts to both edges) |
du | gate | D-pad up as a gate: 1 while held, 0 when released. gate / trigger; gate — acts while the level is high (reacts to both edges) |
dd | gate | D-pad down as a gate: 1 while held, 0 when released. gate / trigger; gate — acts while the level is high (reacts to both edges) |
dl | gate | D-pad left as a gate: 1 while held, 0 when released. gate / trigger; gate — acts while the level is high (reacts to both edges) |
dr | gate | D-pad right as a gate: 1 while held, 0 when released. gate / trigger; gate — acts while the level is high (reacts to both edges) |
start | gate | The Start button as a gate: 1 while held, 0 when released. gate / trigger; gate — acts while the level is high (reacts to both edges) |
back | gate | The Back / Select button as a gate: 1 while held, 0 when released. gate / trigger; gate — acts while the level is high (reacts to both edges) |
controls
| control | what it does |
|---|---|
| PadIndex | Which controller slot to read, 0 to 3 (the Web Gamepad spec allows up to four pads at once). 0 is the first connected controller; raise it to read a second or third pad in a multi-controller setup. |
source
gamepad.ts on GitHub.