2323#include < fcntl.h>
2424#include < linux/input.h>
2525
26- #define test_bit (bit, array ) ((array)[(bit)/ 8 ] & (1 <<((bit)&7 )))
26+ #define test_bit (bit, array ) ((array)[(bit)>> 3 ] & (1 <<((bit)&7 )))
2727
2828static InputDevice::ControlAxis axis_map[] = {
29- InputDevice::C_left_x, InputDevice::C_left_y, InputDevice::C_left_trigger,
30- InputDevice::C_right_x, InputDevice::C_right_y, InputDevice::C_right_trigger
29+ // ABS_X = 0x00
30+ InputDevice::C_left_x,
31+ // ABS_Y = 0x01
32+ InputDevice::C_left_y,
33+ // ABS_Z = 0x02
34+ InputDevice::C_left_trigger,
35+ // ABS_RX = 0x03
36+ InputDevice::C_right_x,
37+ // ABS_RY = 0x04
38+ InputDevice::C_right_y,
39+ // ABS_RZ = 0x05
40+ InputDevice::C_right_trigger,
41+ // ABS_THROTTLE = 0x06
42+ InputDevice::C_throttle,
43+ // ABS_RUDDER = 0x07
44+ InputDevice::C_rudder,
45+ // ABS_WHEEL = 0x08
46+ InputDevice::C_wheel,
47+ // ABS_GAS = 0x09
48+ InputDevice::C_accelerator,
49+ // ABS_BRAKE = 0x0a
50+ InputDevice::C_brake,
51+
52+ InputDevice::C_none,
53+ InputDevice::C_none,
54+ InputDevice::C_none,
55+ InputDevice::C_none,
56+ InputDevice::C_none,
57+
58+ // ABS_HAT0X = 0x10
59+ InputDevice::C_hat_x,
60+ // ABS_HAT0Y = 0x11
61+ InputDevice::C_hat_y,
62+
63+ // ABS_HAT1X = 0x12
64+ // ABS_HAT1Y = 0x13
65+ // ABS_HAT2X = 0x14
66+ // ABS_HAT2Y = 0x15
67+ // ABS_HAT3X = 0x16
68+ // ABS_HAT3Y = 0x17
69+ // ABS_PRESSURE = 0x18
70+ // ABS_DISTANCE = 0x19
71+ // ABS_TILT_X = 0x1a
72+ // ABS_TILT_Y = 0x1b
73+ // ABS_TOOL_WIDTH = 0x1c
3174};
3275
3376TypeHandle EvdevInputDevice::_type_handle;
@@ -189,7 +232,7 @@ init_device() {
189232 }
190233
191234 bool all_values_zero = true ;
192- bool have_dpad_buttons = false ;
235+ bool emulate_dpad = true ;
193236
194237 if (test_bit (EV_KEY, evtypes)) {
195238 // Check which buttons are on the device.
@@ -213,7 +256,7 @@ init_device() {
213256 _buttons[bi]._state = S_up;
214257 }
215258 if (_buttons[bi]._handle == GamepadButton::dpad_left ()) {
216- have_dpad_buttons = true ;
259+ emulate_dpad = false ;
217260 }
218261 ++bi;
219262 }
@@ -241,6 +284,10 @@ init_device() {
241284 }
242285 }
243286
287+ if (_device_class != DC_gamepad) {
288+ emulate_dpad = false ;
289+ }
290+
244291 if (test_bit (EV_ABS, evtypes)) {
245292 // Check which axes are on the device.
246293 uint8_t axes[(ABS_CNT + 7 ) >> 3 ];
@@ -254,7 +301,25 @@ init_device() {
254301 int num_bits = ioctl (_fd, EVIOCGBIT (EV_ABS, sizeof (axes)), axes) << 3 ;
255302 for (int i = 0 ; i < num_bits; ++i) {
256303 if (test_bit (i, axes)) {
257- set_control_map (i, axis_map[i]);
304+ // Emulate D-Pad buttons if necessary.
305+ if (i > ABS_HAT0Y) {
306+ set_control_map (i, C_none);
307+
308+ } else if (i == ABS_HAT0X && emulate_dpad) {
309+ _dpad_x_axis = i;
310+ _dpad_left_button = (int )_buttons.size ();
311+ _buttons.push_back (ButtonState (GamepadButton::dpad_left ()));
312+ _buttons.push_back (ButtonState (GamepadButton::dpad_right ()));
313+
314+ } else if (i == ABS_HAT0Y && emulate_dpad) {
315+ _dpad_y_axis = i;
316+ _dpad_up_button = (int )_buttons.size ();
317+ _buttons.push_back (ButtonState (GamepadButton::dpad_up ()));
318+ _buttons.push_back (ButtonState (GamepadButton::dpad_down ()));
319+
320+ } else {
321+ set_control_map (i, axis_map[i]);
322+ }
258323
259324 // Check the initial value and ranges.
260325 struct input_absinfo absinfo;
@@ -284,20 +349,6 @@ init_device() {
284349 all_values_zero = false ;
285350 }
286351 }
287-
288- // Emulate D-Pad buttons if necessary.
289- if (i == ABS_HAT0X && !have_dpad_buttons) {
290- _dpad_x_axis = i;
291- _dpad_left_button = (int )_buttons.size ();
292- _buttons.push_back (ButtonState (GamepadButton::dpad_left ()));
293- _buttons.push_back (ButtonState (GamepadButton::dpad_right ()));
294- }
295- if (i == ABS_HAT0Y && !have_dpad_buttons) {
296- _dpad_y_axis = i;
297- _dpad_up_button = (int )_buttons.size ();
298- _buttons.push_back (ButtonState (GamepadButton::dpad_up ()));
299- _buttons.push_back (ButtonState (GamepadButton::dpad_down ()));
300- }
301352 }
302353 }
303354 }
0 commit comments