libmx2 2.2.1
C++20 multimedia and game-engine library (SDL2 / OpenGL / Vulkan)
Loading...
Searching...
No Matches
joystick.hpp
Go to the documentation of this file.
1/**
2 * @file joystick.hpp
3 * @brief SDL joystick and game controller RAII wrappers.
4 *
5 * Joystick wraps SDL_Joystick for generic axis/hat/button devices.
6 * Controller wraps SDL_GameController for the higher-level game controller
7 * API (standard button mappings, triggers, etc.).
8 */
9#ifndef __JOYSTICK__H__
10#define __JOYSTICK__H__
11
12#include"SDL.h"
13#include<string>
14#include<optional>
15#include"wrapper.hpp"
16
17namespace mx {
18
19/**
20 * @class Joystick
21 * @brief RAII wrapper for a raw SDL_Joystick device.
22 *
23 * Opens an SDL joystick by index and provides axis, hat, and button
24 * read-back. The handle is automatically closed on destruction.
25 */
26 class Joystick {
27 public:
28 /** @brief Default constructor — device not yet opened. */
29 Joystick();
30 /** @brief Destructor — closes the joystick if open. */
31 ~Joystick();
32
33 Joystick(const Joystick&) = delete;
34 Joystick& operator=(const Joystick&) = delete;
35 Joystick(Joystick&&) = delete;
37
38 /**
39 * @brief Open the joystick at the given device index.
40 * @param index SDL joystick index (0-based).
41 * @return @c true on success.
42 */
43 bool open(int index);
44
45 /**
46 * @brief Return the joystick's name as reported by SDL.
47 * @return Device name string.
48 */
49 std::string name() const;
50
51 /** @brief Close the joystick handle if open. */
52 void close();
53
54 /**
55 * @brief Return the underlying SDL_Joystick handle as an optional.
56 * @return std::optional containing the handle, or std::nullopt.
57 */
58 std::optional<SDL_Joystick*> handle();
59
60 /**
61 * @brief Unwrap the SDL_Joystick pointer, asserting it is open.
62 * @return Raw SDL_Joystick pointer.
63 */
64 SDL_Joystick *unwrap() const;
65
66 /**
67 * @brief Return the device index this joystick was opened with.
68 * @return Device index.
69 */
70 int joystickIndex() const;
71
72 /**
73 * @brief Return the number of connected joysticks.
74 * @return SDL_NumJoysticks() result.
75 */
76 static int joysticks() { return SDL_NumJoysticks(); }
77
78 /** @return Number of buttons on this joystick. */
79 int numButtons();
80 /** @return Number of hats on this joystick. */
81 int numHats();
82 /** @return Number of axes on this joystick. */
83 int numAxes();
84
85 /**
86 * @brief Test whether a button is currently pressed.
87 * @param button Button index.
88 * @return @c true if pressed.
89 */
90 bool getButton(int button);
91
92 /**
93 * @brief Read the position of a POV hat.
94 * @param hat Hat index.
95 * @return SDL hat position bitmask.
96 */
97 Uint8 getHat(int hat);
98
99 /**
100 * @brief Read the current axis value.
101 * @param axis Axis index.
102 * @return Axis value in the range [-32768, 32767].
103 */
104 Sint16 getAxis(int axis);
105
106 /**
107 * @brief Return a Wrapper around the SDL_Joystick handle.
108 * @return Wrapper holding the pointer or nullopt.
109 */
111 if(stick)
112 return stick;
113 return std::nullopt;
114 }
115 protected:
116 SDL_Joystick *stick = nullptr; ///< Underlying SDL joystick handle.
117 int index = -1; ///< Device index (-1 if not open).
118 };
119
120/**
121 * @class Controller
122 * @brief RAII wrapper for SDL_GameController (standard layout mapping).
123 *
124 * Provides button, hat, and axis queries using SDL's gamecontroller API,
125 * which normalises button layouts across different physical devices.
126 */
128 public:
129 /** @brief Default constructor — device not yet opened. */
130 Controller();
131 /** @brief Destructor — closes the controller if open. */
132 ~Controller();
133
134 Controller(const Controller&) = delete;
135 Controller& operator=(const Controller&) = delete;
138
139 /**
140 * @brief Open a game controller by device index.
141 * @param index SDL joystick index of the controller.
142 * @return @c true on success.
143 */
144 bool open(int index);
145
146 /**
147 * @brief Handle a device-added/removed event to maintain connection state.
148 * @param e SDL event to inspect.
149 * @return @c true if the event was a controller connect/disconnect.
150 */
151 bool connectEvent(SDL_Event &e);
152
153 /**
154 * @brief Return the controller's name as reported by SDL.
155 * @return Device name string.
156 */
157 std::string name() const;
158
159 /** @brief Close the controller handle if open. */
160 void close();
161
162 /**
163 * @brief Return the underlying SDL_GameController handle as an optional.
164 * @return std::optional containing the handle, or std::nullopt.
165 */
166 std::optional<SDL_GameController*> handle();
167
168 /**
169 * @brief Unwrap the SDL_GameController pointer, asserting it is open.
170 * @return Raw SDL_GameController pointer.
171 */
172 SDL_GameController *unwrap() const;
173
174 /**
175 * @brief Return the device index this controller was opened with.
176 * @return Device index.
177 */
178 int controllerIndex() const;
179
180 /**
181 * @brief Return the number of connected joysticks/controllers.
182 * @return SDL_NumJoysticks() result.
183 */
184 static int joysticks() { return SDL_NumJoysticks(); }
185
186 /**
187 * @brief Test whether a mapped button is currently pressed.
188 * @param button SDL_GameControllerButton constant.
189 * @return @c true if pressed.
190 */
191 bool getButton(SDL_GameControllerButton button);
192
193 /**
194 * @brief Read the position of a POV hat.
195 * @param hat Hat index.
196 * @return SDL hat position bitmask.
197 */
198 Uint8 getHat(int hat);
199
200 /**
201 * @brief Read the current axis value.
202 * @param axis SDL_GameControllerAxis constant.
203 * @return Axis value in the range [-32768, 32767].
204 */
205 Sint16 getAxis(SDL_GameControllerAxis axis);
206
207 /**
208 * @brief Return a Wrapper around the SDL_GameController handle.
209 * @return Wrapper holding the pointer or nullopt.
210 */
212 if(stick)
213 return stick;
214 return std::nullopt;
215 }
216
217 /**
218 * @brief Check whether the controller is currently usable.
219 * @return @c true if the controller is open and has a valid index.
220 */
221 bool active() const { if(index >= 0 && stick != nullptr) return true; return false; }
222 protected:
223 SDL_GameController *stick = nullptr; ///< Underlying SDL game controller handle.
224 int index = -1; ///< Device index (-1 if not open).
225 };
226}
227
228#endif
Controller & operator=(Controller &&)=delete
std::string name() const
Return the controller's name as reported by SDL.
Definition joystick.cpp:119
int controllerIndex() const
Return the device index this controller was opened with.
Definition joystick.cpp:149
int index
Device index (-1 if not open).
Definition joystick.hpp:224
SDL_GameController * unwrap() const
Unwrap the SDL_GameController pointer, asserting it is open.
Definition joystick.cpp:141
bool getButton(SDL_GameControllerButton button)
Test whether a mapped button is currently pressed.
Definition joystick.cpp:153
bool connectEvent(SDL_Event &e)
Handle a device-added/removed event to maintain connection state.
Definition joystick.cpp:176
mx::Wrapper< SDL_GameController * > wrapper() const
Return a Wrapper around the SDL_GameController handle.
Definition joystick.hpp:211
Sint16 getAxis(SDL_GameControllerAxis axis)
Read the current axis value.
Definition joystick.cpp:169
~Controller()
Destructor — closes the controller if open.
Definition joystick.cpp:103
std::optional< SDL_GameController * > handle()
Return the underlying SDL_GameController handle as an optional.
Definition joystick.cpp:134
void close()
Close the controller handle if open.
Definition joystick.cpp:126
Controller(Controller &&)=delete
Controller & operator=(const Controller &)=delete
Uint8 getHat(int hat)
Read the position of a POV hat.
Definition joystick.cpp:159
Controller()
Default constructor — device not yet opened.
Definition joystick.cpp:101
Controller(const Controller &)=delete
bool open(int index)
Open a game controller by device index.
Definition joystick.cpp:107
static int joysticks()
Return the number of connected joysticks/controllers.
Definition joystick.hpp:184
SDL_GameController * stick
Underlying SDL game controller handle.
Definition joystick.hpp:223
bool active() const
Check whether the controller is currently usable.
Definition joystick.hpp:221
Joystick(const Joystick &)=delete
~Joystick()
Destructor — closes the joystick if open.
Definition joystick.cpp:13
void close()
Close the joystick handle if open.
Definition joystick.cpp:36
Joystick(Joystick &&)=delete
Joystick()
Default constructor — device not yet opened.
Definition joystick.cpp:11
int numAxes()
Definition joystick.cpp:95
int numHats()
Definition joystick.cpp:90
Sint16 getAxis(int axis)
Read the current axis value.
Definition joystick.cpp:77
Joystick & operator=(const Joystick &)=delete
int numButtons()
Definition joystick.cpp:84
int joystickIndex() const
Return the device index this joystick was opened with.
Definition joystick.cpp:59
std::string name() const
Return the joystick's name as reported by SDL.
Definition joystick.cpp:29
SDL_Joystick * unwrap() const
Unwrap the SDL_Joystick pointer, asserting it is open.
Definition joystick.cpp:51
SDL_Joystick * stick
Underlying SDL joystick handle.
Definition joystick.hpp:116
std::optional< SDL_Joystick * > handle()
Return the underlying SDL_Joystick handle as an optional.
Definition joystick.cpp:44
static int joysticks()
Return the number of connected joysticks.
Definition joystick.hpp:76
bool getButton(int button)
Test whether a button is currently pressed.
Definition joystick.cpp:63
bool open(int index)
Open the joystick at the given device index.
Definition joystick.cpp:17
Joystick & operator=(Joystick &&)=delete
int index
Device index (-1 if not open).
Definition joystick.hpp:117
Uint8 getHat(int hat)
Read the position of a POV hat.
Definition joystick.cpp:70
mx::Wrapper< SDL_Joystick * > wrapper() const
Return a Wrapper around the SDL_Joystick handle.
Definition joystick.hpp:110
A nullable smart wrapper around a raw pointer.
Definition wrapper.hpp:36
Definition cfg.cpp:11
Type-safe nullable pointer wrapper inspired by Rust's Option<T>.