游戏手柄 - Arch Linux 中文维基

跳转到内容

# 游戏手柄

来自 Arch Linux 中文维基
翻译状态：

- 本文（或部分内容）译自 Gamepad，最近一次同步于 2024-11-14，若英文版本有所更改，则您可以帮助同步与翻译更改的内容。
- 您可以在 ArchWiki 的对应页面找到本文翻译的原始修订历史。
- 本文可能与英文原文存在出入。

如今，许多游戏手柄可以开箱即用，但由于不同应用程序对游戏手柄的支持差异很大，仍然存在许多潜在的问题和错误来源。

这篇文章的某些内容需要扩充。

原因：Need info about differences between API, how to switch between them. (在 Talk:游戏手柄#Joystick API vibration support 中讨论)

Linux 有两种不同的游戏手柄输入系统——原始的Joystick接口和基于evdev的新接口。

`/dev/input/jsX` 对应 Joystick API 接口而 `/dev/input/event*` 对应于 evdev 接口（这也包括其他输入设备，如鼠标和键盘。 这些设备的符号链接也可以在 `/dev/input/by-id/` 和 `/dev/input/by-path/` 中找到，其中原始的Joystick API 设备名称以 `-joystick` 结尾，而 evdev 设备名称则以 `-event-joystick` 结尾。

大多数新游戏默认使用 evdev 接口，因为它能够提供更详细的按钮和轴的信息，并且还支持力反馈。

许多应用使用 SDL 来访问游戏手柄。

- SDL1 默认使用 evdev 接口， 但可以通过设置环境变量 `SDL_JOYSTICK_DEVICE=/dev/input/js0` 强制使用Joystick。
- SDL2 和 SDL3 默认在最常用的控制器上使用 hidapi，以获得原始访问权限。在其他控制器上，或者如果 hidapi 被禁用，则使用 evdev 代替。

SDL 本身提供了不同的 API，具体使用哪个取决于应用程序。它们的使用是相互独立的，并不是互相排斥的。

- `SDL_Joystick` 在所有版本中都被支持，并将 evdev（或 Joystick）事件与 SDL 自己的事件一一映射。
- `SDL_GameController` 在 SDL2 中得到支持，提供了设备之间的标准化映射。 要支持一个控制器，它需要在一个数据库 `gamecontrollerdb.txt` 中建立 evdev:SDL 映射。 这个 API 在 SDL3 中被 `SDL_Gamepad` 替代。

## 安装

除非你使用的是非常老旧的joystick，且它采用 Gameport 或专有的 USB 协议，否则只需要使用通用的 USB 人机接口设备（HID）模块即可。

要全面了解 Linux 中与joystick相关的所有模块， 你需要访问 Linux 内核源代码——特别是文档部分。 遗憾的是，官方内核软件包并不包含我们需要的内容。如果你已经下载了内核源代码，请查看 `Documentation/input/joydev/`. 你也可以通过访问点击 kernel.org 来浏览内核源代码树。方法是点击你所使用的内核版本旁边的“browse”链接（cgit——git 前端），然后点击页面顶部的“tree”链接。 或者，你也可以查看。最新内核的文档。

有些手柄需要特定的模块， 例如 Microsoft Sidewinder controllers (`sidewinder`)， 或者 Logitech digital controllers (`adi`). 许多老式手柄可以使用简单的 `analog` 模块。 如果你的手柄是通过声卡的游戏端口连接的，你需要加载声卡驱动程序。不过, 有些声卡, （如 Soundblaster Live）有专门的游戏端口驱动 (`emu10k1-gp`). 而一些老式的 ISA 声卡可能需要使用 `ns558` 模块，这是一个标准的游戏端口模块。

如你所见，有许多不同的模块都与在 Linux 中使用手柄有关，因此这里并未涵盖所有内容。详情请查看上述文档。

### 加载模拟设备的模块

你需要为游戏端口加载一个模块 (如 `ns558`, `emu10k1-gp`, `cs461x`... )，为手柄加载一个模块(如`analog`, `sidewinder`, `adi`...), 最后加载内核手柄设备驱动 (`joydev`)。 你可以在启动时加载这些模块 或者用 modprobe 命令手动加载。`gameport` 模块应该会自动加载，因为它是其他模块的依赖项。

### USB 手柄

你需要让 USB 正常工作，然然后使用 modprobe 命令加载你的游戏手柄驱动，通常是 `usbhid`, 以及 `joydev`。 如果你使用的是 USB 鼠标或键盘， `usbhid` 模块会自动加载， 时你只需要加载 `joydev` 模块即可。

注意：如果你的 Xbox 360 游戏手柄是通过 Play&Charge USB 数据线连接的，它会在 `lsusb` 中显示，b但不会作为输入设备出现在 `/dev/input/js*`中。详情请参见 #Xbox 360 controller.

## 配置

### 测试

一旦模块加载完成，你应该能够找到一个新设备:`/dev/input/js0` 以及一个以 `-event-joystick` 结尾的文件，位于 `/dev/input/by-id` 目录下。 你可以通过 `cat` 命令查看这些设备是否正常工作——推动操纵杆、按下任意按键 - 应该能看到乱码输出，表明设备正在正常工作。

如果出现权限错误，请参阅 #设备权限.

Wine 使用 SDL 来模拟 DirectInput 和 XInput，若不支持，则回退到 evdev 。你可以通过运行 `wine control joy.cpl`来测试。 对于 PlayStation 4 和 5 控制器，详见#Using with Wine.

#### Joystick API

有很多应用程序可以用来测试这个旧的 API。, `jstest` (来自 joyutils包 ) 是其中最简单的。如果输出因为行太长而难以阅读，你也可以使用图形化工具。 KDE Plasma 在系统设置 > 输入和输出 > 游戏控制器中内置了一个测试工具。还有 jstest-gtk-gitAUR 可供选择。

使用 `jstest` 非常简单， 只需运行 `jstest /dev/input/js0` 它会打印一行，显示所有摇杆的 (normalised to `{-32767,32767}`) 和按钮状态。

启动`jstest-gtk`后, 它会显示一个可用的游戏杆列表，你只需要选择一个设备，然后点击“属性”按钮。

#### evdev API

'evdev' API 可以通过 `evtest` (来自evtest包) 或 `evtest-qt` (来自evtest-qt-gitAUR)。

要测试设备上的震动反馈，可以使用 `fftest` (来自linuxconsole包):

    $ fftest /dev/input/by-id/usb-*event-joystick

#### SDL APIs

安装 sdl-jstest-gitAUR. 如果连接了多个控制器，请使用 `sdl2-jstest --list` 来获取它们的 ID。

To test the `SDL_Joystick` API on device index 0:

    $ sdl2-jstest --test 0

要测试设备索引为 0 的 `SDL_GameController` API:

    $ sdl2-jstest --gamecontroller 0

#### HTML5 Gamepad API

访问 https://gamepad-tester.com/。 目前，在 Chromium 中支持测试震动和生成游戏手柄的可视化，但 Firefox 不支持。此外，从版本 107.0.5304.121-1 开始，Chromium 可以读取 Joystick 设备，但不能读取 evdev 设备。

### 设置死区和校准

这篇文章的某些内容需要扩充。

原因：Describe calibration instructions for evdev (在 Talk:游戏手柄#Unclear instructions on how to calibrate 中讨论)

如果你想设置（或完全移除）模拟输入的死区，你需要分别为 xorg（用于鼠标和键盘仿真）、Joystick API 和 evdev API 进行设置。

#### 在 Wine 中设置死区

添加以下注册表项并将其设置为 `0` 到 `10000` (影响所有摇杆):

    HKEY_CURRENT_USER\Software\Wine\DirectInput\DefaultDeadZone

Source: Useful Registry Keys

#### Xorg deadzones

在 `/etc/X11/xorg.conf.d/51-joystick.conf` 中添加类似的一行（如果不存在，则需要创建）:

    /etc/X11/xorg.conf.d/51-joystick.conf

    Section "InputClass"
        Option "MapAxis1" "deadzone=1000"
    EndSection

`1000` 是默认值， 你可以设置 `0` 到 {{`30000`之间的任何值。 To get the axis number see the "Testing Your Configuration" section of this article. If you already have an option with a specific axis just type in the `deadzone=value` at the end of the parameter separated by a space.

#### Joystick API 死区和校准

最简单的方法是使用 jstest-gtk-gitAUR中的jstest-gtk 。 选择你想编辑的游戏手柄，点击 Properties（属性）按钮。 在新窗口中，点击 Calibration（校准）按钮 (不要点击 Start Calibration). 然后，你可以设置 `CenterMin` 和 `CenterMax` 值，这两个值控制中心死区; `RangeMin` 和 `RangeMax`，值控制扳机死区的末端。 请注意，校准设置会在应用程序打开设备时生效，因此你需要重新启动你的游戏或测试应用程序，才能看到更新后的校准设置。

在设置完死区后，你还可以创建一个 udev 规则，使所有更改永久生效：

首先，获取手柄的供应商 ID（将`X`替换为手柄编号，通常为`0`）

    $ udevadm info -q property --property ID_VENDOR_ID --value /dev/input/jsX

Also grab the model id:

    $ udevadm info -q property --property ID_MODEL_ID --value /dev/input/jsX

如果上述命令的输出为空，可能是因为控制器是通过蓝牙连接的，因此这些唯一属性只能在父设备上看到。为避免这种情况，您可以尝试运行以下命令查找其他唯一属性：

    $ udevadm info -a /dev/input/jsX

这将列出您设备（及其父设备）所有可用的属性。例如，如果您的操纵杆的父设备具有属性 `ATTRS{uniq}=="a0:b1:c2:d3:e4:f5"`, 或者可能同时具有 `ATTRS{idVendor}=="054c"` 和 `ATTRS{idProduct}=="09cc"`, 那么您可以在下面的 udev 规则中使用这些属性来替代 `ENV{ID_VENDOR_ID}` 和 `ENV{ID_MODEL_ID}`

您也可以同时使用这两条规则，只需用换行将它们分开。

总之，现在使用 jscal 来输出手柄的新校准设置：

    $ jscal -p /dev/input/jsX

现在，使用您获得的值修改这个 udev 规则：

    /etc/udev/rules.d/85-jscal-custom-calibration.rules

    ACTION=="add", KERNEL=="js[0-9]*", ENV{ID_VENDOR_ID}=="054c", ENV{ID_MODEL_ID}=="09cc", RUN+="/usr/bin/jscal -s 1,1,1,1 /dev/input/js%n"

这条规则将在您连接具有供应商 ID 为 `054c` 和型号 ID 为 `09cc` 的手柄时，自动运行 `/usr/bin/jscal -s 1,1,1,1 /dev/input/js%n`。其中的 `/dev/input/js%n` 部分是必需的，用于自动确定正确的摇杆，因此请不要删除它。

最后, 加载新的 udev 规则.

#### evdev API 死区和校准

    linuxconsole包 中的evdev-joystick工具 可以用来查看和更改  evdev 设备的死区。

查看设备配置：

    $ evdev-joystick --showcal /dev/input/by-id/usb-*-event-joystick

要更改某个摇杆的死区，可以使用类似以下的命令：

    $ evdev-joystick --evdev /dev/input/by-id/usb-*-event-joystick --axis 0 --deadzone 0

要同时为所有摇杆设置相同的死区，请省略`--axis 0`选项。

使用 udev 规则文件可以在控制器连接时自动设置这些参数。

请注意，在内核中，该值被称为 `flatness`，并通过 `EVIOCSABS` `ioctl` 来设置。

默认配置与此类似：

    $ evdev-joystick --showcal /dev/input/by-id/usb-Madcatz_Saitek_Pro_Flight_X-55_Rhino_Stick_G0000090-event-joystick

    Supported Absolute axes:
       Absolute axis 0x00 (0) (X Axis) (min: 0, max: 65535, flatness: 4095 (=6.25%), fuzz: 255)
       Absolute axis 0x01 (1) (Y Axis) (min: 0, max: 65535, flatness: 4095 (=6.25%), fuzz: 255)
       Absolute axis 0x05 (5) (Z Rate Axis) (min: 0, max: 4095, flatness: 255 (=6.23%), fuzz: 15)
       Absolute axis 0x10 (16) (Hat zero, x axis) (min: -1, max: 1, flatness: 0 (=0.00%), fuzz: 0)
       Absolute axis 0x11 (17) (Hat zero, y axis) (min: -1, max: 1, flatness: 0 (=0.00%), fuzz: 0)

而更合理的设置应该是这样的（其他轴重复）：

    $ evdev-joystick --evdev /dev/input/by-id/usb-Madcatz_Saitek_Pro_Flight_X-55_Rhino_Stick_G0000090-event-joystick --axis 0 --deadzone 512

    Event device file: /dev/input/by-id/usb-Madcatz_Saitek_Pro_Flight_X-55_Rhino_Stick_G0000090-event-joystick
     Axis index to deal with: 0
     New dead zone value: 512
     Trying to set axis 0 deadzone to: 512
       Absolute axis 0x00 (0) (X Axis) Setting deadzone value to : 512
     (min: 0, max: 65535, flatness: 512 (=0.78%), fuzz: 255)

#### xboxdrv 死区和校准

创建虚拟 Xbox 360 控制器的示例命令，`Y1`轴的死区设置为`4000`,，最小可读值为`-32768` ，中心点为`128`，最大值为`29000`。

    # xboxdrv --deadzone 4000 --calibration Y1=-32768:128:29000

更多选项请参见xboxdrv(1) § AXIS FILTER

### 禁用摇杆控制鼠标

如果您想使用手柄玩游戏，您可能需要禁用它对鼠标光标的操控。

最简单的方法是禁用桌面环境设置中的鼠标设备。否则，编辑 `/etc/X11/xorg.conf.d/51-joystick.conf`（如果不存在，可以创建），使其内容如下所示：

    /etc/X11/xorg.conf.d/51-joystick.conf

    Section "InputClass"
            Identifier "joystick catchall"
            MatchIsJoystick "on"
            MatchDevicePath "/dev/input/event*"
            Driver "joystick"
            Option "StartKeysEnabled" "False"
            Option "StartMouseEnabled" "False"
    EndSection

### 使用游戏手柄发送键盘按键

有几个程序可以将游戏手柄按钮映射到键盘按键：

- qjoypadAUR
- antimicrox包
- sc-controllerAUR
- steam包 - see Steam#Steam Input

所有操作都能正常工作，无需额外的 X.org 配置。

#### Xorg 配置示例

对于很少重启 Xorg 的系统来说，这是一个很好的解决方案，因为它是静态配置，只在 X 启动时加载。 示例在Kodi媒体 PC 上运行，使用 Logitech Cordless RumblePad 2 控制。 由于 d-pad（即“十字方向键”）被识别为另一个轴的问题，使用了 Joy2Key 作为解决方法。由于 kodi包 11.0 版本 和 joy2keyAUR 1.6.3-1 版本 之后，这种设置不再有效，因此创建了以下配置，允许 Xorg 处理摇杆事件。

首先, 安装 xf86-input-joystickAUR 。 然后，创建一个 X 配置文件：

    /etc/X11/xorg.conf.d/51-joystick.conf

    Section "InputClass"
      Identifier "Joystick hat mapping"
      Option "StartKeysEnabled" "True"
      #MatchIsJoystick "on"
      Option "MapAxis5" "keylow=113 keyhigh=114"
      Option "MapAxis6" "keylow=111 keyhigh=116"
     EndSection

注意：`MatchIsJoystick "on"` 这一行似乎不是必需的，但您可能需要取消注释以确保配置能够正常工作。

### 游戏手柄按钮重新映射及更多配置

通过某些程序，您还可以进一步配置游戏手柄，包括以下潜在功能：

- 重新映射按钮和轴
  - 为不同游戏分配映射配置文件
- 模拟不同类型的游戏手柄。某些软件允许将游戏手柄模拟为另一种类型的控制器。比如，很多程序和游戏在识别 Xbox 360 控制器时表现更好，因为它是非常常见的控制器，且许多游戏已经在其上进行过优化和测试
- 额外功能，如宏、屏幕显示等

软件列表:

- SC Controller — Open-source software supporting button remapping and Xbox 360 Controller emulation.

  https://github.com/Ryochan7/sc-controller || sc-controllerAUR

- Steam — Proprietary storefront whose client supports rebinding gamepad inputs via Steam Input. When enabled, Steam exposes a Steam Controller to games that opt into the Steam Input API, as well as an emulated Xbox 360 Controller to games using traditional gamepad APIs. See Steam#Steam Input for further details.

  https://store.steampowered.com/about/ || steam包

- xboxdrv — Xbox 360 controller driver which supports emulating the controller from a different input controller. See #Mimic Xbox 360 controller. It's also a flexible option for remapping and calibration.

  https://github.com/xiota/xboxdrv || xboxdrvAUR

#### 在 SDL2 应用程序上重新映射游戏手柄

可以通过使用 `SDL_GAMECONTROLLERCONFIG` 环境变量重新映射 SDL2 应用程序中的游戏手柄。每行配置包括游戏手柄的 GUID、名称、按钮/轴映射以及平台。要获取控制器的 GUID，可以通过安装 sdl-jstest-gitAUR 然后运行 `sdl2-jstest --list` 来获取。

例如，要映射具有不同 GUID 的 Microsoft Xbox 360 控制器 For example, to map Microsoft Xbox 360 controllers with different GUIDs:

    ~/.bashrc

    export SDL_GAMECONTROLLERCONFIG="
    030000005e0400008e02000001000000,Microsoft Xbox 360,a:b0,b:b1,back:b6,dpdown:h0.1,dpleft:h0.2,dpright:h0.8,dpup:h0.4,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
    030000005e0400008e02000004010000,Microsoft Xbox 360,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
    "

一些应用程序从 `gamecontrollerdb.txt` 文件中提取映射信息。可以通过 controllermapAUR 以图形方式进行编辑。最新的数据库可以在以下位置找到[1]

#### 模拟 Xbox 360 控制器

xboxdrv 可以通过 `--mimic-xpad` 选项将任何控制器模拟为 Xbox 360 控制器。这对于那些原生支持 Xbox 360 控制器，但在检测或使用其他游戏手柄时出现问题的游戏来说，可能会很有用。

你可以使用以下命令来模拟 Xbox 360 控制器：

    $ xboxdrv --evdev /dev/input/event* --evdev-absmap ABS_RX=X2 --evdev-keymap BTN_THUMB2=a,BTN_THUMB=b,BTN_PINKIE=rt --mimic-xpad

上面的示例是不完整的。它仅映射了一个轴和三个按钮用于演示。可以使用 `xboxdrv --help-button` 查看 Xbox 控制器按钮和轴的名称，并通过扩展上述命令来相应地绑定它们。轴映射应放在 `--evdev-absmap` 后面，按钮映射应放在 `--evdev-keymap` 后面（以逗号分隔的列表；不带空格）。

默认情况下，xboxdrv 会将所有事件输出到终端。你可以使用这一功能来测试映射是否正确。如果想保持静默，可以附加 `--silent` 选项。

## 特定设备

虽然大多数游戏手柄，尤其是基于 USB 的游戏手柄都能正常工作，但有些游戏手柄可能需要使用其他驱动程序（或使用其他驱动程序会有更好的效果）。

### 跳舞毯

大多数舞毯垫应该都能正常工作。然而，一些舞蹈毯，尤其是通过适配器从游戏主机连接的舞蹈毯，往往会将方向按钮映射为轴按钮。这会导致无法同时按下左-右或上-下方向键。对于 xpad 识别的设备，可以通过模块选项修复此行为：

    # modprobe -r xpad
    # modprobe xpad dpad_to_buttons=1

如果这样做无效，你可以尝试使用 axisfix-gitAUR 或者修补 `joydev` 内核模块（https://github.com/adiel-mittmann/dancepad）。

### 罗技 Thunderpad Digital

如果使用 `analog`模块，Logitech Thunderpad Digital 将无法显示所有按钮。请使用该控制器专用的 `adi` 模块。

### 任天堂GAMECUBE控制器

Dolphin 模拟器的 Wiki 上有一页解释了如何使用官方的 Nintendo USB 适配器连接 GameCube 控制器。如果将开关设置为“Wii U”，此配置也适用于 Mayflash 控制器适配器。

对于其他应用程序，你可以使用 wii-u-gc-adapterAUR。

### 任天堂 Switch Pro 控制器和 Joy-Con 控制器

这些控制器从内核版本 5.16 开始得到支持。Switch Online 的 NES、SNES 和 N64 控制器从内核版本 6.12 开始也得到支持。

对于较早的内核版本，可以安装 DKMS 模块 hid-nintendo-nso-dkmsAUR。

#### 将 Joy-Con 作为一个设备使用

hid-nintendo 内核驱动将两个 Joy-Con 控制器处理为两个独立的设备。

joycond-gitAUR 是一个用户空间守护进程，它使用 uinput 将两个内核中的 Joy-Con evdev 设备合并为一个虚拟输入设备。当守护进程处于活动状态时，Switch 控制器将进入伪配对模式，LED 灯会开始闪烁。按住扳机可以用来配对控制器并使其可用。要将两个 Joy-Con 配对在一起，按下每个 Joy-Con 上的扳机。

#### 在 SDL2 应用程序中使用位置布局

默认情况下，SDL2 会根据游戏手柄的标签映射 Nintendo 控制器上的按钮，而不是根据按钮的位置。这是通过 SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS 设置启用的，对于已知使用 Nintendo 按钮布局的控制器[2] ，该设置默认为 `1` ，而对于其他控制器[3]则默认为 `0`。可以通过设置 `SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS` 环境变量来覆盖所有控制器的此行为。例如，如果不希望使用 Nintendo 的 A/B 和 X/Y 按钮布局，可以设置 `SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS=0`

### Steam 控制器

注意：内核 4.18 提供了一个内核驱动程序，可以在没有 Steam 的情况下将 Steam 控制器作为有线/无线控制器输入设备使用。

Steam 客户端会识别控制器，并在 Steam 运行时提供键盘/鼠标/游戏手柄仿真。要使游戏手柄仿真正常工作，需要启用并确保 Steam 游戏内覆盖层处于工作状态。如果在安装并运行 Steam 后控制器无法立即工作，可能需要以 root 权限运行 `udevadm trigger`，或者拔出并重新插入适配器。如果仍然无效，尝试在适配器插入的状态下重启计算机。

如果你使用的是通过 Bluetooth LE 连接的控制器，请确保用户属于 `input` 组。

如果你无法让 Steam 控制器正常工作，请参见 #Steam 控制器无法配对。

注意：If you do not use the Steam runtime, you might actually need to disable the overlay for the controller to work in certain games (Rocket Wars, Rocket League, Binding of Isaac, etc.). Right click on a game in your library, select "Properties", and uncheck "Enable Steam Overlay".

### Xbox 360 控制器

有线和无线（使用 Xbox 360 Wireless Receiver for Windows）控制器都受到 `xpad` 内核模块的支持，并且应该无需额外的包即可正常工作。请注意，使用 Play&Charge USB 数据线连接无线 Xbox 360 控制器是无法正常工作的。该数据线仅用于充电，不能通过线缆传输任何输入数据。

有报告指出，默认的 xpad 驱动程序在某些较新的有线和无线控制器上存在一些问题，例如：

- incorrect button mapping. (discussion in Steam bugtracker)
- not-working sync. (discussion in Arch Forum)
- all four LEDs keep blinking, but controller works. TLP's USB autosuspend is one sure cause of this issue with wireless controllers. See below for fix.

如果你使用 TLP 电源管理工具，可能会遇到与 Microsoft 无线适配器的连接问题（例如，适配器连接几秒钟后指示灯熄灭，且控制器连接尝试失败，四个 LED 持续闪烁，但控制器仍然可以正常工作）。这是由于 TLP 的 USB 自动挂起功能导致的，解决方法是将 Microsoft 无线适配器的设备 ID 添加到 TLP 黑名单中（要检查设备 ID，可以运行 `tlp-stat -u`；对于原版的 MS 无线适配器，只需将 `USB_DENYLIST="045e:0719"` 添加到 `/etc/tlp.conf`中）。有关更多细节，请查看 TLP 配置。

如果你遇到此类问题，可以改为使用 #xboxdrv 作为默认的 `xpad` 驱动程序。

为了通过蓝牙连接，请添加以下内核参数：`bluetooth.disable_ertm=1`。

如果你在游戏中遇到震动功能无法正常工作的情况，可能需要设置环境变量 `SDL_JOYSTICK_HIDAPI=0`。

#### xboxdrv

这一章节正在考虑移除。

原因: The driver portion of xboxdrv is deprecated. (在 Talk:游戏手柄 讨论)

xboxdrv is an alternative to `xpad` which provides more functionality and might work better with certain controllers. It works in userspace and can be launched as system service.

Install it with the xboxdrvAUR package. Then start/enable `xboxdrv.service`.

If you have issues with the controller being recognized but not working in steam games or working but with incorrect mappings, it may be required to modify you configuration as such:

    /etc/default/xboxdrv

    [xboxdrv]
    silent = true
    device-name = "Xbox 360 Wireless Receiver"
    mimic-xpad = true
    deadzone = 4000

    [xboxdrv-daemon]
    dbus = disabled

Then restart `xboxdrv.service`.

##### 多个控制器

xboxdrv 支持多种控制器，但需要在 `/etc/default/xboxdrv` 中进行配置。对于每个额外的控制器，添加一行 `next-controller = true`。例如，当使用 4 个控制器时，需要添加 3 次：

    [xboxdrv]
    silent = true
    next-controller = true
    next-controller = true
    next-controller = true
    [xboxdrv-daemon]
    dbus = disabled

然后 restart `xboxdrv.service`.

#### 使用通用/克隆控制器

一些克隆游戏手柄可能需要特定的初始化序列才能正常工作（Super User answer）。为此，你应该以 root 用户身份运行以下 Python 脚本：

    #!/usr/bin/env python3

    import usb.core

    dev = usb.core.find(idVendor=0x045e, idProduct=0x028e)

    if dev is None:
        raise ValueError('Device not found')
    else:
        dev.ctrl_transfer(0xc1, 0x01, 0x0100, 0x00, 0x14)

### Xbox 无线控制器 / Xbox One 无线控制器

#### 通过 USB 数据线连接 Xbox 无线控制器

这是由内核支持的，并且无需任何额外的包即可正常工作。

#### 通过蓝牙连接 Xbox 无线控制器

##### 通过 Windows 10 更新控制器固件

Xbox 无线控制器的固件曾导致与 Bluez 连接/断开连接的循环问题。最佳的解决方法是将控制器（通过 USB 数据线）连接到 Windows 10 计算机，下载 Xbox Accessories 应用程序（通过 Microsoft Store），并更新控制器的固件。

##### xpadneo

一个相对较新的驱动程序叫做 xpadneo，它支持通过蓝牙连接 Xbox One S 和 Xbox Series X|S 控制器。除了这两个型号，它还为 Xbox Elite Series 2 无线控制器提供了基本支持。虽然目前只完全支持这两款控制器，但它提供了许多增强功能，包括读取正确的电池电量、支持震动（甚至包括触发按钮上的震动 - L2/R2）、修正（有时错误的）按钮映射等。

安装可以通过 DKMS 完成：xpadneo-dkmsAUR。

注意：第一次配对 Xbox One S 控制器时可能会遇到一些困难，从完全无法配对到进入连接/断开循环。这些问题可以在 [这里] 找到相关描述。可靠地配对控制器的最佳方法是先在 Windows 10 中配对。但需要注意的是，这必须使用相同的蓝牙适配器。一个解决方案是，在虚拟机中安装免费的 Windows 10 企业版（使用 QEMU 或 VirtualBox，并确保蓝牙适配器通过 USB 设备正确传递），以 Arch Linux 作为主机，然后首先在 Windows 10 中进行配对，再在 Arch Linux 系统中执行相同的操作。之后，配对将成功，并且不再需要使用 Windows 10。

#### 通过 Microsoft Xbox 无线适配器连接 Xbox 无线控制器

xone 是一个 Linux 内核驱动程序，用于支持 Xbox One 和 Xbox Series X|S 配件。它作为一个现代替代品，取代了 xpad 和 xow。目前可以通过有线连接或使用 Microsoft Xbox 无线适配器“适配器”正常工作。该驱动程序的 bug 修复目前由 dlundqvist fork 维护。

安装 xone-dkms-gitAUR，如果使用无线适配器，还需要安装 xone-dongle-firmwareAUR。安装完成后需要重启系统。

注意：

- 需要与你的内核对应的头文件; 请参见 DKMS#安装
- 该适配器使用基于 mt76 的 802.11/15 芯片组，这可能会导致与连接到同一系统或附近的其他无线适配器产生干扰

##### 控制器配对后表现不佳（回报率低）

你需要在 Windows 中使用 Microsoft Store 的 "Xbox Accessories" 应用程序来更新控制器固件。理论上，通过将 USB 设备传递到 Windows 虚拟机中也应该能够完成此操作，但你可能需要双重启动到一个实际的（裸机）Windows 系统，以便 Xbox Accessories 应用能够识别控制器并进行固件更新。

##### 与 Windows 双启动

在 Windows 中配对控制器和适配器可能会导致在 Linux 中丢失配对。每次重启进入 Linux 时，你需要重新配对控制器和适配器。这种情况也会反过来发生——当控制器和适配器在 Linux 中配对时，下次你想在 Windows 中使用它们时，也需要重新配对。

##### 挂起和唤醒后无法连接。

在某些平台上，挂起可能会导致设备进入一个无法正常响应的状态。由于设备被 Linux 识别为蓝牙适配器，因此在挂起时会自动进入关机状态，这也会禁用通过游戏手柄唤醒系统的功能。可以通过在内核命令行中使用 `btusb.enable_autosuspend=n`来缓解此问题。注意：这将禁用系统中所有其他 USB 蓝牙适配器的电源挂起功能。

### PlayStation 3 控制器

#### 通过USB连接

如果你拥有一个 PS3 控制器并且可以通过 USB 连接，将其插入电脑并按下 PS 按钮。控制器将启动，四个 LED 中的一个应该会亮起，表示控制器的编号。

#### 通过蓝牙连接

安装 bluez包 和 bluez-utils包。按照蓝牙#配对的前五个步骤确保蓝牙正常工作，并保持 bluetoothctl 命令运行。然后，通过按下中间的 'PS' 按钮打开控制器（所有 4 个 LED 应该快速闪烁，大约 4 Hz），并通过 USB 将控制器连接到你的电脑。最后，当 bluetoothctl 出现下面的提示输入"yes" `Authorize service 00001124-0000-1000-8000-00805f9b34fb (yes/no)` 替代说明： 要通过蓝牙将 PS3 控制器连接到电脑，首先需要安装 bluez包，然后通过 USB 连接控制器。弹出窗口应会提示进行配对，点击 Trust & Authorize。现在你可以拔掉控制器并按下 PS 按钮，控制器将连接并且一个 LED 会保持常亮。此时你可以用它来玩游戏。仅在控制器已经连接到其他系统后，才需要使用 USB 数据线进行连接。

注意： 在最新版本的 bluez包（截至 2024/01/03），出于安全原因，`ClassicBondedOnly` 的默认值已从 `false` 更改为 `true` [4]。此更改导致无法配对 Dual Shock 3 控制器，因为 `bluetoothctl` 会要求输入 PIN 码，且无法继续配对。为了解决此问题，可以通过在新创建的 `/etc/bluetooth/input.conf` 文件中添加以下行，将 `ClassicBondedOnly` 设置为 `false`：

.

截至 2024年3月9日，`UserspaceHID` 的默认值也已更改为 `true`。虽然连接可以成功，但除非将该值更改为 `false`，否则控制器无法进入操作模式。有关更多信息，请参阅 GitHub issue#771。

    [General]
    ClassicBondedOnly=false
    UserspaceHID=false

请注意，此解决方案在安全性上存在倒退。有关详细信息，请参阅 GitHub。

提示：互联网上有许多关于设置 PS3 控制器的复杂说明，通常需要很多步骤，例如编译和安装 qtsixa 或 sixpair，手动设置控制器，或者用一些特定的补丁修补 bluez。但在现代 Linux 内核上如果安装了 bluez-plugins 后，这些步骤都不再是必须的。

### PlayStation 3/4 控制器

DualShock 3、DualShock 4 和 Sixaxis 控制器在通过 USB 插入时可以即插即用（需要按下 PS 按钮才能开始）。它们也可以通过蓝牙无线使用。

Steam 会正确识别它为 PS3 手柄，并且可以通过 PS 按钮启动 Big Picture 模式。Big Picture 模式和一些游戏可能会将其识别为 360 手柄。默认情况下，手柄控制鼠标功能是开启的。你可能希望在玩游戏之前关闭它，详见#禁用摇杆控制鼠标。

#### 通过蓝牙连接

安装 bluez包 和 bluez-utils包 包，其中包括 sixaxis 插件。然后启动 bluetooth 服务，并确保蓝牙已开启。如果使用 bluetoothctl，在终端中启动它，然后通过 USB 插入控制器。你应该会被提示在 bluetoothctl 中信任该控制器。图形化的蓝牙前端可能会自动将电脑的蓝牙地址写入控制器。按下 PlayStation 按钮并检查在插入时控制器是否正常工作。

现在你可以断开控制器的连接。下次按下 PlayStation 按钮时，它将自动连接，无需任何额外操作。

另外，在 PS4 控制器上，你可以同时按住分享按钮和 PlayStation 按钮（持续几秒钟）将手柄置于配对模式，然后按通常的方式进行配对。

GNOME 的设置也提供了一个图形界面，当控制器通过有线连接时，可以配对 sixaxis 控制器。

记得在使用完后断开控制器的连接，因为控制器在连接时会一直处于开启状态，从而耗尽电池。

注意：如果控制器未能连接，请确保蓝牙接口已开启，并且控制器已被信任。 (详情见 蓝牙)

#### 使用通用/克隆控制器

使用通用/克隆 Dualshock 控制器是可行的，但有一个问题可能需要安装一个补丁包。默认的蓝牙协议栈无法检测到某些克隆控制器。bluez-ps3AUR 包是一个经过补丁的版本，能够检测这些控制器。bluez-plugins-ps3AUR 是另一个包，它只对 bluez-plugins 进行补丁，可能适用于某些控制器。

### PlayStation 4/5 控制器

#### 通过 USB 连接

通过 USB 连接你的控制器并按下 `PS` 按钮。

#### 通过蓝牙连接

如果你想使用蓝牙模式，请同时按住 `PS` 按钮和 `Share` 按钮。控制器的白色 LED 应该会快速地闪烁，随后无线控制器可以与你的蓝牙管理器配对。

#### 在 Wine 中使用

对于这些控制器，Wine 默认使用 hidraw（自 8.0 起），因此支持它们的 Windows 应用程序可以使用它们的所有功能。由于这种类似 Windows 的行为，这些控制器不会作为 XInput 设备暴露，因此无法在许多应用程序中使用。 要禁用此行为，可以将以下文本文件导入 Wine 注册表 regedit:

    Windows Registry Editor Version 5.00
    [HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\winebus]
    "DisableHidraw"=dword:1

Since Wine 9.18, this setting can be controlled from `wine control joy.cpl`.

#### 禁用触摸板作为鼠标使用

如果在Xorg下使用libinput，或使用Wayland，则可以按照Libinput#禁用触摸板禁用触摸板。

注意，由于触摸板只是控制器的一部分，仅通过供应商和产品 ID 选择输入设备是不够的。相反，建议通过设备名称来选择设备。

要查看可用的完整属性集，可以使用 `udevadm info --attribute-walk --name=device_path`，其中 `device_path` 是设备的路径，例如 `/dev/input/eventn` 或 `/dev/input/by-id/identifier`。

要查找设备路径，你可以使用工具，如 evtest包，只需运行 `evtest` 命令。该命令还应打印出设备的名称。

示例代码片段:

    /etc/udev/rules.d/72-ds4tm.rules

    # Disable DS4 touchpad acting as mouse
    # USB
    ATTRS{name}=="Sony Interactive Entertainment Wireless Controller Touchpad", ENV{LIBINPUT_IGNORE_DEVICE}="1"
    # Bluetooth
    ATTRS{name}=="Wireless Controller Touchpad", ENV{LIBINPUT_IGNORE_DEVICE}="1"

对于 DualSense 控制器，将名称替换为 `Sony Interactive Entertainment DualSense Wireless Controller Touchpad` and `DualSense Wireless Controller Touchpad`.

然后，重新加载 udev 规则。重新连接游戏手柄以应用更改。

#### dualsensectl

dualsensectl 是一个可以切换灯条和麦克风（及其 LED）、监控电池状态和关闭控制器电源的工具。要使用它，[[安装］ dualsensectl-gitAUR.

## 提示与技巧

### 通过网络使用游戏手柄

如果你想通过网络将游戏手柄连接到另一台计算机，可以使用 USB/IP 或 netstick-gitAUR 来实现。

## 故障排除

### 设备权限

游戏手柄设备受 udev 规则的影响：除非这些规则授予设备访问权限，否则普通用户将无法读取设备。本节将探讨是否有可能在配置文件中处理这一问题。

Any gamepad device, regardless of whether it is over USB or Bluetooth, is handled by the "input" subsystem of the kernel, corresponding with `/dev/input`. It's also common for udev rules to target the "hidraw" kernel module. Combining these, we can understand udev's handling of these devices by inspecting the configuration shipped by packages:

    $ grep --extended-regexp 'SUBSYSTEM=="input"|KERNEL=="hidraw' --recursive /usr/lib/udev/rules.d

Some examples of applications which ship noteworthy rules:

- systemd's default rules set the group of all `input` devices to `input`, and the mode of joystick devices to `664` [5].
- Steam ships udev rules allowing access to a variety of controllers. See this Steam discussion for further info about the contents of the rules.
- Dolphin emulator ships udev rules allowing access to controllers it supports.

If your system does not already happen to have a udev rule for the device you want to use, you can either write one yourself or install the game-devices-udevAUR package and restart your computer.

注意：It is possible to add a user to the `input` group in order to give them access to all devices. However, this is not recommended [6].

### Gamepad is not recognized by all programs

Some software, Steam for example, will only recognize the first gamepad it encounters. Due to a bug in the driver for Microsoft wireless periphery devices this can in fact be the bluetooth dongle. If you find you have a `/dev/input/js*` and `/dev/input/event*` belonging to you keyboard's bluetooth transceiver you can get automatically get rid of it by creating according udev rules:

    /etc/udev/rules.d/99-btcleanup.rules

    ACTION=="add", KERNEL=="js[0-9]*", SUBSYSTEM=="input", KERNELS=="...", ATTRS{bInterfaceSubClass}=="00", ATTRS{bInterfaceProtocol}=="00", ATTRS{bInterfaceNumber}=="02", RUN+="/usr/bin/rm /dev/input/js%n"
    ACTION=="add", KERNEL=="event*", SUBSYSTEM=="input", KERNELS=="...", ATTRS{bInterfaceSubClass}=="00", ATTRS{bInterfaceProtocol}=="00", ATTRS{bInterfaceNumber}=="02", RUN+="/usr/bin/rm /dev/input/event%n"

Correct the `KERNELS=="..."` to match your device. The correct value can be found by running

    # udevadm info -an /dev/input/js0

Assuming the device in question is `/dev/input/js0`. After you placed the rule reload the rules with

    # udevadm control --reload

Then replug the device making you trouble. The joystick and event devices should be gone, although their number will still be reserved. But the files are out of the way.

### Application only supports Xbox 360 controllers

Some Windows games look for an Xbox 360 controller in particular, missing functionality (like vibration) or not working at all otherwise.

For a workaround, see #Mimic Xbox 360 controller.

### Steam 控制器

#### Steam 控制器无法配对

There are some unknown cases where the packaged udev rule for the Steam controller does not work (FS#47330). The most reliable workaround is to make the controller world readable. Copy the rule `/usr/lib/udev/rules.d/70-steam-controller.rules` to `/etc/udev/rules.d` with a later prioritiy and change anything that says `MODE="0660"` to `MODE="0666"` e.g.

    /etc/udev/rules.d/99-steam-controller-perms.rules

    ...
    SUBSYSTEM=="usb", ATTRS{idVendor}=="28de", MODE="0666"
    ...

You may have to reboot in order for the change to take effect.

#### Steam Controller makes a game crash or not recognized

If your Steam Controller is working well in Steam Big Picture mode, but not recognized by a game or the game starts crashing when you plug in the controller, this may be because of the native driver that has been added to the Linux kernel 4.18. Try to unload it, restart Steam and replug the controller.

The module name of the driver is `hid_steam`, so to unload it you may perform:

    # rmmod hid_steam

### Xbox One Wireless Gamepad detected but no inputs recognized

This can occur when using a third party Xbox One controller with the `xpad` or #xboxdrv drivers. Try switching to #xpadneo.

### Playstation 4 controllers

#### Controller not recognized when using Bluetooth

Install the ds4drvAUR package and run it with the hidraw (`ds4drv --hidraw`) backend parameter.

#### Motion controls taking over joypad controls and/or causing unintended input with joypad controls

本文或本章节的语言、语法或风格需要改进。参考：帮助:风格

原因：Could likely use the same solution as Gamepad#Disable touchpad acting as mouse, which is already refactored into other pages where appropriate.（在Talk:游戏手柄讨论）

With certain cloud gaming applications such as Parsec and Shadow, the Dualshock 4 V1 and V2 motion controls can conflict with the joypad controls resulting in the joypad not working, and with certain input sensitive games, especially racing games, the motion controls can cause unintentional drift during joypad control gameplay.

This can be worked around by disabling the motion controls and the touchpad by adding the following udev rules:

    /etc/udev/rules.d/51-disable-DS3-and-DS4-motion-controls.rules

    SUBSYSTEM=="input", ATTRS{name}=="*Controller Motion Sensors", RUN+="/bin/rm %E{DEVNAME}", ENV{ID_INPUT_JOYSTICK}=""
    SUBSYSTEM=="input", ATTRS{name}=="*Controller Touchpad", RUN+="/bin/rm %E{DEVNAME}", ENV{ID_INPUT_JOYSTICK}=""

Then reload the rules or reboot: these rules should work in both USB and Bluetooth mode.

### Multi-mode wired gamepads

本文或本章节的语言、语法或风格需要改进。参考：帮助:风格

原因：Multiple improvements to be made.（在Talk:游戏手柄讨论）

Some gamepads have 3 modes when wired: Switch, Xbox 360/Windows, Android.

And they also don't have hotkeys to switch between them when connected wired.

When you connect such gamepad to Windows, it is in Xbox 360 Controller mode.

But when you connect such gamepad to Linux, it enters the fallback mode (which happens to be the Android mode), which has a worse polling rate (100 Hz), the Home button acting as `XF86Home`; doesn't expose vibration, gyroscope, and accelerometer; doesn't support xboxdrvAUR without `--evdev`; and identifies itself as e.g. "SHANWAN Android Gamepad" which is not liked by some games (though for SDL2 apps you can set a name in `SDL_GAMECONTROLLERCONFIG`).

When you connect the gamepad, it first tries to be a "Switch Pro Controller", but for some reason the Linux kernel considers the descriptors (sent by the gamepad) invalid, and therefore disconnects the gamepad. This causes the gamepad to reconnect in the aforementioned fallback mode.

In `dmesg` this looks like:

    usb 1-5.3: new full-speed USB device number 37 using xhci_hcd
    usb 1-5.3: unable to read config index 0 descriptor/start: -32
    usb 1-5.3: chopping to 0 config(s)
    usb 1-5.3: can't read configurations, error -32
    usb 1-5.3: new full-speed USB device number 38 using xhci_hcd
    usb 1-5.3: New USB device found, idVendor=0079, idProduct=181c, bcdDevice= 1.00
    usb 1-5.3: New USB device strings: Mfr=1, Product=2, SerialNumber=0
    usb 1-5.3: Product: Android Gamepad
    usb 1-5.3: Manufacturer: SHANWAN

Notice that the "USB Device number" gets increased after the failure. For some USB hubs the error code is `-32` (EPIPE: broken pipe), for others it is `-71` (EPROTO: protocol error).

This error can be fixed by setting a quirk in `usbcore` module (not `usbhid`) for Switch controller's USB ID:

    # If you have already *manually* set quirks for other devices,
    # then don't forget to include them in the two commands below ↓
    echo -n "057e:2009:ik" | sudo tee /sys/module/usbcore/parameters/quirks

    # Optionally constant polling mode:
    sudo modprobe -r usbhid ; sleep 4 ; sudo modprobe -v usbhid "quirks=0x057e:0x2009:0x400"

`ik` are 2 flags (List of all flags).

The flag `i` means "allow bad descriptors".

And the flag `k` means "disable LPM" (link power management). It is specified in the command because it often helps devices of other types. This flag might do nothing because not all USB controllers even have LPM. You can try without `k` aftewards.

You could also try the flag `g` ("200 ms pause after reading the descriptors") because it often helps devices of other types, but at least in the case of iPEGA PG-SW038C (a $10 gamepad) flag `g` causes it infinitely reconnect.

Note that once the gamepad downgrades to the fallback mode, it will never change its mode until you reconnect it. Even `echo 0 then 1 > %sysfsGamepadDir%/authorized` doesn't work. And that's why passing the gamepad to a Windows VM would not help; `usbcore` inits USB devices before passing them to a VM.

Now reconnect the gamepad, it should be finally listed now as `ID 057e:2009 Nintendo Co., Ltd Switch Pro Controller` when you run `lsusb`. If that's true, then you can make this quirk permanent by add this option to GRUB:

`usbcore.quirks="057e:2009:ik"`

along with (optionally) `usbhid.quirks="0x057e:0x2009:0x400"` which stops the pointless blinking of LEDs when the gamepad is unused.

Now that your gamepad is in Switch mode, you'll run into a problem of SDL2 deciding to become a user-space driver (for this it uses libusb包, just like xboxdrvAUR), which causes any SDL2 game to claim the whole gamepad (that is: `/dev/input/*` and `/dev/hidraw*` disappear, yet it's still possible to play this launched game with the gamepad), so you can't use the gamepad in multiple apps anymore.

This can be fixed by adding

    SDL_HIDAPI_DISABLE_LIBUSB=1

into `/etc/environment`, and rebooting.

If you have joycond-gitAUR, then delete it, because it is useless for such Switch-like gamepads, moreover `joycond` has a `udev` rule that disallows Steam to provide its own user-space driver.

Unlike SDL2 (when it uses `/dev/hidraw*` which is its preferred way in 2023), `xboxdrv` and `/dev/input/*` provide incorrect values for the right stick's X axis (it's always ≤0). Probably a bug in `hid-nintendo` or something. For this reason `xboxdrv` is unusable in most games when in Switch mode.

You can test your gyroscope and accelerometer by launching antimicrox包. They are not available in other gamepad modes when connected wired because their values are sent mixed with other event data (RX/RY/etc) in a special format that is not fully compatible with `xpad` and `hid-generic`.

If you see in `dmesg` that `hid-generic` is used by your gamepad, then it's probably because you have built Linux kernel with your own config without `hid-nintendo`. Unfortuately, Switch mode + `hid-generic` is as useless as the fallback mode (even no vibration).

#### Xbox 360 Controller mode

After having completed everything above (i.e. 1-2 quirks, 1 envvar),

add

    blacklist hid_nintendo

into `/etc/modprobe.d/blacklist.conf`

then run `sudo mkinitcpio -P` to rebuild `/boot/initramfs*` (kernel reads `/etc/modprobe.d/` only from its own initramfs, not your rootfs)

Now create the following file:

    /etc/udev/rules.d/10-disallow-generic-driver-for-switch.rules

    # If
    # 1. a gamepad is multi-mode (Switch, X360, PC) and defaults to USB ID 057e:2009
    # AND at the same time
    # 2. `hid-nintendo` module can't be loaded (blacklisted or not compiled)
    # AND at the same time
    # 3. there's already a launched game that immediately grabs a gamepad,
    #
    # Then when you connect such gamepad, it will stay in "Switch Pro" mode,
    # but using the fallback `hid-generic` module
    # which would result in no vibration/etc
    # despite still being listed as a "Switch Pro Controller".

    # But by notifying the gamepad that we abandon to use it as an HID,
    # it automatically downgrades to "Xbox 360 Controller" mode,
    # which causes vibration and `xboxdrv` to work.
    SUBSYSTEM=="hid", DRIVER=="hid-generic", ATTRS{idVendor}=="057e", ATTRS{idProduct}=="2009", RUN="/bin/sh -c 'echo $id:1.0 > /sys/bus/usb/drivers/usbhid/unbind'"

then run `sudo udevadm control --reload-rules && sudo udevadm trigger`

Since you probably don't want to reboot, run `sudo modprobe -r hid_nintendo`

From now on, to switch ("downgrade") from Switch mode to Xbox 360 mode, just run `sudo modprobe -r hid_nintendo` (you don't even need to reconnect it). Within 2 seconds you'll have `045e:028e Microsoft Corp. Xbox360 Controller` in `lsusb`

And if you want to switch vice versa:

1. `sudo modprobe hid_nintendo` (even though it is blacklisted, this command still works because blacklisting just means "don't load this module automatically").
2. Reconnect.

##### Alternative rootless solution

If you don't have root access, then:

1. Power off your PC (not just suspend)
2. Reconnect your gamepad.
3. Power the PC on.
4. UEFI (just like non-virtualized Windows) automatically and successfully initializes the gamepad (even if it's connected through a USB hub in your monitor) despite the invalid descriptors.
5. The gamepad receives info from UEFI (or maybe GRUB) that it's no longer needed as an HID, which causes it to switch ("downgrade") to Xbox 360 Controller mode. Switching between modes is done this way: the gamepad disconnects, then connects under a different USB ID.
6. You can even suspend (without turning off the monitor if that's what it's connected to) and then wake-up the PC, and it will still be in Xbox 360 Controller mode. But if you reconnect the gamepad, it will be in the fallback mode, so you'll have to follow the instruction again.

### USB debugging

You'll probably not need to know this, but this USB ID (057e:2009) was discovered by USB debugging:

    # Allow debugging of the kernel:
    sudo ls /sys/kernel/debug/usb >/dev/null 2>&1 || sudo mount -t debugfs none_debugfs /sys/kernel/debug
    # Load the module that allows sniffing of the traffic of USB buses:
    sudo modprobe usbmon
    # We need only connection events, and in these events
    # we need only a USB ID which is in the pre-pre-last column:
    sudo /bin/grep --line-buffered -Po '(?<=0 0 18 = .{18}).{8}' /sys/kernel/debug/usb/usbmon/99999u | /bin/sed -E 's/([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})/\2\1:\4\3/'

where `99999` must be replaced with the USB Bus number that your gamepad uses, e.g. `1` (without leading zeroes). It can be found by running `lsusb`.

If nothing helped and your gamepad still works in full capacity only in Windows, you can catch USB messages while in Windows, and then replay them while in Linux. See usbrply. For this, Windows must not be in VM because Linux kernel's `usbcore` initializes a USB device before passing it to a VM. This could be avoided by buying a PCI-E USB controller and passing it through (External USB hubs can't be passed through). Or you can pass-through your motherboard's own USB controller if it is in a IOMMU group without devices important for you:

Script which lists IOMMU groups
    list-iommu-groups.sh
    #!/bin/bash
    shopt -s nullglob
    for g in $(find /sys/kernel/iommu_groups/* -maxdepth 0 -type d | sort -V); do
      echo "IOMMU Group ${g##*/}:"
      for d in $g/devices/*; do
          echo -e "\t$(lspci -nns ${d##*/})"
      done;
    done;

## Example xboxdrv configurations

这一章节正在考虑移除。

原因: xboxdrv is very rarely needed, and this section takes up a lot of space for how specific it is. (在 Talk:游戏手柄 讨论)

To give these devices a persistent name, set an udev rule in this format.

    /etc/udev/rules.d/99-btjoy.rules

    #Create a symlink to appropriate /dev/input/eventX at /dev/btjoy
    ACTION=="add", SUBSYSTEM=="input", ATTRS{name}=="Bluetooth Gamepad", ATTRS{uniq}=="00:17:02:01:ae:2a", SYMLINK+="btjoy"

Replace "Bluetooth Gamepad" with your device name and "00:17:02:01:ae:2a" with your device's address.

When you have the configuration and your device is connected you can start the xboxdrvAUR like so:

    # xboxdrv --evdev /dev/btjoy --config .config/xboxdrv/ipega.conf

### iPEGA-9017s

    ~/.config/xboxdrv/ipega.conf

    #iPEGA PG-9017S Config

    [xboxdrv]
    evdev-debug = true
    evdev-grab = true
    rumble = false
    mimic-xpad = true

    [evdev-absmap]
    ABS_HAT0X = dpad_x
    ABS_HAT0Y = dpad_y

    ABS_X = X1
    ABS_Y = Y1

    ABS_Z  = X2
    ABS_RZ = Y2

    [axismap]
    -Y1 = Y1
    -Y2 = Y2

    [evdev-keymap]
    BTN_EAST=a
    BTN_C=b
    BTN_NORTH=y
    BTN_SOUTH=x
    BTN_TR2=start
    BTN_TL2=back
    BTN_Z=rt
    BTN_WEST=lt

    BTN_MODE = guide

### iPEGA-9068 and 9087

    ~/.config/xboxdrv/ipega.conf

    #iPEGA PG-9068 and PG-9087 Config

    [xboxdrv]
    evdev-debug = true
    evdev-grab = true
    rumble = false
    mimic-xpad = true

    [evdev-absmap]
    ABS_HAT0X = dpad_x
    ABS_HAT0Y = dpad_y

    ABS_X = X1
    ABS_Y = Y1

    ABS_Z  = X2
    ABS_RZ = Y2

    [axismap]
    -Y1 = Y1
    -Y2 = Y2

    [evdev-keymap]
    BTN_A=a
    BTN_B=b
    BTN_Y=y
    BTN_X=x
    BTN_TR=rb
    BTN_TL=lb
    BTN_TR2=rt
    BTN_TL2=lt
    BTN_THUMBL=tl
    BTN_THUMBR=tr
    BTN_START=start
    BTN_SELECT=back

    BTN_MODE = guide

### Defender X7

    ~/.config/xboxdrv/defender.conf

    #Defender x7 xboxdrv config

    [xboxdrv]
    evdev-debug = true
    evdev-grab = true
    rumble = false
    mimic-xpad = true

    [evdev-absmap]
    ABS_HAT0X = dpad_x
    ABS_HAT0Y = dpad_y

    ABS_X = X1
    ABS_Y = Y1

    ABS_Z  = X2
    ABS_RZ = Y2

    [axismap]
    -Y1 = Y1
    -Y2 = Y2

    [evdev-keymap]
    BTN_EAST=b
    BTN_NORTH=x
    BTN_SOUTH=a
    BTN_WEST=y
    BTN_TR2=rt
    BTN_TL2=lt
    BTN_TR=rb
    BTN_TL=lb
    BTN_THUMBL=tl
    BTN_THUMBR=tr
    BTN_START=start
    BTN_SELECT=back

    BTN_MODE = guide

### Stadia Controller

    ~/.config/xboxdrv/stadia.conf

    # Stadia xboxdrv config

    [xboxdrv]
    mimic-xpad=true
    silent=true

    [evdev-absmap]
    ABS_X=x1
    ABS_Y=y1
    ABS_Z=x2
    ABS_RZ=y2
    ABS_GAS=rt
    ABS_BRAKE=lt
    ABS_HAT0X=dpad_x
    ABS_HAT0Y=dpad_y

    [axismap]
    -y1=y1
    -y2=y2

    [evdev-keymap]
    BTN_SOUTH=A
    BTN_EAST=B
    BTN_NORTH=X
    BTN_WEST=Y

    BTN_START=start
    BTN_SELECT=back
    BTN_MODE=guide

    BTN_THUMBL=tl
    BTN_THUMBR=tr
    BTN_TR=rb
    BTN_TL=lb

### Logitech Dual Action

    # xboxdrv --evdev /dev/input/event* \
       --evdev-absmap ABS_X=x1,ABS_Y=y1,ABS_RZ=x2,ABS_Z=y2,ABS_HAT0X=dpad_x,ABS_HAT0Y=dpad_y \
       --axismap -Y1=Y1,-Y2=Y2 \
       --evdev-keymap BTN_TRIGGER=x,BTN_TOP=y,BTN_THUMB=a,BTN_THUMB2=b,BTN_BASE3=back,BTN_BASE4=start,BTN_BASE=lt,BTN_BASE2=rt,BTN_TOP2=lb,BTN_PINKIE=rb,BTN_BASE5=tl,BTN_BASE6=tr \
       --mimic-xpad --silent

### PlayStation 2 controller

    # xboxdrv --evdev /dev/input/event* \
       --evdev-absmap ABS_X=x1,ABS_Y=y1,ABS_RZ=x2,ABS_Z=y2,ABS_HAT0X=dpad_x,ABS_HAT0Y=dpad_y \
       --axismap -Y1=Y1,-Y2=Y2 \
       --evdev-keymap   BTN_TOP=x,BTN_TRIGGER=y,BTN_THUMB2=a,BTN_THUMB=b,BTN_BASE3=back,BTN_BASE4=start,BTN_BASE=lb,BTN_BASE2=rb,BTN_TOP2=lt,BTN_PINKIE=rt,BTN_BASE5=tl,BTN_BASE6=tr \
       --mimic-xpad --silent

### PlayStation 4 controller

    # xboxdrv \
       --evdev /dev/input/by-id/usb-Sony_Computer_Entertainment_Wireless_Controller-event-joystick\
       --evdev-absmap ABS_X=x1,ABS_Y=y1                 \
       --evdev-absmap ABS_Z=x2,ABS_RZ=y2                \
       --evdev-absmap ABS_HAT0X=dpad_x,ABS_HAT0Y=dpad_y \
       --evdev-keymap BTN_A=x,BTN_B=a                   \
       --evdev-keymap BTN_C=b,BTN_X=y                   \
       --evdev-keymap BTN_Y=lb,BTN_Z=rb                 \
       --evdev-keymap BTN_TL=lt,BTN_TR=rt               \
       --evdev-keymap BTN_SELECT=tl,BTN_START=tr        \
       --evdev-keymap BTN_TL2=back,BTN_TR2=start        \
       --evdev-keymap BTN_MODE=guide                    \
       --axismap -y1=y1,-y2=y2                          \
       --mimic-xpad                                     \
       --silent

### PlayStation 5 controller

    # xboxdrv \
      --evdev /dev/input/by-id/usb-Sony_Interactive_Entertainment_DualSense_Wireless_Controller-if03-event-joystick \
      --evdev-absmap ABS_HAT0X=dpad_x,ABS_HAT0Y=dpad_y,ABS_X=X1,ABS_Y=Y1,ABS_RX=X2,ABS_RY=Y2,ABS_Z=LT,ABS_RZ=RT \
      --evdev-keymap BTN_SOUTH=A,BTN_EAST=B,BTN_NORTH=Y,BTN_WEST=X,BTN_START=start,BTN_MODE=guide,BTN_SELECT=back \
      --evdev-keymap BTN_TL=LB,BTN_TR=RB,BTN_TL2=LT,BTN_TR2=RT,BTN_THUMBL=TL,BTN_THUMBR=TR \
      --axismap -y1=y1,-y2=y2                          \
      --mimic-xpad                                     \
      --silent

分类：​

- 输入设备
- 游戏
- 使用“模板:Remove”标记的章节
- 使用“模板:风格”标记的页面或章节

游戏手柄
添加话题