遊戲手柄 - Arch Linux 中文维基

跳至內容

# 遊戲手柄

出自 Arch Linux 中文维基
翻譯狀態：

- 本文（或部分內容）譯自 Gamepad，最近一次同步於 2024-11-14，若英文版本有所更改，則您可以幫助同步與翻譯更改的內容。
- 您可以在 ArchWiki 的對應頁面找到本文翻譯的原始修訂歷史。
- 本文可能與英文原文存在出入。

如今，許多遊戲手柄可以開箱即用，但由於不同應用程式對遊戲手柄的支持差異很大，仍然存在許多潛在的問題和錯誤來源。

這篇文章的某些內容需要擴充。

原因：Need info about differences between API, how to switch between them. (在 Talk:遊戲手柄#Joystick API vibration support 中討論)

Linux 有兩種不同的遊戲手柄輸入系統——原始的Joystick接口和基於evdev的新接口。

`/dev/input/jsX` 對應 Joystick API 接口而 `/dev/input/event*` 對應於 evdev 接口（這也包括其他輸入設備，如滑鼠和鍵盤。 這些設備的符號連結也可以在 `/dev/input/by-id/` 和 `/dev/input/by-path/` 中找到，其中原始的Joystick API 設備名稱以 `-joystick` 結尾，而 evdev 設備名稱則以 `-event-joystick` 結尾。

大多數新遊戲默認使用 evdev 接口，因為它能夠提供更詳細的按鈕和軸的信息，並且還支持力反饋。

許多應用使用 SDL 來訪問遊戲手柄。

- SDL1 默認使用 evdev 接口， 但可以通過設置環境變量 `SDL_JOYSTICK_DEVICE=/dev/input/js0` 強制使用Joystick。
- SDL2 和 SDL3 默認在最常用的控制器上使用 hidapi，以獲得原始訪問權限。在其他控制器上，或者如果 hidapi 被禁用，則使用 evdev 代替。

SDL 本身提供了不同的 API，具體使用哪個取決於應用程式。它們的使用是相互獨立的，並不是互相排斥的。

- `SDL_Joystick` 在所有版本中都被支持，並將 evdev（或 Joystick）事件與 SDL 自己的事件一一映射。
- `SDL_GameController` 在 SDL2 中得到支持，提供了設備之間的標準化映射。 要支持一個控制器，它需要在一個資料庫 `gamecontrollerdb.txt` 中建立 evdev:SDL 映射。 這個 API 在 SDL3 中被 `SDL_Gamepad` 替代。

## 安裝

除非你使用的是非常老舊的joystick，且它採用 Gameport 或專有的 USB 協議，否則只需要使用通用的 USB 人機接口設備（HID）模塊即可。

要全面了解 Linux 中與joystick相關的所有模塊， 你需要訪問 Linux 內核原始碼——特別是文檔部分。 遺憾的是，官方內核軟體包並不包含我們需要的內容。如果你已經下載了內核原始碼，請查看 `Documentation/input/joydev/`. 你也可以通過訪問點擊 kernel.org 來瀏覽內核原始碼樹。方法是點擊你所使用的內核版本旁邊的「browse」連結（cgit——git 前端），然後點擊頁面頂部的「tree」連結。 或者，你也可以查看。最新內核的文檔。

有些手柄需要特定的模塊， 例如 Microsoft Sidewinder controllers (`sidewinder`)， 或者 Logitech digital controllers (`adi`). 許多老式手柄可以使用簡單的 `analog` 模塊。 如果你的手柄是通過音效卡的遊戲埠連接的，你需要加載音效卡驅動程序。不過, 有些音效卡, （如 Soundblaster Live）有專門的遊戲埠驅動 (`emu10k1-gp`). 而一些老式的 ISA 音效卡可能需要使用 `ns558` 模塊，這是一個標準的遊戲埠模塊。

如你所見，有許多不同的模塊都與在 Linux 中使用手柄有關，因此這裡並未涵蓋所有內容。詳情請查看上述文檔。

### 加載模擬設備的模塊

你需要為遊戲埠加載一個模塊 (如 `ns558`, `emu10k1-gp`, `cs461x`... )，為手柄加載一個模塊(如`analog`, `sidewinder`, `adi`...), 最後加載內核手柄設備驅動 (`joydev`)。 你可以在啟動時加載這些模塊 或者用 modprobe 命令手動加載。`gameport` 模塊應該會自動加載，因為它是其他模塊的依賴項。

### USB 手柄

你需要讓 USB 正常工作，然然後使用 modprobe 命令加載你的遊戲手柄驅動，通常是 `usbhid`, 以及 `joydev`。 如果你使用的是 USB 滑鼠或鍵盤， `usbhid` 模塊會自動加載， 時你只需要加載 `joydev` 模塊即可。

注意：如果你的 Xbox 360 遊戲手柄是通過 Play&Charge USB 數據線連接的，它會在 `lsusb` 中顯示，b但不會作為輸入設備出現在 `/dev/input/js*`中。詳情請參見 #Xbox 360 controller.

## 配置

### 測試

一旦模塊加載完成，你應該能夠找到一個新設備:`/dev/input/js0` 以及一個以 `-event-joystick` 結尾的文件，位於 `/dev/input/by-id` 目錄下。 你可以通過 `cat` 命令查看這些設備是否正常工作——推動操縱杆、按下任意按鍵 - 應該能看到亂碼輸出，表明設備正在正常工作。

如果出現權限錯誤，請參閱 #設備權限.

Wine 使用 SDL 來模擬 DirectInput 和 XInput，若不支持，則回退到 evdev 。你可以通過運行 `wine control joy.cpl`來測試。 對於 PlayStation 4 和 5 控制器，詳見#Using with Wine.

#### Joystick API

有很多應用程式可以用來測試這個舊的 API。, `jstest` (來自 joyutils包 ) 是其中最簡單的。如果輸出因為行太長而難以閱讀，你也可以使用圖形化工具。 KDE Plasma 在系統設置 > 輸入和輸出 > 遊戲控制器中內置了一個測試工具。還有 jstest-gtk-gitAUR 可供選擇。

使用 `jstest` 非常簡單， 只需運行 `jstest /dev/input/js0` 它會列印一行，顯示所有搖杆的 (normalised to `{-32767,32767}`) 和按鈕狀態。

啟動`jstest-gtk`後, 它會顯示一個可用的遊戲杆列表，你只需要選擇一個設備，然後點擊「屬性」按鈕。

#### evdev API

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

要測試設備上的震動反饋，可以使用 `fftest` (來自linuxconsole包):

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

#### SDL APIs

安裝 sdl-jstest-gitAUR. 如果連接了多個控制器，請使用 `sdl2-jstest --list` 來獲取它們的 ID。

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

    $ sdl2-jstest --test 0

要測試設備索引為 0 的 `SDL_GameController` API:

    $ sdl2-jstest --gamecontroller 0

#### HTML5 Gamepad API

訪問 https://gamepad-tester.com/。 目前，在 Chromium 中支持測試震動和生成遊戲手柄的可視化，但 Firefox 不支持。此外，從版本 107.0.5304.121-1 開始，Chromium 可以讀取 Joystick 設備，但不能讀取 evdev 設備。

### 設置死區和校準

這篇文章的某些內容需要擴充。

原因：Describe calibration instructions for evdev (在 Talk:遊戲手柄#Unclear instructions on how to calibrate 中討論)

如果你想設置（或完全移除）模擬輸入的死區，你需要分別為 xorg（用於滑鼠和鍵盤仿真）、Joystick API 和 evdev API 進行設置。

#### 在 Wine 中設置死區

添加以下註冊表項並將其設置為 `0` 到 `10000` (影響所有搖杆):

    HKEY_CURRENT_USER\Software\Wine\DirectInput\DefaultDeadZone

Source: Useful Registry Keys

#### Xorg deadzones

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

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

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

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

#### Joystick API 死區和校準

最簡單的方法是使用 jstest-gtk-gitAUR中的jstest-gtk 。 選擇你想編輯的遊戲手柄，點擊 Properties（屬性）按鈕。 在新窗口中，點擊 Calibration（校準）按鈕 (不要點擊 Start Calibration). 然後，你可以設置 `CenterMin` 和 `CenterMax` 值，這兩個值控制中心死區; `RangeMin` 和 `RangeMax`，值控制扳機死區的末端。 請注意，校準設置會在應用程式打開設備時生效，因此你需要重新啟動你的遊戲或測試應用程式，才能看到更新後的校準設置。

在設置完死區後，你還可以創建一個 udev 規則，使所有更改永久生效：

首先，獲取手柄的供應商 ID（將`X`替換為手柄編號，通常為`0`）

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

Also grab the model id:

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

如果上述命令的輸出為空，可能是因為控制器是通過藍牙連接的，因此這些唯一屬性只能在父設備上看到。為避免這種情況，您可以嘗試運行以下命令查找其他唯一屬性：

    $ udevadm info -a /dev/input/jsX

這將列出您設備（及其父設備）所有可用的屬性。例如，如果您的操縱杆的父設備具有屬性 `ATTRS{uniq}=="a0:b1:c2:d3:e4:f5"`, 或者可能同時具有 `ATTRS{idVendor}=="054c"` 和 `ATTRS{idProduct}=="09cc"`, 那麼您可以在下面的 udev 規則中使用這些屬性來替代 `ENV{ID_VENDOR_ID}` 和 `ENV{ID_MODEL_ID}`

您也可以同時使用這兩條規則，只需用換行將它們分開。

總之，現在使用 jscal 來輸出手柄的新校準設置：

    $ jscal -p /dev/input/jsX

現在，使用您獲得的值修改這個 udev 規則：

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

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

這條規則將在您連接具有供應商 ID 為 `054c` 和型號 ID 為 `09cc` 的手柄時，自動運行 `/usr/bin/jscal -s 1,1,1,1 /dev/input/js%n`。其中的 `/dev/input/js%n` 部分是必需的，用於自動確定正確的搖杆，因此請不要刪除它。

最後, 加載新的 udev 規則.

#### evdev API 死區和校準

    linuxconsole包 中的evdev-joystick工具 可以用來查看和更改  evdev 設備的死區。

查看設備配置：

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

要更改某個搖杆的死區，可以使用類似以下的命令：

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

要同時為所有搖杆設置相同的死區，請省略`--axis 0`選項。

使用 udev 規則文件可以在控制器連接時自動設置這些參數。

請注意，在內核中，該值被稱為 `flatness`，並通過 `EVIOCSABS` `ioctl` 來設置。

默認配置與此類似：

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

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

而更合理的設置應該是這樣的（其他軸重複）：

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

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

#### xboxdrv 死區和校準

創建虛擬 Xbox 360 控制器的示例命令，`Y1`軸的死區設置為`4000`,，最小可讀值為`-32768` ，中心點為`128`，最大值為`29000`。

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

更多選項請參見xboxdrv(1) § AXIS FILTER

### 禁用搖杆控制滑鼠

如果您想使用手柄玩遊戲，您可能需要禁用它對滑鼠光標的操控。

最簡單的方法是禁用桌面環境設置中的滑鼠設備。否則，編輯 `/etc/X11/xorg.conf.d/51-joystick.conf`（如果不存在，可以創建），使其內容如下所示：

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

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

### 使用遊戲手柄發送鍵盤按鍵

有幾個程序可以將遊戲手柄按鈕映射到鍵盤按鍵：

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

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

#### Xorg 配置示例

對於很少重啟 Xorg 的系統來說，這是一個很好的解決方案，因為它是靜態配置，只在 X 啟動時加載。 示例在Kodi媒體 PC 上運行，使用 Logitech Cordless RumblePad 2 控制。 由於 d-pad（即「十字方向鍵」）被識別為另一個軸的問題，使用了 Joy2Key 作為解決方法。由於 kodi包 11.0 版本 和 joy2keyAUR 1.6.3-1 版本 之後，這種設置不再有效，因此創建了以下配置，允許 Xorg 處理搖杆事件。

首先, 安裝 xf86-input-joystickAUR 。 然後，創建一個 X 配置文件：

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

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

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

### 遊戲手柄按鈕重新映射及更多配置

通過某些程序，您還可以進一步配置遊戲手柄，包括以下潛在功能：

- 重新映射按鈕和軸
  - 為不同遊戲分配映射配置文件
- 模擬不同類型的遊戲手柄。某些軟體允許將遊戲手柄模擬為另一種類型的控制器。比如，很多程序和遊戲在識別 Xbox 360 控制器時表現更好，因為它是非常常見的控制器，且許多遊戲已經在其上進行過優化和測試
- 額外功能，如宏、屏幕顯示等

軟體列表:

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

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

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

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

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

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

#### 在 SDL2 應用程式上重新映射遊戲手柄

可以通過使用 `SDL_GAMECONTROLLERCONFIG` 環境變量重新映射 SDL2 應用程式中的遊戲手柄。每行配置包括遊戲手柄的 GUID、名稱、按鈕/軸映射以及平台。要獲取控制器的 GUID，可以通過安裝 sdl-jstest-gitAUR 然後運行 `sdl2-jstest --list` 來獲取。

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

    ~/.bashrc

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

一些應用程式從 `gamecontrollerdb.txt` 文件中提取映射信息。可以通過 controllermapAUR 以圖形方式進行編輯。最新的資料庫可以在以下位置找到[1]

#### 模擬 Xbox 360 控制器

xboxdrv 可以通過 `--mimic-xpad` 選項將任何控制器模擬為 Xbox 360 控制器。這對於那些原生支持 Xbox 360 控制器，但在檢測或使用其他遊戲手柄時出現問題的遊戲來說，可能會很有用。

你可以使用以下命令來模擬 Xbox 360 控制器：

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

上面的示例是不完整的。它僅映射了一個軸和三個按鈕用於演示。可以使用 `xboxdrv --help-button` 查看 Xbox 控制器按鈕和軸的名稱，並通過擴展上述命令來相應地綁定它們。軸映射應放在 `--evdev-absmap` 後面，按鈕映射應放在 `--evdev-keymap` 後面（以逗號分隔的列表；不帶空格）。

默認情況下，xboxdrv 會將所有事件輸出到終端。你可以使用這一功能來測試映射是否正確。如果想保持靜默，可以附加 `--silent` 選項。

## 特定設備

雖然大多數遊戲手柄，尤其是基於 USB 的遊戲手柄都能正常工作，但有些遊戲手柄可能需要使用其他驅動程序（或使用其他驅動程序會有更好的效果）。

### 跳舞毯

大多數舞毯墊應該都能正常工作。然而，一些舞蹈毯，尤其是通過適配器從遊戲主機連接的舞蹈毯，往往會將方向按鈕映射為軸按鈕。這會導致無法同時按下左-右或上-下方向鍵。對於 xpad 識別的設備，可以通過模塊選項修復此行為：

    # modprobe -r xpad
    # modprobe xpad dpad_to_buttons=1

如果這樣做無效，你可以嘗試使用 axisfix-gitAUR 或者修補 `joydev` 內核模塊（https://github.com/adiel-mittmann/dancepad）。

### 羅技 Thunderpad Digital

如果使用 `analog`模塊，Logitech Thunderpad Digital 將無法顯示所有按鈕。請使用該控制器專用的 `adi` 模塊。

### 任天堂GAMECUBE控制器

Dolphin 模擬器的 Wiki 上有一頁解釋了如何使用官方的 Nintendo USB 適配器連接 GameCube 控制器。如果將開關設置為「Wii U」，此配置也適用於 Mayflash 控制器適配器。

對於其他應用程式，你可以使用 wii-u-gc-adapterAUR。

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

這些控制器從內核版本 5.16 開始得到支持。Switch Online 的 NES、SNES 和 N64 控制器從內核版本 6.12 開始也得到支持。

對於較早的內核版本，可以安裝 DKMS 模塊 hid-nintendo-nso-dkmsAUR。

#### 將 Joy-Con 作為一個設備使用

hid-nintendo 內核驅動將兩個 Joy-Con 控制器處理為兩個獨立的設備。

joycond-gitAUR 是一個用戶空間守護進程，它使用 uinput 將兩個內核中的 Joy-Con evdev 設備合併為一個虛擬輸入設備。當守護進程處於活動狀態時，Switch 控制器將進入偽配對模式，LED 燈會開始閃爍。按住扳機可以用來配對控制器並使其可用。要將兩個 Joy-Con 配對在一起，按下每個 Joy-Con 上的扳機。

#### 在 SDL2 應用程式中使用位置布局

默認情況下，SDL2 會根據遊戲手柄的標籤映射 Nintendo 控制器上的按鈕，而不是根據按鈕的位置。這是通過 SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS 設置啟用的，對於已知使用 Nintendo 按鈕布局的控制器[2] ，該設置默認為 `1` ，而對於其他控制器[3]則默認為 `0`。可以通過設置 `SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS` 環境變量來覆蓋所有控制器的此行為。例如，如果不希望使用 Nintendo 的 A/B 和 X/Y 按鈕布局，可以設置 `SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS=0`

### Steam 控制器

注意：內核 4.18 提供了一個內核驅動程序，可以在沒有 Steam 的情況下將 Steam 控制器作為有線/無線控制器輸入設備使用。

Steam 客戶端會識別控制器，並在 Steam 運行時提供鍵盤/滑鼠/遊戲手柄仿真。要使遊戲手柄仿真正常工作，需要啟用並確保 Steam 遊戲內覆蓋層處於工作狀態。如果在安裝並運行 Steam 後控制器無法立即工作，可能需要以 root 權限運行 `udevadm trigger`，或者拔出並重新插入適配器。如果仍然無效，嘗試在適配器插入的狀態下重啟計算機。

如果你使用的是通過 Bluetooth LE 連接的控制器，請確保用戶屬於 `input` 組。

如果你無法讓 Steam 控制器正常工作，請參見 #Steam 控制器無法配對。

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

### Xbox 360 控制器

有線和無線（使用 Xbox 360 Wireless Receiver for Windows）控制器都受到 `xpad` 內核模塊的支持，並且應該無需額外的包即可正常工作。請注意，使用 Play&Charge USB 數據線連接無線 Xbox 360 控制器是無法正常工作的。該數據線僅用於充電，不能通過線纜傳輸任何輸入數據。

有報告指出，默認的 xpad 驅動程序在某些較新的有線和無線控制器上存在一些問題，例如：

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

如果你使用 TLP 電源管理工具，可能會遇到與 Microsoft 無線適配器的連接問題（例如，適配器連接幾秒鐘後指示燈熄滅，且控制器連接嘗試失敗，四個 LED 持續閃爍，但控制器仍然可以正常工作）。這是由於 TLP 的 USB 自動掛起功能導致的，解決方法是將 Microsoft 無線適配器的設備 ID 添加到 TLP 黑名單中（要檢查設備 ID，可以運行 `tlp-stat -u`；對於原版的 MS 無線適配器，只需將 `USB_DENYLIST="045e:0719"` 添加到 `/etc/tlp.conf`中）。有關更多細節，請查看 TLP 配置。

如果你遇到此類問題，可以改為使用 #xboxdrv 作為默認的 `xpad` 驅動程序。

為了通過藍牙連接，請添加以下內核參數：`bluetooth.disable_ertm=1`。

如果你在遊戲中遇到震動功能無法正常工作的情況，可能需要設置環境變量 `SDL_JOYSTICK_HIDAPI=0`。

#### xboxdrv

這一章節正在考慮移除。

原因: The driver portion of xboxdrv is deprecated. (在 Talk:遊戲手柄 討論)

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

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

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

    /etc/default/xboxdrv

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

    [xboxdrv-daemon]
    dbus = disabled

Then restart `xboxdrv.service`.

##### 多個控制器

xboxdrv 支持多種控制器，但需要在 `/etc/default/xboxdrv` 中進行配置。對於每個額外的控制器，添加一行 `next-controller = true`。例如，當使用 4 個控制器時，需要添加 3 次：

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

然後 restart `xboxdrv.service`.

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

一些克隆遊戲手柄可能需要特定的初始化序列才能正常工作（Super User answer）。為此，你應該以 root 用戶身份運行以下 Python 腳本：

    #!/usr/bin/env python3

    import usb.core

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

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

### Xbox 無線控制器 / Xbox One 無線控制器

#### 通過 USB 數據線連接 Xbox 無線控制器

這是由內核支持的，並且無需任何額外的包即可正常工作。

#### 通過藍牙連接 Xbox 無線控制器

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

Xbox 無線控制器的固件曾導致與 Bluez 連接/斷開連接的循環問題。最佳的解決方法是將控制器（通過 USB 數據線）連接到 Windows 10 計算機，下載 Xbox Accessories 應用程式（通過 Microsoft Store），並更新控制器的固件。

##### xpadneo

一個相對較新的驅動程序叫做 xpadneo，它支持通過藍牙連接 Xbox One S 和 Xbox Series X|S 控制器。除了這兩個型號，它還為 Xbox Elite Series 2 無線控制器提供了基本支持。雖然目前只完全支持這兩款控制器，但它提供了許多增強功能，包括讀取正確的電池電量、支持震動（甚至包括觸發按鈕上的震動 - L2/R2）、修正（有時錯誤的）按鈕映射等。

安裝可以通過 DKMS 完成：xpadneo-dkmsAUR。

注意：第一次配對 Xbox One S 控制器時可能會遇到一些困難，從完全無法配對到進入連接/斷開循環。這些問題可以在 [這裡] 找到相關描述。可靠地配對控制器的最佳方法是先在 Windows 10 中配對。但需要注意的是，這必須使用相同的藍牙適配器。一個解決方案是，在虛擬機中安裝免費的 Windows 10 企業版（使用 QEMU 或 VirtualBox，並確保藍牙適配器通過 USB 設備正確傳遞），以 Arch Linux 作為主機，然後首先在 Windows 10 中進行配對，再在 Arch Linux 系統中執行相同的操作。之後，配對將成功，並且不再需要使用 Windows 10。

#### 通過 Microsoft Xbox 無線適配器連接 Xbox 無線控制器

xone 是一個 Linux 內核驅動程序，用於支持 Xbox One 和 Xbox Series X|S 配件。它作為一個現代替代品，取代了 xpad 和 xow。目前可以通過有線連接或使用 Microsoft Xbox 無線適配器「適配器」正常工作。該驅動程序的 bug 修複目前由 dlundqvist fork 維護。

安裝 xone-dkms-gitAUR，如果使用無線適配器，還需要安裝 xone-dongle-firmwareAUR。安裝完成後需要重啟系統。

注意：

- 需要與你的內核對應的頭文件; 請參見 DKMS#安裝
- 該適配器使用基於 mt76 的 802.11/15 晶片組，這可能會導致與連接到同一系統或附近的其他無線適配器產生干擾

##### 控制器配對後表現不佳（回報率低）

你需要在 Windows 中使用 Microsoft Store 的 "Xbox Accessories" 應用程式來更新控制器固件。理論上，通過將 USB 設備傳遞到 Windows 虛擬機中也應該能夠完成此操作，但你可能需要雙重啟動到一個實際的（裸機）Windows 系統，以便 Xbox Accessories 應用能夠識別控制器並進行固件更新。

##### 與 Windows 雙啟動

在 Windows 中配對控制器和適配器可能會導致在 Linux 中丟失配對。每次重啟進入 Linux 時，你需要重新配對控制器和適配器。這種情況也會反過來發生——當控制器和適配器在 Linux 中配對時，下次你想在 Windows 中使用它們時，也需要重新配對。

##### 掛起和喚醒後無法連接。

在某些平台上，掛起可能會導致設備進入一個無法正常響應的狀態。由於設備被 Linux 識別為藍牙適配器，因此在掛起時會自動進入關機狀態，這也會禁用通過遊戲手柄喚醒系統的功能。可以通過在內核命令行中使用 `btusb.enable_autosuspend=n`來緩解此問題。注意：這將禁用系統中所有其他 USB 藍牙適配器的電源掛起功能。

### PlayStation 3 控制器

#### 通過USB連接

如果你擁有一個 PS3 控制器並且可以通過 USB 連接，將其插入電腦並按下 PS 按鈕。控制器將啟動，四個 LED 中的一個應該會亮起，表示控制器的編號。

#### 通過藍牙連接

安裝 bluez包 和 bluez-utils包。按照藍牙#配對的前五個步驟確保藍牙正常工作，並保持 bluetoothctl 命令運行。然後，通過按下中間的 'PS' 按鈕打開控制器（所有 4 個 LED 應該快速閃爍，大約 4 Hz），並通過 USB 將控制器連接到你的電腦。最後，當 bluetoothctl 出現下面的提示輸入"yes" `Authorize service 00001124-0000-1000-8000-00805f9b34fb (yes/no)` 替代說明： 要通過藍牙將 PS3 控制器連接到電腦，首先需要安裝 bluez包，然後通過 USB 連接控制器。彈出窗口應會提示進行配對，點擊 Trust & Authorize。現在你可以拔掉控制器並按下 PS 按鈕，控制器將連接並且一個 LED 會保持常亮。此時你可以用它來玩遊戲。僅在控制器已經連接到其他系統後，才需要使用 USB 數據線進行連接。

注意： 在最新版本的 bluez包（截至 2024/01/03），出於安全原因，`ClassicBondedOnly` 的默認值已從 `false` 更改為 `true` [4]。此更改導致無法配對 Dual Shock 3 控制器，因為 `bluetoothctl` 會要求輸入 PIN 碼，且無法繼續配對。為了解決此問題，可以通過在新創建的 `/etc/bluetooth/input.conf` 文件中添加以下行，將 `ClassicBondedOnly` 設置為 `false`：

.

截至 2024年3月9日，`UserspaceHID` 的默認值也已更改為 `true`。雖然連接可以成功，但除非將該值更改為 `false`，否則控制器無法進入操作模式。有關更多信息，請參閱 GitHub issue#771。

    [General]
    ClassicBondedOnly=false
    UserspaceHID=false

請注意，此解決方案在安全性上存在倒退。有關詳細信息，請參閱 GitHub。

提示：網際網路上有許多關於設置 PS3 控制器的複雜說明，通常需要很多步驟，例如編譯和安裝 qtsixa 或 sixpair，手動設置控制器，或者用一些特定的補丁修補 bluez。但在現代 Linux 內核上如果安裝了 bluez-plugins 後，這些步驟都不再是必須的。

### PlayStation 3/4 控制器

DualShock 3、DualShock 4 和 Sixaxis 控制器在通過 USB 插入時可以即插即用（需要按下 PS 按鈕才能開始）。它們也可以通過藍牙無線使用。

Steam 會正確識別它為 PS3 手柄，並且可以通過 PS 按鈕啟動 Big Picture 模式。Big Picture 模式和一些遊戲可能會將其識別為 360 手柄。默認情況下，手柄控制滑鼠功能是開啟的。你可能希望在玩遊戲之前關閉它，詳見#禁用搖杆控制滑鼠。

#### 通過藍牙連接

安裝 bluez包 和 bluez-utils包 包，其中包括 sixaxis 插件。然後啟動 bluetooth 服務，並確保藍牙已開啟。如果使用 bluetoothctl，在終端中啟動它，然後通過 USB 插入控制器。你應該會被提示在 bluetoothctl 中信任該控制器。圖形化的藍牙前端可能會自動將電腦的藍牙地址寫入控制器。按下 PlayStation 按鈕並檢查在插入時控制器是否正常工作。

現在你可以斷開控制器的連接。下次按下 PlayStation 按鈕時，它將自動連接，無需任何額外操作。

另外，在 PS4 控制器上，你可以同時按住分享按鈕和 PlayStation 按鈕（持續幾秒鐘）將手柄置於配對模式，然後按通常的方式進行配對。

GNOME 的設置也提供了一個圖形界面，當控制器通過有線連接時，可以配對 sixaxis 控制器。

記得在使用完後斷開控制器的連接，因為控制器在連接時會一直處於開啟狀態，從而耗盡電池。

注意：如果控制器未能連接，請確保藍牙接口已開啟，並且控制器已被信任。 (詳情見 藍牙)

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

使用通用/克隆 Dualshock 控制器是可行的，但有一個問題可能需要安裝一個補丁包。默認的藍牙協議棧無法檢測到某些克隆控制器。bluez-ps3AUR 包是一個經過補丁的版本，能夠檢測這些控制器。bluez-plugins-ps3AUR 是另一個包，它只對 bluez-plugins 進行補丁，可能適用於某些控制器。

### PlayStation 4/5 控制器

#### 通過 USB 連接

通過 USB 連接你的控制器並按下 `PS` 按鈕。

#### 通過藍牙連接

如果你想使用藍牙模式，請同時按住 `PS` 按鈕和 `Share` 按鈕。控制器的白色 LED 應該會快速地閃爍，隨後無線控制器可以與你的藍牙管理器配對。

#### 在 Wine 中使用

對於這些控制器，Wine 默認使用 hidraw（自 8.0 起），因此支持它們的 Windows 應用程式可以使用它們的所有功能。由於這種類似 Windows 的行為，這些控制器不會作為 XInput 設備暴露，因此無法在許多應用程式中使用。 要禁用此行為，可以將以下文本文件導入 Wine 註冊表 regedit:

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

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

#### 禁用觸摸板作為滑鼠使用

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

注意，由於觸摸板只是控制器的一部分，僅通過供應商和產品 ID 選擇輸入設備是不夠的。相反，建議通過設備名稱來選擇設備。

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

要查找設備路徑，你可以使用工具，如 evtest包，只需運行 `evtest` 命令。該命令還應列印出設備的名稱。

示例代碼片段:

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

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

對於 DualSense 控制器，將名稱替換為 `Sony Interactive Entertainment DualSense Wireless Controller Touchpad` and `DualSense Wireless Controller Touchpad`.

然後，重新加載 udev 規則。重新連接遊戲手柄以應用更改。

#### dualsensectl

dualsensectl 是一個可以切換燈條和麥克風（及其 LED）、監控電池狀態和關閉控制器電源的工具。要使用它，[[安裝］ dualsensectl-gitAUR.

## 提示與技巧

### 通過網絡使用遊戲手柄

如果你想通過網絡將遊戲手柄連接到另一台計算機，可以使用 USB/IP 或 netstick-gitAUR 來實現。

## 故障排除

### 設備權限

遊戲手柄設備受 udev 規則的影響：除非這些規則授予設備訪問權限，否則普通用戶將無法讀取設備。本節將探討是否有可能在配置文件中處理這一問題。

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

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

Some examples of applications which ship noteworthy rules:

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

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

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

### Gamepad is not recognized by all programs

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

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

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

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

    # udevadm info -an /dev/input/js0

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

    # udevadm control --reload

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

### Application only supports Xbox 360 controllers

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

For a workaround, see #Mimic Xbox 360 controller.

### Steam 控制器

#### Steam 控制器無法配對

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

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

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

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

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

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

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

    # rmmod hid_steam

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

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

### Playstation 4 controllers

#### Controller not recognized when using Bluetooth

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

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

本文或本章節的語言、語法或風格需要改進。參考：幫助:風格

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

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

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

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

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

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

### Multi-mode wired gamepads

本文或本章節的語言、語法或風格需要改進。參考：幫助:風格

原因：Multiple improvements to be made.（在Talk:遊戲手柄討論）

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

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

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

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

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

In `dmesg` this looks like:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

This can be fixed by adding

    SDL_HIDAPI_DISABLE_LIBUSB=1

into `/etc/environment`, and rebooting.

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

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

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

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

#### Xbox 360 Controller mode

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

add

    blacklist hid_nintendo

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

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

Now create the following file:

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

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

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

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

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

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

And if you want to switch vice versa:

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

##### Alternative rootless solution

If you don't have root access, then:

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

### USB debugging

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

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

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

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

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

## Example xboxdrv configurations

這一章節正在考慮移除。

原因: xboxdrv is very rarely needed, and this section takes up a lot of space for how specific it is. (在 Talk:遊戲手柄 討論)

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

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

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

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

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

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

### iPEGA-9017s

    ~/.config/xboxdrv/ipega.conf

    #iPEGA PG-9017S Config

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

    [evdev-absmap]
    ABS_HAT0X = dpad_x
    ABS_HAT0Y = dpad_y

    ABS_X = X1
    ABS_Y = Y1

    ABS_Z  = X2
    ABS_RZ = Y2

    [axismap]
    -Y1 = Y1
    -Y2 = Y2

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

    BTN_MODE = guide

### iPEGA-9068 and 9087

    ~/.config/xboxdrv/ipega.conf

    #iPEGA PG-9068 and PG-9087 Config

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

    [evdev-absmap]
    ABS_HAT0X = dpad_x
    ABS_HAT0Y = dpad_y

    ABS_X = X1
    ABS_Y = Y1

    ABS_Z  = X2
    ABS_RZ = Y2

    [axismap]
    -Y1 = Y1
    -Y2 = Y2

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

    BTN_MODE = guide

### Defender X7

    ~/.config/xboxdrv/defender.conf

    #Defender x7 xboxdrv config

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

    [evdev-absmap]
    ABS_HAT0X = dpad_x
    ABS_HAT0Y = dpad_y

    ABS_X = X1
    ABS_Y = Y1

    ABS_Z  = X2
    ABS_RZ = Y2

    [axismap]
    -Y1 = Y1
    -Y2 = Y2

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

    BTN_MODE = guide

### Stadia Controller

    ~/.config/xboxdrv/stadia.conf

    # Stadia xboxdrv config

    [xboxdrv]
    mimic-xpad=true
    silent=true

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

    [axismap]
    -y1=y1
    -y2=y2

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

    BTN_START=start
    BTN_SELECT=back
    BTN_MODE=guide

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

### Logitech Dual Action

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

### PlayStation 2 controller

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

### PlayStation 4 controller

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

### PlayStation 5 controller

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

分類：​

- 輸入設備
- 遊戲
- 使用「模板:Remove」標記的章節
- 使用「模板:風格」標記的頁面或章節

遊戲手柄
新增話題