Преглед изворни кода

Correct the sensor axis ordering with the Linux Nintendo driver

Fixes https://github.com/libsdl-org/SDL/issues/14552

Manual cherry-pick of 5e9163592fb90ee0a5121b9c9e9a1b168d5594ad by Sam Lantinga <slouken@libsdl.org>
Alexandre Derumier пре 3 месеци
родитељ
комит
cf5dabd6ea
1 измењених фајлова са 31 додато и 6 уклоњено
  1. 31 6
      src/joystick/linux/SDL_sysjoystick.c

+ 31 - 6
src/joystick/linux/SDL_sysjoystick.c

@@ -154,6 +154,8 @@ typedef struct SDL_joylist_item
 {
 {
     SDL_JoystickID device_instance;
     SDL_JoystickID device_instance;
     char *path; /* "/dev/input/event2" or whatever */
     char *path; /* "/dev/input/event2" or whatever */
+    Uint16 vendor;
+    Uint16 product;
     char *name; /* "SideWinder 3D Pro" or whatever */
     char *name; /* "SideWinder 3D Pro" or whatever */
     SDL_JoystickGUID guid;
     SDL_JoystickGUID guid;
     dev_t devnum;
     dev_t devnum;
@@ -483,6 +485,8 @@ static void MaybeAddDevice(const char *path)
         item->devnum = sb.st_rdev;
         item->devnum = sb.st_rdev;
         item->steam_virtual_gamepad_slot = -1;
         item->steam_virtual_gamepad_slot = -1;
         item->path = SDL_strdup(path);
         item->path = SDL_strdup(path);
+        item->vendor = vendor;
+        item->product = product;
         item->name = name;
         item->name = name;
         item->guid = guid;
         item->guid = guid;
 
 
@@ -1932,6 +1936,20 @@ static void PollAllValues(SDL_Joystick *joystick)
     /* Joyballs are relative input, so there's no poll state. Events only! */
     /* Joyballs are relative input, so there's no poll state. Events only! */
 }
 }
 
 
+static void CorrectSensorData(struct joystick_hwdata *hwdata, float *values, float *data)
+{
+    if (hwdata->item->vendor == USB_VENDOR_NINTENDO) {
+        // The Nintendo driver uses a different axis order than SDL
+        data[0] = -values[1];
+        data[1] = values[2];
+        data[2] = -values[0];
+    } else {
+        data[0] = values[0];
+        data[1] = values[1];
+        data[2] = values[2];
+    }
+}
+
 static void PollAllSensors(SDL_Joystick *joystick)
 static void PollAllSensors(SDL_Joystick *joystick)
 {
 {
     struct input_absinfo absinfo;
     struct input_absinfo absinfo;
@@ -1942,27 +1960,31 @@ static void PollAllSensors(SDL_Joystick *joystick)
     SDL_assert(joystick->hwdata->fd_sensor >= 0);
     SDL_assert(joystick->hwdata->fd_sensor >= 0);
 
 
     if (joystick->hwdata->has_gyro) {
     if (joystick->hwdata->has_gyro) {
-        float data[3] = {0.0f, 0.0f, 0.0f};
+        float values[3] = {0.0f, 0.0f, 0.0f};
+        float data[3];
         for (i = 0; i < 3; i++) {
         for (i = 0; i < 3; i++) {
             if (ioctl(joystick->hwdata->fd_sensor, EVIOCGABS(ABS_RX + i), &absinfo) >= 0) {
             if (ioctl(joystick->hwdata->fd_sensor, EVIOCGABS(ABS_RX + i), &absinfo) >= 0) {
-                data[i] = absinfo.value * (M_PI / 180.f) / joystick->hwdata->gyro_scale[i];
+                values[i] = absinfo.value * (M_PI / 180.f) / joystick->hwdata->gyro_scale[i];
 #ifdef DEBUG_INPUT_EVENTS
 #ifdef DEBUG_INPUT_EVENTS
                 SDL_Log("Joystick : Re-read Gyro (axis %d) val= %f\n", i, data[i]);
                 SDL_Log("Joystick : Re-read Gyro (axis %d) val= %f\n", i, data[i]);
 #endif
 #endif
             }
             }
         }
         }
+        CorrectSensorData(joystick->hwdata, values, data);
         SDL_PrivateJoystickSensor(joystick, SDL_SENSOR_GYRO, joystick->hwdata->sensor_tick, data, 3);
         SDL_PrivateJoystickSensor(joystick, SDL_SENSOR_GYRO, joystick->hwdata->sensor_tick, data, 3);
     }
     }
     if (joystick->hwdata->has_accelerometer) {
     if (joystick->hwdata->has_accelerometer) {
-        float data[3] = {0.0f, 0.0f, 0.0f};
+        float values[3] = {0.0f, 0.0f, 0.0f};
+        float data[3];
         for (i = 0; i < 3; i++) {
         for (i = 0; i < 3; i++) {
             if (ioctl(joystick->hwdata->fd_sensor, EVIOCGABS(ABS_X + i), &absinfo) >= 0) {
             if (ioctl(joystick->hwdata->fd_sensor, EVIOCGABS(ABS_X + i), &absinfo) >= 0) {
-                data[i] = absinfo.value * SDL_STANDARD_GRAVITY / joystick->hwdata->accelerometer_scale[i];
+                values[i] = absinfo.value * SDL_STANDARD_GRAVITY / joystick->hwdata->accelerometer_scale[i];
 #ifdef DEBUG_INPUT_EVENTS
 #ifdef DEBUG_INPUT_EVENTS
                 SDL_Log("Joystick : Re-read Accelerometer (axis %d) val= %f\n", i, data[i]);
                 SDL_Log("Joystick : Re-read Accelerometer (axis %d) val= %f\n", i, data[i]);
 #endif
 #endif
             }
             }
         }
         }
+        CorrectSensorData(joystick->hwdata, values, data);
         SDL_PrivateJoystickSensor(joystick, SDL_SENSOR_ACCEL, joystick->hwdata->sensor_tick, data, 3);
         SDL_PrivateJoystickSensor(joystick, SDL_SENSOR_ACCEL, joystick->hwdata->sensor_tick, data, 3);
     }
     }
 }
 }
@@ -2132,12 +2154,15 @@ static void HandleInputEvents(SDL_Joystick *joystick)
                             joystick->hwdata->recovering_from_dropped_sensor = SDL_FALSE;
                             joystick->hwdata->recovering_from_dropped_sensor = SDL_FALSE;
                             PollAllSensors(joystick); /* try to sync up to current state now */
                             PollAllSensors(joystick); /* try to sync up to current state now */
                         } else {
                         } else {
+                            float data[3];
+                            CorrectSensorData(joystick->hwdata, joystick->hwdata->gyro_data, data);
                             SDL_PrivateJoystickSensor(joystick, SDL_SENSOR_GYRO,
                             SDL_PrivateJoystickSensor(joystick, SDL_SENSOR_GYRO,
                                                    joystick->hwdata->sensor_tick,
                                                    joystick->hwdata->sensor_tick,
-                                                   joystick->hwdata->gyro_data, 3);
+                                                   data, 3);
+                            CorrectSensorData(joystick->hwdata, joystick->hwdata->accel_data, data);
                             SDL_PrivateJoystickSensor(joystick, SDL_SENSOR_ACCEL,
                             SDL_PrivateJoystickSensor(joystick, SDL_SENSOR_ACCEL,
                                                    joystick->hwdata->sensor_tick,
                                                    joystick->hwdata->sensor_tick,
-                                                   joystick->hwdata->accel_data, 3);
+                                                   data, 3);
                         }
                         }
                         break;
                         break;
                     default:
                     default: