Skip to content

fix: decode the Guide button bit in decodeXInput360 (XInput-360 family) - #162

Merged
emir-hasanbegovic merged 2 commits into
TinkerNorth:mainfrom
MichaelWilsonSNC:fix/luna-center-guide-button
Aug 18, 2026
Merged

fix: decode the Guide button bit in decodeXInput360 (XInput-360 family)#162
emir-hasanbegovic merged 2 commits into
TinkerNorth:mainfrom
MichaelWilsonSNC:fix/luna-center-guide-button

Conversation

@MichaelWilsonSNC

Copy link
Copy Markdown
Contributor

Description

decodeXInput360 (the shared decoder for every Parser::XINPUT_360 /
XINPUT_360_WIRELESS device in the kKnown table — genuine Xbox 360
controllers and its many licensed clones, plus the Amazon Luna
Controller) never read byte 3 bit 0x04 of the wired report. That bit
is the standard Guide/Xbox button position in the XInput wired
protocol (the same bit Linux's xpad driver treats as BTN_MODE); the
other bits in that byte (0x01/0x02 bumpers, 0x10..0x80 face
buttons) were already decoded, but 0x04 was dead, so any pad's
center/Guide button silently produced no input at all instead of
XUSB_GUIDE.

Found on real hardware: a live raw-report capture from an Amazon Luna
Controller (USB VID:PID 1949:041A, wired mode, from #153) showed
byte 3 going to exactly 0x04 and nothing else when its center button
was pressed, with A/B/X/Y independently confirmed against their own
existing bits (0x10/0x20/0x40/0x80) in the same capture. Fix is
a single added line, decoding that bit the same way every other button
in the function already is, with no change to the report layout or any
other bit.

No wire-protocol changes; nothing to coordinate with satellite,
dish-linux, or dish-mac.

Scope note for review: this is a generic decoder fix, not a Luna-only
special case, so it affects every device riding XINPUT_360/
XINPUT_360_WIRELESS in kKnown (Mad Catz, PDP, Hori, PowerA,
Afterglow, dance pads, fight sticks, etc.). Pads without a physical
Guide button never assert that bit in hardware, so this is a no-op for
them. The only theoretical residual risk is an unlicensed clone that
reused bit 0x04 for some other custom function instead of leaving it
unused; if one exists, worst case is that button now also raises
Guide/Home, not a crash or corrupted input.

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing
    functionality to not work as expected)
  • Refactor (code change that neither fixes a bug nor adds a feature)
  • Documentation update

How Has This Been Tested?

  • Unit tests
  • Instrumented tests
  • Manual testing on device/emulator

Added Decode.Xbox360WiredGuideButtonSetsGuideBit to
usb_parsers_test.cpp, asserting byte 3 0x04 sets XUSB_GUIDE
through decodeReport(Parser::XINPUT_360, ...). Full native host
suite: 241/241 passing (ctest across all app/src/test/cpp binaries).

Manual testing: real Amazon Luna Controller, wired directly to an
Android phone running dish, Direct mode. Captured raw USB interrupt
reports for A/B/X/Y and the center button before the fix (center
button produced no bit at all in wButtons); after the fix, rebuilt
and reinstalled the app and confirmed the center button now reaches
the Guide/Home action end-to-end through a satellite host.

Checklist

  • My code follows the project's style guidelines (ktlint/detekt
    untouched — no Kotlin changed; clang-format skipped locally, not
    installed at the pinned 22.1.4 version, but the change is a
    single line matching the exact formatting of every neighboring
    line in the same if chain, and CI's own clang-format gate will
    catch it if not)
  • I have performed a self-review of my code
  • Any non-obvious code explains why, not what (no comment added —
    the fix reads identically to every other bit check in the same
    function, so a comment here would be inconsistent with the rest
    of the file)
  • I have made corresponding changes to documentation
    (CHANGELOG.md, under [Unreleased])
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my
    feature works
  • New and existing unit tests pass locally with my changes
    (241/241 native host tests, assembleDebug)

MichaelWilsonSNC and others added 2 commits August 17, 2026 19:17
Byte 3 bit 0x04 of the Xbox 360 wired report is the standard Guide/Xbox
button bit, but decodeXInput360 never read it, so every XINPUT_360-family
pad (including the Amazon Luna Controller) silently dropped a center-button
press instead of reporting it as Guide. Confirmed the Luna's center button
sets exactly this bit via a live raw-report capture on device.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@emir-hasanbegovic
emir-hasanbegovic merged commit cc96bc8 into TinkerNorth:main Aug 18, 2026
10 checks passed
emir-hasanbegovic added a commit that referenced this pull request Aug 18, 2026
1.1.1 shipped 2026-08-17. Main has picked up two user-facing fixes
since: the Guide button on XInput wired pads (#162) and the "Use wired"
card action when a Bluetooth pad's cable is plugged in (#163). This keys
the release docs to 1.1.2 so the tag can ship them; tag 1.1.2 derives
versionCode 10102.

- CHANGELOG.md: retitle Unreleased to 1.1.2, dated 2026-08-18
- changelogs/10102.txt in all 5 locales, quoting each locale's actual UI
strings for the card badge and button

Validated locally: `EXPECTED_VERSION_CODE=10102 python
scripts/check_play_metadata.py` reports 0 errors (only the known 512x512
icon warnings).

## Releasing after merge

```
git fetch origin
git tag 1.1.2 origin/main
git push origin 1.1.2
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants