1919
2020#define JOY_ID_START 10
2121#define STICK_DPAD 3
22- #define DEADZONE_BUTTON_STICK 3000
22+ #define INNER_DEADZONE_BUTTON_STICK 2000
23+ #define OUTER_DEADZONE_BUTTON_STICK 3000
2324
2425#if !defined(CONTROLLER_SUPPORT)
25- inline int Steam_Controller:: DetectGamepads (ControllerHandle_t* handlesOut) { return 0 ; };
26- inline bool Steam_Controller:: GamepadInit (void ) { return false ; };
27- inline void Steam_Controller:: GamepadShutdown (void ) {} ;
28- inline void Steam_Controller:: GamepadUpdate (void ) {} ;
29- inline bool Steam_Controller:: GamepadButtonDown (ControllerHandle_t id, GAMEPAD_BUTTON button) { return false ; };
30- inline float Steam_Controller:: GamepadTriggerLength (ControllerHandle_t id, GAMEPAD_TRIGGER trigger) { return 0 .0f ; };
31- inline void Steam_Controller:: GamepadStickXY (ControllerHandle_t id, GAMEPAD_STICK stick, float * outX , float * outY ) {};
32- inline void Steam_Controller:: GamepadStickNormXY (ControllerHandle_t id, GAMEPAD_STICK stick, float * outX , float * outY ) {};
33- inline void Steam_Controller:: GamepadSetRumble (ControllerHandle_t id, unsigned short left, unsigned short right, unsigned int rumble_length_ms) {};
34- inline ESteamInputType Steam_Controller:: GamepadGetType (ControllerHandle_t id) {};
26+ int DetectGamepads (std::vector< ControllerHandle_t>& handlesOut, std::vector<ControllerHandle_t>& newHandlesOut ) {return 0 ;}
27+ bool GamepadInit (void ) { return false ; };
28+ void GamepadShutdown (void );
29+ void GamepadUpdate (void );
30+ bool GamepadButtonDown (ControllerHandle_t id, GAMEPAD_BUTTON button) { return false ; };
31+ float GamepadTriggerLength (ControllerHandle_t id, GAMEPAD_TRIGGER trigger) { return 0 .0f ; };
32+ void GamepadStickXY (ControllerHandle_t id, GAMEPAD_STICK stick, float * out_x , float * out_y ) {};
33+ void GamepadStickNormXY (ControllerHandle_t id, GAMEPAD_STICK stick, float * out_x , float * out_y, Sint16 inner_deadzone, Sint16 outer_deadzone ) {};
34+ void GamepadSetRumble (ControllerHandle_t id, unsigned short left, unsigned short right, unsigned int rumble_length_ms) {};
35+ ESteamInputType GamepadGetType (ControllerHandle_t id) { return k_ESteamInputType_Unknown; };
3536#else
36-
37- inline bool Steam_Controller::GamepadInit (void ) {
38- SDL_SetHint (SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, " 1" );
39-
40- SDL_SetHint (SDL_HINT_JOYSTICK_HIDAPI_PS4, " 1" );
41- SDL_SetHint (SDL_HINT_JOYSTICK_HIDAPI_PS5, " 1" );
42-
43- SDL_SetHint (SDL_HINT_JOYSTICK_ENHANCED_REPORTS, " 1" );
44-
45- SDL_SetHint (SDL_HINT_JOYSTICK_HIDAPI_GAMECUBE, " 1" );
46- SDL_SetHint (SDL_HINT_JOYSTICK_HIDAPI_SWITCH, " 1" );
47- SDL_SetHint (SDL_HINT_JOYSTICK_HIDAPI_JOY_CONS, " 1" );
48- SDL_SetHint (SDL_HINT_JOYSTICK_HIDAPI_STADIA, " 1" );
49- SDL_SetHint (SDL_HINT_JOYSTICK_HIDAPI_STEAM, " 1" );
50- SDL_SetHint (SDL_HINT_JOYSTICK_HIDAPI_LUNA, " 1" );
51-
52- if (!SDL_Init (SDL_INIT_JOYSTICK | SDL_INIT_GAMEPAD | SDL_INIT_HAPTIC | SDL_INIT_EVENTS))
53- return false ;
54-
55- SDL_SetGamepadEventsEnabled (false );
56-
57- return true ;
58- }
59-
60- inline void Steam_Controller::GamepadShutdown (void ) {
61- for (auto & c : controllers) {
62- SDL_Gamepad* gamepad = SDL_GetGamepadFromID (static_cast <SDL_JoystickID>(c.first ));
63- if (gamepad)
64- SDL_CloseGamepad (gamepad);
65- }
66-
67- SDL_QuitSubSystem (SDL_INIT_JOYSTICK | SDL_INIT_GAMEPAD | SDL_INIT_HAPTIC | SDL_INIT_EVENTS);
68- }
69-
70- inline void Steam_Controller::GamepadUpdate (void ) {
71- SDL_UpdateGamepads ();
72- }
73-
74- /* Detects gamepad connect/disconnects. Pass in nullptr to skip copying ids */
75- inline int Steam_Controller::DetectGamepads (ControllerHandle_t *handlesOut) {
76- int count = 0 ;
77-
78- SDL_JoystickID* gamepads = SDL_GetGamepads (&count);
79-
80- for (int i = 0 ; i < count && i < GAMEPAD_COUNT; ++i) {
81- SDL_JoystickID id = gamepads[i];
82-
83- auto controller = controllers.find (id);
84-
85- if (controller == controllers.end ()) {
86- SDL_Gamepad* gamepadHandle = SDL_OpenGamepad (id);
87- struct Controller_Action cont_action (id);
88- // Activate the first action set.
89- // TODO: check exactly what decides which gets activated by default
90- if (action_handles.size () >= 1 ) {
91- cont_action.activate_action_set (action_handles.begin ()->second , controller_maps);
92- }
93-
94- controllers.insert (std::pair<ControllerHandle_t, struct Controller_Action >(id, cont_action));
95-
96- }
97-
98- if (handlesOut) {
99- *handlesOut = id;
100- ++handlesOut;
101- }
102- }
103-
104- SDL_free (gamepads);
105-
106- return count;
107- }
108-
109- inline bool Steam_Controller::GamepadButtonDown (ControllerHandle_t id, GAMEPAD_BUTTON button) {
110- SDL_Gamepad* gamepad = SDL_GetGamepadFromID (static_cast <SDL_JoystickID>(id));
111- if (!gamepad)
112- return false ;
113- return SDL_GetGamepadButton (gamepad, (SDL_GamepadButton)button);
114- }
115-
116- inline float Steam_Controller::GamepadTriggerLength (ControllerHandle_t id, GAMEPAD_TRIGGER trigger) {
117- SDL_Gamepad* gamepad = SDL_GetGamepadFromID (static_cast <SDL_JoystickID>(id));
118- if (!gamepad)
119- return 0 .0f ;
120- if (trigger == TRIGGER_LEFT)
121- return static_cast <float >(SDL_GetGamepadAxis (gamepad, SDL_GAMEPAD_AXIS_LEFT_TRIGGER));
122- else if (trigger == TRIGGER_RIGHT)
123- return static_cast <float >(SDL_GetGamepadAxis (gamepad, SDL_GAMEPAD_AXIS_RIGHT_TRIGGER));
124- return 0 .0f ;
125- }
126-
127- inline void Steam_Controller::GamepadStickNormXY (ControllerHandle_t id, GAMEPAD_STICK stick, float * outX, float * outY) {
128- float x = 0 .0f , y = 0 .0f ;
129- GamepadStickXY (id, stick, &x, &y);
130-
131- // normalize X and Y
132- bool sign_x = x >= 0 ; bool sign_y = y >= 0 ;
133- x = abs (x); y = abs (y);
134-
135- x = std::max (0 .0f , (x - DEADZONE_BUTTON_STICK) / (SDL_JOYSTICK_AXIS_MAX - 2 * DEADZONE_BUTTON_STICK));
136- y = std::max (0 .0f , (y - DEADZONE_BUTTON_STICK) / (SDL_JOYSTICK_AXIS_MAX - 2 * DEADZONE_BUTTON_STICK));
137-
138- x = sign_x ? x : -x;
139- y = sign_y ? y : -y;
140-
141-
142- // fix special case
143- x = std::max (x, -1 .0f );
144- y = std::max (y, -1 .0f );
145-
146- *outX = x;
147- *outY = y;
148- }
149-
150- inline void Steam_Controller::GamepadStickXY (ControllerHandle_t id, GAMEPAD_STICK stick, float * outX, float * outY) {
151- SDL_Gamepad* gamepad = SDL_GetGamepadFromID (static_cast <SDL_JoystickID>(id));
152- if (!gamepad)
153- return ;
154-
155- if (stick == STICK_LEFT) {
156- *outX = static_cast <float >(SDL_GetGamepadAxis (gamepad, SDL_GAMEPAD_AXIS_LEFTX));
157- *outY = static_cast <float >(-SDL_GetGamepadAxis (gamepad, SDL_GAMEPAD_AXIS_LEFTY));
158- }
159- else if (stick == STICK_RIGHT) {
160- *outX = static_cast <float >(SDL_GetGamepadAxis (gamepad, SDL_GAMEPAD_AXIS_RIGHTX));
161- *outY = static_cast <float >(-SDL_GetGamepadAxis (gamepad, SDL_GAMEPAD_AXIS_RIGHTY));
162- }
163- }
164-
165- inline void Steam_Controller::GamepadSetRumble (ControllerHandle_t id, unsigned short left, unsigned short right, unsigned int rumble_length_ms) {
166- SDL_Gamepad* gamepad = SDL_GetGamepadFromID (static_cast <SDL_JoystickID>(id));
167- if (!gamepad)
168- return ;
169- SDL_RumbleGamepad (gamepad, left, right, rumble_length_ms);
170- SDL_UpdateGamepads ();
171- }
172-
173- inline ESteamInputType Steam_Controller::GamepadGetType (ControllerHandle_t id) {
174- SDL_Gamepad* gamepad = SDL_GetGamepadFromID (static_cast <SDL_JoystickID>(id));
175- if (!gamepad)
176- return k_ESteamInputType_Unknown;
177- switch (SDL_GetGamepadType (gamepad)) {
178- case SDL_GAMEPAD_TYPE_XBOX360:
179- return k_ESteamInputType_XBox360Controller;
180- case SDL_GAMEPAD_TYPE_XBOXONE:
181- return k_ESteamInputType_XBoxOneController;
182- case SDL_GAMEPAD_TYPE_PS3:
183- return k_ESteamInputType_PS3Controller;
184- case SDL_GAMEPAD_TYPE_PS4:
185- return k_ESteamInputType_PS4Controller;
186- case SDL_GAMEPAD_TYPE_PS5:
187- return k_ESteamInputType_PS5Controller;
188- case SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_PRO:
189- return k_ESteamInputType_SwitchProController;
190- case SDL_GAMEPAD_TYPE_STANDARD:
191- return k_ESteamInputType_GenericGamepad;
192- default :
193- return k_ESteamInputType_Unknown;
194- }
195- }
196-
197-
198-
37+ using namespace gamepad_provider ::sdl;
19938#endif
20039
20140Controller_Action::Controller_Action (ControllerHandle_t controller_handle) {
@@ -406,7 +245,20 @@ bool Steam_Controller::Init(bool bExplicitlyCallRunFrame)
406245
407246 GamepadInit ();
408247 GamepadUpdate ();
409- DetectGamepads (nullptr );
248+
249+ std::vector<ControllerHandle_t> newHandles{};
250+ std::vector<ControllerHandle_t> handles{};
251+ DetectGamepads (handles, newHandles);
252+
253+ for (auto &id : handles) {
254+ struct Controller_Action cont_action (id);
255+ // Activate the first action set.
256+ // TODO: check exactly what decides which gets activated by default
257+ if (action_handles.size () >= 1 ) {
258+ cont_action.activate_action_set (action_handles.begin ()->second , controller_maps);
259+ }
260+ controllers.insert (std::pair<ControllerHandle_t, struct Controller_Action >(id, cont_action));
261+ }
410262
411263 // rumble_thread_data = new Rumble_Thread_Data();
412264 // background_rumble_thread = std::thread(background_rumble, rumble_thread_data);
@@ -538,22 +390,24 @@ int Steam_Controller::GetConnectedControllers( ControllerHandle_t *handlesOut )
538390 return 0 ;
539391 }
540392
541- // Cleanup disconnected controllers
393+ std::vector<ControllerHandle_t> newHandles{};
394+ std::vector<ControllerHandle_t> handles{};
395+ int count = DetectGamepads (handles, newHandles);
542396
543- for (auto & c : controllers) {
544- SDL_JoystickID id = static_cast <SDL_JoystickID>(c.first );
545- SDL_Gamepad* gamepadHandle = SDL_GetGamepadFromID (id);
546- if (gamepadHandle) {
547- if (SDL_GamepadConnected (gamepadHandle)) {
548- // Controller is in use
549- continue ;
550- }
551- // Controller is not in use, close gamepad
552- SDL_CloseGamepad (gamepadHandle);
397+ for (const auto & id : newHandles) {
398+ PRINT_DEBUG (" creating new controller with id %i" , id);
399+ struct Controller_Action cont_action (id);
400+ // Activate the first action set.
401+ // TODO: check exactly what decides which gets activated by default
402+ if (action_handles.size () >= 1 ) {
403+ cont_action.activate_action_set (action_handles.begin ()->second , controller_maps);
553404 }
405+ controllers.insert (std::pair<ControllerHandle_t, struct Controller_Action >(id, cont_action));
554406 }
555407
556- int count = DetectGamepads (handlesOut);
408+ std::copy (handles.begin (), handles.end (), handlesOut);
409+
410+ PRINT_DEBUG (" first controller handle is %i" , handlesOut[0 ]);
557411
558412 PRINT_DEBUG (" returned %i connected controllers" , count);
559413 return count;
@@ -687,7 +541,7 @@ ControllerDigitalActionData_t Steam_Controller::GetDigitalActionData( Controller
687541 case BUTTON_STICK_LEFT_LEFT:
688542 case BUTTON_STICK_LEFT_RIGHT: {
689543 float x = 0 , y = 0 ;
690- GamepadStickNormXY (controllerHandle, STICK_LEFT, &x, &y);
544+ GamepadStickNormXY (controllerHandle, STICK_LEFT, &x, &y, INNER_DEADZONE_BUTTON_STICK, OUTER_DEADZONE_BUTTON_STICK );
691545 if (button == BUTTON_STICK_LEFT_DOWN || button == BUTTON_STICK_LEFT_UP) pressed = y != 0 .0f ;
692546 if (button == BUTTON_STICK_LEFT_RIGHT || button == BUTTON_STICK_LEFT_LEFT) pressed = x != 0 .0f ;
693547 break ;
@@ -697,7 +551,7 @@ ControllerDigitalActionData_t Steam_Controller::GetDigitalActionData( Controller
697551 case BUTTON_STICK_RIGHT_LEFT:
698552 case BUTTON_STICK_RIGHT_RIGHT: {
699553 float x = 0 , y = 0 ;
700- GamepadStickNormXY (controllerHandle, STICK_RIGHT , &x, &y);
554+ GamepadStickNormXY (controllerHandle, STICK_LEFT , &x, &y, INNER_DEADZONE_BUTTON_STICK, OUTER_DEADZONE_BUTTON_STICK );
701555 if (button == BUTTON_STICK_RIGHT_DOWN || button == BUTTON_STICK_RIGHT_UP) pressed = y != 0 .0f ;
702556 if (button == BUTTON_STICK_RIGHT_RIGHT || button == BUTTON_STICK_RIGHT_LEFT) pressed = x != 0 .0f ;
703557 break ;
@@ -1252,7 +1106,7 @@ ControllerAnalogActionData_t Steam_Controller::GetAnalogActionData( ControllerHa
12521106 data.y = data.y * length;
12531107 }
12541108 } else {
1255- GamepadStickNormXY (controllerHandle, (GAMEPAD_STICK) joystick_id, &data.x , &data.y );
1109+ GamepadStickNormXY (controllerHandle, (GAMEPAD_STICK) joystick_id, &data.x , &data.y , INNER_DEADZONE_BUTTON_STICK, OUTER_DEADZONE_BUTTON_STICK );
12561110 }
12571111 } else {
12581112 data.x = GamepadTriggerLength (controllerHandle, (GAMEPAD_TRIGGER) a);
@@ -1655,6 +1509,7 @@ ESteamInputType Steam_Controller::GetInputTypeForHandle( ControllerHandle_t cont
16551509{
16561510 auto controller = controllers.find (controllerHandle);
16571511 if (controller == controllers.end ()) {
1512+ // Hack: Why does Elden Ring query controllerHandle 0? Are we returning empty handles somewhere else?
16581513 if (controllers.size () != 0 )
16591514 controller = controllers.begin ();
16601515 else {
0 commit comments