Skip to content

Commit 7f0ac22

Browse files
committed
device: fix mappings for various generic gamepads on Windows
See also panda3d#576
1 parent cc4d525 commit 7f0ac22

File tree

1 file changed

+42
-7
lines changed

1 file changed

+42
-7
lines changed

panda/src/device/winRawInputDevice.cxx

Lines changed: 42 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,12 @@ enum QuirkBits : int {
3232

3333
// Throttle is reversed.
3434
QB_reversed_throttle = 4,
35+
36+
// Right stick uses Z and Rz inputs.
37+
QB_rstick_from_z = 8,
38+
39+
// Axes on the right stick are swapped, using x for y and vice versa.
40+
QB_right_axes_swapped = 64,
3541
};
3642

3743
// Some nonstandard gamepads have different button mappings.
@@ -42,12 +48,17 @@ static const struct DeviceMapping {
4248
int quirks;
4349
const char *buttons[16];
4450
} mapping_presets[] = {
45-
// SNES-style USB gamepad
51+
// SNES-style USB gamepad, or cheap unbranded USB gamepad with no sticks
52+
// ABXY are mapped based on their position, not based on their label.
4653
{0x0810, 0xe501, InputDevice::DeviceClass::gamepad, QB_no_analog_triggers,
47-
{"face_x", "face_a", "face_b", "face_y", "lshoulder", "rshoulder", "none", "none", "back", "start"}
54+
{"face_y", "face_b", "face_a", "face_x", "lshoulder", "rshoulder", "ltrigger", "rtrigger", "back", "start"}
55+
},
56+
// Unbranded generic cheap USB gamepad
57+
{0x0810, 0x0001, InputDevice::DeviceClass::gamepad, QB_rstick_from_z | QB_no_analog_triggers | QB_right_axes_swapped,
58+
{"face_y", "face_b", "face_a", "face_x", "lshoulder", "rshoulder", "ltrigger", "rtrigger", "back", "start", "lstick", "rstick"}
4859
},
49-
// SPEED Link SL-6535-SBK-01
50-
{0x0079, 0x0006, InputDevice::DeviceClass::gamepad, QB_no_analog_triggers,
60+
// Trust GXT 24 / SPEED Link SL-6535-SBK-01
61+
{0x0079, 0x0006, InputDevice::DeviceClass::gamepad, QB_rstick_from_z | QB_no_analog_triggers,
5162
{"face_y", "face_b", "face_a", "face_x", "lshoulder", "rshoulder", "ltrigger", "rtrigger", "back", "start", "lstick", "rstick"}
5263
},
5364
// T.Flight Hotas X
@@ -56,7 +67,7 @@ static const struct DeviceMapping {
5667
},
5768
// NVIDIA Shield Controller
5869
{0x0955, 0x7214, InputDevice::DeviceClass::gamepad, 0,
59-
{"face_a", "face_b", "n", "face_x", "face_y", "rshoulder", "lshoulder", "rshoulder", "e", "f", "g", "start", "h", "lstick", "rstick", "i"}
70+
{"face_a", "face_b", 0, "face_x", "face_y", "rshoulder", "lshoulder", "rshoulder", 0, 0, 0, "start", 0, "lstick", "rstick", 0}
6071
},
6172
{0},
6273
};
@@ -422,7 +433,14 @@ on_arrival(HANDLE handle, const RID_DEVICE_INFO &info, std::string name) {
422433
break;
423434
case HID_USAGE_GENERIC_Z:
424435
if (_device_class == DeviceClass::gamepad) {
425-
if ((quirks & QB_no_analog_triggers) == 0) {
436+
if (quirks & QB_rstick_from_z) {
437+
if (quirks & QB_right_axes_swapped) {
438+
axis = InputDevice::Axis::right_y;
439+
swap(cap.LogicalMin, cap.LogicalMax);
440+
} else {
441+
axis = InputDevice::Axis::right_x;
442+
}
443+
} else if ((quirks & QB_no_analog_triggers) == 0) {
426444
axis = Axis::left_trigger;
427445
}
428446
} else if (_device_class == DeviceClass::flight_stick) {
@@ -455,7 +473,14 @@ on_arrival(HANDLE handle, const RID_DEVICE_INFO &info, std::string name) {
455473
break;
456474
case HID_USAGE_GENERIC_RZ:
457475
if (_device_class == DeviceClass::gamepad) {
458-
if ((quirks & QB_no_analog_triggers) == 0) {
476+
if (quirks & QB_rstick_from_z) {
477+
if (quirks & QB_right_axes_swapped) {
478+
axis = InputDevice::Axis::right_x;
479+
} else {
480+
axis = InputDevice::Axis::right_y;
481+
swap(cap.LogicalMin, cap.LogicalMax);
482+
}
483+
} else if ((quirks & QB_no_analog_triggers) == 0) {
459484
axis = Axis::right_trigger;
460485
}
461486
} else {
@@ -481,6 +506,16 @@ on_arrival(HANDLE handle, const RID_DEVICE_INFO &info, std::string name) {
481506
break;
482507
}
483508

509+
// If this axis already exists, don't double-map it, but take the first
510+
// one. This is important for the Trust GXT 24 / SL-6535-SBK-01 which
511+
// have a weird extra Z axis with DataIndex 2 that should be ignored.
512+
for (size_t i = 0; i < _axes.size(); ++i) {
513+
if (_axes[i].axis == axis) {
514+
axis = Axis::none;
515+
break;
516+
}
517+
}
518+
484519
int axis_index;
485520
if (!is_signed) {
486521
// All axes on the weird XInput-style mappings go from -1 to 1

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy