首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Playstation usb适配器缺少按钮

Playstation usb适配器缺少按钮
EN

Unix & Linux用户
提问于 2019-03-20 16:53:24
回答 1查看 351关注 0票数 0

我试图在PC/Linux上使用PS2吉他英雄II控制器。在尝试了多个Playstation到usb适配器之后,我终于找到了一个不会导致任何输入滞后的适配器。

但是,正如在linux输入邮件列表线程中所讨论的,我在检测linux下的所有按钮时遇到了问题。

Windows

  • 所有的按钮都被检测到了,但是D-pad (上/下)被错误地映射到与"Whammy bar“相同的轴上。这不是破坏游戏,而是不方便。

Linux

  • Linux检测控制器为ID 054c:0268 Sony Corp. Batoh Device / PlayStation 3 Controller,有13个按钮和6个轴。
  • 某些按钮不会导致/dev/input/jsX中的任何事件
  • /dev/hidrawX中检测到,非工作按钮确实会导致HID事件.

现在,我知道这是一个bug,我应该等待对驱动程序的修复。在修复过程中,我想找到一个解决办法。

我能很容易地编写一些udev规则来将原始HID事件映射到输入事件吗?

此外,我还捕获了在windows下使用wireshark进行USB握手的过程。

EN

回答 1

Unix & Linux用户

回答已采纳

发布于 2019-03-22 05:59:47

我通过使用巨蟒的希达皮实现了它。最后,这很容易,我只是错过了工具。

如果有人需要指导,下面是完整的脚本:

代码语言:javascript
复制
from __future__ import print_function

import hid
import time
import uinput

MAPPING = {
    'green': uinput.BTN_0,
    'red': uinput.BTN_1,
    'yellow': uinput.BTN_2,
    'blue': uinput.BTN_3,
    'orange': uinput.BTN_4,
    'tilt': uinput.BTN_SELECT,  # SELECT
    'start': uinput.BTN_START,  # START
    'select': uinput.BTN_SELECT,  # SELECT
    'whammy': uinput.ABS_X,  # WHAMMY
    'strumdown': uinput.BTN_DPAD_DOWN,
    'strumup': uinput.BTN_DPAD_UP,
}

DEVICE = uinput.Device(MAPPING.values())

# enumerate USB devices

for d in hid.enumerate():
    keys = list(d.keys())
    keys.sort()
    for key in keys:
        print("%s : %s" % (key, d[key]))
    print()

# try opening a device, then perform write and read


def diff(new_arr, old_arr):
    for i in range(len(new_arr)):
        if new_arr[i] != old_arr[i]:
            yield (i, new_arr[i]) 


try:
    print("Opening the device")

    h = hid.device()
    h.open(0x054c, 0x0268)  # VendorID/ProductID

    print("Manufacturer: %s" % h.get_manufacturer_string())
    print("Product: %s" % h.get_product_string())
    print("Serial No: %s" % h.get_serial_number_string())

    # enable non-blocking mode
    h.set_nonblocking(1)

    # write some data to the device
    print("Write the data")
    h.write([0, 63, 35, 35] + [0] * 61)

    # wait
    time.sleep(0.05)

    # read back the answer
    print("Read the data")
    previous = None
    INPUT = {
        'green': False,
        'red': False,
        'yellow': False,
        'blue': False,
        'orange': False,
        'tilt': False,
        'start': False,
        'select': False,
        'whammy': False,
        'strumdown': False,
        'strumup': False,
    }

    def set_input(key, val, tmp):
        prev = INPUT[key]
        if tmp >= val:
            tmp -= val
            INPUT[key] = True
        else:
            INPUT[key] = False

        if prev != INPUT[key]:
            # SEND EVENT
            DEVICE.emit(MAPPING[key], INPUT[key])
            pass

        return tmp

    counter = 0
    while True:
        try:
            time.sleep(0.001)
            d = h.read(64)
            counter += 1
            if d:
                if previous and d != previous:
                    for ret in diff(d, previous):
                        if ret[0] == 7:
                            DEVICE.emit(MAPPING['whammy'], ret[1])

                        if ret[0] == 2:
                            tmp = ret[1] - 128
                            tmp = set_input('strumdown', 64, tmp)
                            tmp = set_input('strumup', 16, tmp)
                            tmp = set_input('start', 8, tmp)
                            tmp = set_input('select', 1, tmp)

                        if ret[0] == 3:
                            tmp = ret[1]
                            tmp = set_input('orange', 128, tmp)
                            tmp = set_input('blue', 64, tmp)
                            tmp = set_input('red', 32, tmp)
                            tmp = set_input('yellow', 16, tmp)
                            tmp = set_input('green', 2, tmp)
                            tmp = set_input('tilt', 1, tmp)

                previous = d
            else:
                continue
        except KeyboardInterrupt:
            break
        print(counter, end="\r")
        # print(INPUT)

    print("Closing the device")
    h.close()

except IOError as ex:
    print(ex)
    print("You probably don't have the hard coded device. Update the hid.device line")
    print("in this script with one from the enumeration list output above and try again.")

print("Done")
票数 1
EN
页面原文内容由Unix & Linux提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://unix.stackexchange.com/questions/507488

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档