You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使uinput.Device实例重建后仍被Zsnes等软件识别为同一设备?

解决python-uinput虚拟手柄重建后Zsnes识别问题

问题背景

在Python3中使用python-uinput模块创建双摇杆标准游戏手柄(方向键为离散ABS_X/ABS_Y,左摇杆为模拟ABS_X/ABS_Y,右摇杆为模拟ABS_RX/ABS_RY)时,发现以下问题:

  • 创建实例时指定bustype(0x06为虚拟设备)、自定义vendor ID、product ID及version等参数,和仅指定name的效果一致
  • 设备未断开时运行正常,但在Zsnes中会出现识别异常:
    1. 创建实例:device = uinput.Device(events, "My-Gamepad-1")
    2. 在Zsnes中配置输入并正常使用
    3. 调用device.destroy()断开设备
    4. 用相同参数重建实例
    5. 重启Zsnes后无法识别该设备,或无法重新配置输入

Unity可正常识别重建后的设备,但Zsnes依赖特定设备标识符匹配,需实现让重建后的设备同时兼容两者的创建方式。

解决方案

核心思路是让重建后的设备保持固定的硬件标识符与持久化设备节点,避免Zsnes将其识别为新设备。

1. 配置udev规则生成固定设备链接

Zsnes依赖udev生成的设备路径识别设备,通过udev规则为虚拟手柄绑定固定的符号链接,确保重建后设备路径不变:

  • 创建udev规则文件/etc/udev/rules.d/99-my-gamepad.rules,内容如下:
SUBSYSTEM=="input", ATTRS{name}=="My-Gamepad-1", ATTRS{idVendor}=="2357", ATTRS{idProduct}=="0001", SYMLINK+="input/my-gamepad"

注意:规则中的idVendor和idProduct要与后续创建uinput设备时的参数对应(0x2357转字符串为"2357",0x1转字符串为"0001")。

  • 重新加载udev规则:
sudo udevadm control --reload-rules
sudo udevadm trigger

2. 严格固定uinput设备的所有硬件参数

确保创建实例时明确传递所有参数且值完全一致,避免python-uinput默认行为覆盖设置:

import uinput

# 定义双摇杆手柄完整事件列表
events = [
    # 左摇杆模拟输入
    uinput.ABS_X + (-32768, 32767, 0, 0),
    uinput.ABS_Y + (-32768, 32767, 0, 0),
    # 右摇杆模拟输入
    uinput.ABS_RX + (-32768, 32767, 0, 0),
    uinput.ABS_RY + (-32768, 32767, 0, 0),
    # 方向键离散输入
    uinput.ABS_HAT0X + (-1, 1, 0, 0),
    uinput.ABS_HAT0Y + (-1, 1, 0, 0),
    # 基础按键事件
    uinput.BTN_A, uinput.BTN_B, uinput.BTN_X, uinput.BTN_Y,
    uinput.BTN_TL, uinput.BTN_TR
]

# 创建设备时严格固定所有参数
device = uinput.Device(
    events,
    name="My-Gamepad-1",
    bustype=0x06,
    vendor=0x2357,
    product=0x0001,
    version=0x0100
)

注意:product ID需写成0x0001而非0x1,确保与udev规则中的字符串匹配;version参数也需固定,避免重建时变化。

3. 规范设备销毁与重建流程

销毁设备后等待udev完成设备移除处理,再用完全相同的参数重建:

# 销毁设备
device.destroy()
# 等待udev处理设备移除
import time
time.sleep(0.5)
# 用完全一致的参数重建设备
device = uinput.Device(
    events,
    name="My-Gamepad-1",
    bustype=0x06,
    vendor=0x2357,
    product=0x0001,
    version=0x0100
)

原理说明

Zsnes等老模拟器依赖硬件标识符组合(vendor ID、product ID、name、version)及udev生成的持久化路径识别设备,Unity对设备标识符兼容性更强。通过固定所有硬件参数并配置udev规则生成固定链接,可让Zsnes将重建后的设备识别为同一设备,同时兼容Unity。

内容的提问来源于stack exchange,提问作者Luis Masuelli

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 08:43:25