Как реализовать левый и правый аналоговые триггеры в HID Gamepad для Android - PullRequest
1 голос
/ 11 февраля 2020

Я работаю над геймпадом HID с 4 осями (14 бит), 16 кнопками, 2 аналоговыми триггерами (1 байт) и шляпным переключателем. В настоящее время я использую оси X и Y для левой аналоговой ручки, оси Rx и Ry для правой аналоговой ручки и оси Z и Rz для левого и правого триггеров. Я могу зарегистрировать все кнопки и аналоговые показания (которые были протестированы с Gamepad tester в android и jstest-gtk в linux), но проблема в том, что в (Android) В играх триггерами должны быть ось 7 и ось 8, а в моем случае Z и Rz назначены оси 14 и 15. Я также пытался использовать Ускорение (ось: 11), Тормоз (ось: 12) , Rudder (ось: 9) и Throttle (ось: 10), но оси 7 и 8 (которые являются осями запуска по умолчанию) не назначаются.

Вот мой дескриптор отчета HID: -

0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)
0x09, 0x05,                    // USAGE (Game Pad)
0xa1, 0x01,                    // COLLECTION (Application)

0x85, 0x01,                    //   REPORT_ID (1)
0x09, 0x01,                    //   USAGE (Pointer)
0xa1, 0x00,                    //   COLLECTION (Physical)
0x09, 0x30,                    //     USAGE (X) - Left Analog Left(-ve),Right(+ve)
0x09, 0x31,                    //     USAGE (Y) - Left Analog Up(-ve), Down(+ve)
0x09, 0x33,                    //     USAGE (Rx) - Right Analog Left(-ve), Right(+ve)
0x09, 0x34,                    //     USAGE (Ry) - Right Analog Up(-ve), Down(+ve)
0x16, 0x01, 0xE0,              //     LOGICAL_MINIMUM (-8191)
0x26, 0xFF, 0x1F,              //     LOGICAL_MAXIMUM (8191)        
0x75, 0x10,                    //     REPORT_SIZE (16)
0x95, 0x04,                    //     REPORT_COUNT (4)
0x81, 0x02,                    //     INPUT (Data,Var,Abs)
0xc0,                          //   END_COLLECTION
0x05, 0x01,                    //     USAGE_PAGE (Generic Desktop) 
0x15, 0x00,                    //     LOGICAL_MINIMUM (0)
0x26, 0xFF, 0x00,              //     LOGICAL_MAXIMUM (255)
0x09, 0x32,                    //     USAGE (Z) - L2 Trigger(Shoulderpads Trigger)
0x09, 0x35,                    //     USAGE (Rz) - R2 Trigger(Shoulderpads Trigger)    
0x75, 0x08,                    //     REPORT_SIZE (8)    
0x95, 0x02,                    //     REPORT_COUNT (2)    
0x81, 0x02,                    //     INPUT (Data,Var,Abs)    

0x05, 0x09,                    //   USAGE_PAGE (Button)
0x19, 0x01,                    //   USAGE_MINIMUM (Button 1)    
0x29, 0x10,                    //   USAGE_MAXIMUM (Button 16)
0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
0x25, 0x01,                    //   LOGICAL_MAXIMUM (1)     
0x95, 0x10,                    //   REPORT_COUNT (16)
0x75, 0x01,                    //   REPORT_SIZE (1)
0x81, 0x02,                    //   INPUT (Data,Var,Abs)

0x05, 0x01,                    //   USAGE_PAGE (Generic Desktop)
0x09, 0x39,                    //   USAGE (Hat switch)
0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
0x25, 0x07,                    //   LOGICAL_MAXIMUM (7)
0x35, 0x00,                    //   PHYSICAL_MINIMUM (0)
0x46, 0x3b, 0x01,              //   PHYSICAL_MAXIMUM (315)
0x65, 0x14,                    //   UNIT (Eng Rotation:Centimeter)
0x75, 0x04,                    //   REPORT_SIZE (4)
0x95, 0x01,                    //   REPORT_COUNT (1)
0x81, 0x42,                    //   INPUT (Data,Var,Abs,Null)
0x95, 0x01,                    //   REPORT_COUNT (1)
0x75, 0x04,                    //   REPORT_SIZE (4)
0x81, 0x43,                    //   INPUT (Cnst,Var,Abs,Null)

0xc0                           // END_COLLECTION

Любая помощь будет высоко оценена, спасибо.

Редактировать: - Вот новый дескриптор отчета, который я пробовал на основе документа CDR Anrdoid, указанного Nipo: -

0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)
0x09, 0x05,                    // USAGE (Game Pad)
0xa1, 0x01,                    // COLLECTION (Application)
0x85, 0x01,                    //   REPORT_ID (1)
0x09, 0x01,                    //   USAGE (Pointer)
0xa1, 0x00,                    //   COLLECTION (Physical)
0x05, 0x01,                    //     USAGE_PAGE (Generic Desktop)
0x09, 0x30,                    //     USAGE (X) - Left Analog Left(-ve),Right(+ve)
0x09, 0x31,                    //     USAGE (Y) - Left Analog Up(-ve), Down(+ve)
0x09, 0x32,                    //     USAGE (Z) - Right Analog X
0x09, 0x35,                    //     USAGE (Rz) - Right Analog Y
0x15, 0x81,                    //     LOGICAL_MINIMUM (-127)
0x25, 0x7F,                    //     LOGICAL_MAXIMUM (127)       
0x75, 0x08,                    //     REPORT_SIZE (8)
0x95, 0x04,                    //     REPORT_COUNT (4)
0x81, 0x02,                    //     INPUT (Data,Var,Abs)
0x05, 0x02,                    // USAGE_PAGE (Simulation Control)            
0x15, 0x00,                    //     LOGICAL_MINIMUM (0)
0x26, 0xFF, 0x00,              //     LOGICAL_MAXIMUM (255)        
0x09, 0xC4,                    //     USAGE(Acceleration)
0x09, 0xC5,                    //     USAGE(Brake)        
0x75, 0x08,                    //     REPORT_SIZE (8)
0x95, 0x02,                    //     REPORT_COUNT (2)    
0x81, 0x02,                    //     INPUT (Data,Var,Abs)
0x05, 0x09,                    //   USAGE_PAGE (Button)
0x09, 0x01,                    //   USAGE(Button 1)
0x09, 0x02,                    //   USAGE(Button 2)
0x09, 0x04,                    //   USAGE(Button 4)
0x09, 0x05,                    //   USAGE(Button 5)
0x09, 0x07,                    //   USAGE(Button 7)
0x09, 0x08,                    //   USAGE(Button 8)
0x09, 0x0E,                    //   USAGE(Button 14)
0x09, 0x0F,                    //   USAGE(Button 15)
0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
0x25, 0x01,                    //   LOGICAL_MAXIMUM (1)     
0x95, 0x08,                    //   REPORT_COUNT (8)
0x75, 0x01,                    //   REPORT_SIZE (1)
0x81, 0x02,                    //   INPUT (Data,Var,Abs)           
0x05, 0x01,                    //   USAGE_PAGE (Generic Desktop)
0x09, 0x39,                    //   USAGE (Hat switch)
0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
0x25, 0x07,                    //   LOGICAL_MAXIMUM (7)
0x35, 0x00,                    //   PHYSICAL_MINIMUM (0)
0x46, 0x3b, 0x01,              //   PHYSICAL_MAXIMUM (315)
0x65, 0x14,                    //   UNIT (Eng Rotation:Centimeter)
0x75, 0x04,                    //   REPORT_SIZE (4)
0x95, 0x01,                    //   REPORT_COUNT (1)
0x81, 0x42,                    //   INPUT (Data,Var,Abs,Null)
0x65, 0x00,                    // Unit (None)
/*!@ The below section is taken from the page 31 of the document given
  in the link below.
  https://www.silabs.com/documents/public/application-notes/AN993.pdf
 */
0x05, 0x0C,                    //   USAGE_PAGE (Consumer)
0x0A, 0x23, 0x02,              //   USAGE (AC Home)
0x0A, 0x24, 0x02,              //   USAGE (AC Back)
0x75, 0x01,                    //   REPORT_SIZE(1)
0x95, 0x02,                    //   REPORT_COUNT(2)
0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
0x25, 0x01,                    //   LOGICAL_MAXIMUM (1)
0x35, 0x00,                    //   PHYSICAL_MINIMUM (0)
0x45, 0x01,                    //   PHYSICAL_MAXIMUM (1)
0x81, 0x42,                    //   INPUT (Data,Var,Abs,Null)
0x95, 0x01,                    //   REPORT_COUNT (2)
0x75, 0x02,                    //   REPORT_SIZE (1)
0x81, 0x43,                    //   INPUT (Cnst,Var,Abs,Null)
0xc0,                          //   END_COLLECTION
0xc0,                          //   END_COLLECTION

1 Ответ

0 голосов
/ 04 марта 2020

Вот дескриптор отчета, который работал для меня: -

0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)
0x09, 0x05,                    // USAGE (Game Pad)
0xa1, 0x01,                    // COLLECTION (Application)    

0x85, 0x01,                    //   REPORT_ID (1)
0x09, 0x01,                    //   USAGE (Pointer)
0xa1, 0x00,                    //   COLLECTION (Physical)    
0x05, 0x01,                    //     USAGE_PAGE (Generic Desktop)
0x09, 0x30,                    //     USAGE (X) - Left Analog Left(-ve),Right(+ve)
0x09, 0x31,                    //     USAGE (Y) - Left Analog Up(-ve), Down(+ve)    
0x09, 0x32,                    //     USAGE (Z) - Right Analog Left(-ve)Right(+ve)
0x09, 0x35,                    //     USAGE (Rz)- Right Analog Up(-ve), Down(+ve)
0x15, 0x81,                    //     LOGICAL_MINIMUM (-127)
0x25, 0x7f,                    //     LOGICAL_MAXIMUM (127)
0x75, 0x08,                    //     REPORT_SIZE (8)
0x95, 0x04,                    //     REPORT_COUNT (4)
0x81, 0x02,                    //     INPUT (Data,Var,Abs)
0xc0,                          //   END_COLLECTION

0x05, 0x02,                    //     USAGE_PAGE (Simulation Control)
0x15, 0x00,                    //     LOGICAL_MINIMUM (0)
0x26, 0xFF, 0x00,              //     LOGICAL_MAXIMUM (255)
0x09, 0xC4,                    //     USAGE(Acceleration)
0x09, 0xC5,                    //     USAGE(Brake)           
0x75, 0x08,                    //     REPORT_SIZE (8)
0x95, 0x02,                    //     REPORT_COUNT (2)
0x81, 0x02,                    //     INPUT (Data,Var,Abs)

0x05, 0x09,                    //   USAGE_PAGE (Button)
0x19, 0x01,                    //   USAGE_MINIMUM (Button 1)
0x29, 0x10,                    //   USAGE_MAXIMUM (Button 16)
0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
0x25, 0x01,                    //   LOGICAL_MAXIMUM (1)
0x95, 0x10,                    //   REPORT_COUNT (16)
0x75, 0x01,                    //   REPORT_SIZE (1)
0x81, 0x02,                    //   INPUT (Data,Var,Abs)

0x05, 0x01,                    //   USAGE_PAGE (Generic Desktop)
0x09, 0x39,                    //   USAGE (Hat switch)
0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
0x25, 0x07,                    //   LOGICAL_MAXIMUM (7)
0x35, 0x00,                    //   PHYSICAL_MINIMUM (0)
0x46, 0x3b, 0x01,              //   PHYSICAL_MAXIMUM (315)
0x65, 0x14,                    //   UNIT (Eng Rotation:Centimeter)
0x75, 0x04,                    //   REPORT_SIZE (4)
0x95, 0x01,                    //   REPORT_COUNT (1)
0x81, 0x42,                    //   INPUT (Data,Var,Abs,Null)
0x95, 0x01,                    //   REPORT_COUNT (1)
0x75, 0x04,                    //   REPORT_SIZE (4)
0x81, 0x43,                    //   INPUT (Cnst,Var,Abs,Null)
0x65, 0x00,                    //   Unit (None)

0x05, 0x0C,                    //   USAGE_PAGE (Consumer)
0x0A, 0x23, 0x02,              //   USAGE (AC Home)
0x0A, 0x24, 0x02,              //   USAGE (AC Back)
0x75, 0x01,                    //   REPORT_SIZE(1)
0x95, 0x02,                    //   REPORT_COUNT(2)
0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
0x25, 0x01,                    //   LOGICAL_MAXIMUM (1)
0x35, 0x00,                    //   PHYSICAL_MINIMUM (0)
0x45, 0x01,                    //   PHYSICAL_MAXIMUM (1)
0x81, 0x42,                    //   INPUT (Data,Var,Abs,Null)

0x95, 0x01,                    //   REPORT_COUNT (2)
0x75, 0x02,                    //   REPORT_SIZE (1)
0x81, 0x43,                    //   INPUT (Cnst,Var,Abs,Null)

0xc0                           // END_COLLECTION

Вот некоторые выводы, которые я смог увидеть во время тестирования: -

  1. Но приведенный выше дескриптор не будет работать в каждой игре, я смог найти только то, что в некоторых играх в Android есть возможность настроить / настроить отображение кнопок, например DEAD TRIGGER 2 - Zomb ie Survival Shooter FPS, но в таких играх осью по умолчанию для правого джойстика являются Rx и Ry, поэтому в таких играх правый джойстик и триггеры (оси, используемые для триггеров, все еще остается загадкой) должны быть отображены явно.
  2. Но в играх, где нет возможности изменить отображение кнопок, этот дескриптор HID будет работать корректно, даже триггеры (это заставило меня поверить, что это правильный способ определения дескриптора).
...