From d2050211eb620fee4b5ce07b1287eca6b748a84f Mon Sep 17 00:00:00 2001
From: wankey <[EMAIL REDACTED]>
Date: Mon, 21 Sep 2026 01:18:35 +0800
Subject: [PATCH] Flydigi Apex 6 support (#16343)
---
src/hidapi/SDL_hidapi.c | 2 +-
src/joystick/SDL_gamepad.c | 4 ++--
src/joystick/SDL_joystick.c | 2 +-
src/joystick/hidapi/SDL_hidapi_flydigi.c | 29 +++++++++++++++++++++---
src/joystick/hidapi/SDL_hidapi_flydigi.h | 2 +-
src/joystick/usb_ids.h | 1 +
6 files changed, 32 insertions(+), 8 deletions(-)
diff --git a/src/hidapi/SDL_hidapi.c b/src/hidapi/SDL_hidapi.c
index 12356305a793e..d00c06a924aae 100644
--- a/src/hidapi/SDL_hidapi.c
+++ b/src/hidapi/SDL_hidapi.c
@@ -1177,7 +1177,7 @@ bool SDL_HIDAPI_ShouldIgnoreDevice(int bus, Uint16 vendor_id, Uint16 product_id,
}
return true;
} else if (vendor_id == USB_VENDOR_FLYDIGI_V2 &&
- (product_id == USB_PRODUCT_FLYDIGI_V2_APEX || product_id == USB_PRODUCT_FLYDIGI_V2_VADER)) {
+ (product_id == USB_PRODUCT_FLYDIGI_V2_APEX || product_id == USB_PRODUCT_FLYDIGI_V2_VADER || product_id == USB_PRODUCT_FLYDIGI_V2_APEX6)) {
if (usage_page == USB_USAGEPAGE_VENDOR_FLYDIGI) {
return false;
}
diff --git a/src/joystick/SDL_gamepad.c b/src/joystick/SDL_gamepad.c
index f3e4686dc08fc..180323eae0201 100644
--- a/src/joystick/SDL_gamepad.c
+++ b/src/joystick/SDL_gamepad.c
@@ -1300,8 +1300,8 @@ static GamepadMapping_t *SDL_CreateMappingForHIDAPIGamepad(SDL_GUID guid)
// Vader 5 has additional shoulder macro buttons and a circle button
SDL_strlcat(mapping_string, "misc4:b17,misc5:b18,misc6:b19", sizeof(mapping_string));
}
- } else if (guid.data[15] == SDL_FLYDIGI_APEX5) {
- // Apex 5 has additional shoulder macro buttons
+ } else if (guid.data[15] == SDL_FLYDIGI_APEX5 || guid.data[15] == SDL_FLYDIGI_APEX6) {
+ // Apex 5 and Apex 6 have additional shoulder macro buttons
SDL_strlcat(mapping_string, "misc2:b15,misc3:b16,", sizeof(mapping_string));
}
} else if (SDL_IsJoystickGameSirController(vendor, product) &&
diff --git a/src/joystick/SDL_joystick.c b/src/joystick/SDL_joystick.c
index 4fbe70b0abc94..c1d131b31209e 100644
--- a/src/joystick/SDL_joystick.c
+++ b/src/joystick/SDL_joystick.c
@@ -3551,7 +3551,7 @@ bool SDL_IsJoystickFlydigiController(Uint16 vendor_id, Uint16 product_id)
}
}
if (vendor_id == USB_VENDOR_FLYDIGI_V2) {
- if (product_id == USB_PRODUCT_FLYDIGI_V2_APEX || product_id == USB_PRODUCT_FLYDIGI_V2_VADER) {
+ if (product_id == USB_PRODUCT_FLYDIGI_V2_APEX || product_id == USB_PRODUCT_FLYDIGI_V2_VADER || product_id == USB_PRODUCT_FLYDIGI_V2_APEX6) {
return true;
}
}
diff --git a/src/joystick/hidapi/SDL_hidapi_flydigi.c b/src/joystick/hidapi/SDL_hidapi_flydigi.c
index 989609ca53c2d..4cb9ce9733186 100644
--- a/src/joystick/hidapi/SDL_hidapi_flydigi.c
+++ b/src/joystick/hidapi/SDL_hidapi_flydigi.c
@@ -182,6 +182,11 @@ static void HIDAPI_DriverFlydigi_UpdateDeviceIdentity(SDL_HIDAPI_Device *device)
case 134:
controller_type = SDL_FLYDIGI_APEX5;
break;
+ case 149: //Apex6
+ case 150: //Apex6 Pro
+ case 152: //Apex 6 Pro Phantom Blade Zero
+ controller_type = SDL_FLYDIGI_APEX6;
+ break;
default:
// Try to guess from the name of the controller
if (SDL_strcasestr(device->name, "VADER") != NULL) {
@@ -203,6 +208,8 @@ static void HIDAPI_DriverFlydigi_UpdateDeviceIdentity(SDL_HIDAPI_Device *device)
controller_type = SDL_FLYDIGI_APEX4;
} else if (SDL_strstr(device->name, "APEX5") != NULL) {
controller_type = SDL_FLYDIGI_APEX5;
+ } else if (SDL_strstr(device->name, "APEX6") != NULL) {
+ controller_type = SDL_FLYDIGI_APEX6;
}
}
break;
@@ -232,6 +239,14 @@ static void HIDAPI_DriverFlydigi_UpdateDeviceIdentity(SDL_HIDAPI_Device *device)
ctx->gyroScale = DEG2RAD(2000.0f);
ctx->sensor_timestamp_step_ns = ctx->wireless ? SENSOR_INTERVAL_APEX5_DONGLE_NS : SENSOR_INTERVAL_APEX5_WIRED_NS;
break;
+ case SDL_FLYDIGI_APEX6:
+ HIDAPI_SetDeviceName(device, "Flydigi Apex 6");
+ ctx->has_lmrm = true;
+ ctx->sensors_supported = true;
+ ctx->accelScale = SDL_STANDARD_GRAVITY / 4096.0f;
+ ctx->gyroScale = DEG2RAD(2000.0f);
+ ctx->sensor_timestamp_step_ns = ctx->wireless ? SENSOR_INTERVAL_APEX5_DONGLE_NS : SENSOR_INTERVAL_APEX5_WIRED_NS;
+ break;
case SDL_FLYDIGI_VADER2:
// The Vader 2 controller has sensors, but they're only reported when gyro mouse is enabled
HIDAPI_SetDeviceName(device, "Flydigi Vader 2");
@@ -299,7 +314,7 @@ static int HIDAPI_DriverFlydigi_WritePacket(SDL_HIDAPI_Device *device, const Uin
{
// We know that at the very least the Vader 5 now uses unnumbered reports for commands instead of FLYDIGI_V2_CMD_REPORT_ID.
// If other Flydigi things prove to do the same, we can tweak this check to be more general.
- bool bUsesUnnumberedReports = (device->vendor_id == USB_VENDOR_FLYDIGI_V2 && device->product_id == USB_PRODUCT_FLYDIGI_V2_VADER);
+ bool bUsesUnnumberedReports = (device->vendor_id == USB_VENDOR_FLYDIGI_V2 && (device->product_id == USB_PRODUCT_FLYDIGI_V2_VADER || device->product_id == USB_PRODUCT_FLYDIGI_V2_APEX6));
if (bUsesUnnumberedReports && data[0] == FLYDIGI_V2_CMD_REPORT_ID) {
// Zero out the report byte.
@@ -434,11 +449,19 @@ static void HIDAPI_DriverFlydigi_HandleInfoResponse(SDL_Joystick *joystick, SDL_
switch (status) {
case 0:
state = SDL_POWERSTATE_ON_BATTERY;
- percent = level * 20;
+ if (ctx->device->guid.data[15] == SDL_FLYDIGI_APEX6) {
+ percent = level * 10;
+ } else {
+ percent = level * 20;
+ }
break;
case 1:
state = SDL_POWERSTATE_CHARGING;
- percent = level * 20;
+ if (ctx->device->guid.data[15] == SDL_FLYDIGI_APEX6) {
+ percent = level * 10;
+ } else {
+ percent = level * 20;
+ }
break;
case 2:
state = SDL_POWERSTATE_CHARGED;
diff --git a/src/joystick/hidapi/SDL_hidapi_flydigi.h b/src/joystick/hidapi/SDL_hidapi_flydigi.h
index cf60bed0f2d5b..12ea9adc63753 100644
--- a/src/joystick/hidapi/SDL_hidapi_flydigi.h
+++ b/src/joystick/hidapi/SDL_hidapi_flydigi.h
@@ -28,6 +28,7 @@ typedef enum
SDL_FLYDIGI_APEX3,
SDL_FLYDIGI_APEX4,
SDL_FLYDIGI_APEX5,
+ SDL_FLYDIGI_APEX6,
SDL_FLYDIGI_VADER2 = (1 << 4),
SDL_FLYDIGI_VADER2_PRO,
SDL_FLYDIGI_VADER3,
@@ -35,4 +36,3 @@ typedef enum
SDL_FLYDIGI_VADER4_PRO,
SDL_FLYDIGI_VADER5_PRO,
} SDL_FlyDigiControllerType;
-
diff --git a/src/joystick/usb_ids.h b/src/joystick/usb_ids.h
index f81a906823a28..821d069419835 100644
--- a/src/joystick/usb_ids.h
+++ b/src/joystick/usb_ids.h
@@ -93,6 +93,7 @@
#define USB_PRODUCT_EVORETRO_GAMECUBE_ADAPTER3 0x1846
#define USB_PRODUCT_FLYDIGI_V1_GAMEPAD 0x2412
#define USB_PRODUCT_FLYDIGI_V2_APEX 0x2501
+#define USB_PRODUCT_FLYDIGI_V2_APEX6 0x2502
#define USB_PRODUCT_FLYDIGI_V2_VADER 0x2401
#define USB_PRODUCT_GAMESIR_GAMEPAD_G7_PRO_8K 0x10B8 // Wired/2.4G/Bluetooth 8K mode
#define USB_PRODUCT_GAMESIR_GAMEPAD_TARANTULA_8K 0x103C // Wired/2.4G/Bluetooth Tarantula 8K