feat(rumble): forward MSG_RUMBLE to SDL controller (rumble + lightbar) - #14
Merged
Conversation
emir-hasanbegovic
force-pushed
the
feature/ui-overhaul-and-async-bind
branch
from
May 14, 2026 13:18
0c808b5 to
d97e5bd
Compare
Adds the dish-side handler for the satellite's reverse-direction rumble
message (MSG_RUMBLE = 0x0009). SatelliteClient::processIncoming parses
the wire format via a pure static parseRumbleMessage decoder, the
per-WifiConnection rumble handler resolves connId → slotId → deviceId
via the ConnectionHub bindings, and SDLGamepadBridge::applyRumble drives
the matching SDL_GameController.
* Wire format documented in satellite/README.md#rumble-return-path:
ctrlIdx(u8) strong(u16 BE) weak(u16 BE) durMs(u16 BE) flags(u8)
[R, G, B] (u8×3 if flags bit 0 set)
* SDL_GameControllerRumble passes the strong/weak magnitudes through
verbatim (XInput scale matches). SDL_GameControllerSetLED is invoked
when the satellite published a DS4 lightbar colour; both are silent
no-ops on pads that don't support the feature.
* AppModel::installRumbleHandlers walks the WifiConnection pool on every
poolChanged signal and attaches a handler to any new connection that
doesn't already have one. Idempotent.
* WifiConnection caches the handler so it survives reconnects:
markConnected re-installs it on the new SatelliteClient instance.
* parseRumbleMessage is exposed as a static helper so it can be unit-
tested without driving a live socket. New Catch2 suite covers: byte-
layout decoding, stop requests, max magnitudes, lightbar tail, lightbar
flag with truncated tail, forward-compat with extra trailing bytes,
reserved flag bits, big-endian boundary cases.
Stacked on top of feature/ui-overhaul-and-async-bind. PR base set to the
parent branch so the diff shows only rumble.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
emir-hasanbegovic
force-pushed
the
feat/rumble
branch
from
May 14, 2026 13:21
2d5f2eb to
8858547
Compare
emir-hasanbegovic
changed the base branch from
feature/ui-overhaul-and-async-bind
to
main
May 14, 2026 13:21
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
MSG_RUMBLE = 0x0009).SatelliteClient::processIncomingparses the wire format via a pure staticparseRumbleMessagedecoder; per-WifiConnectionrumble handler resolvesconnId → slotId → deviceIdvia theConnectionHubbindings;SDLGamepadBridge::applyRumbledrives the matchingSDL_GameController(SDL_GameControllerRumble+SDL_GameControllerSetLEDfor DS4 lightbar).AppModel::installRumbleHandlerswalks the pool on everypoolChangedand attaches a handler to any new connection that doesn't already have one. Idempotent. Handler caching onWifiConnectionsurvives reconnects.Stacking
Wire format
Documented in
satellite/README.md#rumble-return-path:Test plan
scripts/build.sh debug test— newtests/test_satellite_client_rumble.cpp(8 Catch2 cases) covers byte-layout decoding, stop requests, max magnitudes, lightbar tail, lightbar-flag-with-truncated-tail rejection, forward-compat trailing bytes, reserved flag bits, big-endian boundariesXInputSetState, verify a paired Xbox/DualSense controller buzzesRelated
🤖 Generated with Claude Code