Skip to content

fix: Correct inverted Android D-pad Up/Down (AXIS_HAT_Y double-inversion) - #128

Open
GhagSagar23 wants to merge 1 commit into
flame-engine:mainfrom
GhagSagar23:fix/123-gamepadbutton-dpadup-dpaddown-invert
Open

fix: Correct inverted Android D-pad Up/Down (AXIS_HAT_Y double-inversion)#128
GhagSagar23 wants to merge 1 commit into
flame-engine:mainfrom
GhagSagar23:fix/123-gamepadbutton-dpadup-dpaddown-invert

Conversation

@GhagSagar23

Copy link
Copy Markdown

Summary

Fixes #123.

On Android, pressing the D-pad Up emitted GamepadButton.dpadDown (value 1.0), and Down emitted dpadUp. Root cause is a double inversion of the D-pad Y hat axis:

  • gamepads_android's EventListener registers AXIS_HAT_Y with invert = true (EventListener.kt:27), so the value delivered to Dart is already flipped to up = +1.0 / down = −1.0 — the opposite of Android's native AXIS_HAT_Y (up = −1.0 / down = +1.0).
  • AndroidMapping.normalizeDpadAxis still mapped per Android's native convention (value > 0 → dpadDown, value < 0 → dpadUp), so the two flips compounded.

AXIS_HAT_X is not inverted natively, so D-pad left/right were unaffected — matching the report.

Change

Corrected the sign comparison in a single canonical location — the AXIS_HAT_Y branch of AndroidMapping.normalizeDpadAxis — so dpadUp fires on value > 0 and dpadDown on value < 0, with a comment citing #123. EventListener.kt is intentionally left unchanged to avoid re-introducing a double-inversion.

  • packages/gamepads/lib/src/mappings/android_mapping.dart
  • packages/gamepads/test/mappings_test.dart — both-direction AXIS_HAT_Y regression

Fix-location decision (maintainer call welcome)

The reporter raised a genuine design choice for where to fix this:

  1. Kotlin (EventListener.kt): drop the AXIS_HAT_Y inversion → raw/unnormalized values would then follow Android's 1.0 == down.
  2. Dart (android_mapping.dart, this PR): keeps the library's existing 1.0 == up raw convention.

This PR takes option 2 to preserve the current raw-value convention (no breaking change) and because the mapping is pure Dart and directly unit-testable. Happy to switch to the Kotlin approach if you prefer — but the fix must live in exactly one place; applying it in both would double-invert and silently reintroduce the bug.

Tests

Added a both-direction regression to AndroidMapping > "normalizes hat d-pad axes":

  • raw AXIS_HAT_Y = +1.0 (physical up) → dpadUp = 1.0, dpadDown = 0.0
  • raw AXIS_HAT_Y = -1.0 (physical down) → dpadDown = 1.0, dpadUp = 0.0

This fails on the pre-fix code (which returned dpadDown = 1.0 for +1.0) and passes after the fix.

Note: the containerized Flutter runner was gated in this non-interactive session, so the fail→pass transition was verified by tracing, not executed. Please run before merge:

flutter pub get && flutter test packages/gamepads/test/mappings_test.dart
flutter analyze packages/gamepads

End-to-end hardware confirmation (physical Android device + controller, e.g. the reporter's SM-G781B + GameSir G8 Pro) is out of CI scope.

Deferred

  • Analog stick Y-axis (leftStickY/rightStickY): the reporter separately observed up reading -1.0. Left untouched here — confirm it's a genuine inversion vs. Android's native joystick convention before changing; tracked as a follow-up reusing this PR's convention decision.
  • CHANGELOG / version bump: not hand-edited — this melos workspace generates them at release time from the fix: PR title (CONTRIBUTING.md, "Creating a release").

Coordination

Thanks @fescrb for the precise root-cause analysis. You'd offered to submit this — glad to defer to you or just help with review; sharing this as a ready-to-go option while the fix-location question is settled.

@GhagSagar23 GhagSagar23 changed the title fix: correct inverted Android D-pad Up/Down (AXIS_HAT_Y double-inversion) fix: Correct inverted Android D-pad Up/Down (AXIS_HAT_Y double-inversion) Aug 17, 2026
@GhagSagar23
GhagSagar23 marked this pull request as ready for review August 17, 2026 07:00
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.

GamepadButton.dpadUp/.dpadDown inverted for Android

1 participant