docs(gamepad/android): document the two-motor vibratorIds ordering assumption (G20)
The two-motor split assumes ids[0] = light/right and ids[1] = heavy/left, an ordering `VibratorManager.getVibratorIds()` does not guarantee. Record the assumption and its tactile-only failure mode (a heavy-first pad inverts the feel but nothing silences or crashes) at the call site. No behavior change: a per-pad fix needs on-glass verification, and a blanket count-based fallback is unsafe (extra ids may be DualSense trigger actuators that must stay silent). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -214,7 +214,13 @@ class GamepadFeedback(private val handle: Long, private val router: GamepadRoute
|
|||||||
}
|
}
|
||||||
val combo = CombinedVibration.startParallel()
|
val combo = CombinedVibration.startParallel()
|
||||||
if (bind.amplitudeControlled && bind.ids.size >= 2) {
|
if (bind.amplitudeControlled && bind.ids.size >= 2) {
|
||||||
// ids[0] = light/right, ids[1] = heavy/left (XInput/Moonlight convention).
|
// Two-motor split — ASSUMPTION: ids[0] = light/right, ids[1] = heavy/left
|
||||||
|
// (XInput/Moonlight convention). Android does not guarantee the order of
|
||||||
|
// VibratorManager.getVibratorIds(), so a pad that enumerates heavy-first would
|
||||||
|
// invert the feel: the stronger amplitude drives the physically-lighter motor.
|
||||||
|
// Failure mode is tactile only — both motors still fire, nothing silences or
|
||||||
|
// crashes — so this stays the default pending per-pad on-glass verification (G20).
|
||||||
|
// ids beyond the first two (rare) are left alone here.
|
||||||
if (hi != 0) combo.addVibrator(bind.ids[0], oneShot(hi, durationMs))
|
if (hi != 0) combo.addVibrator(bind.ids[0], oneShot(hi, durationMs))
|
||||||
if (lo != 0) combo.addVibrator(bind.ids[1], oneShot(lo, durationMs))
|
if (lo != 0) combo.addVibrator(bind.ids[1], oneShot(lo, durationMs))
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Reference in New Issue
Block a user