fix(pad): build SDL with HIDAPI so DualSense output reaches the controller

The bundled SDL was configured with SDL_HIDAPI OFF, so a DualSense went
through the generic joystick driver of the platform: no touchpad, no
light bar and no DualSense effect reports, which left the light bar,
trigger effect and (on Linux) rumble requests that PadInput already
sends through SDL without effect on the controller. With HIDAPI, SDL's
PS5 driver handles the pad: touchpad, light bar, rumble, trigger effects
and the motion sensors.

A USB pad always uses the driver's enhanced reports.
SDL_HINT_JOYSTICK_HIDAPI_PS5_RUMBLE enables them for a Bluetooth pad as
well, which otherwise stays on the simple report without effects.

pad_sdl checks that the bundled SDL is built with the HIDAPI joystick
driver.
This commit is contained in:
Dean Galvin 2026-10-01 00:35:57 +13:00
parent fc0596240d
commit e2609a87be
4 changed files with 21 additions and 1 deletions

View File

@ -27,7 +27,7 @@ set(SDL_OPENGLES OFF CACHE BOOL "" FORCE)
set(SDL_VULKAN ON CACHE BOOL "" FORCE)
set(SDL_JOYSTICK ON CACHE BOOL "" FORCE)
set(SDL_HAPTIC OFF CACHE BOOL "" FORCE)
set(SDL_HIDAPI OFF CACHE BOOL "" FORCE)
set(SDL_HIDAPI ON CACHE BOOL "" FORCE)
set(SDL_SENSOR OFF CACHE BOOL "" FORCE)
set(SDL_STATIC_PIC ON CACHE BOOL "" FORCE)
set(ANYPS5_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS}")

View File

@ -30,3 +30,9 @@ target_include_directories(video_out_flip_tests PRIVATE ${LIBS_INCLUDE_DIR} ${CM
target_link_libraries(video_out_flip_tests PRIVATE libSceVideoOut libSceAgcDriver libkernel libc)
set_target_properties(video_out_flip_tests PROPERTIES CXX_EXTENSIONS OFF)
configure_windows_unwind(video_out_flip_tests)
if(BUILD_TESTING)
add_executable(pad_sdl_tests tests/PadSdl.cpp)
target_link_libraries(pad_sdl_tests PRIVATE SDL2-static)
add_test(NAME pad_sdl COMMAND pad_sdl_tests)
endif()

View File

@ -25,6 +25,7 @@ PadInput::~PadInput() {
void PadInput::openFirstAvailableController() {
if (controller != nullptr) return;
SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, "1");
SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_PS5_RUMBLE, "1");
if ((SDL_WasInit(SDL_INIT_GAMECONTROLLER) & SDL_INIT_GAMECONTROLLER) == 0) {
if (SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER) != 0) {
APS5_LOG_ERR("Pad: SDL game controller init failed: %s", SDL_GetError());

View File

@ -0,0 +1,13 @@
#include "SDL_config.h"
#include <cstdio>
int main() {
#ifdef SDL_JOYSTICK_HIDAPI
std::puts("pad_sdl: SDL drives controllers through HIDAPI");
return 0;
#else
std::fputs("pad_sdl: SDL is built without HIDAPI, so a DualSense gets no light bar, touchpad or trigger effects\n", stderr);
return 1;
#endif
}