Normalization

Always use App._hat_to_nav(value) to convert raw hat values to logical directions:

dx, dy = self._hat_to_nav(event.value)
# dy == -1 → physical UP
# dy ==  1 → physical DOWN
# dx == -1 → physical LEFT
# dx ==  1 → physical RIGHT

This helper is used for: - Chat list navigation - Message list navigation - Menu overlay selection - On-screen keyboard grid navigation

Joystick Axis (correct, standard polarity)

Axis 1 (left stick vertical) uses standard pygame polarity: - value < -0.5 → UP - value > 0.5 → DOWN

No inversion needed for joystick axis events.

Why This Happens

The RG40XX-V hat wiring is inverted relative to pygame/SDL expectations. HERON/Pearl Diver code handles this by mapping (0, 1) → scroll_up directly. AQUAPING normalizes via _hat_to_nav() for consistency.