Skip to content

Commit b0eb680

Browse files
committed
refactor: separated sdl code to gamepad_provider::sdl
fix: GetConnectedControllers()
1 parent da4332b commit b0eb680

6 files changed

Lines changed: 332 additions & 243 deletions

File tree

dll/dll/common_includes.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -147,9 +147,6 @@ static inline void reset_LastError()
147147

148148
// Other libs includes
149149
// #include "gamepad/gamepad.h"
150-
#include <SDL3/SDL.h>
151-
#include <SDL3/SDL_gamepad.h>
152-
153150

154151
// Steamsdk includes
155152
#include "steam/steam_api.h"

dll/dll/steam_controller.h

Lines changed: 1 addition & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
#define GAMEPAD_COUNT 4
2121

2222
#include "base.h"
23-
23+
#include "gamepad_provider/gamepad_provider.hpp"
2424

2525
struct Controller_Map {
2626
std::map<ControllerDigitalActionHandle_t, std::set<int>> active_digital{};
@@ -52,24 +52,6 @@ struct Rumble_Thread_Data {
5252
} data[GAMEPAD_COUNT];
5353
};
5454

55-
enum GAMEPAD_BUTTON {
56-
BUTTON_DPAD_UP = SDL_GAMEPAD_BUTTON_DPAD_UP, /**< UP on the direction pad */
57-
BUTTON_DPAD_DOWN = SDL_GAMEPAD_BUTTON_DPAD_DOWN, /**< DOWN on the direction pad */
58-
BUTTON_DPAD_LEFT = SDL_GAMEPAD_BUTTON_DPAD_LEFT, /**< LEFT on the direction pad */
59-
BUTTON_DPAD_RIGHT = SDL_GAMEPAD_BUTTON_DPAD_RIGHT, /**< RIGHT on the direction pad */
60-
BUTTON_START = SDL_GAMEPAD_BUTTON_START, /**< START button */
61-
BUTTON_BACK = SDL_GAMEPAD_BUTTON_BACK, /**< BACK button */
62-
BUTTON_LEFT_THUMB = SDL_GAMEPAD_BUTTON_LEFT_STICK, /**< Left analog stick button */
63-
BUTTON_RIGHT_THUMB = SDL_GAMEPAD_BUTTON_RIGHT_STICK, /**< Right analog stick button */
64-
BUTTON_LEFT_SHOULDER = SDL_GAMEPAD_BUTTON_LEFT_SHOULDER, /**< Left bumper button */
65-
BUTTON_RIGHT_SHOULDER = SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER, /**< Right bumper button */
66-
BUTTON_A = SDL_GAMEPAD_BUTTON_SOUTH, /**< A button */
67-
BUTTON_B = SDL_GAMEPAD_BUTTON_EAST, /**< B button */
68-
BUTTON_X = SDL_GAMEPAD_BUTTON_WEST, /**< X button */
69-
BUTTON_Y = SDL_GAMEPAD_BUTTON_NORTH, /**< Y button */
70-
BUTTON_COUNT = 16
71-
};
72-
7355
enum EXTRA_GAMEPAD_BUTTONS {
7456
BUTTON_LTRIGGER = BUTTON_COUNT + 1,
7557
BUTTON_RTRIGGER = BUTTON_COUNT + 2,
@@ -83,25 +65,6 @@ enum EXTRA_GAMEPAD_BUTTONS {
8365
BUTTON_STICK_RIGHT_RIGHT = BUTTON_COUNT + 10,
8466
};
8567

86-
/**
87-
* Enumeration of the possible pressure/trigger buttons.
88-
*/
89-
enum GAMEPAD_TRIGGER {
90-
TRIGGER_LEFT = 0, /**< Left trigger */
91-
TRIGGER_RIGHT = 1, /**< Right trigger */
92-
TRIGGER_COUNT /**< Number of triggers */
93-
};
94-
95-
/**
96-
* Enumeration of the analog sticks.
97-
*/
98-
enum GAMEPAD_STICK {
99-
STICK_LEFT = 0, /**< Left stick */
100-
STICK_RIGHT = 1, /**< Right stick */
101-
STICK_COUNT /**< Number of analog sticks */
102-
};
103-
104-
10568
class Steam_Controller :
10669
// --- ISteamController
10770
public ISteamController001,
@@ -147,18 +110,6 @@ public ISteamInput
147110
bool initialized{};
148111
bool explicitly_call_run_frame{};
149112

150-
inline int DetectGamepads(ControllerHandle_t *handlesOut);
151-
inline bool GamepadInit(void);
152-
inline void GamepadShutdown(void);
153-
inline void GamepadUpdate(void);
154-
static inline bool GamepadButtonDown(ControllerHandle_t id, GAMEPAD_BUTTON button);
155-
static inline float GamepadTriggerLength(ControllerHandle_t id, GAMEPAD_TRIGGER trigger);
156-
static inline void GamepadStickXY(ControllerHandle_t id, GAMEPAD_STICK stick, float* outX, float* outY);
157-
static inline void GamepadStickNormXY(ControllerHandle_t id, GAMEPAD_STICK stick, float* outX, float* outY);
158-
static inline void GamepadSetRumble(ControllerHandle_t id, unsigned short left, unsigned short right, unsigned int rumble_length_ms);
159-
static inline ESteamInputType GamepadGetType(ControllerHandle_t id);
160-
161-
162113
void set_handles(std::map<std::string, std::map<std::string, std::pair<std::set<std::string>, std::string>>> action_sets);
163114

164115
void RunCallbacks();

dll/steam_controller.cpp

Lines changed: 45 additions & 190 deletions
Original file line numberDiff line numberDiff line change
@@ -19,183 +19,22 @@
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

20140
Controller_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

Comments
 (0)