MXVK Vulkan Framework 0.35.0
C++20 Vulkan rendering framework for practical 2D and 3D application development with SDL3.
Loading...
Searching...
No Matches
mxvk_controller.cpp
Go to the documentation of this file.
1/**
2 * @file mxvk_controller.cpp
3 * @brief Implementation of mxvk::VK_Joystick and mxvk::VK_Controller SDL3 wrappers.
4 */
5
7
9
10#include <SDL3/SDL_stdinc.h>
11
12namespace mxvk {
13
14 VK_Joystick::VK_Joystick() = default;
15
17
19 int count = 0;
20 SDL_JoystickID *ids = SDL_GetJoysticks(&count);
21 if (ids != nullptr) {
22 SDL_free(ids);
23 }
24 return count;
25 }
26
27 bool VK_Joystick::open(const int index) {
28 close();
29
30 int count = 0;
31 SDL_JoystickID *ids = SDL_GetJoysticks(&count);
32 if (ids == nullptr || index < 0 || index >= count) {
33 if (ids != nullptr) {
34 SDL_free(ids);
35 }
36 return false;
37 }
38
39 const SDL_JoystickID openedInstanceId = ids[index];
40 SDL_free(ids);
41
42 stick = SDL_OpenJoystick(openedInstanceId);
43 if (stick == nullptr) {
44 return false;
45 }
46
47 deviceIndex = index;
48 instanceId = openedInstanceId;
49 SDL_SetJoystickEventsEnabled(true);
50 return true;
51 }
52
53 std::string VK_Joystick::name() const {
54 if (stick != nullptr) {
55 const char *device_name = SDL_GetJoystickName(stick);
56 if (device_name != nullptr) {
57 return device_name;
58 }
59 }
60 return "Joystick Not Opened.";
61 }
62
64 if (stick != nullptr) {
65 SDL_CloseJoystick(stick);
66 }
67
68 stick = nullptr;
69 deviceIndex = -1;
70 instanceId = 0;
71 }
72
73 std::optional<SDL_Joystick *> VK_Joystick::handle() const {
74 if (stick != nullptr) {
75 return stick;
76 }
77 return std::nullopt;
78 }
79
80 SDL_Joystick *VK_Joystick::unwrap() const {
81 if (stick != nullptr) {
82 return stick;
83 }
84 throw mxvk::Exception("Invalid joystick handle");
85 }
86
88
89 bool VK_Joystick::getButton(const int button) const {
90 if (stick == nullptr) {
91 return false;
92 }
93 return SDL_GetJoystickButton(stick, button);
94 }
95
96 Uint8 VK_Joystick::getHat(const int hat) const {
97 if (stick == nullptr) {
98 return 0;
99 }
100 return SDL_GetJoystickHat(stick, hat);
101 }
102
103 Sint16 VK_Joystick::getAxis(const int axis) const {
104 if (stick == nullptr) {
105 return 0;
106 }
107 return SDL_GetJoystickAxis(stick, axis);
108 }
109
111 if (stick == nullptr) {
112 return 0;
113 }
114 const int count = SDL_GetNumJoystickButtons(stick);
115 return count < 0 ? 0 : count;
116 }
117
119 if (stick == nullptr) {
120 return 0;
121 }
122 const int count = SDL_GetNumJoystickHats(stick);
123 return count < 0 ? 0 : count;
124 }
125
127 if (stick == nullptr) {
128 return 0;
129 }
130 const int count = SDL_GetNumJoystickAxes(stick);
131 return count < 0 ? 0 : count;
132 }
133
135
137
139 int count = 0;
140 SDL_JoystickID *ids = SDL_GetGamepads(&count);
141 if (ids != nullptr) {
142 SDL_free(ids);
143 }
144 return count;
145 }
146
147 bool VK_Controller::openByInstanceId(const SDL_JoystickID newInstanceId, const int index_hint) {
148 close();
149
150 stick = SDL_OpenGamepad(newInstanceId);
151 if (stick == nullptr) {
152 return false;
153 }
154
155 deviceIndex = index_hint;
156 instanceId = newInstanceId;
157 SDL_SetGamepadEventsEnabled(true);
158 return true;
159 }
160
161 bool VK_Controller::open(const int index) {
162 int count = 0;
163 SDL_JoystickID *ids = SDL_GetGamepads(&count);
164 if (ids == nullptr || index < 0 || index >= count) {
165 if (ids != nullptr) {
166 SDL_free(ids);
167 }
168 return false;
169 }
170
171 const SDL_JoystickID openedInstanceId = ids[index];
172 SDL_free(ids);
173 return openByInstanceId(openedInstanceId, index);
174 }
175
176 std::string VK_Controller::name() const {
177 if (stick != nullptr) {
178 const char *device_name = SDL_GetGamepadName(stick);
179 if (device_name != nullptr) {
180 return device_name;
181 }
182 }
183 return "Controller Not Opened.";
184 }
185
187 if (stick != nullptr) {
188 SDL_CloseGamepad(stick);
189 }
190
191 stick = nullptr;
192 deviceIndex = -1;
193 instanceId = 0;
194 }
195
196 std::optional<SDL_Gamepad *> VK_Controller::handle() const {
197 if (stick != nullptr) {
198 return stick;
199 }
200 return std::nullopt;
201 }
202
203 SDL_Gamepad *VK_Controller::unwrap() const {
204 if (stick != nullptr) {
205 return stick;
206 }
207 throw mxvk::Exception("Invalid controller handle");
208 }
209
211
212 bool VK_Controller::getButton(const SDL_GamepadButton button) const {
213 if (stick == nullptr) {
214 return false;
215 }
216 return SDL_GetGamepadButton(stick, button);
217 }
218
219 Uint8 VK_Controller::getHat(const int hat) const {
220 if (stick == nullptr) {
221 return 0;
222 }
223
224 SDL_Joystick *joystick = SDL_GetGamepadJoystick(stick);
225 if (joystick == nullptr) {
226 return 0;
227 }
228 return SDL_GetJoystickHat(joystick, hat);
229 }
230
231 Sint16 VK_Controller::getAxis(const SDL_GamepadAxis axis) const {
232 if (stick == nullptr) {
233 return 0;
234 }
235 return SDL_GetGamepadAxis(stick, axis);
236 }
237
238 bool VK_Controller::active() const { return stick != nullptr && SDL_GamepadConnected(stick); }
239
240 bool VK_Controller::connectEvent(SDL_Event &e) {
241 if (e.type == SDL_EVENT_GAMEPAD_ADDED) {
242 return openByInstanceId(e.gdevice.which);
243 }
244
245 if (e.type == SDL_EVENT_GAMEPAD_REMOVED) {
246 if (stick != nullptr && instanceId == e.gdevice.which) {
247 close();
248 }
249 return true;
250 }
251
252 return false;
253 }
254
255} // namespace mxvk
std::optional< SDL_Gamepad * > handle() const
Return the underlying SDL_Gamepad handle as an optional.
int controllerIndex() const
Return the device index this controller was opened with.
void close()
Close the controller handle if open.
Sint16 getAxis(SDL_GamepadAxis axis) const
Read the current axis value.
SDL_Gamepad * unwrap() const
Unwrap the SDL_Gamepad pointer, asserting it is open.
SDL_Gamepad * stick
Underlying SDL gamepad handle.
SDL_JoystickID instanceId
Stable SDL gamepad instance identifier.
bool active() const
Check whether the controller is currently usable.
int deviceIndex
Open index in the current gamepad list.
bool openByInstanceId(SDL_JoystickID instanceId, int index_hint=-1)
bool getButton(SDL_GamepadButton button) const
Test whether a mapped button is currently pressed.
VK_Controller()
Default constructor — device not yet opened.
bool connectEvent(SDL_Event &e)
Handle a device-added/removed event to maintain connection state.
Uint8 getHat(int hat) const
Read the position of a POV hat.
static int joysticks()
Return the number of connected joysticks/controllers.
~VK_Controller() noexcept
Destructor — closes the controller if open.
bool open(int index)
Open a gamepad by device index.
std::string name() const
Return the controller's name as reported by SDL.
SDL_JoystickID instanceId
Stable SDL joystick instance identifier.
VK_Joystick()
Default constructor — device not yet opened.
~VK_Joystick() noexcept
Destructor — closes the joystick if open.
SDL_Joystick * unwrap() const
Unwrap the SDL_Joystick pointer, asserting it is open.
bool getButton(int button) const
Test whether a button is currently pressed.
bool open(int index)
Open the joystick at the given device index.
Uint8 getHat(int hat) const
Read the position of a POV hat.
static int joysticks()
Return the number of connected joysticks.
int deviceIndex
Open index in the current joystick list.
int joystickIndex() const
Return the device index this joystick was opened with.
SDL_Joystick * stick
Underlying SDL joystick handle.
std::optional< SDL_Joystick * > handle() const
Return the underlying SDL_Joystick handle as an optional.
std::string name() const
Return the joystick's name as reported by SDL.
Sint16 getAxis(int axis) const
Read the current axis value.
void close()
Close the joystick handle if open.
SDL3 joystick and gamepad RAII wrappers.
Utilities for loading and saving PNG images.
Definition mxvk.hpp:31