Last active
November 12, 2019 14:13
-
-
Save underdoeg/2b1539fd2fe10a3ed88cc73526f83e1e to your computer and use it in GitHub Desktop.
HDE PS2 controller mapping for linux
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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