游戏手柄

来自 ArchWiki

现在许多游戏手柄都可以即插即用,但是由于应用程序中的游戏手柄支持差异很大,仍然存在许多潜在问题和错误来源。

本文或章节需要扩充。

原因: 需要关于 API 之间差异的信息,以及如何在它们之间切换。(在Talk:Gamepad#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 自己的事件 1:1 映射。
  • SDL_GameController,在 SDL2 上受支持,提供设备之间的标准化映射。为了支持控制器,它需要在数据库 gamecontrollerdb.txt 中有一个 evdev:SDL 映射。此 API 在 SDL3 中被 SDL_Gamepad 替代。

安装

除非您使用的是非常旧的使用 Gameport 或专有 USB 协议的摇杆,否则您只需要通用的 USB 人机接口设备 (HID) 模块。

要全面了解 Linux 中所有与摇杆相关的模块,您需要访问 Linux 内核源代码——特别是 Documentation 部分。不幸的是,官方内核包不包含我们需要的内容。如果您已下载内核源代码,请查看 Documentation/input/joydev/。您可以通过单击您正在使用的内核的“browse”(cgit - git 前端)链接,然后在顶部附近单击“tree”链接,在 kernel.org 上浏览内核源代码树。或者,请参阅来自最新内核的文档

一些摇杆需要特定的模块,例如 Microsoft Sidewinder 控制器 (sidewinder) 或 Logitech 数字控制器 (adi)。许多较旧的摇杆可以使用简单的 analog 模块。如果您的摇杆插入声卡提供的游戏端口,您将需要加载声卡驱动程序——但是,某些声卡(如 Soundblaster Live)具有特定的游戏端口驱动程序 (emu10k1-gp)。较旧的 ISA 声卡可能需要 ns558 模块,这是一个标准的 gameport 模块。

如您所见,有许多不同的模块与使您的摇杆在 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 中,但不会在 /dev/input/js* 中显示为输入设备,请参阅 #Xbox 360 手柄

配置

测试

加载模块后,您应该能够找到一个新设备:/dev/input/js0/dev/input/by-id 目录中以 -event-joystick 结尾的文件。您可以简单地 cat 这些设备来查看摇杆是否工作——移动摇杆,按下所有按钮 - 当您移动摇杆或按下按钮时,您应该看到乱码打印出来。

如果您收到权限错误,请参阅 #设备权限

Wine 使用 SDL 进行 DirectInput 和 XInput 模拟,并将 evdev 作为后备。您可以使用 wine control joy.cpl 对其进行测试。对于 PlayStation 4 和 5 控制器,请参阅 #在 Wine 中使用

Joystick API

有很多应用程序可以测试这个旧的 API,来自 joyutils 软件包的 jstest 是最简单的一个。如果输出由于打印的行太长而无法读取,您也可以使用图形工具。KDE Plasma 在系统设置 > 输入设备 > 游戏控制器中内置了一个。还有一个替代方案 jstest-gtk-gitAUR 软件包仓库

jstest 的使用非常简单,您只需运行 jstest /dev/input/js0,它将打印一行,其中包含所有轴(标准化为 {-32767,32767})和按钮的状态。

启动 jstest-gtk 后,它将只显示可用的摇杆列表,您只需选择一个并按“属性”。

evdev API

可以使用来自 evtestevtest 或来自 evtest-qt-gitAUR 软件包仓库evtest-qt 测试 'evdev' API。

要测试设备上的力反馈,请使用来自 linuxconsolefftest

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

SDL APIs

安装 sdl-jstest-gitAUR 软件包仓库。如果连接了多个控制器,请使用 sdl2-jstest --list 获取它们的 ID。

要测试设备索引 0 上的 SDL_Joystick API

$ sdl2-jstest --test 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 设备。

设置死区和校准

本文或章节需要扩充。

原因: 描述 evdev 的校准说明(在 Talk:Gamepad#Unclear instructions on how to calibrate 中讨论)

如果您想设置死区(或完全删除它们)模拟输入,您必须为 xorg(用于鼠标和键盘模拟)、Joystick API 和 evdev API 分别进行设置。

Wine 死区

添加以下注册表项并将其设置为从 010000 的字符串(影响所有轴)

HKEY_CURRENT_USER\Software\Wine\DirectInput\DefaultDeadZone

来源:Useful Registry Keys

Xorg 死区

/etc/X11/xorg.conf.d/51-joystick.conf 中添加类似的行(如果不存在则创建)

/etc/X11/xorg.conf.d/51-joystick.conf
Section "InputClass"
    Option "MapAxis1" "deadzone=1000"
EndSection

1000 是默认值,但您可以设置介于 030000 之间的任何值。要获取轴号,请参阅本文的“测试您的配置”部分。如果您已经有一个带有特定轴的选项,只需在参数末尾键入 deadzone=value,并用空格分隔。

Joystick API 死区和校准

最简单的方法是使用来自 jstest-gtk-gitAUR 软件包仓库jstest-gtk。选择您要编辑的摇杆,单击属性按钮。在新窗口中,单击校准按钮(之后不要单击开始校准)。然后,您可以设置 CenterMinCenterMax 值,它们控制中心死区,以及 RangeMinRangeMax,它们控制行程结束死区。请注意,校准设置在应用程序打开设备时应用,因此您需要重新启动您的游戏或测试应用程序才能看到更新的校准设置。

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

首先,获取您的摇杆的供应商 ID(将 X 替换为您的摇杆编号,通常为 0

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

还要获取型号 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 API 设备的死区和校准。

要查看您的设备配置

$ 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

使用游戏手柄发送按键

存在一些程序可以将游戏手柄按钮映射到键盘按键,包括

所有这些程序都运行良好,无需额外的 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 — 开源软件,支持按钮重新映射和 Xbox 360 控制器模拟。
https://github.com/Ryochan7/sc-controller || sc-controllerAUR 软件包仓库
  • Steam — 专有商店,其客户端通过 Steam Input 支持重新绑定游戏手柄输入。启用后,Steam 会向选择加入 Steam Input API 的游戏公开 Steam Controller,并向使用传统游戏手柄 API 的游戏公开模拟的 Xbox 360 Controller。有关更多详细信息,请参阅 Steam#Steam Input
https://store.steampowered.com/about/ || steam
  • xboxdrv — Xbox 360 控制器驱动程序,支持从不同的输入控制器模拟控制器。参见 #模拟 Xbox 360 控制器。它也是重新映射和校准的灵活选项。
https://github.com/xiota/xboxdrv || xboxdrvAUR 软件包仓库

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

可以使用 SDL_GAMECONTROLLERCONFIG 环境变量为 SDL2 应用程序重新映射游戏手柄。对于每一行,它都包含游戏手柄的 GUID、名称、按钮/轴映射和平台。控制器的 GUID 可以通过安装 sdl-jstest-gitAUR 软件包仓库 然后运行 sdl2-jstest --list 来检索。

例如,要映射具有不同 GUID 的 Microsoft Xbox 360 控制器

~/.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

上面的示例是不完整的。它仅映射一个轴和 3 个按钮以进行演示。使用 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)。

Logitech Thunderpad Digital

如果您使用 analog 模块,Logitech Thunderpad Digital 将不会显示所有按钮。为此控制器使用设备特定的 adi 模块。

Nintendo Gamecube Controller

Dolphin Emulator 在其 wiki 页面 上解释了如何在 Dolphin 中使用官方 Nintendo USB 适配器和 GameCube 控制器。如果开关设置为“Wii U”,此配置也适用于 Mayflash Controller Adapter。

对于其他应用程序,您可以使用 wii-u-gc-adapterAUR 软件包仓库

Nintendo Switch Pro Controller 和 Joy-Cons

自内核版本 5.16 起支持这些控制器。自内核版本 6.12 起也支持 Switch Online NES、SNES 和 N64 控制器。

对于早期内核版本,可以安装 DKMS 模块 hid-nintendo-nso-dkmsAUR 软件包仓库

用户空间守护进程

joycond-gitAUR 软件包仓库 是一个用户空间守护进程,为 Nintendo Switch 控制器提供更好的集成。当守护进程处于活动状态时,处于配对模式(LED 闪烁)的 Switch 控制器可以同时按下其触发器进行配对,然后准备好供应用程序使用。请参阅 [2]

将 Joy-Cons 用作一个设备

hid-nintendo 内核驱动程序将两个 Joy-Cons 处理为两个单独的设备。

要将两个 Joy-Cons 配对在一起,请确保 joycond 正在运行且两个 Joy-Cons 都处于配对模式。然后,同时按下每个 Joy-Con 上的一个触发器。

在 SDL2 应用程序上使用位置布局

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

Steam Controller

Steam 客户端将识别控制器,并在 Steam 运行时提供键盘/鼠标/游戏手柄模拟。需要启用并正常运行游戏内 Steam 覆盖才能使游戏手柄模拟工作。如果控制器在安装和运行 Steam 后没有立即工作,您可能需要以 root 权限运行 udevadm trigger 或拔下并重新插入接收器。如果所有其他方法都失败,请尝试在插入接收器的情况下重启计算机。

如果您正在使用通过蓝牙 LE 连接的控制器,请确保用户是 input 组的成员。

如果您无法使 Steam Controller 工作,请参阅 #Steam Controller 无法配对

注意: 如果您不使用 Steam runtime,您可能实际上需要禁用覆盖才能使控制器在某些游戏中工作(Rocket Wars、Rocket League、Binding of Isaac 等)。右键单击库中的游戏,选择“属性”,然后取消选中“启用 Steam 覆盖”。

Xbox 360 手柄

有线和无线(带有适用于 Windows 的 Xbox 360 无线接收器)控制器都由 xpad 内核模块支持,应该无需其他软件包即可工作。请注意,使用带有 Play&Charge USB 线缆的无线 Xbox 360 控制器将无法工作。该线缆仅用于充电,不通过电线传输任何输入数据。

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

  • 错误的按钮映射。(Steam bugtracker 中的讨论
  • 不同步。(Arch 论坛中的讨论
  • 所有四个 LED 灯持续闪烁,但控制器工作。TLP 的 USB 自动挂起是无线控制器的此问题的确切原因之一。请参阅下文以获取修复。

如果您使用 TLP 电源管理工具,您可能会遇到 Microsoft 无线适配器的连接问题(例如,指示灯 LED 将在适配器连接几秒钟后熄灭,并且控制器连接尝试失败,四个 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

本文或章节正在考虑移除。

原因: xboxdrv 的驱动程序部分已弃用。(在 Talk:Gamepad 中讨论)

xboxdrvxpad 的替代方案,它提供更多功能,并且可能在某些控制器上工作得更好。它在用户空间中工作,可以作为系统服务启动。

使用 xboxdrvAUR 软件包仓库 软件包安装它。然后 启动/启用 xboxdrv.service

如果您在 Steam 游戏中遇到控制器被识别但不工作,或者工作但不映射不正确的问题,则可能需要修改您的配置,如下所示

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

[xboxdrv-daemon]
dbus = disabled

然后 重启 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

然后 重启 xboxdrv.service

使用通用/克隆控制器

一些克隆游戏手柄可能需要特定的初始化序列才能工作(Super User 答案)。为此,您应该以 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 计算机,通过 Microsoft Store 下载 Xbox 配件应用程序,并更新控制器的固件。

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 评估版的免费副本(使用 QEMUVirtualBox,注意蓝牙适配器直通要求,例如 作为 USB 设备),使用 Arch Linux 作为您的主机,首先在 Windows 10 中配对,然后在您的 Arch Linux 系统下再次执行相同的操作。然后配对将成功,并且无需进一步使用 Windows 10。

使用 Microsoft Xbox 无线适配器连接 Xbox 无线控制器

xone 是 Xbox One 和 Xbox Series X|S 配件的 Linux 内核驱动程序。它是 xpad 和 xow 的现代替代品和替代者。目前可通过有线或使用 Microsoft Xbox 无线适配器“dongle”工作。此驱动程序的错误修复现在由原始驱动程序的 dlundqvist 分支 维护。

安装 xone-dkms-gitAUR,如果使用无线 dongle,则安装 xone-dongle-firmwareAUR。安装需要重启您的系统。

注意
  • 需要与您的内核对应的头文件;请参阅 DKMS#安装
  • 该适配器使用基于 mt76 的 802.11/15 芯片组,这可能会导致与连接到同一系统或附近的其它无线适配器发生干扰。


控制器配对后性能不佳(轮询率低)

您将需要在 Windows 中使用 Microsoft Store 中的“Xbox 配件”应用程序更新控制器的固件。理论上,这应该可以通过 USB 直通到 Windows 虚拟机来实现,但您可能需要双启动到实际(裸机)Windows 安装,以便 Xbox 配件应用程序看到控制器并进行固件更新。

与 Windows 双启动

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

在挂起和唤醒后,无法通过游戏手柄使用连接。

在某些平台上,挂起可能会导致设备进入不正常响应的状态。由于 Linux 将该设备识别为蓝牙适配器,因此在挂起时会自动将其置于断电状态,这也禁用了从游戏手柄唤醒系统。这可以通过在内核命令行上使用 btusb.enable_autosuspend=n 来缓解。注意:这将禁用系统上所有其他 USB 蓝牙适配器的电源挂起。

PlayStation 3 控制器

通过 USB 配对

如果您拥有 PS3 控制器并且可以通过 USB 连接,请将其插入您的计算机并按下 PS 按钮。控制器将启动,四个 LED 指示灯中的一个应亮起,指示控制器的编号。

通过蓝牙配对

安装 bluezbluez-utils。按照 蓝牙#配对 的前五个步骤确保蓝牙工作正常,并保持 bluetoothctl 命令运行,然后通过按下中间的“PS”按钮打开控制器(所有 4 个 LED 指示灯应快速闪烁 ~4 hz),并使用 USB 连接到您的计算机。最后,当 bluetoothctl 提示符询问“Authorize service 00001124-0000-1000-8000-00805f9b34fb (yes/no)”时,输入 yes。

注意

在最新版本的 bluez 中(截至 2024/01/03),出于安全原因 [5]ClassicBondedOnly 的默认值已从 false 更改为 true。此更改使得无法配对 Dual Shock 3 控制器,因为 bluetoothctl 会要求输入 PIN 并且无法继续。为了解决这个问题,通过在 /etc/bluetooth/input.conf 中新创建的文件中添加以下行,将 ClassicBondedOnly 设置为 false

截至 2024-03-09,UserspaceHID 的默认值也已更改为 true。虽然连接成功,但除非将此值更改为 false,否则控制器无法再设置为运行模式。有关更多信息,请参阅 Github 上的 issue #771

[General]
ClassicBondedOnly=false
UserspaceHID=false

请注意,此解决方案会降低安全性。有关详细信息,请参阅 GitHub

提示: 互联网上有许多关于设置 PS3 控制器的复杂说明,这些说明需要许多步骤,例如编译和安装 qtsixa 或 sixpair 并手动设置控制器,或者使用一些特定补丁修补 bluez。在现代 Linux 内核上以及安装 bluez-utils 后,所有这些都是不必要的。

PlayStation 3/4 控制器

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

Steam 可以正确地将其识别为 PS3 手柄,并且可以使用 PS 按钮启动 Big Picture 模式。Big Picture 模式和某些游戏可能会表现得好像它是 360 控制器一样。默认情况下,游戏手柄控制鼠标是开启的。您可能需要在玩游戏之前将其关闭,请参阅 #禁用操纵杆控制鼠标

通过蓝牙配对

安装 bluezbluez-utils 软件包,其中包括 sixaxis 插件。然后 启动 蓝牙 服务,并确保蓝牙已开启。如果使用 bluetoothctl,请在终端中启动它,然后通过 USB 插入控制器。系统应提示您在 bluetoothctl 中信任控制器。图形化蓝牙前端可能会自动将您 PC 的蓝牙地址编程到控制器中。按下 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 设备公开,这阻止了它们在许多应用程序中工作。

要禁用此行为,请使用 regedit 将以下文本文件导入到 Wine 注册表中

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

自 Wine 9.18 起,此设置可以从 wine control joy.cpl 控制。

禁用触摸板充当鼠标

如果将 libinputXorg 一起使用,或者如果使用 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 TouchpadDualSense Wireless Controller Touchpad

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

dualsensectl

dualsensectl 是一个可以切换灯条和麦克风(及其 LED 指示灯)、监控电池状态以及关闭控制器电源的工具。要使用它,请安装 dualsensectl-gitAUR

技巧与窍门

网络游戏手柄

如果您想通过网络将游戏手柄与另一台计算机一起使用,可以使用 USB/IPnetstick-gitAUR 来实现。

故障排除

设备权限

游戏手柄设备受 udev 规则的影响:除非它们授予对设备的访问权限,否则用户将无法读取它。本节调查您是否已拥有处理此问题的配置文件的可能性。

任何游戏手柄设备,无论它是通过 USB 还是蓝牙连接,都由 内核的“input”子系统 处理,对应于 /dev/input。udev 规则也通常以 “hidraw”内核模块 为目标。结合这些,我们可以通过检查软件包附带的配置来了解 udev 对这些设备的处理

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

一些附带值得注意规则的应用程序示例

  • systemd 的默认规则将所有 input 设备的组设置为 input,并将操纵杆设备的模式设置为 664 [6]
  • Steam 附带 udev 规则,允许访问各种控制器。有关规则内容的更多信息,请参阅 此 Steam 讨论
  • Dolphin 模拟器 附带 udev 规则,允许访问其支持的控制器。

如果您的系统恰好没有您想要使用的设备的 udev 规则,您可以自己编写一个,或者安装 game-devices-udevAUR 软件包并重启您的计算机。

注意: 可以将用户添加到 input 组,以便授予他们访问所有设备的权限。但是,不建议这样做 [7]

并非所有程序都识别游戏手柄

某些软件,例如 Steam,只会识别它遇到的第一个游戏手柄。由于 Microsoft 无线外围设备的驱动程序中的错误,这实际上可能是蓝牙 dongle。如果您发现您有一个 /dev/input/js*/dev/input/event* 属于您键盘的蓝牙收发器,您可以通过创建相应的 udev 规则来自动摆脱它

/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"

更正 KERNELS=="..." 以匹配您的设备。可以通过运行找到正确的值

# udevadm info -an /dev/input/js0

假设有问题的设备是 /dev/input/js0。在您放置规则后,使用重新加载规则

# udevadm control --reload

然后重新插入给您带来麻烦的设备。操纵杆和事件设备应该消失了,尽管它们的编号仍将被保留。但是这些文件已经不再碍事了。

应用程序仅支持 Xbox 360 控制器

一些 Windows 游戏特别寻找 Xbox 360 控制器,否则会缺少功能(如震动)或根本无法工作。

对于解决方法,请参阅 #模拟 Xbox 360 控制器

Steam Controller

Steam 控制器无法配对

在某些未知情况下,Steam 控制器的打包 udev 规则不起作用 (FS#47330)。最可靠的解决方法是使控制器世界可读。将规则 /usr/lib/udev/rules.d/70-steam-controller.rules 复制到 /etc/udev/rules.d,优先级更高,并将任何说 MODE="0660" 的内容更改为 MODE="0666",例如

/etc/udev/rules.d/99-steam-controller-perms.rules
...
SUBSYSTEM=="usb", ATTRS{idVendor}=="28de", MODE="0666"
...

您可能需要重启才能使更改生效。

Steam 控制器导致游戏崩溃或无法识别

如果您的 Steam 控制器在 Steam Big Picture 模式下运行良好,但游戏无法识别它,或者当您插入控制器时游戏开始崩溃,这可能是因为已添加到 Linux 内核 4.18 的原生驱动程序。尝试卸载它,重启 Steam 并重新插入控制器。

驱动程序的模块名称是 hid_steam,因此要卸载它,您可以执行

# rmmod hid_steam

Xbox One 无线游戏手柄检测到但无法识别任何输入

当将第三方 Xbox One 控制器与 xpad#xboxdrv 驱动程序一起使用时,可能会发生这种情况。尝试切换到 #xpadneo

Playstation 4 控制器

使用蓝牙时无法识别控制器

安装 ds4drvAUR 软件包,并使用 hidraw (ds4drv --hidraw) 后端参数运行它。

体感控制接管游戏手柄控制和/或导致游戏手柄控制的意外输入

本文或章节需要语言、wiki 语法或风格方面的改进。有关参考,请参阅 Help:Style

原因: 可能可以使用与 Gamepad#禁用触摸板充当鼠标 相同的解决方案,该解决方案已在其他页面中适当重构。(在 Talk:Gamepad 中讨论)

对于某些云游戏应用程序(例如 Parsec 和 Shadow),Dualshock 4 V1 和 V2 体感控制可能会与游戏手柄控制冲突,导致游戏手柄无法工作,并且对于某些输入敏感的游戏,尤其是赛车游戏,体感控制可能会在游戏手柄控制游戏过程中导致意外漂移。

可以通过禁用体感控制和触摸板来解决此问题,方法是添加以下 udev 规则

/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}=""

然后 重新加载规则 或重启:这些规则应在 USB 和蓝牙模式下均有效。

多模式有线游戏手柄

本文或章节需要语言、wiki 语法或风格方面的改进。有关参考,请参阅 Help:Style

原因: 需要进行多项改进。(在 Talk:Gamepad 中讨论)

一些游戏手柄在有线连接时具有 3 种模式:Switch、Xbox 360/Windows、Android。

并且它们也没有在有线连接时在它们之间切换的热键。

当您将此类游戏手柄连接到 Windows 时,它处于 Xbox 360 控制器模式。

但是当您将此类游戏手柄连接到 Linux 时,它会进入后备模式(恰好是 Android 模式),该模式具有更差的轮询率 (100 Hz),Home 按钮充当 XF86Home;不公开震动、陀螺仪和加速度计;不支持不带 --evdevxboxdrvAUR;并将自身标识为例如“SHANWAN Android Gamepad”,这不受某些游戏的欢迎(尽管对于 SDL2 应用程序,您可以在 SDL_GAMECONTROLLERCONFIG 中设置名称)。

当您连接游戏手柄时,它首先尝试成为“Switch Pro Controller”,但由于某种原因,Linux 内核认为(游戏手柄发送的)描述符无效,因此断开游戏手柄的连接。这导致游戏手柄在上述后备模式下重新连接。

dmesg 中,这看起来像

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

请注意,“USB 设备编号”在失败后会增加。对于某些 USB 集线器,错误代码为 -32 (EPIPE: broken pipe),对于其他集线器,错误代码为 -71 (EPROTO: protocol error)。

可以通过在 usbcore 模块(而不是 usbhid)中为 Switch 控制器的 USB ID 设置 quirk 来修复此错误

# 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 是 2 个标志(所有标志的列表)。

标志 i 表示“允许错误的描述符”。

标志 k 表示“禁用 LPM”(链接电源管理)。在命令中指定它是因为它通常有助于其他类型的设备。此标志可能不起作用,因为并非所有 USB 控制器都具有 LPM。您可以稍后尝试不带 k 的情况。

您也可以尝试标志 g(“读取描述符后暂停 200 毫秒”),因为它通常有助于其他类型的设备,但至少在 iPEGA PG-SW038C(一个 10 美元的游戏手柄)的情况下,标志 g 会导致它无限期地重新连接。

请注意,一旦游戏手柄降级到后备模式,它将永远不会更改其模式,直到您重新连接它。即使 echo 0 then 1 > %sysfsGamepadDir%/authorized 也不起作用。这就是为什么将游戏手柄传递给 Windows VM 也无济于事的原因;usbcore 会在将 USB 设备传递给 VM 之前对其进行初始化。


现在重新连接游戏手柄,当您运行 lsusb 时,它最终应列为 ID 057e:2009 Nintendo Co., Ltd Switch Pro Controller。如果这是真的,那么您可以通过将此选项添加到 GRUB 来使此 quirk 永久生效

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

以及(可选)usbhid.quirks="0x057e:0x2009:0x400",这会停止游戏手柄未使用时 LED 指示灯的无意义闪烁。

现在您的游戏手柄处于 Switch 模式,您会遇到 SDL2 决定成为用户空间驱动程序的问题(为此它使用 libusb,就像 xboxdrvAUR 一样),这会导致任何 SDL2 游戏声明整个游戏手柄(即:/dev/input/*/dev/hidraw* 消失,但仍然可以使用游戏手柄玩这个启动的游戏),因此您无法再在多个应用程序中使用游戏手柄。

可以通过添加以下内容来修复此问题

SDL_HIDAPI_DISABLE_LIBUSB=1

/etc/environment 中,然后重启。

如果您有 joycond-gitAUR,则删除它,因为它对于这种类似 Switch 的游戏手柄毫无用处,而且 joycond 具有一个 udev 规则,该规则不允许 Steam 提供其自己的用户空间驱动程序。

与 SDL2(当它使用 /dev/hidraw* 时,这是它在 2023 年的首选方式)不同,xboxdrv/dev/input/* 为右摇杆的 X 轴提供不正确的值(它始终 ≤0)。可能是 hid-nintendo 或其他东西中的错误。因此,当处于 Switch 模式时,xboxdrv 在大多数游戏中都不可用。

您可以通过启动 antimicrox 来测试您的陀螺仪和加速度计。当有线连接时,它们在其他游戏手柄模式下不可用,因为它们的值以特殊格式与其他事件数据(RX/RY/等)混合发送,该格式与 xpadhid-generic 不完全兼容。

如果您在 dmesg 中看到 hid-generic 被您的游戏手柄使用,那么这可能是因为您使用自己的配置构建了 Linux 内核,而没有 hid-nintendo。不幸的是,Switch 模式 + hid-generic 与后备模式一样无用(甚至没有震动)。

Xbox 360 控制器模式

在完成以上所有操作(即 1-2 个 quirks,1 个环境变量)之后,

添加

blacklist hid_nintendo

/etc/modprobe.d/blacklist.conf

然后运行 sudo mkinitcpio -P 以重建 /boot/initramfs*(内核仅从其自己的 initramfs 读取 /etc/modprobe.d/,而不是您的 rootfs)

现在创建以下文件

/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'"

然后运行 sudo udevadm control --reload-rules && sudo udevadm trigger

由于您可能不想重启,请运行 sudo modprobe -r hid_nintendo

从现在开始,要从 Switch 模式切换(“降级”)到 Xbox 360 模式,只需运行 sudo modprobe -r hid_nintendo(您甚至不需要重新连接它)。在 2 秒钟内,您将在 lsusb 中看到 045e:028e Microsoft Corp. Xbox360 Controller

如果您想反向切换

  1. sudo modprobe hid_nintendo(即使它被列入黑名单,此命令仍然有效,因为列入黑名单仅表示“不要自动加载此模块”)。
  2. 重新连接。
替代的无 root 解决方案

如果您没有 root 访问权限,则

  1. 关闭您的 PC 电源(不仅仅是挂起)
  2. 重新连接您的游戏手柄。
  3. 打开 PC 电源。
  4. UEFI(就像非虚拟化的 Windows 一样)会自动成功初始化游戏手柄(即使它通过显示器中的 USB 集线器连接),尽管描述符无效。
  5. 游戏手柄从 UEFI(或可能是 GRUB)接收信息,表明不再需要将其用作 HID,这会导致它切换(“降级”)到 Xbox 360 控制器模式。模式之间的切换是通过这种方式完成的:游戏手柄断开连接,然后以不同的 USB ID 连接。
  6. 您甚至可以挂起(如果连接到显示器,则无需关闭显示器)然后唤醒 PC,它仍将处于 Xbox 360 控制器模式。但是,如果您重新连接游戏手柄,它将处于后备模式,因此您必须再次按照说明进行操作。

USB 调试

您可能不需要了解这一点,但此 USB ID (057e:2009) 是通过 USB 调试发现的

# 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/'

其中 99999 必须替换为您的游戏手柄使用的 USB 总线编号,例如 1(不带前导零)。可以通过运行 lsusb 找到它。

如果没有任何帮助,并且您的游戏手柄仍然只能在 Windows 中充分发挥其功能,您可以捕获在 Windows 中时的 USB 消息,然后在 Linux 中重放它们。请参阅 usbrply。为此,Windows 不能在 VM 中,因为 Linux 内核的 usbcore 会在将 USB 设备传递给 VM 之前对其进行初始化。可以通过购买 PCI-E USB 控制器并将其直通来避免这种情况(外部 USB 集线器无法直通)。或者,如果您的主板自己的 USB 控制器位于没有对您重要的设备的 IOMMU 组中,您可以将其直通

xboxdrv 配置示例

本文或章节正在考虑移除。

原因: xboxdrv 非常少见,并且本节占据了大量空间,但其针对性很强。(在 Talk:Gamepad 中讨论)

要为这些设备提供持久名称,请设置以下格式的 udev 规则。

/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"

将“Bluetooth Gamepad”替换为您的设备名称,将“00:17:02:01:ae:2a”替换为您的设备地址。

当您拥有配置并且您的设备已连接时,您可以像这样启动 xboxdrvAUR

# 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 和 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 控制器

~/.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 控制器

# 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 控制器

# 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 控制器

# 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