From 8b49bff35387e44e7b49784c8a315d376c06e775 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Sun, 17 May 2026 21:42:49 -0700
Subject: [PATCH] Fixed Nintendo Switch Pro controller sensors on Android
---
src/joystick/android/SDL_sysjoystick.c | 28 +++++++++++++++++++-----
src/joystick/android/SDL_sysjoystick_c.h | 2 ++
2 files changed, 24 insertions(+), 6 deletions(-)
diff --git a/src/joystick/android/SDL_sysjoystick.c b/src/joystick/android/SDL_sysjoystick.c
index 265c32e391568..16992e8255fb2 100644
--- a/src/joystick/android/SDL_sysjoystick.c
+++ b/src/joystick/android/SDL_sysjoystick.c
@@ -344,7 +344,6 @@ void Android_OnJoySensor(int device_id, int sensor_type, Uint64 sensor_timestamp
Uint64 timestamp = SDL_GetTicksNS();
SDL_joylist_item *item;
SDL_SensorType sensor;
- float data[3];
if (sensor_type == 1) { // Sensor.TYPE_ACCELEROMETER
sensor = SDL_SENSOR_ACCEL;
@@ -355,14 +354,29 @@ void Android_OnJoySensor(int device_id, int sensor_type, Uint64 sensor_timestamp
return;
}
- // The axes of sensor events and their signs are the same as SDL's, so no conversion required
- data[0] = x;
- data[1] = y;
- data[2] = z;
-
SDL_LockJoysticks();
item = JoystickByDeviceId(device_id);
if (item && item->joystick) {
+ float data[3];
+
+ if (item->vendor_id == USB_VENDOR_NINTENDO) {
+ // The Nintendo driver uses a different axis order than SDL
+ data[0] = -y;
+ data[1] = z;
+ data[2] = -x;
+
+ if (sensor == SDL_SENSOR_GYRO) {
+ // The values are experimentally 3x what they should be
+ data[0] /= 3;
+ data[1] /= 3;
+ data[2] /= 3;
+ }
+ } else {
+ // The axes of sensor events and their signs are the same as SDL's, so no conversion required
+ data[0] = x;
+ data[1] = y;
+ data[2] = z;
+ }
SDL_SendJoystickSensor(timestamp, item->joystick, sensor, sensor_timestamp, data, 3);
}
SDL_UnlockJoysticks();
@@ -427,6 +441,8 @@ void Android_AddJoystick(int device_id, const char *name, const char *desc, int
SDL_zerop(item);
item->guid = guid;
item->device_id = device_id;
+ item->vendor_id = vendor_id;
+ item->product_id = product_id;
item->name = SDL_CreateJoystickName(vendor_id, product_id, NULL, name);
if (!item->name) {
SDL_free(item);
diff --git a/src/joystick/android/SDL_sysjoystick_c.h b/src/joystick/android/SDL_sysjoystick_c.h
index f99abb5e61bf0..027071a2bbcf7 100644
--- a/src/joystick/android/SDL_sysjoystick_c.h
+++ b/src/joystick/android/SDL_sysjoystick_c.h
@@ -42,6 +42,8 @@ typedef struct SDL_joylist_item
{
int device_instance;
int device_id; // Android's device id
+ Uint16 vendor_id;
+ Uint16 product_id;
char *name; // "SideWinder 3D Pro" or whatever
SDL_GUID guid;
SDL_Joystick *joystick;