evdev:查找游戏手柄轴的"rest"值



如何找到游戏控制器任何轴的静止值是多少?例如,在我的 Dualshock 4 上,以下是来自evtest的相关数据:

Event code 0 (ABS_X)
Value    126
Min        0
Max      255
Flat      15
Event code 1 (ABS_Y)
Value    127
Min        0
Max      255
Flat      15
Event code 2 (ABS_Z)
Value    255
Min        0
Max      255
Flat      15
Event code 3 (ABS_RX)
Value    127
Min        0
Max      255
Flat      15
Event code 4 (ABS_RY)
Value    123
Min        0
Max      255
Flat      15
Event code 5 (ABS_RZ)
Value      0
Min        0
Max      255
Flat      15

在上面的例子中,我在跑evtest时一直扣动右扳机;因此,ABS_Zvalue从0变成了255。那么,既然我们不能将value用于此目的,那么他们有什么方法可以找出静止值是什么吗?


编辑:我正在使用libevdevAPI访问游戏手柄。上面打印的信息可以从input_absinfo结构访问。

这通常不能仅使用evdev提供的信息来完成。

大多数游戏手柄使用前 6 个轴报告轴输入(操纵杆和触发器(:

ABS_X
ABS_Y
ABS_Z
ABS_RX
ABS_RY
ABS_RZ

左摇杆始终使用ABS_X和ABS_Y。右摇杆有时使用ABS_Z和ABS_RZ,但也可以使用ABS_RX和ABS_RY DS4 就是这种情况。对于操纵杆轴,中性值介于最小值和最大值之间。

触发器通常使用剩余的内容。例如,如果右摇杆是ABS_Z/ABS_RZ则触发器通常是ABS_RX/ABS_RY。某些游戏手柄改用 ABS_BRAKE/ABS_GAS。对于触发轴,中性值为最小值。

某些设备正确报告操纵杆轴的负最小值。例如,以下是evtest通过USB连接的Xbox One控制器获得的内容:

Event code 0 (ABS_X)
Value      0
Min   -32768
Max    32767
Fuzz      16
Flat     128
Event code 1 (ABS_Y)
Value      0
Min   -32768
Max    32767
Fuzz      16
Flat     128
Event code 2 (ABS_Z)
Value      0
Min        0
Max     1023
Event code 3 (ABS_RX)
Value      0
Min   -32768
Max    32767
Fuzz      16
Flat     128
Event code 4 (ABS_RY)
Value      0
Min   -32768
Max    32767
Fuzz      16
Flat     128
Event code 5 (ABS_RZ)
Value      0
Min        0
Max     1023

在这种情况下,驱动程序 (xpad( 识别设备并知道每个轴的逻辑范围,而无需依赖设备报告的信息。DS4 的问题在于它是一个符合 HID 标准的游戏手柄。HID 协议允许设备定义其逻辑范围,DS4 报告每个轴的最小值为 0。DS4 驱动程序(hid-sony(按原样报告这些轴边界。

下面是定义操纵杆轴的 DS4 HID 报告描述符部分的外观:

0x09, 0x30,        //   Usage (X)
0x09, 0x31,        //   Usage (Y)
0x09, 0x32,        //   Usage (Z)
0x09, 0x35,        //   Usage (Rz)
0x15, 0x00,        //   Logical Minimum (0)
0x26, 0xFF, 0x00,  //   Logical Maximum (255)
0x75, 0x08,        //   Report Size (8)
0x95, 0x04,        //   Report Count (4)
0x81, 0x02,        //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)

带有"用法"的行定义每个轴输入使用哪些轴。X、Y、Z 和 Rz 在 evdev 中被翻译成 ABS_X、ABS_Y、ABS_Z ABS_RZ。轴范围由适用于所有四个轴的"逻辑最小值"和"逻辑最大值"定义。我们还可以从"报告大小"中看到,每个轴都是一个 8 位值。

以下是定义触发器的部分,请注意,逻辑范围的定义与操纵杆轴的定义完全相同:

0x09, 0x33,        //   Usage (Rx)
0x09, 0x34,        //   Usage (Ry)
0x15, 0x00,        //   Logical Minimum (0)
0x26, 0xFF, 0x00,  //   Logical Maximum (255)
0x75, 0x08,        //   Report Size (8)
0x95, 0x02,        //   Report Count (2)
0x81, 0x02,        //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)

由于这些歧义,您不能仅仅依靠启发式方法来区分扳机轴和操纵杆轴。为了在一般情况下做到这一点,您需要一个已知游戏手柄的注册表,告诉您哪些输入映射到哪些轴。SDL2 非常适合此,它有一个庞大的游戏手柄注册表,包括许多控制台游戏手柄,如 DS4。

https://github.com/spurious/SDL-mirror/blob/master/src/joystick/controller_type.h#L72

相关内容

  • 没有找到相关文章

最新更新