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
core.cpp
Go to the documentation of this file.
2
3#include <SDL3/SDL.h>
4#include <SDL3_mixer/SDL_mixer.h>
5#include <SDL3_ttf/SDL_ttf.h>
6#include <algorithm>
7#include <format>
8
12#include "./asw/modules/input.h"
13#include "./asw/modules/log.h"
14#include "./asw/modules/sound.h"
15#include "./asw/modules/util.h"
16
17namespace {
18bool exiting = false;
19}
20
22{
24
25 SDL_Event e;
26
27 while (SDL_PollEvent(&e)) {
28 switch (e.type) {
29 case SDL_EVENT_WINDOW_RESIZED: {
31 if (r == nullptr) {
32 break;
33 }
34
35 // Maintain aspect ratio
36 SDL_Point window_size;
37 SDL_GetRenderOutputSize(r, &window_size.x, &window_size.y);
38
39 SDL_Point render_size;
40 SDL_GetRenderLogicalPresentation(r, &render_size.x, &render_size.y, nullptr);
41
42 const auto x_scale
43 = static_cast<float>(window_size.x) / static_cast<float>(render_size.x);
44
45 const auto y_scale
46 = static_cast<float>(window_size.y) / static_cast<float>(render_size.y);
47
48 const auto scale = std::min(x_scale, y_scale);
49
50 SDL_SetWindowSize(asw::display::get_window(),
51 static_cast<int>(static_cast<float>(render_size.x) * scale),
52 static_cast<int>(static_cast<float>(render_size.y) * scale));
53 break;
54 }
55
56 case SDL_EVENT_KEY_DOWN: {
57 if (!e.key.repeat) {
58 asw::input::_key_down(e.key.scancode);
59 }
60 break;
61 }
62
63 case SDL_EVENT_KEY_UP: {
64 if (!e.key.repeat) {
65 asw::input::_key_up(e.key.scancode);
66 }
67 break;
68 }
69
70 case SDL_EVENT_MOUSE_BUTTON_DOWN: {
71 asw::input::_mouse_button_down(e.button.button);
72 break;
73 }
74
75 case SDL_EVENT_MOUSE_BUTTON_UP: {
76 asw::input::_mouse_button_up(e.button.button);
77 break;
78 }
79
80 case SDL_EVENT_MOUSE_MOTION: {
81 // Ensure scale is applied to mouse coordinates
83 if (r != nullptr) {
84 SDL_ConvertEventToRenderCoordinates(r, &e);
85 }
86
87 asw::input::_mouse_motion(e.motion.x, e.motion.y, e.motion.xrel, e.motion.yrel);
88 break;
89 }
90
91 case SDL_EVENT_MOUSE_WHEEL: {
92 asw::input::_mouse_wheel(e.wheel.y);
93 break;
94 }
95
96 case SDL_EVENT_GAMEPAD_AXIS_MOTION: {
97 asw::input::_controller_axis_motion(e.gaxis.which, e.gaxis.axis, e.gaxis.value);
98 break;
99 }
100
101 case SDL_EVENT_GAMEPAD_BUTTON_DOWN: {
102 asw::input::_controller_button_down(e.gbutton.which, e.gbutton.button);
103 break;
104 }
105
106 case SDL_EVENT_GAMEPAD_BUTTON_UP: {
107 asw::input::_controller_button_up(e.gbutton.which, e.gbutton.button);
108 break;
109 }
110
111 case SDL_EVENT_GAMEPAD_ADDED: {
112 asw::input::_controller_added(e.gdevice.which);
113 break;
114 }
115
116 case SDL_EVENT_GAMEPAD_REMOVED: {
117 asw::input::_controller_removed(e.gdevice.which);
118 break;
119 }
120
121 case SDL_EVENT_TEXT_INPUT: {
122 asw::input::_append_text(e.text.text);
123 break;
124 }
125
126 case SDL_EVENT_QUIT: {
127 exit();
128 }
129
130 default:
131 break;
132 }
133 }
134}
135
136void asw::core::init(int width, int height, int scale)
137{
138 if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMEPAD)) {
139 asw::util::abort_on_error("SDL_Init");
140 }
141
142 if (!TTF_Init()) {
143 asw::util::abort_on_error("TTF_Init");
144 }
145
146 if (!asw::sound::_init()) {
147 asw::util::abort_on_error("Sound initialization failed");
148 }
149
150 asw::display::_init(width, height, scale);
151}
152
153void asw::core::init_opengl(int width, int height, int scale)
154{
155 if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMEPAD)) {
156 asw::util::abort_on_error("SDL_Init");
157 }
158
159 if (!TTF_Init()) {
160 asw::util::abort_on_error("TTF_Init");
161 }
162
163 if (!asw::sound::_init()) {
164 asw::util::abort_on_error("Sound initialization failed");
165 }
166
167 // --- Set GL attributes before creating the window ---
168 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); // Request OpenGL 3.x
169 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
170 SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
171 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
172
173 asw::display::_init_opengl(width, height, scale);
174}
175
177{
178 asw::log::info("ASW Info");
179 asw::log::info("========");
180
181 const char* renderer_name = "none";
182 if (auto* r = asw::display::get_renderer(); r != nullptr) {
183 renderer_name = SDL_GetRendererName(r);
184 }
185
187 "SDL Version: {}.{}.{}", SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_MICRO_VERSION);
188 asw::log::info("Renderer: {}", renderer_name);
189}
190
192{
193 exiting = true;
194}
195
197{
199
200 // Clear asset caches while SDL resources are still valid — SDL_Destroy*
201 // calls in the shared_ptr deleters are safe at this point.
203
204 // _shutdown() nulls the renderer/window pointers BEFORE calling
205 // SDL_DestroyRenderer/SDL_DestroyWindow. Any outstanding shared_ptr<SDL_Texture>
206 // held by user code will see a null renderer in their deleter and skip the
207 // SDL_DestroyTexture call, preventing use-after-free.
209
210 // Same pattern for sound: null mixer pointer before teardown so any
211 // surviving Sample/Music shared_ptrs become no-ops.
213
214 TTF_Quit();
215 SDL_Quit();
216}
217
219{
220 return exiting;
221}
Action binding system for the ASW library.
Asset routines for the ASW library.
Core routines including main loop and initialization.
Display and window routines for the ASW library.
Input module for the ASW library.
Structured logging system.
void clear_all()
Clear all cached assets. This will remove all cached textures, fonts, samples, and music.
Definition assets.cpp:237
void exit()
Exit the application. Sets exiting flag to true, which will cause the main loop to exit on the next u...
Definition core.cpp:191
void print_info()
Prints information about the core module.
Definition core.cpp:176
void init_opengl(int width, int height, int scale=1)
Initializes the core module for opengl.
Definition core.cpp:153
void shutdown()
Cleanup resources used by the core module. Should be called on application exit.
Definition core.cpp:196
void init(int width, int height, int scale=1)
Initializes the core module.
Definition core.cpp:136
void update()
Updates core module functionality.
Definition core.cpp:21
bool is_exiting()
Return exiting status.
Definition core.cpp:218
void _init_opengl(int width, int height, int scale)
Initialize the display module with OpenGL support. Called by asw::core::init().
Definition display.cpp:29
void _shutdown()
Shut down the display module. Called by asw::core::shutdown(). Nulls the renderer and window pointers...
Definition display.cpp:47
asw::Renderer * get_renderer()
Get the SDL renderer.
Definition display.cpp:62
asw::Window * get_window()
Get the SDL window.
Definition display.cpp:67
void _init(int width, int height, int scale)
Initialize the display module. Called by asw::core::init().
Definition display.cpp:15
void _mouse_button_up(uint8_t button)
Mouse button up hook.
Definition input.cpp:250
void _mouse_button_down(uint8_t button)
Mouse button down hook.
Definition input.cpp:241
void _key_up(SDL_Scancode scancode)
Key up hook.
Definition input.cpp:235
void _controller_removed(SDL_JoystickID id)
Controller removed hook.
Definition input.cpp:291
void reset()
Reset all input states. Called by the core.
Definition input.cpp:61
void _mouse_wheel(float delta_z)
Mouse wheel hook.
Definition input.cpp:265
void clear_actions()
Remove all registered actions and their bindings.
Definition action.cpp:136
void _controller_axis_motion(SDL_JoystickID id, uint32_t axis, float value)
Axis moved hook.
Definition input.cpp:309
void _controller_added(SDL_JoystickID id)
Controller added hook.
Definition input.cpp:270
void _append_text(const char *text)
Event Hooks.
Definition input.cpp:56
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
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 _shutdown()
Shut down the sound module. Called automatically by asw::core::shutdown().
Definition sound.cpp:48
bool _init()
Initialize the sound module. Called automatically by asw::core::init().
Definition sound.cpp:58
void abort_on_error(const std::string &message)
Abort program and display error message.
Definition util.cpp:8
Sound module for the ASW library.
General utility functions.