Skip to content

Instantly share code, notes, and snippets.

@underdoeg
Last active November 12, 2019 14:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save underdoeg/2b1539fd2fe10a3ed88cc73526f83e1e to your computer and use it in GitHub Desktop.
Save underdoeg/2b1539fd2fe10a3ed88cc73526f83e1e to your computer and use it in GitHub Desktop.
HDE PS2 controller mapping for linux
from __future__ import print_function
import hid
import time
import uinput
buttons = [
uinput.BTN_START,
uinput.BTN_SELECT,
uinput.BTN_NORTH,
uinput.BTN_WEST,
uinput.BTN_EAST,
uinput.BTN_SOUTH,
uinput.BTN_TR,
uinput.BTN_TR2,
uinput.BTN_TL,
uinput.BTN_TL2,
uinput.BTN_THUMBL,
uinput.BTN_THUMBR,
uinput.BTN_DPAD_UP,
uinput.BTN_DPAD_RIGHT,
uinput.BTN_DPAD_DOWN,
uinput.BTN_DPAD_LEFT,
]
mapping = buttons + [
uinput.ABS_X + (-128, 128, 0, 0),
uinput.ABS_Y + (-128, 128, 0, 0),
uinput.ABS_RX + (-128, 128, 0, 0),
uinput.ABS_RY + (-128, 128, 0, 0),
]
events = (
uinput.BTN_JOYSTICK,
uinput.ABS_X + (0, 255, 0, 0),
uinput.ABS_Y + (0, 255, 0, 0),
)
device = uinput.Device(mapping, "PLAYSTATION(R)2 Controller")
# 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
# buttons on the PS2 are analog but treat them as though they are digital
btnStates = {}
for button in buttons:
btnStates[button] = False
def emit_button(btn, value):
# do not emit multiple times for each analog value
if value > 0 and btnStates[btn]:
return
btnStates[btn] = value > 0
device.emit(btn, btnStates[btn])
counter = 0
while True:
try:
time.sleep(0.001)
d = h.read(64)
counter += 1
if d:
if previous and d != previous:
for val in diff(d, previous):
index = val[0]
value = val[1]
#print(index)
if index == 6:
device.emit(uinput.ABS_X, value - 128)
elif index == 7:
device.emit(uinput.ABS_Y, value - 128)
elif index == 8:
device.emit(uinput.ABS_RX, value - 128)
elif index == 9:
device.emit(uinput.ABS_RY, value - 128)
# buttons
elif index == 24:
# print(val)
emit_button(uinput.BTN_SOUTH, value)
elif index == 23:
emit_button(uinput.BTN_EAST, value)
elif index == 22:
emit_button(uinput.BTN_NORTH, value)
elif index == 25:
emit_button(uinput.BTN_WEST, value)
elif index == 25:
emit_button(uinput.BTN_WEST, value)
elif index == 2:
if value == 0:
# any button was released
for btn in [uinput.BTN_SELECT, uinput.BTN_START, uinput.BTN_THUMBL, uinput.BTN_THUMBR]:
if btnStates[btn]:
emit_button(btn, 0)
if value == 8:
# start was pressed
emit_button(uinput.BTN_START, 1)
elif value == 1:
# select was pressed
emit_button(uinput.BTN_SELECT, 1)
elif value == 2:
emit_button(uinput.BTN_THUMBL, 1)
elif value == 4:
emit_button(uinput.BTN_THUMBR, 1)
elif index == 20:
emit_button(uinput.BTN_TL, value)
elif index == 18:
emit_button(uinput.BTN_TL2, value)
elif index == 21:
emit_button(uinput.BTN_TR, value)
elif index == 19:
emit_button(uinput.BTN_TR2, value)
elif index == 15:
emit_button(uinput.BTN_DPAD_RIGHT, value)
elif index == 17:
emit_button(uinput.BTN_DPAD_LEFT, value)
elif index == 14:
emit_button(uinput.BTN_DPAD_UP, value)
elif index == 16:
emit_button(uinput.BTN_DPAD_DOWN, value)
previous = d
else:
continue
except KeyboardInterrupt:
break
print("Closing the device")
device.destroy()
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")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment