ASW Lib
A.D.S. Games SDL Wrapper Library. A library targeted at Allegro4 users who want to switch to SDL3 and use modern c++.
Loading...
Searching...
No Matches
input.cpp
Go to the documentation of this file.
2
3#include <unordered_map>
4#include <vector>
5
7#include "./asw/modules/log.h"
8
9namespace {
12 std::array<bool, asw::input::NUM_CONTROLLER_BUTTONS> pressed { false };
13 std::array<bool, asw::input::NUM_CONTROLLER_BUTTONS> released { false };
14 std::array<bool, asw::input::NUM_CONTROLLER_BUTTONS> down { false };
15
16 bool any_pressed { false };
17 int last_pressed { -1 };
18 float dead_zone { 0.25F };
19
20 std::array<float, asw::input::NUM_CONTROLLER_AXES> axis { 0 };
21
22 SDL_Gamepad* gamepad { nullptr };
23 std::string name;
24};
25
28std::array<SDL_Cursor*, asw::input::NUM_CURSORS> cursors { nullptr };
29
31std::vector<ControllerState> controller {};
32
34std::unordered_map<SDL_JoystickID, uint32_t> controller_id_map {};
35
38std::string text_input;
39} // namespace
40
45
50
51const std::string& asw::input::get_text_input()
52{
53 return text_input;
54}
55
56void asw::input::_append_text(const char* text)
57{
58 text_input += text;
59}
60
62{
63 // Snapshot action states before raw input arrays are cleared.
65
66 auto& k_state = keyboard;
67 auto& m_state = mouse;
68
69 // Clear key state
70 k_state.any_pressed = false;
71 k_state.last_pressed = -1;
72
73 for (auto& pressed : k_state.pressed) {
74 pressed = false;
75 }
76
77 for (auto& released : k_state.released) {
78 released = false;
79 }
80
81 // Clear mouse state
82 m_state.any_pressed = false;
83 m_state.change = { 0.0F, 0.0F };
84 m_state.z = 0;
85
86 for (auto& pressed : m_state.pressed) {
87 pressed = false;
88 }
89
90 for (auto& released : m_state.released) {
91 released = false;
92 }
93
94 // Clear text input
95 text_input.clear();
96
97 // Clear controller state
98 for (auto& cont : controller) {
99 cont.any_pressed = false;
100 cont.last_pressed = -1;
101
102 for (auto& button : cont.pressed) {
103 button = false;
104 }
105
106 for (auto& button : cont.released) {
107 button = false;
108 }
109 }
110}
111
112// ---- MOUSE ----
113//
114
116{
117 return mouse.down[static_cast<int>(button)];
118}
119
121{
122 return mouse.pressed[static_cast<int>(button)];
123}
124
126{
127 return mouse.released[static_cast<int>(button)];
128}
129
131{
132 auto cursor_int = static_cast<uint32_t>(cursor);
133
134 if (cursor_int >= cursors.size()) {
135 return;
136 }
137
138 if (cursors[cursor_int] == nullptr) {
139 cursors[cursor_int] = SDL_CreateSystemCursor(static_cast<SDL_SystemCursor>(cursor_int));
140 }
141
142 SDL_SetCursor(cursors[cursor_int]);
143}
144
145// ---- KEYBOARD ----
146//
147
149{
150 return keyboard.down[static_cast<int>(key)];
151}
152
154{
155 return keyboard.pressed[static_cast<int>(key)];
156}
157
159{
160 return keyboard.released[static_cast<int>(key)];
161}
162
163// ---- CONTROLLER ----
164//
165
167{
168 if (index >= controller.size()) {
169 return false;
170 }
171
172 return controller[index].down[static_cast<int>(button)];
173}
174
176{
177 if (index >= controller.size()) {
178 return false;
179 }
180
181 return controller[index].pressed[static_cast<int>(button)];
182}
183
185{
186 if (index >= controller.size()) {
187 return false;
188 }
189
190 return controller[index].released[static_cast<int>(button)];
191}
192
194{
195 if (index >= controller.size()) {
196 return 0.0F;
197 }
198
199 return controller[index].axis[static_cast<int>(axis)];
200}
201
202void asw::input::set_controller_dead_zone(uint32_t index, float dead_zone)
203{
204 if (index >= controller.size()) {
205 return;
206 }
207
208 controller[index].dead_zone = dead_zone;
209}
210
212{
213 return controller.size();
214}
215
216std::string asw::input::get_controller_name(uint32_t index)
217{
218 if (index >= controller.size()) {
219 return "";
220 }
221
222 return controller.at(index).name;
223}
224
226
227void asw::input::_key_down(SDL_Scancode scancode)
228{
229 keyboard.pressed[scancode] = true;
230 keyboard.down[scancode] = true;
231 keyboard.any_pressed = true;
232 keyboard.last_pressed = scancode;
233}
234
235void asw::input::_key_up(SDL_Scancode scancode)
236{
237 keyboard.released[scancode] = true;
238 keyboard.down[scancode] = false;
239}
240
242{
243 const auto button_int = static_cast<int>(button);
244 mouse.pressed[button_int] = true;
245 mouse.down[button_int] = true;
246 mouse.any_pressed = true;
247 mouse.last_pressed = button_int;
248}
249
251{
252 const auto button_int = static_cast<int>(button);
253 mouse.released[button_int] = true;
254 mouse.down[button_int] = false;
255}
256
257void asw::input::_mouse_motion(float x, float y, float delta_x, float delta_y)
258{
259 mouse.position.x = x;
260 mouse.position.y = y;
261 mouse.change.x = delta_x;
262 mouse.change.y = delta_y;
263}
264
265void asw::input::_mouse_wheel(float delta_z)
266{
267 mouse.z = delta_z;
268}
269
270void asw::input::_controller_added(SDL_JoystickID id)
271{
272 if (!SDL_IsGamepad(id)) {
273 asw::log::warn("Failed to open gamepad: {}", id);
274 return;
275 }
276
277 auto* opened = SDL_OpenGamepad(id);
278 if (opened == nullptr) {
279 asw::log::warn("Failed to open gamepad: {}", id);
280 }
281
282 // Add controller
283 auto& new_controller = controller.emplace_back();
284 new_controller.gamepad = opened;
285 new_controller.name = SDL_GetGamepadName(opened);
286 controller_id_map[id] = controller.size() - 1;
287
288 asw::log::info("Gamepad added: {} (ID: {})", new_controller.name, id);
289}
290
291void asw::input::_controller_removed(SDL_JoystickID id)
292{
293 const auto it = controller_id_map.find(id);
294 if (it == controller_id_map.end()) {
295 return;
296 }
297
298 // Erase from vector and map
299 const auto index = it->second;
300 controller_id_map.erase(it);
301 controller.erase(controller.begin() + index);
302
303 // Close gamepad if it exists
304 if (auto* existing = SDL_GetGamepadFromID(id); existing != nullptr) {
305 SDL_CloseGamepad(existing);
306 }
307}
308
309void asw::input::_controller_axis_motion(SDL_JoystickID id, uint32_t axis, float value)
310{
311 const auto it = controller_id_map.find(id);
312 if (it == controller_id_map.end()) {
313 return;
314 }
315
316 const auto index = it->second;
317 if (index >= controller.size() || axis >= asw::input::NUM_CONTROLLER_AXES) {
318 return;
319 }
320
321 controller[index].axis[axis] = value / 32768.0F; // Normalize to [-1, 1]
322}
323
324void asw::input::_controller_button_down(SDL_JoystickID id, uint32_t button)
325{
326 const auto it = controller_id_map.find(id);
327 if (it == controller_id_map.end()) {
328 return;
329 }
330
331 const auto index = it->second;
332 if (index >= controller.size()) {
333 return;
334 }
335
336 controller[index].pressed[button] = true;
337 controller[index].down[button] = true;
338 controller[index].any_pressed = true;
339 controller[index].last_pressed = button;
340}
341
342void asw::input::_controller_button_up(SDL_JoystickID id, uint32_t button)
343{
344 const auto it = controller_id_map.find(id);
345 if (it == controller_id_map.end()) {
346 return;
347 }
348
349 const auto index = it->second;
350 if (index >= controller.size()) {
351 return;
352 }
353
354 controller[index].released[button] = true;
355 controller[index].down[button] = false;
356}
Action binding system for the ASW library.
Input module for the ASW library.
Structured logging system.
struct ControllerState { std::array< bool, asw::input::NUM_CONTROLLER_BUTTONS > pressed { false }; std::array< bool, asw::input::NUM_CONTROLLER_BUTTONS > released { false }; std::array< bool, asw::input::NUM_CONTROLLER_BUTTONS > down { false }; bool any_pressed { false }; int last_pressed { -1 }; float dead_zone { 0.25F }; std::array< float, asw::input::NUM_CONTROLLER_AXES > axis { 0 }; SDL_Gamepad *gamepad { nullptr }; std::string name;} ControllerState
Data structure for controller state, including button states and axis values.
Definition input.cpp:11
std::vector< ControllerState > controller
Global controller state.
Definition input.cpp:31
std::unordered_map< SDL_JoystickID, uint32_t > controller_id_map
Map of SDL_JoystickID to controller index in the controller vector.
Definition input.cpp:34
asw::input::MouseState mouse
Definition input.cpp:37
asw::input::KeyState keyboard
Definition input.cpp:36
std::array< SDL_Cursor *, asw::input::NUM_CURSORS > cursors
Active cursor stores the current active cursor. It is updated by the core.
Definition input.cpp:28
void _mouse_button_up(uint8_t button)
Mouse button up hook.
Definition input.cpp:250
bool get_controller_button_up(uint32_t index, asw::input::ControllerButton button)
Check if a controller button was released since the last update.
Definition input.cpp:184
bool get_controller_button_down(uint32_t index, asw::input::ControllerButton button)
Check if a controller button was pressed since the last update.
Definition input.cpp:175
bool get_key(asw::input::Key key)
Check if a key is down.
Definition input.cpp:148
struct KeyState { std::array< bool, NUM_KEYS > pressed { false }; std::array< bool, NUM_KEYS > released { false }; std::array< bool, NUM_KEYS > down { false }; bool any_pressed { false }; int last_pressed { -1 };} KeyState
Keyboard state stores the current state of the keyboard. It is updated by the core.
Definition input.h:351
void _mouse_button_down(uint8_t button)
Mouse button down hook.
Definition input.cpp:241
bool get_controller_button(uint32_t index, asw::input::ControllerButton button)
Check if a controller button is down.
Definition input.cpp:166
CursorId
System cursor Ids.
Definition input.h:279
void _key_up(SDL_Scancode scancode)
Key up hook.
Definition input.cpp:235
std::string get_controller_name(uint32_t index)
Get the name of a controller.
Definition input.cpp:216
void set_cursor(asw::input::CursorId cursor)
Change cursor.
Definition input.cpp:130
void _controller_removed(SDL_JoystickID id)
Controller removed hook.
Definition input.cpp:291
bool get_key_up(asw::input::Key key)
Check if a key was released since the last update.
Definition input.cpp:158
void reset()
Reset all input states. Called by the core.
Definition input.cpp:61
const KeyState & get_keyboard()
Get the current keyboard state.
Definition input.cpp:41
void set_controller_dead_zone(uint32_t index, float dead_zone)
Set the joystick deadzone for a controller.
Definition input.cpp:202
bool get_key_down(asw::input::Key key)
Check if a key was pressed since the last update.
Definition input.cpp:153
void _mouse_wheel(float delta_z)
Mouse wheel hook.
Definition input.cpp:265
Key
Enumeration of keys in the ASW library.
Definition input.h:37
int get_controller_count()
Get the number of controllers connected.
Definition input.cpp:211
const MouseState & get_mouse()
Get the current mouse state.
Definition input.cpp:46
bool get_mouse_button(asw::input::MouseButton button)
Check if a mouse button is down.
Definition input.cpp:115
constexpr int NUM_CONTROLLER_AXES
Number of axes on a game controller.
Definition input.h:429
void _controller_axis_motion(SDL_JoystickID id, uint32_t axis, float value)
Axis moved hook.
Definition input.cpp:309
ControllerButton
Mappings from SDL game controller buttons to ASW buttons.
Definition input.h:403
void update_actions()
Update cached action states from current raw input.
Definition action.cpp:165
float get_controller_axis(uint32_t index, asw::input::ControllerAxis axis)
Get the value of a controller axis.
Definition input.cpp:193
bool get_mouse_button_up(asw::input::MouseButton button)
Check if a mouse button was released since the last update.
Definition input.cpp:125
void _controller_added(SDL_JoystickID id)
Controller added hook.
Definition input.cpp:270
bool get_mouse_button_down(asw::input::MouseButton button)
Check if a mouse button was pressed since the last update.
Definition input.cpp:120
void _append_text(const char *text)
Event Hooks.
Definition input.cpp:56
MouseButton
Enumeration of mouse buttons in the ASW library.
Definition input.h:27
const std::string & get_text_input()
Get the text input received this frame.
Definition input.cpp:51
void _controller_button_down(SDL_JoystickID id, uint32_t button)
Button down hook.
Definition input.cpp:324
void _controller_button_up(SDL_JoystickID id, uint32_t button)
Button up hook.
Definition input.cpp:342
struct MouseState { bool any_pressed { false }; int last_pressed { -1 }; Vec2< float > change { 0.0F, 0.0F }; Vec2< float > position { 0.0F, 0.0F }; float z { 0.0F }; std::array< bool, NUM_MOUSE_BUTTONS > pressed { false }; std::array< bool, NUM_MOUSE_BUTTONS > released { false }; std::array< bool, NUM_MOUSE_BUTTONS > down { false };} MouseState
Mouse state stores the current state of the mouse. It is updated by the core.
Definition input.h:305
ControllerAxis
Mappings from SDL game controller axes to ASW axes.
Definition input.h:432
void _mouse_motion(float x, float y, float delta_x, float delta_y)
Mouse motion hook.
Definition input.cpp:257
void _key_down(SDL_Scancode scancode)
Key down hook.
Definition input.cpp:227
void info(const std::string &message)
Log an info message.
Definition log.cpp:168
void warn(const std::string &message)
Log a warning message.
Definition log.cpp:173