游戏手柄

来自 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) 或罗技数字控制器 (adi)。许多较旧的摇杆可以使用简单的 analog 模块。如果您的摇杆插入到声卡提供的游戏端口,您将需要加载您的声卡驱动程序——但是,某些声卡(如 Soundblaster Live)具有特定的游戏端口驱动程序 (emu10k1-gp)。较旧的 ISA 声卡可能需要 ns558 模块,这是一个标准的游戏端口模块。

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

加载模拟设备的模块

您需要加载游戏端口的模块 (ns558, emu10k1-gp, cs461x, etc...)、摇杆的模块 (analog, sidewinder, adi, etc...),最后是内核摇杆设备驱动程序 (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 API

安装 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-gitAURjstest-gtk。选择您要编辑的操纵杆,单击属性按钮。在这个新窗口中,单击校准按钮(之后不要单击开始校准)。然后您可以设置 CenterMinCenterMax 值,它们控制中心死区,以及 RangeMinRangeMax 值,它们控制行程末端死区。请注意,校准设置在应用程序打开设备时应用,因此您需要重启您的游戏或测试应用程序才能看到更新的校准设置。

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

首先,获取您操纵杆的 vendor id(将 X 替换为您的操纵杆编号,通常为 0

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

同时获取 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"

每当您连接 vendor id 为 054c 且 model 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 控制。由于方向键(又名“帽子”)被识别为另一个轴的问题,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 可以使用 --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 控制器

Dolphin 模拟器的 wiki 上有一个页面,解释了如何在 Dolphin 中使用官方 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 控制器提供更好的集成。当守护进程处于活动状态时,将 Switch 控制器置于配对模式(LED 闪烁)可以同时按下它们的触发器进行配对,然后就可以被应用程序使用。请参阅 [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 后控制器未立即工作,您可能需要使用 root 权限运行 udevadm trigger 命令,或拔下并重新插入适配器。 如果所有方法都失败,请尝试在插入适配器的情况下重启计算机。

如果您使用蓝牙 LE 连接控制器,请确保用户属于 input 组。

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

注意: 如果您不使用 Steam 运行时库,您可能实际上需要禁用覆盖层才能使控制器在某些游戏中工作(例如《火箭战争》、《火箭联盟》、《以撒的结合》等)。 在您的库中右键单击游戏,选择“属性”,然后取消选中“启用 Steam 覆盖层”。

Xbox 360 控制器

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

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

  • 按键映射不正确。(Steam 错误跟踪器中的讨论
  • 同步无法工作。(Arch 论坛中的讨论
  • 所有四个 LED 指示灯持续闪烁,但控制器可以工作。 TLP 的 USB 自动挂起是无线控制器的此问题的一个确切原因。 请参阅下文了解修复方法。

如果您使用 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

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

原因: 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,如果使用无线适配器,则安装 xone-dongle-firmwareAUR。 安装需要重启您的系统。

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


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

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

与 Windows 双启动

在 Windows 中配对控制器和适配器可能会导致在 Linux 中丢失配对。 当您重启进入 Linux 时,您将需要重新配对控制器和适配器。 这也会发生在另一个方向 — 当控制器和适配器在 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),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 控制器。

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

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

使用通用/克隆控制器

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

禁用触摸板作为鼠标

如果使用带有 Xorglibinput,或者如果使用 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 无线外围设备驱动程序中的一个错误,这实际上可能是蓝牙适配器。如果您发现您的键盘蓝牙收发器有 /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 内核 4.18 的原生驱动程序造成的。尝试卸载它,重启 Steam 并重新插拔控制器。

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

# rmmod hid_steam

Xbox One 无线手柄被检测到但没有输入被识别

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

Playstation 4 控制器

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

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

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

本文或本节需要改进语言、wiki 语法或风格。请参阅 Help:Style 以获取参考。

原因: 可能可以使用与 游戏手柄#禁用触摸板作为鼠标 相同的解决方案,该解决方案已重构到其他适当的页面中。(在 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 不同(SDL2 在 2023 年首选使用 /dev/hidraw*),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 个怪癖,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

反之,如果你想切换回 Switch 模式

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

如果你没有 root 权限,那么

  1. 关闭你的电脑(不仅仅是挂起)
  2. 重新连接你的游戏手柄。
  3. 开启电脑。
  4. UEFI(就像非虚拟化的 Windows 一样)会自动且成功地初始化游戏手柄(即使它通过显示器上的 USB 集线器连接),尽管存在无效的描述符。
  5. 游戏手柄从 UEFI(或可能是 GRUB)接收到它不再需要作为 HID 的信息,这导致它切换(“降级”)到 Xbox 360 手柄模式。模式切换是这样完成的:游戏手柄断开连接,然后以不同的 USB ID 连接。
  6. 你甚至可以挂起电脑(如果显示器连接到电脑,可以不关闭显示器),然后唤醒电脑,它仍然会处于 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 手柄

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