В моем случае я использую Logitech F310 в режиме Xinput (у него есть переключатель для выбора между DirectInput и Xinput). Я написал небольшое приложение, которое считывает значения осей геймпада. Получается, что правый аналоговый джойстик использует оси MotionEvent.AXIS_RX
и MotionEvent.AXIS_RY
, а двухплечевые аналоговые триггеры используют оси MotionEvent.AXIS_Z
и MotionEvent.AXIS_RZ
.
Но согласно документации AXIS_Z и AXIS_RZ следует использовать для правый аналоговый джойстик:
публичный статический окончательный int AXIS_RZ
Константа оси: Z Ось вращения события движения.
Для джойстика сообщает абсолютный угол поворота вокруг оси Z. Значение нормализовано в диапазоне от -1,0 (против часовой стрелки) до 1,0 (по часовой стрелке). На геймпадах с двумя аналоговыми джойстиками эта ось часто интерпретируется заново, чтобы сообщать об абсолютном положении Y второго джойстика.
Это проблема игр, в которых нет возможности переназначить кнопки и аналоговые джойстики геймпадов. Например, GTA San Andreas считает, что два аналоговых триггера — это правильный аналоговый джойстик. Но так как нейтральное значение триггера, когда он не нажат, равно -1 вместо 0, как было бы с аналоговым стиком в нейтральном состоянии, то камера постоянно крутится. (правый аналоговый джойстик используется для движения камеры в этой игре)
Где сохраняется сопоставление осей? Это жестко закодировано в геймпаде? Или он назначается в подсистеме устройств Linux? Или, может быть, в рамках Android InputDevice? Если да, то можно ли его изменить?
Другим возможным решением может быть перехват MotionEvents между диспетчером событий и принимающим приложением и изменение значений оси. Возможно ли это или что-то подобное в Android? Возможно, даже на более низком уровне: при наличии root-доступа можно читать необработанные входные данные с устройства /dev/input/event6 (в моем случае event6 — это геймпад). Можно ли постоянно перезаписывать этот файл скорректированными значениями осей?