Repository navigation
Add Steam Controller (2026) support on macOS - #221
thehobbit85 wants to merge 8 commits into
Conversation
421e920 to
f7c2f2f
Compare
|
I tested this PR with a real 2026 Steam Controller. Rumble works. Gyro data reaches the game, but TotK's gyro aiming does not respond to it. Details below. Setup
Results
Axes and signsA read-only IOKit probe (sends nothing to the controller) guided four moves and integrated the raw gyro at offset 40, using the PR's scale. The accelerometer is at offset 34.
So the controller's axes are the Switch's, and the PR's mapping ( What TotK receivesI added a temporary trace, TotK 1.4.3 imports only
A Side finding: six-axis handle encoding
Not done
|
Follow-up: gyro aiming works with a stick deadzoneI found why TotK's bow aiming ignored the gyro. The motion data was correct throughout. The Steam Controller's sticks have no deadzone in this PR.
With a radial deadzone in --- a/dm/host/steam_input.h
+++ b/dm/host/steam_input.h
@@ #pragma once
+#include <math.h>
#include <stddef.h>
+#include <stdlib.h>
#include <string.h>
@@
+// The raw HID sticks rest a few counts off centre; the console's input service reports a centred stick as exactly 0 (a radial deadzone), and games rely on it:
+// Tears of the Kingdom treats any non-zero stick as stick input and stops gyro aiming. Radial deadzone of DM_STEAM_DEADZONE (fraction of full scale, default 0.10),
+// rescaled so the edge still reaches full scale
+static inline void steam_deadzone(int32_t *x, int32_t *y) {
+ static float dz = -1; if (dz < 0) { const char *e = getenv("DM_STEAM_DEADZONE"); dz = e ? (float)atof(e) : 0.10f; if (!(dz >= 0 && dz < 0.9f)) dz = 0.10f; }
+ float fx = *x / 32767.0f, fy = *y / 32767.0f, m = sqrtf(fx * fx + fy * fy);
+ if (m <= dz) { *x = *y = 0; return; }
+ float k = (m - dz) / (1 - dz) / m; // each axis clamped on its own, so a full diagonal stays at full scale on both axes
+ *x = (int32_t)lrintf(fmaxf(-1, fminf(1, fx * k)) * 32767); *y = (int32_t)lrintf(fmaxf(-1, fminf(1, fy * k)) * 32767);
+}
@@ steam_decode
s->rx = steam_axis(p + 14); s->ry = steam_axis(p + 16);
+ steam_deadzone(&s->lx, &s->ly); steam_deadzone(&s->rx, &s->ry);
How it was traced (TotK 1.4.3,
Corrections to my comment above:
Still not tested: trackpads, rear buttons, the mapping window, Bluetooth and the Puck. |
a9d9941 to
eb44c9b
Compare
|
Heads-up: #388 proposes treating controls as data that every UI writes (#388 (comment)): the key and button maps (#386's |
e2bdbaf to
f115432
Compare
|
The fixes for the USB-C findings and gyro-aiming follow-up are included in the cleaned three-commit series:
Implementation and regressions: motion/rumble foundations and controller input. The full host suite, ASan/UBSan and thread checks passed locally, as did the Mac host build. Both code commits also build and pass the host suite independently. The remaining hardware limits are documented: gyro scale calibration is still unconfirmed, and this final revision needs physical trackpad/rear-button/transport retesting. Recenter keeps a truthful identity pose; we have not added a fabricated rotation to avoid TotK's identity check. No game was launched during this update. |
|
The shared-controls coordination comment is now implemented in 075ce81. The launcher and host use #386's Launch environment and Synthetic integration tests cover launcher/host domain agreement, precedence, malformed choices, session-only edits, model isolation and panel actions. They passed, along with the packaging/docs tests and lint ratchet. The store contract and player guide describe the behavior. This incorporates #386 at |
64410df to
26b6fcb
Compare
a1e0012 to
506259d
Compare
c2b75bc to
8dfa9c6
Compare
8dfa9c6 to
f6dc6c2
Compare
57fbd49 to
fbc476a
Compare
52e4b72 to
c50e83c
Compare
c50e83c to
7938dee
Compare
Keep independent motion histories and complete mapped Shake gestures per player, while retaining live native orientation and upstream source selection. Encode SDK six-axis handles consistently. Add lifecycle-safe direct rumble sinks using the shared intensity cutoff and deterministic refresh tests.
Add physical-device-scoped Triton USB-C, Bluetooth and Puck input without disturbing other controllers. Support rumble, gyro, trackpads, extra buttons and the resting-stick deadzone through the existing player, motion and haptics policies. Use the shared DM_KEYMAP and DM_PAD_MAP parser and saved-choice contract from PR seedds#386 at 97eaa98, with an additive Shake target. Keep launch overrides temporary, support session-only edits and explicit legacy import, and test both adapters, the mapping panel and the launcher/host preference domain.
Describe Steam Controller capabilities, per-player Shake, shared frontend preferences, explicit legacy import and Input Monitoring recovery after a rebuild. Record the TotK hardware findings and remaining calibration limits.
7938dee to
eb53ebb
Compare
Adds Steam Controller (2026/Triton) input on macOS with USB-C, Bluetooth and Puck protocol handling, per-player motion and rumble, configurable trackpads/rear buttons, and a shared controls panel. Standard mappings apply to every controller; device-specific extras cannot override them. Generic HID and GameController input share player slots, focus handling and ownership, so connecting one controller preserves other players. Deferred generic devices recover when ownership becomes available.
Related to #388: the launcher and host share
DM_KEYMAP/DM_PAD_MAPparsing and per-game saved choices. Launch overrides remain fixed;DM_SAVED_CHOICES=0makes edits session-only. Main and related #382 do not provide the Triton adapter and panel. The existing malformed-HMMA signature regression coverage from #870 is retained.Revision
eb53ebb22ac84324a8e72e31546bd9a7d9f3e902integrates main99330eb81c873c3aafe9fc92194c9687d77fcdbb. Main already incorporates the exact #855 audio wakeup fix, so there is no separate audio prerequisite. Controller implementation, fixtures and build recipes are unchanged from the previous published head; upstream's corrected pipeline-archive reuse semantics remain intact.Fresh validation:
t_controllers_mac,t_pad_map,t_pad_motionandt_haptics_applepass;t_hidpasses 251 checks,t_input_map48, andt_audio_stats26. Built withmake -C dm/host/tests GAME=010015100B514000and the named targets. Synthetic coverage includes ownership/open-failure recovery, mixed player slots, report decoding, mapping persistence, motion, touch and rumble; it does not establish device compatibility./opt/homebrew/bin/python3 -m unittest dm.tools.tests.test_docs dm.tools.tests.test_usage dm.tools.tests.test_nsp_mac_app dm.gfx.tests.test_dmsh_hmma: 69 pass. An initial sandboxed run stopped at unchangediconutilsynthetic-icon generation; the identical suite passes with normal macOS host-tool access.dm/tools/lint_c.py compdb --game 010015100B514000produces 219 sources. Mac frontend/controller syntax checks pass (one existing unused-activity warning). Symptom-index regeneration, links, main ancestry, range-diff andgit diff --checkpass. No chain tool or compiler lock changed.Historical evidence remains separate: the previous published head
7938dee4eaeca3a9b07702ee53770137617d91edpassed all eight CI checks. Earlier native/sanitizer/GPU campaigns were not repeated; #855's 300-run/33-million-release audio stress is historical. Current local checks use macOS 26.6 and Xcode 27.0 / Metal .921; supported CI uses Xcode 27.2 / Metal .922. Local LLVM 23 clang-tidy and a fresh full graphics campaign are not claimed. CI for this revision is pending.Game impact:
regress.py impact 99330eb8..HEADidentifies Hades (vibration/player styles), Breath of the Wild (motion and controller styles), Pokémon Scarlet (player/style selection), and Tears of the Kingdom (gyro, vibration and player state); 123 profiles lack usage manifests and remain unknown. Super Mario Odyssey's shake-based actions also exercise the changed six-axis behavior. No games were launched or extracted caches rebuilt in this scoped update, and no newregress.py checkresult is claimed. Earlier unavailable-build results and Z-A's missing smoke route remain limitations, not passes. RePOP automated gameplay remains stopped.The USB-C hardware report and gyro follow-up cover TotK 1.4.3 on an M4 Pro, macOS 27.0.1, Xcode 26.3: buttons, sticks and rumble worked, and the proposed 10% radial deadzone restored bow gyro aiming after walking and while moving. The six-axis handle mismatch was a separate finding. These are contributor reports on earlier revisions, not new tests. Gyro scale calibration, trackpads, rear buttons, mapping persistence, Bluetooth/Puck operation and physical hotplug still need testing on this revision; no new gameplay, display-sleep/fullscreen, performance or iOS-device result is claimed.
The player guide, shared frontend contract and developer documentation describe current behavior. TotK's note retains durable findings and limitations, with subsystem references under “Found on this game”; detailed validation is recorded here. No agent planning/execution artifacts or game data are included.