游戏手柄

出自 ArchWiki
(重定向自 Steam Controller)

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

本条目或章节需要扩充。

原因: 需要有关 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,选择哪个 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/。您可以在 kernel.org 上浏览内核源代码树,方法是单击您正在使用的内核的“browse”(cgit - git 前端)链接,然后单击顶部的“tree”链接。或者,请参阅最新内核的文档

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

如您所见,有许多不同的模块与使您的摇杆在 Linux 中工作相关,因此此处未涵盖所有内容。请查看上面提到的文档以获取详细信息。

加载模拟设备的模块

您需要为您的游戏端口(ns558emu10k1-gpcs461x 等)、您的摇杆(analogsidewinderadi 等)以及最终的内核摇杆设备驱动程序 (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

可以使用 evtest 中的 evtestevtest-qt-gitAUR 中的 evtest-qt 测试“evdev”API。

要测试设备上的力反馈,请使用 linuxconsole 中的 fftest

$ 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 是默认值,但您可以设置介于 0 和 {{30000 之间的任何值。要获取轴号,请参阅本文的“测试您的配置”部分。如果您已经有一个带有特定轴的选项,只需在参数末尾键入 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 控制器,并向使用传统游戏手柄 API 的游戏公开模拟的 Xbox 360 控制器。有关更多详细信息,请参阅 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 可以用于使任何控制器注册为 Xbox 360 控制器,使用 --mimic-xpad 开关。对于开箱即用支持 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 手柄

Dolphin 模拟器在其 wiki 页面上解释了如何将官方 Nintendo USB 适配器与 GameCube 控制器一起使用。如果开关设置为“Wii U”,此配置也适用于 Mayflash 控制器适配器。

对于其他应用程序,您可以使用 wii-u-gc-adapterAUR

Nintendo Switch Pro 手柄和 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 控制器

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

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

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

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

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

Xbox 360 手柄

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

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

  • 错误的按钮映射。(Steam 错误跟踪器中的讨论
  • 无法同步。(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。通过执行 Bluetooth#配对 的前五个步骤确保蓝牙工作正常,并保持 bluetoothctl 命令运行,然后通过按下中间的“PS”按钮打开控制器(所有 4 个 LED 指示灯应快速闪烁 ~4 hz),并使用 USB 连接到您的计算机。最后,当 bluetoothctl 提示符询问“Authorize service 00001124-0000-1000-8000-00805f9b34fb (yes/no)”时,输入 yes。

注意

在最新版本的 bluez 中(截至 2024/01/03),出于安全原因,ClassicBondedOnly 的默认值已从 false 更改为 true [5]。此更改使得无法配对 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 插件。然后启动 bluetooth 服务并确保蓝牙已开启。如果使用 bluetoothctl,请在终端中启动它,然后通过 USB 插入控制器。系统应提示您在 bluetoothctl 中信任控制器。图形化的蓝牙前端可能会自动将您 PC 的蓝牙地址编程到控制器中。按下 PlayStation 按钮并检查控制器在插入时是否工作。

您现在可以断开控制器的连接。下次您按下 PlayStation 按钮时,它将连接,而无需询问任何其他内容。

或者,在 PS4 控制器上,您可以同时按住 share 按钮和 PlayStation 按钮(几秒钟)以将游戏手柄置于配对模式,并像往常一样配对。

GNOME 的设置也提供了图形界面,用于在有线连接时配对 sixaxis 控制器。

当您完成操作后,请记住断开控制器的连接,因为控制器在连接时会保持开启状态并耗尽电池电量。

注意: 如果控制器未连接,请确保蓝牙接口已开启并且控制器已被信任。(请参阅 Bluetooth

使用通用/克隆控制器

可以使用通用/克隆 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 控制器

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 kernel 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 而不是您的 rootfs 读取 /etc/modprobe.d/

现在创建以下文件

/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 必须不在虚拟机中,因为 Linux 内核的 usbcore 在将 USB 设备传递到虚拟机之前对其进行初始化。这可以通过购买 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 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