From 54fdeb9e79550a03feac1b6fbe1fee1cb5166fe6 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Tue, 13 Jan 2026 16:23:05 -0800 Subject: [PATCH] Added support for the Razer Raiju V5 Pro in wireless mode --- src/joystick/controller_list.h | 3 ++- src/joystick/hidapi/SDL_hidapi_ps5.c | 32 ++++++++++++++++++---------- src/joystick/usb_ids.h | 3 ++- 3 files changed, 25 insertions(+), 13 deletions(-) diff --git a/src/joystick/controller_list.h b/src/joystick/controller_list.h index 2980f82dc2..5cf4e2c405 100644 --- a/src/joystick/controller_list.h +++ b/src/joystick/controller_list.h @@ -159,7 +159,8 @@ static const ControllerDescription_t arrControllers[] = { { MAKE_CONTROLLER_ID( 0x1532, 0x100b ), k_eControllerType_PS5Controller, NULL }, // Razer Wolverine V2 Pro (Wired) { MAKE_CONTROLLER_ID( 0x1532, 0x100c ), k_eControllerType_PS5Controller, NULL }, // Razer Wolverine V2 Pro (Wireless) { MAKE_CONTROLLER_ID( 0x1532, 0x1012 ), k_eControllerType_PS5Controller, NULL }, // Razer Kitsune - { MAKE_CONTROLLER_ID( 0x1532, 0x1024 ), k_eControllerType_PS5Controller, NULL }, // Razer Raiju V3 Pro + { MAKE_CONTROLLER_ID( 0x1532, 0x1024 ), k_eControllerType_PS5Controller, NULL }, // Razer Raiju V5 Pro (PS5 mode wired) + { MAKE_CONTROLLER_ID( 0x1532, 0x1026 ), k_eControllerType_PS5Controller, NULL }, // Razer Raiju V5 Pro (PS5 mode with dongle) { MAKE_CONTROLLER_ID( 0x3285, 0x0d18 ), k_eControllerType_PS5Controller, NULL }, // NACON Revolution 5 Pro (PS5 mode with dongle) { MAKE_CONTROLLER_ID( 0x3285, 0x0d19 ), k_eControllerType_PS5Controller, NULL }, // NACON Revolution 5 Pro (PS5 mode wired) { MAKE_CONTROLLER_ID( 0x358a, 0x0104 ), k_eControllerType_PS5Controller, NULL }, // Backbone One PlayStation Edition for iOS diff --git a/src/joystick/hidapi/SDL_hidapi_ps5.c b/src/joystick/hidapi/SDL_hidapi_ps5.c index 5e6d7cf979..526d6a3706 100644 --- a/src/joystick/hidapi/SDL_hidapi_ps5.c +++ b/src/joystick/hidapi/SDL_hidapi_ps5.c @@ -230,7 +230,7 @@ typedef struct { SDL_HIDAPI_Device *device; SDL_Joystick *joystick; - bool is_nacon_dongle; + bool is_dongle; bool use_alternate_report; bool sensors_supported; bool lightbar_supported; @@ -516,7 +516,8 @@ static bool HIDAPI_DriverPS5_InitDevice(SDL_HIDAPI_Device *device) ctx->use_alternate_report = true; } else if (device->vendor_id == USB_VENDOR_RAZER && (device->product_id == USB_PRODUCT_RAZER_KITSUNE || - device->product_id == USB_PRODUCT_RAZER_RAIJU_V3_PRO)) { + device->product_id == USB_PRODUCT_RAZER_RAIJU_V3_PRO_PS5_WIRED || + device->product_id == USB_PRODUCT_RAZER_RAIJU_V3_PRO_PS5_WIRELESS)) { // The Razer Kitsune and Raiju don't respond to the detection protocol, but have a touchpad joystick_type = SDL_JOYSTICK_TYPE_ARCADE_STICK; ctx->touchpad_supported = true; @@ -525,9 +526,13 @@ static bool HIDAPI_DriverPS5_InitDevice(SDL_HIDAPI_Device *device) } ctx->effects_supported = (ctx->lightbar_supported || ctx->vibration_supported || ctx->playerled_supported); - if (device->vendor_id == USB_VENDOR_NACON_ALT && - device->product_id == USB_PRODUCT_NACON_REVOLUTION_5_PRO_PS5_WIRELESS) { - ctx->is_nacon_dongle = true; + if ((device->vendor_id == USB_VENDOR_NACON_ALT && + device->product_id == USB_PRODUCT_NACON_REVOLUTION_5_PRO_PS5_WIRELESS) || + (device->vendor_id == USB_VENDOR_RAZER && + (device->product_id == USB_PRODUCT_NACON_REVOLUTION_5_PRO_PS5_WIRELESS || + device->product_id == USB_PRODUCT_RAZER_WOLVERINE_V2_PRO_PS5_WIRELESS || + device->product_id == USB_PRODUCT_RAZER_RAIJU_V3_PRO_PS5_WIRELESS))) { + ctx->is_dongle = true; } device->joystick_type = joystick_type; @@ -541,7 +546,7 @@ static bool HIDAPI_DriverPS5_InitDevice(SDL_HIDAPI_Device *device) } HIDAPI_SetDeviceSerial(device, serial); - if (ctx->is_nacon_dongle) { + if (ctx->is_dongle) { // We don't know if this is connected yet, wait for reports return true; } @@ -965,6 +970,10 @@ static bool HIDAPI_DriverPS5_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystic joystick->nhats = 1; joystick->firmware_version = ctx->firmware_version; + if (ctx->is_dongle) { + joystick->connection_state = SDL_JOYSTICK_CONNECTION_WIRELESS; + } + SDL_AddHintCallback(SDL_HINT_JOYSTICK_ENHANCED_REPORTS, SDL_PS5EnhancedReportsChanged, ctx); SDL_AddHintCallback(SDL_HINT_JOYSTICK_HIDAPI_PS5_PLAYER_LED, @@ -1465,15 +1474,16 @@ static bool HIDAPI_DriverPS5_IsPacketValid(SDL_DriverPS5_Context *ctx, Uint8 *da { switch (data[0]) { case k_EPS5ReportIdState: - if (ctx->is_nacon_dongle && size >= (1 + sizeof(PS5StatePacketAlt_t))) { + if (ctx->is_dongle && size >= (1 + sizeof(PS5StatePacketAlt_t))) { // The report timestamp doesn't change when the controller isn't connected PS5StatePacketAlt_t *packet = (PS5StatePacketAlt_t *)&data[1]; if (SDL_memcmp(packet->rgucPacketSequence, ctx->last_state.state.rgucPacketSequence, sizeof(packet->rgucPacketSequence)) == 0) { return false; } - if (ctx->last_state.alt_state.rgucAccelX[0] == 0 && ctx->last_state.alt_state.rgucAccelX[1] == 0 && - ctx->last_state.alt_state.rgucAccelY[0] == 0 && ctx->last_state.alt_state.rgucAccelY[1] == 0 && - ctx->last_state.alt_state.rgucAccelZ[0] == 0 && ctx->last_state.alt_state.rgucAccelZ[1] == 0) { + if (ctx->last_state.state.rgucPacketSequence[0] == 0 && + ctx->last_state.state.rgucPacketSequence[1] == 0 && + ctx->last_state.state.rgucPacketSequence[2] == 0 && + ctx->last_state.state.rgucPacketSequence[3] == 0) { // We don't have any state to compare yet, go ahead and copy it SDL_memcpy(&ctx->last_state, &data[1], sizeof(PS5StatePacketAlt_t)); return false; @@ -1572,7 +1582,7 @@ static bool HIDAPI_DriverPS5_UpdateDevice(SDL_HIDAPI_Device *device) } } - if (ctx->is_nacon_dongle) { + if (ctx->is_dongle) { if (packet_count == 0) { if (device->num_joysticks > 0) { // Check to see if it looks like the device disconnected diff --git a/src/joystick/usb_ids.h b/src/joystick/usb_ids.h index f0daf382ff..29c9fc379a 100644 --- a/src/joystick/usb_ids.h +++ b/src/joystick/usb_ids.h @@ -124,7 +124,8 @@ #define USB_PRODUCT_RAZER_PANTHERA 0x0401 #define USB_PRODUCT_RAZER_PANTHERA_EVO 0x1008 #define USB_PRODUCT_RAZER_RAIJU 0x1000 -#define USB_PRODUCT_RAZER_RAIJU_V3_PRO 0x1024 +#define USB_PRODUCT_RAZER_RAIJU_V3_PRO_PS5_WIRED 0x1024 +#define USB_PRODUCT_RAZER_RAIJU_V3_PRO_PS5_WIRELESS 0x1026 #define USB_PRODUCT_RAZER_TOURNAMENT_EDITION_USB 0x1007 #define USB_PRODUCT_RAZER_TOURNAMENT_EDITION_BLUETOOTH 0x100a #define USB_PRODUCT_RAZER_ULTIMATE_EDITION_USB 0x1004