@rydr/game-sdk 7.0.0 → 7.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. package/README.md +19 -0
  2. package/dist/protocol/glyphs.d.ts +7 -0
  3. package/dist/protocol/glyphs.d.ts.map +1 -1
  4. package/dist/protocol/glyphs.js +26 -0
  5. package/dist/protocol/glyphs.js.map +1 -1
  6. package/dist/protocol/version.d.ts +1 -1
  7. package/dist/protocol/version.js +1 -1
  8. package/dist/three/perf-overlay.d.ts +52 -2
  9. package/dist/three/perf-overlay.d.ts.map +1 -1
  10. package/dist/three/perf-overlay.js +188 -3
  11. package/dist/three/perf-overlay.js.map +1 -1
  12. package/dist/ui/README.md +119 -0
  13. package/dist/ui/controller/combo-demo.d.ts +74 -0
  14. package/dist/ui/controller/combo-demo.d.ts.map +1 -0
  15. package/dist/ui/controller/combo-demo.js +295 -0
  16. package/dist/ui/controller/combo-demo.js.map +1 -0
  17. package/dist/ui/controller/combo-strip.d.ts +36 -0
  18. package/dist/ui/controller/combo-strip.d.ts.map +1 -0
  19. package/dist/ui/controller/combo-strip.js +66 -0
  20. package/dist/ui/controller/combo-strip.js.map +1 -0
  21. package/dist/ui/controller/control-trainer.d.ts +132 -0
  22. package/dist/ui/controller/control-trainer.d.ts.map +1 -0
  23. package/dist/ui/controller/control-trainer.js +570 -0
  24. package/dist/ui/controller/control-trainer.js.map +1 -0
  25. package/dist/ui/controller/controller-map.d.ts +82 -0
  26. package/dist/ui/controller/controller-map.d.ts.map +1 -0
  27. package/dist/ui/controller/controller-map.js +291 -0
  28. package/dist/ui/controller/controller-map.js.map +1 -0
  29. package/dist/ui/controller/controller-pad.d.ts +122 -0
  30. package/dist/ui/controller/controller-pad.d.ts.map +1 -0
  31. package/dist/ui/controller/controller-pad.js +200 -0
  32. package/dist/ui/controller/controller-pad.js.map +1 -0
  33. package/dist/ui/controller/index.d.ts +26 -0
  34. package/dist/ui/controller/index.d.ts.map +1 -0
  35. package/dist/ui/controller/index.js +26 -0
  36. package/dist/ui/controller/index.js.map +1 -0
  37. package/dist/ui/controller/input-chip.d.ts +100 -0
  38. package/dist/ui/controller/input-chip.d.ts.map +1 -0
  39. package/dist/ui/controller/input-chip.js +322 -0
  40. package/dist/ui/controller/input-chip.js.map +1 -0
  41. package/dist/ui/controller/layouts/dualsense.d.ts +12 -0
  42. package/dist/ui/controller/layouts/dualsense.d.ts.map +1 -0
  43. package/dist/ui/controller/layouts/dualsense.js +64 -0
  44. package/dist/ui/controller/layouts/dualsense.js.map +1 -0
  45. package/dist/ui/controller/layouts/index.d.ts +20 -0
  46. package/dist/ui/controller/layouts/index.d.ts.map +1 -0
  47. package/dist/ui/controller/layouts/index.js +34 -0
  48. package/dist/ui/controller/layouts/index.js.map +1 -0
  49. package/dist/ui/controller/layouts/joycon.d.ts +21 -0
  50. package/dist/ui/controller/layouts/joycon.d.ts.map +1 -0
  51. package/dist/ui/controller/layouts/joycon.js +76 -0
  52. package/dist/ui/controller/layouts/joycon.js.map +1 -0
  53. package/dist/ui/controller/layouts/switch-pro.d.ts +12 -0
  54. package/dist/ui/controller/layouts/switch-pro.d.ts.map +1 -0
  55. package/dist/ui/controller/layouts/switch-pro.js +60 -0
  56. package/dist/ui/controller/layouts/switch-pro.js.map +1 -0
  57. package/dist/ui/controller/layouts/xbox.d.ts +11 -0
  58. package/dist/ui/controller/layouts/xbox.d.ts.map +1 -0
  59. package/dist/ui/controller/layouts/xbox.js +59 -0
  60. package/dist/ui/controller/layouts/xbox.js.map +1 -0
  61. package/dist/ui/controller/layouts/zwift.d.ts +27 -0
  62. package/dist/ui/controller/layouts/zwift.d.ts.map +1 -0
  63. package/dist/ui/controller/layouts/zwift.js +62 -0
  64. package/dist/ui/controller/layouts/zwift.js.map +1 -0
  65. package/dist/ui/controller/pad-svg.d.ts +105 -0
  66. package/dist/ui/controller/pad-svg.d.ts.map +1 -0
  67. package/dist/ui/controller/pad-svg.js +289 -0
  68. package/dist/ui/controller/pad-svg.js.map +1 -0
  69. package/dist/ui/controller/parts-map.d.ts +96 -0
  70. package/dist/ui/controller/parts-map.d.ts.map +1 -0
  71. package/dist/ui/controller/parts-map.js +187 -0
  72. package/dist/ui/controller/parts-map.js.map +1 -0
  73. package/dist/ui/controller/styles.d.ts +19 -0
  74. package/dist/ui/controller/styles.d.ts.map +1 -0
  75. package/dist/ui/controller/styles.js +364 -0
  76. package/dist/ui/controller/styles.js.map +1 -0
  77. package/dist/ui/controller/tokens.d.ts +106 -0
  78. package/dist/ui/controller/tokens.d.ts.map +1 -0
  79. package/dist/ui/controller/tokens.js +50 -0
  80. package/dist/ui/controller/tokens.js.map +1 -0
  81. package/dist/ui/controller/types.d.ts +157 -0
  82. package/dist/ui/controller/types.d.ts.map +1 -0
  83. package/dist/ui/controller/types.js +61 -0
  84. package/dist/ui/controller/types.js.map +1 -0
  85. package/dist/ui/index.d.ts +8 -0
  86. package/dist/ui/index.d.ts.map +1 -1
  87. package/dist/ui/index.js +8 -0
  88. package/dist/ui/index.js.map +1 -1
  89. package/dist/ui/keycap.d.ts +14 -0
  90. package/dist/ui/keycap.d.ts.map +1 -1
  91. package/dist/ui/keycap.js +5 -0
  92. package/dist/ui/keycap.js.map +1 -1
  93. package/dist/ui/showcase/gallery.d.ts +13 -1
  94. package/dist/ui/showcase/gallery.d.ts.map +1 -1
  95. package/dist/ui/showcase/gallery.js.map +1 -1
  96. package/dist/ui/showcase/index.d.ts.map +1 -1
  97. package/dist/ui/showcase/index.js +257 -1
  98. package/dist/ui/showcase/index.js.map +1 -1
  99. package/package.json +1 -1
@@ -0,0 +1,289 @@
1
+ /**
2
+ * The one SVG renderer for every controller silhouette, plus the animation layer that drives it.
3
+ *
4
+ * `buildPadSvg` emits nodes and hands back the node caches directly — `parts`, `sticks`, `meters`. That
5
+ * is the ONLY coupling between the drawing and whatever animates it: nothing ever re-renders the SVG
6
+ * per frame; a driver mutates classes and attributes on cached nodes. (The platform's Lit version had
7
+ * to re-scan the shadow root with `querySelectorAll` after each render to rebuild these maps; building
8
+ * them as we go is strictly less machinery.)
9
+ *
10
+ * `createPadDriver` is that animation layer. It keeps a `lastVal` dirty-guard so an **idle pad costs
11
+ * zero DOM writes** even when polled at 60 Hz — that guard is not an optimisation to trim, it's the
12
+ * reason this is cheap enough to run beside a game loop.
13
+ *
14
+ * Both are input-agnostic: they know about positions (`PadPart`), never about `ButtonName`s, key codes
15
+ * or gamepad indices. `controller-pad.ts` owns the translation from canonical input to positions.
16
+ */
17
+ import { partCentre } from "./types.js";
18
+ const NS = "http://www.w3.org/2000/svg";
19
+ /**
20
+ * Parts a game can never bind, so the drawing must never light them.
21
+ *
22
+ * The bumpers are the rider's resistance − / + and `select`/`home` are the shell's own menu and guide —
23
+ * all four are handled by the shell and are never delivered to a game (see `protocol/buttons.ts` on
24
+ * the shell-owned keys). They are still DRAWN, faintly, because a rider needs to tell "this game
25
+ * doesn't use that button" apart from "that button isn't the game's to use".
26
+ *
27
+ * `setPart` refuses them outright rather than trusting callers: today no `ButtonName` maps here, and
28
+ * enforcing it in the driver keeps that true if someone later adds one by mistake.
29
+ */
30
+ export const SHELL_OWNED_PARTS = new Set(["lb", "rb", "select", "home"]);
31
+ /** Below this, a stick move is sub-pixel at every render size — skip the DOM write entirely. */
32
+ const STICK_EPSILON = 0.02;
33
+ /** Past this deflection the stick glows like a pressed button. Matches the shell's feel. */
34
+ export const STICK_LIT_DEADZONE = 0.18;
35
+ function el(tag, attrs, className) {
36
+ const node = document.createElementNS(NS, tag);
37
+ if (className)
38
+ node.setAttribute("class", className);
39
+ if (attrs)
40
+ for (const [k, v] of Object.entries(attrs))
41
+ node.setAttribute(k, String(v));
42
+ return node;
43
+ }
44
+ function geomEl(g, className) {
45
+ switch (g.kind) {
46
+ case "circle":
47
+ return el("circle", { cx: g.cx, cy: g.cy, r: g.r }, className);
48
+ case "rect":
49
+ return el("rect", { x: g.x, y: g.y, width: g.w, height: g.h, rx: g.rx ?? 2 }, className);
50
+ case "path":
51
+ return el("path", { d: g.d }, className);
52
+ }
53
+ }
54
+ function titled(parent, text) {
55
+ const t = el("title");
56
+ t.textContent = text;
57
+ parent.appendChild(t);
58
+ }
59
+ /**
60
+ * How far a pressed control travels, in viewBox units, and equally how far its shadow sits below it at
61
+ * rest. One number for both, because the effect only reads if the face lands exactly ON its own shadow.
62
+ */
63
+ export const PRESS_DEPTH = 1.4;
64
+ /**
65
+ * One highlightable part: a `<g data-part>` holding a fixed drop shadow and a `.rydr-pad-face` group
66
+ * (shape + glyph) that sinks onto it when pressed.
67
+ *
68
+ * The shadow is what makes a press read as *down* rather than merely *coloured*. A recolour alone says
69
+ * "this one is involved"; a face that drops onto its own shadow says "this one is held". Same trick as
70
+ * the kit's keycaps, which raise on a `box-shadow` and sink by the same distance — this is the SVG
71
+ * equivalent, since an SVG shape can't take one.
72
+ *
73
+ * The face is a GROUP so the glyph travels with the button; a shape that moved while its letter stayed
74
+ * put would look broken rather than pressed.
75
+ */
76
+ function buildPart(name, spec, showGlyph, smallGlyph = false) {
77
+ const g = el("g", { "data-part": name }, "rydr-pad-part" + (SHELL_OWNED_PARTS.has(name) ? " shell-owned" : ""));
78
+ titled(g, spec.label);
79
+ const shadow = geomEl(spec.geom, "rydr-pad-shadow");
80
+ shadow.setAttribute("transform", `translate(0 ${PRESS_DEPTH})`);
81
+ g.appendChild(shadow);
82
+ const face = el("g", {}, "rydr-pad-face");
83
+ face.appendChild(geomEl(spec.geom, "rydr-pad-shape"));
84
+ if (showGlyph) {
85
+ const c = partCentre(spec.geom);
86
+ if (spec.glyphPath) {
87
+ // Vector glyph (PlayStation's ✕ ◯ ▢ △), drawn centred on (0,0) then translated onto the part.
88
+ face.appendChild(el("path", { d: spec.glyphPath, transform: `translate(${c.x} ${c.y})` }, "rydr-pad-glyph-vec"));
89
+ }
90
+ else if (spec.glyph) {
91
+ const t = el("text", { x: c.x, y: c.y }, "rydr-pad-glyph" + (smallGlyph ? " sm" : ""));
92
+ t.textContent = spec.glyph;
93
+ face.appendChild(t);
94
+ }
95
+ }
96
+ g.appendChild(face);
97
+ return { g, face };
98
+ }
99
+ /** A trigger: the same part shape, plus a meter rect that fills bottom-up as travel goes 0 → 1. */
100
+ function buildTrigger(name, spec, side, showGlyph) {
101
+ const { g, face } = buildPart(name, spec, false);
102
+ const m = spec.meter;
103
+ // Starts empty: y at the BOTTOM of the band with zero height, so growth reads upward. It lives in the
104
+ // face group so the fill travels down with the trigger instead of hovering where the trigger used to be.
105
+ const meter = el("rect", { "data-meter": side, x: m.x, y: m.y + m.h, width: m.w, height: 0, rx: m.rx ?? 2 }, "rydr-pad-meter");
106
+ face.appendChild(meter);
107
+ if (showGlyph) {
108
+ const c = partCentre(spec.geom);
109
+ const t = el("text", { x: c.x, y: c.y }, "rydr-pad-glyph sm");
110
+ t.textContent = spec.glyph;
111
+ face.appendChild(t);
112
+ }
113
+ return { g, meter };
114
+ }
115
+ /**
116
+ * Build the drawing for `layout`.
117
+ *
118
+ * Draw order matters and matches the shell's: body → decor → triggers → bumpers → d-pad → face →
119
+ * system → sticks. Sticks come last so a deflected cap draws over the shell rather than under it.
120
+ */
121
+ export function buildPadSvg(layout, opts = {}) {
122
+ const labels = opts.labels ?? true;
123
+ const [minX, minY, w, h] = layout.viewBox;
124
+ const svg = el("svg", {
125
+ viewBox: `${minX} ${minY} ${w} ${h}`,
126
+ preserveAspectRatio: "xMidYMid meet",
127
+ role: "img",
128
+ "aria-label": `${layout.displayName} — button map`,
129
+ });
130
+ const parts = new Map();
131
+ const sticks = {};
132
+ const meters = {};
133
+ const add = (name, spec, showGlyph, smallGlyph = false) => {
134
+ const { g } = buildPart(name, spec, showGlyph, smallGlyph);
135
+ parts.set(name, g);
136
+ svg.appendChild(g);
137
+ };
138
+ svg.appendChild(el("path", { d: layout.body.d }, "rydr-pad-body"));
139
+ for (const d of layout.decor ?? []) {
140
+ const g = el("g", d.opacity != null ? { opacity: d.opacity } : {}, "rydr-pad-decor");
141
+ g.appendChild(geomEl(d.geom, "rydr-pad-shape"));
142
+ svg.appendChild(g);
143
+ }
144
+ if (layout.triggers) {
145
+ for (const [side, name] of [["l", "lt"], ["r", "rt"]]) {
146
+ const spec = side === "l" ? layout.triggers.l : layout.triggers.r;
147
+ const { g, meter } = buildTrigger(name, spec, side, labels);
148
+ parts.set(name, g);
149
+ meters[side] = meter;
150
+ svg.appendChild(g);
151
+ }
152
+ }
153
+ if (layout.bumpers) {
154
+ add("lb", layout.bumpers.l, labels);
155
+ add("rb", layout.bumpers.r, labels);
156
+ }
157
+ if (layout.dpad) {
158
+ // The d-pad never carries a glyph: the arrows are the same on every pad and the arms are too
159
+ // small to letter legibly at this scale.
160
+ add("dpadUp", layout.dpad.up, false);
161
+ add("dpadDown", layout.dpad.down, false);
162
+ add("dpadLeft", layout.dpad.left, false);
163
+ add("dpadRight", layout.dpad.right, false);
164
+ }
165
+ add("faceTop", layout.face.top, labels);
166
+ add("faceRight", layout.face.right, labels);
167
+ add("faceBottom", layout.face.bottom, labels);
168
+ add("faceLeft", layout.face.left, labels);
169
+ if (layout.system?.select)
170
+ add("select", layout.system.select, labels, true);
171
+ if (layout.system?.start)
172
+ add("start", layout.system.start, labels, true);
173
+ if (layout.system?.home)
174
+ add("home", layout.system.home, false);
175
+ if (layout.sticks) {
176
+ for (const [side, pressPart] of [["l", "lstickPress"], ["r", "rstickPress"]]) {
177
+ const spec = side === "l" ? layout.sticks.l : layout.sticks.r;
178
+ const group = el("g", {}, "rydr-pad-stickgrp");
179
+ titled(group, spec.label);
180
+ group.appendChild(el("circle", { cx: spec.cx, cy: spec.cy, r: spec.well }, "rydr-pad-well"));
181
+ // ONE group carries both the translate and `.deflected`. The `[data-part]` node inside it is the
182
+ // stick CLICK, whose `.on` class `setPart` owns — two writers on one class would fight.
183
+ const moving = el("g", { "data-stick": side, transform: "translate(0 0)" }, "rydr-pad-stick");
184
+ // Same shadow-and-face pairing as a button, so CLICKING the stick reads as pressing it down —
185
+ // distinct from deflecting it, which is the outer group's translate.
186
+ const press = el("g", { "data-part": pressPart }, "rydr-pad-part");
187
+ press.appendChild(el("circle", { cx: spec.cx, cy: spec.cy + PRESS_DEPTH, r: spec.cap }, "rydr-pad-shadow"));
188
+ const capFace = el("g", {}, "rydr-pad-face");
189
+ capFace.appendChild(el("circle", { cx: spec.cx, cy: spec.cy, r: spec.cap }, "rydr-pad-shape"));
190
+ press.appendChild(capFace);
191
+ moving.appendChild(press);
192
+ group.appendChild(moving);
193
+ svg.appendChild(group);
194
+ parts.set(pressPart, press);
195
+ sticks[side] = moving;
196
+ }
197
+ }
198
+ return { svg, parts, sticks, meters };
199
+ }
200
+ export function createPadDriver(pad, layout, opts = {}) {
201
+ /** Dirty-guard: last value written per key, so an unchanged frame does no DOM work at all. */
202
+ const lastVal = new Map();
203
+ /** Numeric codes, because `lastVal` is a number map (it also holds stick offsets). */
204
+ const STATE_CODE = { off: 0, on: 1, hint: 2, done: 3 };
205
+ const setPartState = (part, state) => {
206
+ if (SHELL_OWNED_PARTS.has(part) && !opts.allowShellOwned)
207
+ return;
208
+ const code = STATE_CODE[state];
209
+ if (lastVal.get(part) === code)
210
+ return;
211
+ lastVal.set(part, code);
212
+ const node = pad.parts.get(part);
213
+ if (!node)
214
+ return;
215
+ node.classList.toggle("on", state === "on");
216
+ node.classList.toggle("hint", state === "hint");
217
+ node.classList.toggle("done", state === "done");
218
+ };
219
+ const setPart = (part, on) => setPartState(part, on ? "on" : "off");
220
+ const setStick = (side, x, y, lit = "auto") => {
221
+ const node = pad.sticks[side];
222
+ if (!node)
223
+ return; // this layout has no stick on that side (Zwift Play has neither)
224
+ // Lit state FIRST, and outside the epsilon guard below: a stick released in a single frame must
225
+ // still stop glowing even though the move itself is too small to redraw.
226
+ const litKey = `${side}lit`;
227
+ const resolved = lit === "auto" ? (Math.hypot(x, y) > STICK_LIT_DEADZONE ? "on" : "off") : lit;
228
+ const code = resolved === "on" ? 1 : resolved === "hint" ? 2 : 0;
229
+ if (lastVal.get(litKey) !== code) {
230
+ lastVal.set(litKey, code);
231
+ node.classList.toggle("deflected", resolved === "on");
232
+ node.classList.toggle("hint", resolved === "hint");
233
+ }
234
+ const travel = (side === "l" ? layout.sticks?.l : layout.sticks?.r)?.travel ?? 0;
235
+ const dx = x * travel;
236
+ // NEGATED, and this is the one line that differs from the shell. The shell feeds raw W3C axes,
237
+ // where stick-DOWN is +1 — the same direction SVG's y grows — so it deliberately does not invert.
238
+ // The SDK's AxisName convention is up = +1 (see protocol/buttons.ts), so here we must.
239
+ const dy = -y * travel;
240
+ const lastX = lastVal.get(`${side}x`) ?? 0;
241
+ const lastY = lastVal.get(`${side}y`) ?? 0;
242
+ if (Math.abs(dx - lastX) < STICK_EPSILON && Math.abs(dy - lastY) < STICK_EPSILON)
243
+ return;
244
+ lastVal.set(`${side}x`, dx);
245
+ lastVal.set(`${side}y`, dy);
246
+ node.setAttribute("transform", `translate(${dx.toFixed(2)} ${dy.toFixed(2)})`);
247
+ };
248
+ const setMeter = (side, v01) => {
249
+ const node = pad.meters[side];
250
+ if (!node)
251
+ return;
252
+ const v = Math.max(0, Math.min(1, v01));
253
+ const key = `${side}m`;
254
+ if (Math.abs((lastVal.get(key) ?? 0) - v) < 0.01)
255
+ return;
256
+ lastVal.set(key, v);
257
+ const m = (side === "l" ? layout.triggers?.l : layout.triggers?.r)?.meter;
258
+ if (!m)
259
+ return;
260
+ const filled = m.h * v;
261
+ node.setAttribute("y", String(m.y + m.h - filled));
262
+ node.setAttribute("height", String(filled));
263
+ };
264
+ return {
265
+ setPart,
266
+ setPartState,
267
+ setStick,
268
+ setMeter,
269
+ setAvailable(available) {
270
+ for (const [name, node] of pad.parts) {
271
+ const dim = available != null && !available.includes(name) && !SHELL_OWNED_PARTS.has(name);
272
+ node.classList.toggle("unavailable", dim);
273
+ }
274
+ },
275
+ clearAll() {
276
+ for (const [name, node] of pad.parts) {
277
+ node.classList.remove("on", "hint", "done");
278
+ lastVal.set(name, 0);
279
+ }
280
+ for (const side of ["l", "r"]) {
281
+ pad.sticks[side]?.classList.remove("deflected", "hint");
282
+ lastVal.delete(`${side}lit`);
283
+ setStick(side, 0, 0, "off");
284
+ setMeter(side, 0);
285
+ }
286
+ },
287
+ };
288
+ }
289
+ //# sourceMappingURL=pad-svg.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pad-svg.js","sourceRoot":"","sources":["../../../src/ui/controller/pad-svg.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,96 @@
1
+ /**
2
+ * Canonical input → drawn position. This module is where "the game said `DIAMOND_DOWN`" becomes "light
3
+ * the bottom face button", and it is the reason one action list draws correctly on every controller.
4
+ *
5
+ * **It maps to POSITIONS, never to letters.** `DIAMOND_DOWN` → `faceBottom` on every pad; each layout
6
+ * places `faceBottom` where that brand actually puts it, and `buttonLabel()` supplies the letter printed
7
+ * on it. So a Switch Pro (which prints `A` on the RIGHT button and `B` on the bottom) still highlights
8
+ * the bottom button for confirm — only the lettering shifts. Getting that backwards is the single most
9
+ * likely way a controller diagram lies to a rider.
10
+ *
11
+ * There are deliberately TWO lookups, because "which part lights up" and "which part a callout line
12
+ * points at" are not the same question — see {@link litPartOfButton} and {@link anchorPartOfToken}.
13
+ */
14
+ import type { ButtonName } from "../../protocol/buttons.js";
15
+ import { type ComboToken, type ControlAction, type ControlName, type ShellControl } from "./tokens.js";
16
+ import { type PadLayout, type PadPart, type PartGeom } from "./types.js";
17
+ /**
18
+ * Which part to LIGHT when a button is held.
19
+ *
20
+ * Partial on purpose: the right stick's digital directions (`RUP`/`RDOWN`/`RLEFT`/`RRIGHT`) map to
21
+ * nothing here. Lighting the stick's *click* for a *direction* would be a lie, and the truthful visual
22
+ * already exists — the cap physically moves, driven by the `RX`/`RY` axes, which the platform emits for
23
+ * every controller (quantized to the endpoints on non-hall hardware, and synthesized from the numpad on
24
+ * a keyboard). So a right-stick direction shows up as deflection, not as a highlight.
25
+ *
26
+ * `OPTIONS` lands on `start`, the button labelled "Options" on a DualSense and "Menu" on an Xbox pad —
27
+ * the game's own menu button. The shell's overlay menu is a different key and never reaches a game.
28
+ */
29
+ export declare const LIT_PART_OF_BUTTON: Readonly<Partial<Record<ButtonName, PadPart>>>;
30
+ /**
31
+ * The shell-owned controls, which have no {@link ButtonName} but do have a place on the drawing: the
32
+ * upper shoulders ARE the rider's resistance − / +.
33
+ *
34
+ * Kept separate from {@link LIT_PART_OF_BUTTON} so that nothing which walks the game vocabulary can
35
+ * accidentally light them — a game never receives these, and the drawing renders them faint by default
36
+ * (see `SHELL_OWNED_PARTS`). Only an explicit opt-in lets them light, which is exactly what a lesson
37
+ * teaching the rider where they are needs.
38
+ */
39
+ export declare const PART_OF_SHELL_CONTROL: Readonly<Record<ShellControl, PadPart>>;
40
+ export declare function litPartOfButton(name: ButtonName): PadPart | undefined;
41
+ /** The part to light for any control — game button or shell-owned. */
42
+ export declare function litPartOfControl(name: ControlName): PadPart | undefined;
43
+ /** The four canonical directions the LEFT stick shares with the d-pad, and their axis signs. */
44
+ export declare const DPAD_DIRECTIONS: Readonly<Record<"UP" | "DOWN" | "LEFT" | "RIGHT", readonly [number, number]>>;
45
+ /**
46
+ * Which part a callout LINE should point at.
47
+ *
48
+ * Differs from {@link litPartOfButton} in exactly one way: a right-stick direction (or a bare stick
49
+ * token) resolves to that stick, because "this action uses the right stick" is precisely what the line
50
+ * should be saying — even though a *direction* shouldn't light the stick's click.
51
+ */
52
+ export declare function anchorPartOfToken(token: ComboToken): PadPart | undefined;
53
+ /**
54
+ * The movement controls that many actions share, so a callout line to one of them says nothing useful.
55
+ *
56
+ * Both sticks (whole or directional), both stick clicks, the d-pad, and the right-stick directions. In a
57
+ * game where the left stick steers, half the actions mention it; anchoring all their lines there makes a
58
+ * hairball around one part, while the distinctive button in each combination is what actually identifies
59
+ * the action.
60
+ */
61
+ export declare function isGenericToken(token: ComboToken): boolean;
62
+ /**
63
+ * Which token the callout line points at: **the first non-generic token**, falling back to the first
64
+ * token when every one of them is generic.
65
+ *
66
+ * ["LSTICK_PRESS", "LT"] → LT (the distinctive button, not the shared stick)
67
+ * ["LSTICK:left", "RT"] → RT
68
+ * ["LT", "DIAMOND_DOWN"] → LT (first, since neither is generic)
69
+ * ["LSTICK"] → LSTICK (all generic → the first, so "Move" points at the stick)
70
+ * ["DIAMOND_DOWN"] → DIAMOND_DOWN
71
+ *
72
+ * `action.anchor` overrides this outright, so the rule is a sensible default rather than a ceiling.
73
+ */
74
+ export declare function anchorTokenOf(action: ControlAction): ComboToken | undefined;
75
+ /**
76
+ * The geometry of a drawn part in a given layout, or `undefined` when that layout has no such part (a
77
+ * Zwift pod has no sticks, no triggers and no system buttons).
78
+ *
79
+ * Stick clicks are synthesised from the {@link StickSpec} — the cap circle — since they have no
80
+ * `PartSpec` of their own.
81
+ */
82
+ export declare function partGeomOf(layout: PadLayout, part: PadPart): PartGeom | undefined;
83
+ /** Where a part sits in the layout's own viewBox units, for ordering and side placement. */
84
+ export declare function partCentreOf(layout: PadLayout, part: PadPart): {
85
+ x: number;
86
+ y: number;
87
+ } | undefined;
88
+ /**
89
+ * Which column a callout belongs in: the side of the pad its anchor is physically on.
90
+ *
91
+ * Derived from the layout rather than hardcoded per brand, so it stays right across four very different
92
+ * control arrangements — Xbox's diagonal offset, DualSense's symmetric sticks, and the two-pod shapes —
93
+ * and for any layout added later.
94
+ */
95
+ export declare function sideOfPart(layout: PadLayout, part: PadPart): "left" | "right";
96
+ //# sourceMappingURL=parts-map.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parts-map.d.ts","sourceRoot":"","sources":["../../../src/ui/controller/parts-map.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EAA8B,KAAK,UAAU,EAAE,KAAK,aAAa,EAAE,KAAK,WAAW,EAAE,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AACnI,OAAO,EAAc,KAAK,SAAS,EAAE,KAAK,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,CAAC;AAErF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,kBAAkB,EAAE,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC,CAc7E,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,qBAAqB,EAAE,QAAQ,CAAC,MAAM,CAAC,YAAY,EAAE,OAAO,CAAC,CAGzE,CAAC;AAEF,wBAAgB,eAAe,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,GAAG,SAAS,CAErE;AAED,sEAAsE;AACtE,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,GAAG,SAAS,CAEvE;AAED,gGAAgG;AAChG,eAAO,MAAM,eAAe,EAAE,QAAQ,CAAC,MAAM,CAAC,IAAI,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAKzG,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,GAAG,SAAS,CAYxE;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAkBzD;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,aAAa,GAAG,UAAU,GAAG,SAAS,CAG3E;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,GAAG,QAAQ,GAAG,SAAS,CA0BjF;AAED,4FAA4F;AAC5F,wBAAgB,YAAY,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,GAAG;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAGnG;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,OAAO,CAI7E"}
@@ -0,0 +1,187 @@
1
+ /**
2
+ * Canonical input → drawn position. This module is where "the game said `DIAMOND_DOWN`" becomes "light
3
+ * the bottom face button", and it is the reason one action list draws correctly on every controller.
4
+ *
5
+ * **It maps to POSITIONS, never to letters.** `DIAMOND_DOWN` → `faceBottom` on every pad; each layout
6
+ * places `faceBottom` where that brand actually puts it, and `buttonLabel()` supplies the letter printed
7
+ * on it. So a Switch Pro (which prints `A` on the RIGHT button and `B` on the bottom) still highlights
8
+ * the bottom button for confirm — only the lettering shifts. Getting that backwards is the single most
9
+ * likely way a controller diagram lies to a rider.
10
+ *
11
+ * There are deliberately TWO lookups, because "which part lights up" and "which part a callout line
12
+ * points at" are not the same question — see {@link litPartOfButton} and {@link anchorPartOfToken}.
13
+ */
14
+ import { isShellControl, parseToken } from "./tokens.js";
15
+ import { partCentre } from "./types.js";
16
+ /**
17
+ * Which part to LIGHT when a button is held.
18
+ *
19
+ * Partial on purpose: the right stick's digital directions (`RUP`/`RDOWN`/`RLEFT`/`RRIGHT`) map to
20
+ * nothing here. Lighting the stick's *click* for a *direction* would be a lie, and the truthful visual
21
+ * already exists — the cap physically moves, driven by the `RX`/`RY` axes, which the platform emits for
22
+ * every controller (quantized to the endpoints on non-hall hardware, and synthesized from the numpad on
23
+ * a keyboard). So a right-stick direction shows up as deflection, not as a highlight.
24
+ *
25
+ * `OPTIONS` lands on `start`, the button labelled "Options" on a DualSense and "Menu" on an Xbox pad —
26
+ * the game's own menu button. The shell's overlay menu is a different key and never reaches a game.
27
+ */
28
+ export const LIT_PART_OF_BUTTON = {
29
+ UP: "dpadUp",
30
+ DOWN: "dpadDown",
31
+ LEFT: "dpadLeft",
32
+ RIGHT: "dpadRight",
33
+ DIAMOND_UP: "faceTop",
34
+ DIAMOND_RIGHT: "faceRight",
35
+ DIAMOND_DOWN: "faceBottom",
36
+ DIAMOND_LEFT: "faceLeft",
37
+ LT: "lt",
38
+ RT: "rt",
39
+ LSTICK_PRESS: "lstickPress",
40
+ RSTICK_PRESS: "rstickPress",
41
+ OPTIONS: "start",
42
+ };
43
+ /**
44
+ * The shell-owned controls, which have no {@link ButtonName} but do have a place on the drawing: the
45
+ * upper shoulders ARE the rider's resistance − / +.
46
+ *
47
+ * Kept separate from {@link LIT_PART_OF_BUTTON} so that nothing which walks the game vocabulary can
48
+ * accidentally light them — a game never receives these, and the drawing renders them faint by default
49
+ * (see `SHELL_OWNED_PARTS`). Only an explicit opt-in lets them light, which is exactly what a lesson
50
+ * teaching the rider where they are needs.
51
+ */
52
+ export const PART_OF_SHELL_CONTROL = {
53
+ LB: "lb",
54
+ RB: "rb",
55
+ };
56
+ export function litPartOfButton(name) {
57
+ return LIT_PART_OF_BUTTON[name];
58
+ }
59
+ /** The part to light for any control — game button or shell-owned. */
60
+ export function litPartOfControl(name) {
61
+ return isShellControl(name) ? PART_OF_SHELL_CONTROL[name] : LIT_PART_OF_BUTTON[name];
62
+ }
63
+ /** The four canonical directions the LEFT stick shares with the d-pad, and their axis signs. */
64
+ export const DPAD_DIRECTIONS = {
65
+ UP: [0, 1],
66
+ DOWN: [0, -1],
67
+ LEFT: [-1, 0],
68
+ RIGHT: [1, 0],
69
+ };
70
+ /**
71
+ * Which part a callout LINE should point at.
72
+ *
73
+ * Differs from {@link litPartOfButton} in exactly one way: a right-stick direction (or a bare stick
74
+ * token) resolves to that stick, because "this action uses the right stick" is precisely what the line
75
+ * should be saying — even though a *direction* shouldn't light the stick's click.
76
+ */
77
+ export function anchorPartOfToken(token) {
78
+ const t = parseToken(token);
79
+ if (t.kind === "stick")
80
+ return t.stick === "LSTICK" ? "lstickPress" : "rstickPress";
81
+ switch (t.name) {
82
+ case "RUP":
83
+ case "RDOWN":
84
+ case "RLEFT":
85
+ case "RRIGHT":
86
+ return "rstickPress";
87
+ default:
88
+ return litPartOfControl(t.name);
89
+ }
90
+ }
91
+ /**
92
+ * The movement controls that many actions share, so a callout line to one of them says nothing useful.
93
+ *
94
+ * Both sticks (whole or directional), both stick clicks, the d-pad, and the right-stick directions. In a
95
+ * game where the left stick steers, half the actions mention it; anchoring all their lines there makes a
96
+ * hairball around one part, while the distinctive button in each combination is what actually identifies
97
+ * the action.
98
+ */
99
+ export function isGenericToken(token) {
100
+ const t = parseToken(token);
101
+ if (t.kind === "stick")
102
+ return true;
103
+ switch (t.name) {
104
+ case "UP":
105
+ case "DOWN":
106
+ case "LEFT":
107
+ case "RIGHT":
108
+ case "RUP":
109
+ case "RDOWN":
110
+ case "RLEFT":
111
+ case "RRIGHT":
112
+ case "LSTICK_PRESS":
113
+ case "RSTICK_PRESS":
114
+ return true;
115
+ default:
116
+ return false;
117
+ }
118
+ }
119
+ /**
120
+ * Which token the callout line points at: **the first non-generic token**, falling back to the first
121
+ * token when every one of them is generic.
122
+ *
123
+ * ["LSTICK_PRESS", "LT"] → LT (the distinctive button, not the shared stick)
124
+ * ["LSTICK:left", "RT"] → RT
125
+ * ["LT", "DIAMOND_DOWN"] → LT (first, since neither is generic)
126
+ * ["LSTICK"] → LSTICK (all generic → the first, so "Move" points at the stick)
127
+ * ["DIAMOND_DOWN"] → DIAMOND_DOWN
128
+ *
129
+ * `action.anchor` overrides this outright, so the rule is a sensible default rather than a ceiling.
130
+ */
131
+ export function anchorTokenOf(action) {
132
+ if (action.anchor)
133
+ return action.anchor;
134
+ return action.combo.find((t) => !isGenericToken(t)) ?? action.combo[0];
135
+ }
136
+ /**
137
+ * The geometry of a drawn part in a given layout, or `undefined` when that layout has no such part (a
138
+ * Zwift pod has no sticks, no triggers and no system buttons).
139
+ *
140
+ * Stick clicks are synthesised from the {@link StickSpec} — the cap circle — since they have no
141
+ * `PartSpec` of their own.
142
+ */
143
+ export function partGeomOf(layout, part) {
144
+ switch (part) {
145
+ case "dpadUp": return layout.dpad?.up.geom;
146
+ case "dpadDown": return layout.dpad?.down.geom;
147
+ case "dpadLeft": return layout.dpad?.left.geom;
148
+ case "dpadRight": return layout.dpad?.right.geom;
149
+ case "faceTop": return layout.face.top.geom;
150
+ case "faceRight": return layout.face.right.geom;
151
+ case "faceBottom": return layout.face.bottom.geom;
152
+ case "faceLeft": return layout.face.left.geom;
153
+ case "lb": return layout.bumpers?.l.geom;
154
+ case "rb": return layout.bumpers?.r.geom;
155
+ case "lt": return layout.triggers?.l.geom;
156
+ case "rt": return layout.triggers?.r.geom;
157
+ case "start": return layout.system?.start?.geom;
158
+ case "select": return layout.system?.select?.geom;
159
+ case "home": return layout.system?.home?.geom;
160
+ case "lstickPress": {
161
+ const s = layout.sticks?.l;
162
+ return s && { kind: "circle", cx: s.cx, cy: s.cy, r: s.cap };
163
+ }
164
+ case "rstickPress": {
165
+ const s = layout.sticks?.r;
166
+ return s && { kind: "circle", cx: s.cx, cy: s.cy, r: s.cap };
167
+ }
168
+ }
169
+ }
170
+ /** Where a part sits in the layout's own viewBox units, for ordering and side placement. */
171
+ export function partCentreOf(layout, part) {
172
+ const geom = partGeomOf(layout, part);
173
+ return geom && partCentre(geom);
174
+ }
175
+ /**
176
+ * Which column a callout belongs in: the side of the pad its anchor is physically on.
177
+ *
178
+ * Derived from the layout rather than hardcoded per brand, so it stays right across four very different
179
+ * control arrangements — Xbox's diagonal offset, DualSense's symmetric sticks, and the two-pod shapes —
180
+ * and for any layout added later.
181
+ */
182
+ export function sideOfPart(layout, part) {
183
+ const centre = partCentreOf(layout, part);
184
+ const midX = layout.viewBox[0] + layout.viewBox[2] / 2;
185
+ return (centre?.x ?? midX) < midX ? "left" : "right";
186
+ }
187
+ //# sourceMappingURL=parts-map.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parts-map.js","sourceRoot":"","sources":["../../../src/ui/controller/parts-map.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Scoped `.rydr-pad-*` CSS for the controller family — the pad drawing, the input chips, the static
3
+ * controller map and the combo demo — injected once into `<head>`.
4
+ *
5
+ * Self-contained like the rest of `@rydr/game-sdk/ui`: no global styles, no dependence on host CSS
6
+ * variables, no font loading. The pad's own tokens (`--pad-body`, `--pad-accent`, …) are declared on
7
+ * `.rydr-pad` itself, so a caller theming the accent sets ONE property via the `accent` option rather
8
+ * than reaching into this stylesheet.
9
+ *
10
+ * Ported from the platform shell's `rydr-controller-diagram.ts`, with `:host` rewritten to `.rydr-pad`
11
+ * and every internal class prefixed — the shell had shadow DOM to scope bare `.part` / `.shape` names;
12
+ * we don't, so the prefix IS the scoping.
13
+ *
14
+ * The type sizes and dimensions here are tuned for a **trainer screen read from a few feet away while
15
+ * pedaling**, exactly as the rest of the kit. They are part of the contract, not defaults to override.
16
+ */
17
+ /** Force the controller CSS into `<head>`. Components call this for you; idempotent. */
18
+ export declare function injectPadCss(): void;
19
+ //# sourceMappingURL=styles.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../../../src/ui/controller/styles.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAKH,wFAAwF;AACxF,wBAAgB,YAAY,IAAI,IAAI,CAUnC"}