4. Linux 游戏手柄规范

作者:

2013 年 David Herrmann <dh.herrmann@gmail.com>

4.1. 引言

Linux 为游戏手柄硬件提供了许多不同的输入驱动程序。为了避免用户空间处理每个游戏手柄的不同按钮映射,本文档定义了游戏手柄应该如何报告其数据。

4.2. 几何形状

我们将 “游戏手柄” 定义为大致如下形状的设备

          ____________________________              __
         / [__ZL__]          [__ZR__] \               |
        / [__ TL __]        [__ TR __] \              | Front Triggers
     __/________________________________\__         __|
    /                                  _   \          |
   /      /\           __             (N)   \         |
  /       ||      __  |MO|  __     _       _ \        | Main Pad
 |    <===DP===> |SE|      |ST|   (W) -|- (E) |       |
  \       ||    ___          ___       _     /        |
  /\      \/   /   \        /   \     (S)   /\      __|
 /  \________ | LS  | ____ |  RS | ________/  \       |
|         /  \ \___/ /    \ \___/ /  \         |      | Control Sticks
|        /    \_____/      \_____/    \        |    __|
|       /                              \       |
 \_____/                                \_____/

     |________|______|    |______|___________|
       D-Pad    Left       Right   Action Pad
               Stick       Stick

                 |_____________|
                    Menu Pad

大多数游戏手柄具有以下特性

  • 动作键: 4 个按钮呈菱形排列(在右侧)。大多数设备上的按钮标签不同,因此我们将其定义为“北”、“南”、“西”和“东”。

  • 方向键(D-Pad):4 个按钮(在左侧),分别指向上、下、左和右。

  • 菜单键:不同的组合,但大多数时候是 2 个按钮:“选择 (SELECT)” - “开始 (START)”。此外,许多游戏手柄都有一个花哨的品牌按钮,用作特殊的系统按钮。它通常看起来与其他按钮不同,用于弹出系统菜单或系统设置。

  • 模拟摇杆:模拟摇杆提供可自由移动的摇杆来控制方向。并非所有设备都有两个或任何一个,但大多数时候它们都存在。如果您按下模拟摇杆,它们也可以提供一个数字按钮。

  • 扳机:扳机位于手柄的上侧,呈垂直方向。并非所有设备都提供它们,但上面的按钮通常被称为“左扳机”和“右扳机”,下面的按钮被称为“Z 左”和“Z 右”。

  • 震动:许多设备都提供力反馈功能。但大多数只是简单的震动马达。

4.3. 检测

所有遵循此处描述的协议的游戏手柄都映射 BTN_GAMEPAD。这是 BTN_SOUTH/BTN_A 的别名。它可用于识别游戏手柄。但是,并非所有游戏手柄都提供所有功能,因此您需要首先测试您需要的所有功能。下面描述了如何映射每个功能。

旧驱动程序通常不符合这些规则。由于我们不能为了向后兼容性而更改它们,因此您需要在用户空间中提供修复映射。其中一些还可能提供模块选项来更改映射,因此您可以建议用户设置这些选项。

所有新的游戏手柄都应该符合此映射。如果它们不符合,请报告任何错误。

有很多功能较少/性能较低的设备,它们会重复使用此协议中的按钮。但是,它们会尝试以兼容的方式执行此操作。例如,“任天堂 Wii 双截棍”提供了两个扳机按钮和一个模拟摇杆。它报告它们就像是一个只有一个模拟摇杆和右侧有两个扳机按钮的游戏手柄。但这意味着,如果您仅支持“真实”的游戏手柄,则必须测试设备报告的_所有_您需要的事件。否则,您还会获得报告一小部分事件的设备。

其他看起来/感觉不像游戏手柄的设备不得报告这些事件。

4.4. 事件

游戏手柄报告以下事件

  • 动作键

    每个游戏手柄设备至少有 2 个动作按钮。这意味着,每个设备都会报告 BTN_SOUTH(BTN_GAMEPAD 是其别名)。无论按钮上的标签是什么,都会根据按钮的物理位置发送代码。

    请注意,2 键和 3 键手柄非常罕见和陈旧。您可能需要过滤掉不报告所有四个按钮的游戏手柄。

    • 2 键手柄

      如果只有 2 个动作按钮,则它们被报告为 BTN_SOUTH 和 BTN_EAST。对于垂直布局,上面的按钮为 BTN_EAST。对于水平布局,右侧的按钮为 BTN_EAST。

    • 3 键手柄

      如果只有 3 个动作按钮,则它们被报告为(从左到右):BTN_WEST、BTN_SOUTH、BTN_EAST。如果按钮完全垂直对齐,则它们被报告为(从上到下):BTN_WEST、BTN_SOUTH、BTN_EAST

    • 4 键手柄

      如果存在所有 4 个动作按钮,则它们可以按两种不同的形式排列。如果是菱形,则根据它们的物理位置报告为 BTN_NORTH、BTN_WEST、BTN_SOUTH、BTN_EAST。如果是矩形,则左上角的按钮为 BTN_NORTH,左下角的按钮为 BTN_WEST,右下角的按钮为 BTN_SOUTH,右上角的按钮为 BTN_EAST。

  • 方向键(D-Pad)

    每个游戏手柄都提供一个具有四个方向的方向键:上、下、左、右。其中一些可用作数字按钮,另一些可用作模拟按钮。有些甚至可能同时报告两者。内核不会在两者之间进行转换,因此应用程序应同时支持两者,并在两者都被报告时选择更合适的按钮。

    • 数字按钮报告为

      BTN_DPAD_*

    • 模拟按钮报告为

      ABS_HAT0X 和 ABS_HAT0Y

    (对于 ABS 值,负值为左/上,正值为右/下)

  • 模拟摇杆

    左模拟摇杆报告为 ABS_X、ABS_Y。右模拟摇杆报告为 ABS_RX、ABS_RY。可能存在零个、一个或两个摇杆。如果模拟摇杆提供数字按钮,则它们将相应地映射为 BTN_THUMBL(第一个/左)和 BTN_THUMBR(第二个/右)。

    (对于 ABS 值,负值为左/上,正值为右/下)

  • 扳机

    扳机按钮可以作为数字或模拟按钮提供,或者两者都提供。用户空间必须正确处理任何情况并选择最合适的模式。

    上面的扳机按钮报告为 BTN_TR 或 ABS_HAT1X(右)和 BTN_TL 或 ABS_HAT1Y(左)。下面的扳机按钮报告为 BTN_TR2 或 ABS_HAT2X(右/ZR)和 BTN_TL2 或 ABS_HAT2Y(左/ZL)。

    如果只存在一个扳机按钮组合(上+下),则它们将报告为“右”扳机(BTN_TR/ABS_HAT1X)。

    (ABS 扳机值从 0 开始,压力报告为正值)

  • 菜单键

    菜单按钮始终是数字的,并根据它们的位置而不是标签进行映射。即

    • 1 键手柄

      映射为 BTN_START

    • 2 键手柄

      左按钮映射为 BTN_SELECT,右按钮映射为 BTN_START

    许多手柄还有一个第三个按钮,它带有品牌或特殊符号和含义。此类按钮映射为 BTN_MODE。例如,任天堂的 “HOME” 按钮、Xbox 的 “X” 按钮或索尼 PlayStation 的 “PS” 按钮。

  • 震动

    震动宣传为 FF_RUMBLE。

  • 配置文件

    某些手柄提供多值配置文件选择开关。例如,XBox Adaptive 和 XBox Elite 2 控制器。当切换活动配置文件时,其新选择的值将作为 ABS_PROFILE 事件发出。