forked from ringnutz/retropie-pcsx2-wrapper
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgamepad_wrapper.py
134 lines (120 loc) · 6.12 KB
/
gamepad_wrapper.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#!/usr/bin/python3
from evdev import InputDevice, categorize, ecodes, list_devices
import psutil
from select import select
import json
import os.path
from sys import argv
############# Configuration ##############
if len(argv) <= 1:
print("No application specified! Exiting.")
exit()
mode = "normal" # change to debug for additional output
# More information from https://core-electronics.com.au/tutorials/using-usb-and-bluetooth-controllers-with-python.html
dev_config = dict()
# Set an entry for the controller with its name
# Change script mode to debug to see the connected controller names and paths
dev_config["Xbox Wireless Controller"] = dict()
# Configure the buttons to be pressed simultaneously to terminate the emulator
# The first button acts as hotkey enable and must be pressed before the other buttons
# You can set up as many buttons as you like
# Change script mode to debug to see your button presses (run script manually)
dev_config["Xbox Wireless Controller"]["buttons"] = [158, 315]
# Process to look for to kill when all keys are pressed
procName = '/usr/games/PCSX2'
config_file = "gamepad_wrapper.json"
config_file = os.path.dirname(os.path.abspath(__file__)) + "/" + config_file
if os.path.isfile(config_file):
with open(config_file, 'r') as json_config:
json_data = json.load(json_config)
if "mode" in json_data:
mode = json_data["mode"]
if "dev_config" in json_data:
valid = True
for entry in json_data["dev_config"].values():
if not "buttons" in entry:
valid = False
if valid:
dev_config = json_data["dev_config"]
else:
print("Error parsing dev_config")
if "proc_names" in json_data:
if not mode == "test":
if argv[1] not in json_data["proc_names"].keys():
print("Specified application not configured. Exiting.")
exit()
procName = json_data["proc_names"][argv[1]]
else:
print("No config file found! Using default values.")
############# Functionality ##############
available_devices = [InputDevice(path) for path in list_devices()]
gamepads = {}
buttons_pressed = []
if mode == "debug" or mode == "test":
print("Available devices:")
for device in available_devices:
if mode == "debug" or mode == "test":
print(device.name, device.path)
if device.name in dev_config.keys():
gamepads[device.fd] = {
"device": device,
"buttons": dev_config[device.name]["buttons"],
"buttons_pressed": [False for element in range(len(dev_config[device.name]["buttons"]))]
}
if len(gamepads.keys()) == 0:
print("Specified device not found. Exiting...")
exit()
if mode == "debug" or mode == "test":
print("Chosen device paths: ", *(gamepads[dev]["device"].path for dev in gamepads.keys()), sep='\n')
active = True
while active:
try:
r, w, x = select(gamepads, [], []) # efficiently wait for input of any gamepad
for fd in r:
for event in gamepads[fd]["device"].read():
if event.type == ecodes.EV_KEY:
if event.value == 1: # Button pressed
if mode == "debug" or mode == "test":
print("Button pressed for device ", gamepads[fd]["device"].path)
print(event.code)
if event.code in ecodes.KEY:
print(ecodes.KEY[event.code])
# if the first defined button (acting as hotkey enable) is pressed
# or already has been pressed, update the respective buttons_pressed values
if event.code == gamepads[fd]["buttons"][0] \
or gamepads[fd]["buttons_pressed"][0]:
if event.code in gamepads[fd]["buttons"]:
index = gamepads[fd]["buttons"].index(event.code)
gamepads[fd]["buttons_pressed"][index] = True
elif event.value == 0: # Button released
if mode == "debug" or mode == "test":
print("Button released for device ", gamepads[fd]["device"].path)
print(event.code)
if event.code in ecodes.KEY:
print(ecodes.KEY[event.code])
# if the hotkey enable button is released, we reset all buttons
if event.code == gamepads[fd]["buttons"][0]:
gamepads[fd]["buttons_pressed"] = [False for element in range(len(gamepads[fd]["buttons"]))]
elif event.code in gamepads[fd]["buttons"]:
index = gamepads[fd]["buttons"].index(event.code)
gamepads[fd]["buttons_pressed"][index] = False
# if all values are true, i.e. all buttons are pressed, terminate the application
if len([button for button in gamepads[fd]["buttons_pressed"] if button]) == len(
gamepads[fd]["buttons"]):
if mode == "debug" or mode == "test":
print("PS button and terminate buttons pressed")
for process in psutil.process_iter():
if procName.lower() in [line.lower() for line in process.cmdline()]:
if mode == "debug":
print('Process found. Terminating it.')
if mode != "test":
process.terminate()
print('Process terminated due to button event')
active = False
exit()
break
else:
print('Process found. We would terminate it now, but we are in test mode...')
except Exception as e:
print(e)
active = False