-
Notifications
You must be signed in to change notification settings - Fork 41
/
generate-gamepad-mappings
executable file
·125 lines (98 loc) · 2.84 KB
/
generate-gamepad-mappings
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
#!/usr/bin/env python2.7
import argparse
import json
def get_max_size(val):
return {
'head': 4,
'axes': 13,
'button': 45
}.get(val, 0)
def get_key_name(val):
return {
'b': 'button',
'a': 'axes',
'h': 'head'
}.get(val, val)
def get_button_name(name):
return {
"dpup": "up",
"dpright": "right",
"dpleft": "left",
"dpdown": "down",
"lefty": "leftStickY",
"righty": "rightStickY",
"leftx": "leftStickX",
"rightx": "rightStickX",
"righttrigger": "rightTrigger",
"leftshoulder": "leftBumper",
"rightshoulder": "rightBumper",
"rightstick": "rightStick",
"lefttrigger": "leftTrigger",
"leftstick": "leftStick"
}.get(name, name)
def save(filename, data):
with open(filename, 'w') as file_:
file_.write(data)
def change_endian(hexString):
return ''.join(sum([(c,d,a,b) for a,b,c,d in zip(*[iter(hexString)]*4)], ()))
def parse_file(filePath, resPath):
with open(filePath) as f:
content = f.readlines()
result = {}
platform = ""
for line in content:
line = line.strip(" \t\r\n")
if len(line) == 0:
continue
if line[0] == '#': # skip OS lines
platform = line[2:]
continue
tokens = line.split(',')
if len(tokens) <= 1:
continue
gamepad = {}
vendor = tokens[0][:16]
product = tokens[0][16:32]
if platform.lower() == "linux":
vendor = str(int(change_endian(vendor)[8:12], 16))
product = str(int(change_endian(product)[8:12], 16))
else:
vendor = str(int(change_endian(vendor)[0:4], 16))
product = str(int(change_endian(product)[0:4], 16))
id = vendor + ":" + product
gamepad['name'] = tokens[1]
gamepad['mapping'] = {}
gamepad['mapping']['button'] = [0] * 45 # 45 - max button number
gamepad['mapping']['axes'] = [0] * 13 # 13 - max axes count
max_button = 0
max_axes = 0
for t in tokens:
if len(t) == 0:
continue
item = t.split(':')
if len(item) <= 1 or item[0] == "platform" or len(item[0]) == 0 or len(item[1]) == 0:
continue
key = get_key_name(item[1][0])
if key == "head":
continue
val = get_button_name(item[0])
idx = int(item[1][1:])
gamepad['mapping'][key][idx] = val
if key == "button":
if max_button < idx:
max_button = idx
elif key == "axes":
if max_axes < idx:
max_axes = idx
gamepad['mapping']['button'] = gamepad['mapping']['button'][:max_button + 1] if max_button > 0 else []
gamepad['mapping']['axes'] = gamepad['mapping']['axes'][:max_axes + 1] if max_axes > 0 else []
result[id] = gamepad
save(resPath, json.dumps(result, sort_keys=True))
if __name__ == '__main__':
parser = argparse.ArgumentParser()
# input file example
# https://raw.githubusercontent.com/gabomdq/SDL_GameControllerDB/master/gamecontrollerdb.txt
parser.add_argument('file')
parser.add_argument('output')
args = parser.parse_args()
parse_file(args.file, args.output)