yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
sdl_compat.h
Go to the documentation of this file.
1#ifndef YAZE_APP_PLATFORM_SDL_COMPAT_H_
2#define YAZE_APP_PLATFORM_SDL_COMPAT_H_
3
13#ifdef YAZE_USE_SDL3
14#include <SDL3/SDL.h>
15#include <SDL3/SDL_gamepad.h>
16#else
17#include <SDL.h>
18#endif
19
20namespace yaze {
21namespace platform {
22
23// ============================================================================
24// Type Aliases
25// ============================================================================
26
27#ifdef YAZE_USE_SDL3
28// SDL3 uses bool* for keyboard state
29using KeyboardState = const bool*;
30#else
31// SDL2 uses Uint8* for keyboard state
32using KeyboardState = const Uint8*;
33#endif
34
35// ============================================================================
36// Event Type Constants
37// ============================================================================
38
39#ifdef YAZE_USE_SDL3
40constexpr auto kEventKeyDown = SDL_EVENT_KEY_DOWN;
41constexpr auto kEventKeyUp = SDL_EVENT_KEY_UP;
42constexpr auto kEventMouseMotion = SDL_EVENT_MOUSE_MOTION;
43constexpr auto kEventMouseButtonDown = SDL_EVENT_MOUSE_BUTTON_DOWN;
44constexpr auto kEventMouseButtonUp = SDL_EVENT_MOUSE_BUTTON_UP;
45constexpr auto kEventMouseWheel = SDL_EVENT_MOUSE_WHEEL;
46constexpr auto kEventQuit = SDL_EVENT_QUIT;
47constexpr auto kEventDropFile = SDL_EVENT_DROP_FILE;
48constexpr auto kEventWindowCloseRequested = SDL_EVENT_WINDOW_CLOSE_REQUESTED;
49constexpr auto kEventWindowResized = SDL_EVENT_WINDOW_RESIZED;
50constexpr auto kEventGamepadAdded = SDL_EVENT_GAMEPAD_ADDED;
51constexpr auto kEventGamepadRemoved = SDL_EVENT_GAMEPAD_REMOVED;
52#else
53constexpr auto kEventKeyDown = SDL_KEYDOWN;
54constexpr auto kEventKeyUp = SDL_KEYUP;
55constexpr auto kEventMouseMotion = SDL_MOUSEMOTION;
56constexpr auto kEventMouseButtonDown = SDL_MOUSEBUTTONDOWN;
57constexpr auto kEventMouseButtonUp = SDL_MOUSEBUTTONUP;
58constexpr auto kEventMouseWheel = SDL_MOUSEWHEEL;
59constexpr auto kEventQuit = SDL_QUIT;
60constexpr auto kEventDropFile = SDL_DROPFILE;
61// SDL2 uses SDL_WINDOWEVENT with sub-types, not individual events
62// These are handled specially in window code
63constexpr auto kEventWindowEvent = SDL_WINDOWEVENT;
64constexpr auto kEventControllerDeviceAdded = SDL_CONTROLLERDEVICEADDED;
65constexpr auto kEventControllerDeviceRemoved = SDL_CONTROLLERDEVICEREMOVED;
66#endif
67
68// ============================================================================
69// Key Constants
70// ============================================================================
71
72#ifdef YAZE_USE_SDL3
73#include <SDL3/SDL_keycode.h>
74
75constexpr auto kKeyA = 'a';
76constexpr auto kKeyB = 'b';
77constexpr auto kKeyC = 'c';
78constexpr auto kKeyD = 'd';
79constexpr auto kKeyS = 's';
80constexpr auto kKeyX = 'x';
81constexpr auto kKeyY = 'y';
82constexpr auto kKeyZ = 'z';
83constexpr auto kKeyReturn = SDLK_RETURN;
84constexpr auto kKeyRShift = SDLK_RSHIFT;
85constexpr auto kKeyUp = SDLK_UP;
86constexpr auto kKeyDown = SDLK_DOWN;
87constexpr auto kKeyLeft = SDLK_LEFT;
88constexpr auto kKeyRight = SDLK_RIGHT;
89#else
90constexpr auto kKeyA = SDLK_a;
91constexpr auto kKeyB = SDLK_b;
92constexpr auto kKeyC = SDLK_c;
93constexpr auto kKeyD = SDLK_d;
94constexpr auto kKeyS = SDLK_s;
95constexpr auto kKeyX = SDLK_x;
96constexpr auto kKeyY = SDLK_y;
97constexpr auto kKeyZ = SDLK_z;
98constexpr auto kKeyReturn = SDLK_RETURN;
99constexpr auto kKeyRShift = SDLK_RSHIFT;
100constexpr auto kKeyUp = SDLK_UP;
101constexpr auto kKeyDown = SDLK_DOWN;
102constexpr auto kKeyLeft = SDLK_LEFT;
103constexpr auto kKeyRight = SDLK_RIGHT;
104#endif
105
106// ============================================================================
107// Keyboard Helpers
108// ============================================================================
109
115inline SDL_Keycode GetKeyFromEvent(const SDL_Event& event) {
116#ifdef YAZE_USE_SDL3
117 return event.key.key;
118#else
119 return event.key.keysym.sym;
120#endif
121}
122
128inline SDL_Scancode GetScancodeFromKey(SDL_Keycode key) {
129#ifdef YAZE_USE_SDL3
130 return SDL_GetScancodeFromKey(key, nullptr);
131#else
132 return SDL_GetScancodeFromKey(key);
133#endif
134}
135
142inline bool IsKeyPressed(KeyboardState state, SDL_Scancode scancode) {
143#ifdef YAZE_USE_SDL3
144 // SDL3 returns bool*
145 return state[scancode];
146#else
147 // SDL2 returns Uint8*, non-zero means pressed
148 return state[scancode] != 0;
149#endif
150}
151
152// ============================================================================
153// Gamepad/Controller Helpers
154// ============================================================================
155
156#ifdef YAZE_USE_SDL3
157// SDL3 uses SDL_Gamepad instead of SDL_GameController
158using GamepadHandle = SDL_Gamepad*;
159
160inline GamepadHandle OpenGamepad(int index) {
161 SDL_JoystickID* joysticks = SDL_GetGamepads(nullptr);
162 if (joysticks && index < 4) {
163 SDL_JoystickID id = joysticks[index];
164 SDL_free(joysticks);
165 return SDL_OpenGamepad(id);
166 }
167 if (joysticks) SDL_free(joysticks);
168 return nullptr;
169}
170
171inline void CloseGamepad(GamepadHandle gamepad) {
172 if (gamepad) SDL_CloseGamepad(gamepad);
173}
174
175inline bool GetGamepadButton(GamepadHandle gamepad, SDL_GamepadButton button) {
176 return SDL_GetGamepadButton(gamepad, button);
177}
178
179inline int16_t GetGamepadAxis(GamepadHandle gamepad, SDL_GamepadAxis axis) {
180 return SDL_GetGamepadAxis(gamepad, axis);
181}
182
183inline bool IsGamepadConnected(int index) {
184 int count = 0;
185 SDL_JoystickID* joysticks = SDL_GetGamepads(&count);
186 if (joysticks) {
187 SDL_free(joysticks);
188 }
189 return index < count;
190}
191#else
192// SDL2 uses SDL_GameController
193using GamepadHandle = SDL_GameController*;
194
195inline GamepadHandle OpenGamepad(int index) {
196 if (SDL_IsGameController(index)) {
197 return SDL_GameControllerOpen(index);
198 }
199 return nullptr;
200}
201
202inline void CloseGamepad(GamepadHandle gamepad) {
203 if (gamepad) SDL_GameControllerClose(gamepad);
204}
205
206inline bool GetGamepadButton(GamepadHandle gamepad,
207 SDL_GameControllerButton button) {
208 return SDL_GameControllerGetButton(gamepad, button) != 0;
209}
210
211inline int16_t GetGamepadAxis(GamepadHandle gamepad,
212 SDL_GameControllerAxis axis) {
213 return SDL_GameControllerGetAxis(gamepad, axis);
214}
215
216inline bool IsGamepadConnected(int index) {
217 return SDL_IsGameController(index);
218}
219#endif
220
221// ============================================================================
222// Button/Axis Type Aliases
223// ============================================================================
224
225#ifdef YAZE_USE_SDL3
226using GamepadButton = SDL_GamepadButton;
227using GamepadAxis = SDL_GamepadAxis;
228
229constexpr auto kGamepadButtonA = SDL_GAMEPAD_BUTTON_SOUTH;
230constexpr auto kGamepadButtonB = SDL_GAMEPAD_BUTTON_EAST;
231constexpr auto kGamepadButtonX = SDL_GAMEPAD_BUTTON_WEST;
232constexpr auto kGamepadButtonY = SDL_GAMEPAD_BUTTON_NORTH;
233constexpr auto kGamepadButtonBack = SDL_GAMEPAD_BUTTON_BACK;
234constexpr auto kGamepadButtonStart = SDL_GAMEPAD_BUTTON_START;
235constexpr auto kGamepadButtonLeftShoulder = SDL_GAMEPAD_BUTTON_LEFT_SHOULDER;
236constexpr auto kGamepadButtonRightShoulder = SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER;
237constexpr auto kGamepadButtonDpadUp = SDL_GAMEPAD_BUTTON_DPAD_UP;
238constexpr auto kGamepadButtonDpadDown = SDL_GAMEPAD_BUTTON_DPAD_DOWN;
239constexpr auto kGamepadButtonDpadLeft = SDL_GAMEPAD_BUTTON_DPAD_LEFT;
240constexpr auto kGamepadButtonDpadRight = SDL_GAMEPAD_BUTTON_DPAD_RIGHT;
241
242constexpr auto kGamepadAxisLeftX = SDL_GAMEPAD_AXIS_LEFTX;
243constexpr auto kGamepadAxisLeftY = SDL_GAMEPAD_AXIS_LEFTY;
244#else
245using GamepadButton = SDL_GameControllerButton;
246using GamepadAxis = SDL_GameControllerAxis;
247
248constexpr auto kGamepadButtonA = SDL_CONTROLLER_BUTTON_A;
249constexpr auto kGamepadButtonB = SDL_CONTROLLER_BUTTON_B;
250constexpr auto kGamepadButtonX = SDL_CONTROLLER_BUTTON_X;
251constexpr auto kGamepadButtonY = SDL_CONTROLLER_BUTTON_Y;
252constexpr auto kGamepadButtonBack = SDL_CONTROLLER_BUTTON_BACK;
253constexpr auto kGamepadButtonStart = SDL_CONTROLLER_BUTTON_START;
254constexpr auto kGamepadButtonLeftShoulder = SDL_CONTROLLER_BUTTON_LEFTSHOULDER;
255constexpr auto kGamepadButtonRightShoulder = SDL_CONTROLLER_BUTTON_RIGHTSHOULDER;
256constexpr auto kGamepadButtonDpadUp = SDL_CONTROLLER_BUTTON_DPAD_UP;
257constexpr auto kGamepadButtonDpadDown = SDL_CONTROLLER_BUTTON_DPAD_DOWN;
258constexpr auto kGamepadButtonDpadLeft = SDL_CONTROLLER_BUTTON_DPAD_LEFT;
259constexpr auto kGamepadButtonDpadRight = SDL_CONTROLLER_BUTTON_DPAD_RIGHT;
260
261constexpr auto kGamepadAxisLeftX = SDL_CONTROLLER_AXIS_LEFTX;
262constexpr auto kGamepadAxisLeftY = SDL_CONTROLLER_AXIS_LEFTY;
263#endif
264
265// ============================================================================
266// Renderer Helpers
267// ============================================================================
268
275inline SDL_Renderer* CreateRenderer(SDL_Window* window) {
276#ifdef YAZE_USE_SDL3
277 return SDL_CreateRenderer(window, nullptr);
278#else
279 return SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
280#endif
281}
282
289inline void SetRenderVSync(SDL_Renderer* renderer, int interval) {
290#ifdef YAZE_USE_SDL3
291 SDL_SetRenderVSync(renderer, interval);
292#else
293 // SDL2 sets vsync at creation time, this is a no-op
294 (void)renderer;
295 (void)interval;
296#endif
297}
298
307inline bool RenderTexture(SDL_Renderer* renderer, SDL_Texture* texture,
308 const SDL_Rect* srcrect, const SDL_Rect* dstrect) {
309#ifdef YAZE_USE_SDL3
310 SDL_FRect src_frect, dst_frect;
311 SDL_FRect* src_ptr = nullptr;
312 SDL_FRect* dst_ptr = nullptr;
313
314 if (srcrect) {
315 src_frect.x = static_cast<float>(srcrect->x);
316 src_frect.y = static_cast<float>(srcrect->y);
317 src_frect.w = static_cast<float>(srcrect->w);
318 src_frect.h = static_cast<float>(srcrect->h);
319 src_ptr = &src_frect;
320 }
321
322 if (dstrect) {
323 dst_frect.x = static_cast<float>(dstrect->x);
324 dst_frect.y = static_cast<float>(dstrect->y);
325 dst_frect.w = static_cast<float>(dstrect->w);
326 dst_frect.h = static_cast<float>(dstrect->h);
327 dst_ptr = &dst_frect;
328 }
329
330 return SDL_RenderTexture(renderer, texture, src_ptr, dst_ptr);
331#else
332 return SDL_RenderCopy(renderer, texture, srcrect, dstrect) == 0;
333#endif
334}
335
336// ============================================================================
337// Surface Helpers
338// ============================================================================
339
346inline void FreeSurface(SDL_Surface* surface) {
347 if (!surface) return;
348#ifdef YAZE_USE_SDL3
349 SDL_DestroySurface(surface);
350#else
351 SDL_FreeSurface(surface);
352#endif
353}
354
361inline SDL_Surface* ConvertSurfaceFormat(SDL_Surface* surface, uint32_t format,
362 uint32_t flags = 0) {
363 if (!surface) return nullptr;
364#ifdef YAZE_USE_SDL3
365 (void)flags; // SDL3 removed flags parameter
366 return SDL_ConvertSurface(surface, static_cast<SDL_PixelFormat>(format));
367#else
368 return SDL_ConvertSurfaceFormat(surface, format, flags);
369#endif
370}
371
375inline SDL_Palette* GetSurfacePalette(SDL_Surface* surface) {
376 if (!surface) return nullptr;
377#ifdef YAZE_USE_SDL3
378 return SDL_GetSurfacePalette(surface);
379#else
380 return surface->format ? surface->format->palette : nullptr;
381#endif
382}
383
390inline Uint32 GetSurfaceFormat(SDL_Surface* surface) {
391#ifdef YAZE_USE_SDL3
392 return surface ? static_cast<Uint32>(surface->format) : SDL_PIXELFORMAT_UNKNOWN;
393#else
394 return (surface && surface->format) ? surface->format->format
395 : SDL_PIXELFORMAT_UNKNOWN;
396#endif
397}
398
402inline Uint32 MapRGB(SDL_Surface* surface, Uint8 r, Uint8 g, Uint8 b) {
403 if (!surface) return 0;
404#ifdef YAZE_USE_SDL3
405 const SDL_PixelFormatDetails* details =
406 SDL_GetPixelFormatDetails(surface->format);
407 if (!details) return 0;
408 SDL_Palette* palette = SDL_GetSurfacePalette(surface);
409 return SDL_MapRGB(details, palette, r, g, b);
410#else
411 return SDL_MapRGB(surface->format, r, g, b);
412#endif
413}
414
418inline SDL_Surface* CreateSurface(int width, int height, int depth,
419 uint32_t format) {
420#ifdef YAZE_USE_SDL3
421 (void)depth; // SDL3 infers depth from format
422 return SDL_CreateSurface(width, height, static_cast<SDL_PixelFormat>(format));
423#else
424 return SDL_CreateRGBSurfaceWithFormat(0, width, height, depth, format);
425#endif
426}
427
434inline int GetSurfaceBitsPerPixel(SDL_Surface* surface) {
435 if (!surface) return 0;
436#ifdef YAZE_USE_SDL3
437 const SDL_PixelFormatDetails* details =
438 SDL_GetPixelFormatDetails(surface->format);
439 return details ? details->bits_per_pixel : 0;
440#else
441 return surface->format ? surface->format->BitsPerPixel : 0;
442#endif
443}
444
454inline bool EnsureSurfacePalette256(SDL_Surface* surface) {
455 if (!surface) return false;
456
457 SDL_Palette* existing = GetSurfacePalette(surface);
458 if (existing && existing->ncolors >= 256) {
459 return true; // Already has proper palette
460 }
461
462 // Check if this is an indexed format that needs a palette
463 int bpp = GetSurfaceBitsPerPixel(surface);
464 if (bpp != 8) {
465 return true; // Not an indexed format, no palette needed
466 }
467
468 // Create a new 256-color palette (SDL2: SDL_AllocPalette, SDL3: SDL_CreatePalette)
469#ifdef YAZE_USE_SDL3
470 SDL_Palette* new_palette = SDL_CreatePalette(256);
471#else
472 SDL_Palette* new_palette = SDL_AllocPalette(256);
473#endif
474 if (!new_palette) {
475 SDL_Log("Warning: Failed to create 256-color palette: %s", SDL_GetError());
476 return false;
477 }
478
479 // Initialize with grayscale as a safe default
480 SDL_Color colors[256];
481 for (int i = 0; i < 256; i++) {
482 colors[i].r = colors[i].g = colors[i].b = static_cast<Uint8>(i);
483 colors[i].a = 255;
484 }
485 SDL_SetPaletteColors(new_palette, colors, 0, 256);
486
487 // Attach to surface
488 if (SDL_SetSurfacePalette(surface, new_palette) != 0) {
489 SDL_Log("Warning: Failed to set surface palette: %s", SDL_GetError());
490#ifdef YAZE_USE_SDL3
491 SDL_DestroyPalette(new_palette);
492#else
493 SDL_FreePalette(new_palette);
494#endif
495 return false;
496 }
497
498 return true;
499}
500
507inline int GetSurfaceBytesPerPixel(SDL_Surface* surface) {
508 if (!surface) return 0;
509#ifdef YAZE_USE_SDL3
510 const SDL_PixelFormatDetails* details =
511 SDL_GetPixelFormatDetails(surface->format);
512 return details ? details->bytes_per_pixel : 0;
513#else
514 return surface->format ? surface->format->BytesPerPixel : 0;
515#endif
516}
517
518// ============================================================================
519// Window Event Compatibility Macros
520// These macros allow code to handle window events consistently across SDL2/SDL3
521// ============================================================================
522
523#ifdef YAZE_USE_SDL3
524
525// SDL3 has individual window events at the top level
526#define YAZE_SDL_QUIT SDL_EVENT_QUIT
527#define YAZE_SDL_WINDOWEVENT 0 // Placeholder - SDL3 has no combined event
528
529// SDL3 window events are individual event types
530#define YAZE_SDL_WINDOW_CLOSE SDL_EVENT_WINDOW_CLOSE_REQUESTED
531#define YAZE_SDL_WINDOW_RESIZED SDL_EVENT_WINDOW_RESIZED
532#define YAZE_SDL_WINDOW_SIZE_CHANGED SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED
533#define YAZE_SDL_WINDOW_MINIMIZED SDL_EVENT_WINDOW_MINIMIZED
534#define YAZE_SDL_WINDOW_MAXIMIZED SDL_EVENT_WINDOW_MAXIMIZED
535#define YAZE_SDL_WINDOW_RESTORED SDL_EVENT_WINDOW_RESTORED
536#define YAZE_SDL_WINDOW_SHOWN SDL_EVENT_WINDOW_SHOWN
537#define YAZE_SDL_WINDOW_HIDDEN SDL_EVENT_WINDOW_HIDDEN
538#define YAZE_SDL_WINDOW_EXPOSED SDL_EVENT_WINDOW_EXPOSED
539#define YAZE_SDL_WINDOW_FOCUS_GAINED SDL_EVENT_WINDOW_FOCUS_GAINED
540#define YAZE_SDL_WINDOW_FOCUS_LOST SDL_EVENT_WINDOW_FOCUS_LOST
541
542// SDL3 has no nested window events
543#define YAZE_SDL_HAS_INDIVIDUAL_WINDOW_EVENTS 1
544
545#else // SDL2
546
547// SDL2 event types
548#define YAZE_SDL_QUIT SDL_QUIT
549#define YAZE_SDL_WINDOWEVENT SDL_WINDOWEVENT
550
551// SDL2 window events are nested under SDL_WINDOWEVENT
552#define YAZE_SDL_WINDOW_CLOSE SDL_WINDOWEVENT_CLOSE
553#define YAZE_SDL_WINDOW_RESIZED SDL_WINDOWEVENT_RESIZED
554#define YAZE_SDL_WINDOW_SIZE_CHANGED SDL_WINDOWEVENT_SIZE_CHANGED
555#define YAZE_SDL_WINDOW_MINIMIZED SDL_WINDOWEVENT_MINIMIZED
556#define YAZE_SDL_WINDOW_MAXIMIZED SDL_WINDOWEVENT_MAXIMIZED
557#define YAZE_SDL_WINDOW_RESTORED SDL_WINDOWEVENT_RESTORED
558#define YAZE_SDL_WINDOW_SHOWN SDL_WINDOWEVENT_SHOWN
559#define YAZE_SDL_WINDOW_HIDDEN SDL_WINDOWEVENT_HIDDEN
560#define YAZE_SDL_WINDOW_EXPOSED SDL_WINDOWEVENT_EXPOSED
561#define YAZE_SDL_WINDOW_FOCUS_GAINED SDL_WINDOWEVENT_FOCUS_GAINED
562#define YAZE_SDL_WINDOW_FOCUS_LOST SDL_WINDOWEVENT_FOCUS_LOST
563
564// SDL2 uses nested window events
565#define YAZE_SDL_HAS_INDIVIDUAL_WINDOW_EVENTS 0
566
567#endif // YAZE_USE_SDL3
568
569// ============================================================================
570// Window Event Helper Functions
571// ============================================================================
572
577inline bool IsWindowCloseEvent(const SDL_Event& event) {
578#ifdef YAZE_USE_SDL3
579 return event.type == SDL_EVENT_WINDOW_CLOSE_REQUESTED;
580#else
581 return event.type == SDL_WINDOWEVENT &&
582 event.window.event == SDL_WINDOWEVENT_CLOSE;
583#endif
584}
585
589inline bool IsWindowResizeEvent(const SDL_Event& event) {
590#ifdef YAZE_USE_SDL3
591 return event.type == SDL_EVENT_WINDOW_RESIZED ||
592 event.type == SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED;
593#else
594 return event.type == SDL_WINDOWEVENT &&
595 (event.window.event == SDL_WINDOWEVENT_RESIZED ||
596 event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED);
597#endif
598}
599
603inline bool IsWindowMinimizedEvent(const SDL_Event& event) {
604#ifdef YAZE_USE_SDL3
605 return event.type == SDL_EVENT_WINDOW_MINIMIZED;
606#else
607 return event.type == SDL_WINDOWEVENT &&
608 event.window.event == SDL_WINDOWEVENT_MINIMIZED;
609#endif
610}
611
615inline bool IsWindowRestoredEvent(const SDL_Event& event) {
616#ifdef YAZE_USE_SDL3
617 return event.type == SDL_EVENT_WINDOW_RESTORED;
618#else
619 return event.type == SDL_WINDOWEVENT &&
620 event.window.event == SDL_WINDOWEVENT_RESTORED;
621#endif
622}
623
627inline int GetWindowEventWidth(const SDL_Event& event) {
628 return event.window.data1;
629}
630
634inline int GetWindowEventHeight(const SDL_Event& event) {
635 return event.window.data2;
636}
637
638// ============================================================================
639// Initialization Helpers
640// ============================================================================
641
648inline bool InitSucceeded(int result) {
649#ifdef YAZE_USE_SDL3
650 // SDL3 returns bool (non-zero for success)
651 return result != 0;
652#else
653 // SDL2 returns 0 for success
654 return result == 0;
655#endif
656}
657
663inline uint32_t GetDefaultInitFlags() {
664#ifdef YAZE_USE_SDL3
665 return SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_EVENTS;
666#else
667 return SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER | SDL_INIT_EVENTS;
668#endif
669}
670
671// ============================================================================
672// Surface Helpers
673// ============================================================================
674
678inline SDL_Surface* CreateRGBSurface(Uint32 flags, int width, int height, int depth,
679 Uint32 Rmask, Uint32 Gmask, Uint32 Bmask,
680 Uint32 Amask) {
681#ifdef YAZE_USE_SDL3
682 // SDL3 uses SDL_CreateSurface with pixel format
683 return SDL_CreateSurface(width, height,
684 SDL_GetPixelFormatForMasks(depth, Rmask, Gmask, Bmask, Amask));
685#else
686 return SDL_CreateRGBSurface(flags, width, height, depth, Rmask, Gmask, Bmask,
687 Amask);
688#endif
689}
690
694inline void DestroySurface(SDL_Surface* surface) {
695#ifdef YAZE_USE_SDL3
696 SDL_DestroySurface(surface);
697#else
698 SDL_FreeSurface(surface);
699#endif
700}
701
702// ============================================================================
703// Renderer Helpers
704// ============================================================================
705
709inline int GetRendererOutputSize(SDL_Renderer* renderer, int* w, int* h) {
710#ifdef YAZE_USE_SDL3
711 return SDL_GetCurrentRenderOutputSize(renderer, w, h);
712#else
713 return SDL_GetRendererOutputSize(renderer, w, h);
714#endif
715}
716
723inline SDL_Surface* ReadPixelsToSurface(SDL_Renderer* renderer, int width,
724 int height, const SDL_Rect* rect) {
725#ifdef YAZE_USE_SDL3
726 return SDL_RenderReadPixels(renderer, rect);
727#else
728 // Create surface to read into (ARGB8888 to match typical screenshot needs)
729 SDL_Surface* surface = SDL_CreateRGBSurface(0, width, height, 32, 0x00FF0000,
730 0x0000FF00, 0x000000FF, 0xFF000000);
731 if (!surface) return nullptr;
732
733 if (SDL_RenderReadPixels(renderer, rect, SDL_PIXELFORMAT_ARGB8888,
734 surface->pixels, surface->pitch) != 0) {
735 SDL_FreeSurface(surface);
736 return nullptr;
737 }
738 return surface;
739#endif
740}
741
742
743
747inline SDL_Surface* LoadBMP(const char* file) {
748#ifdef YAZE_USE_SDL3
749 return SDL_LoadBMP(file);
750#else
751 return SDL_LoadBMP(file);
752#endif
753}
754
755} // namespace platform
756} // namespace yaze
757
758#endif // YAZE_APP_PLATFORM_SDL_COMPAT_H_
constexpr auto kKeyB
Definition sdl_compat.h:91
constexpr auto kGamepadButtonA
Definition sdl_compat.h:248
constexpr auto kEventKeyDown
Definition sdl_compat.h:53
constexpr auto kEventMouseButtonUp
Definition sdl_compat.h:57
constexpr auto kEventDropFile
Definition sdl_compat.h:60
SDL_Scancode GetScancodeFromKey(SDL_Keycode key)
Get scancode from keycode.
Definition sdl_compat.h:128
void DestroySurface(SDL_Surface *surface)
Destroy a surface.
Definition sdl_compat.h:694
int GetWindowEventWidth(const SDL_Event &event)
Get window width from resize event data.
Definition sdl_compat.h:627
constexpr auto kEventControllerDeviceAdded
Definition sdl_compat.h:64
SDL_Surface * ConvertSurfaceFormat(SDL_Surface *surface, uint32_t format, uint32_t flags=0)
Convert a surface to a specific pixel format.
Definition sdl_compat.h:361
constexpr auto kGamepadButtonLeftShoulder
Definition sdl_compat.h:254
constexpr auto kKeyX
Definition sdl_compat.h:95
int GetRendererOutputSize(SDL_Renderer *renderer, int *w, int *h)
Get renderer output size.
Definition sdl_compat.h:709
Uint32 GetSurfaceFormat(SDL_Surface *surface)
Get the pixel format of a surface as Uint32.
Definition sdl_compat.h:390
constexpr auto kKeyC
Definition sdl_compat.h:92
bool IsWindowRestoredEvent(const SDL_Event &event)
Check if an event is a window restore event.
Definition sdl_compat.h:615
int GetSurfaceBitsPerPixel(SDL_Surface *surface)
Get bits per pixel from a surface.
Definition sdl_compat.h:434
int GetSurfaceBytesPerPixel(SDL_Surface *surface)
Get bytes per pixel from a surface.
Definition sdl_compat.h:507
constexpr auto kKeyRShift
Definition sdl_compat.h:99
constexpr auto kEventMouseMotion
Definition sdl_compat.h:55
constexpr auto kEventQuit
Definition sdl_compat.h:59
int16_t GetGamepadAxis(GamepadHandle gamepad, SDL_GameControllerAxis axis)
Definition sdl_compat.h:211
constexpr auto kGamepadAxisLeftY
Definition sdl_compat.h:262
constexpr auto kEventMouseWheel
Definition sdl_compat.h:58
constexpr auto kEventWindowEvent
Definition sdl_compat.h:63
bool IsWindowMinimizedEvent(const SDL_Event &event)
Check if an event is a window minimize event.
Definition sdl_compat.h:603
constexpr auto kGamepadButtonDpadDown
Definition sdl_compat.h:257
SDL_Surface * CreateRGBSurface(Uint32 flags, int width, int height, int depth, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask)
Create an RGB surface.
Definition sdl_compat.h:678
bool InitSucceeded(int result)
Check if SDL initialization succeeded.
Definition sdl_compat.h:648
bool IsWindowCloseEvent(const SDL_Event &event)
Check if an event is a window close event Works correctly for both SDL2 (nested) and SDL3 (individual...
Definition sdl_compat.h:577
SDL_Renderer * CreateRenderer(SDL_Window *window)
Create a renderer with default settings.
Definition sdl_compat.h:275
constexpr auto kEventMouseButtonDown
Definition sdl_compat.h:56
SDL_Surface * LoadBMP(const char *file)
Load a BMP file.
Definition sdl_compat.h:747
constexpr auto kGamepadAxisLeftX
Definition sdl_compat.h:261
SDL_GameController * GamepadHandle
Definition sdl_compat.h:193
constexpr auto kGamepadButtonDpadRight
Definition sdl_compat.h:259
bool IsWindowResizeEvent(const SDL_Event &event)
Check if an event is a window resize event.
Definition sdl_compat.h:589
SDL_GameControllerButton GamepadButton
Definition sdl_compat.h:245
constexpr auto kKeyRight
Definition sdl_compat.h:103
Uint32 MapRGB(SDL_Surface *surface, Uint8 r, Uint8 g, Uint8 b)
Map an RGB color to the surface's pixel format.
Definition sdl_compat.h:402
constexpr auto kKeyA
Definition sdl_compat.h:90
constexpr auto kEventKeyUp
Definition sdl_compat.h:54
SDL_Surface * CreateSurface(int width, int height, int depth, uint32_t format)
Create a surface using the appropriate API.
Definition sdl_compat.h:418
constexpr auto kKeyLeft
Definition sdl_compat.h:102
constexpr auto kKeyY
Definition sdl_compat.h:96
constexpr auto kKeyZ
Definition sdl_compat.h:97
SDL_Surface * ReadPixelsToSurface(SDL_Renderer *renderer, int width, int height, const SDL_Rect *rect)
Read pixels from renderer to a surface.
Definition sdl_compat.h:723
constexpr auto kKeyUp
Definition sdl_compat.h:100
GamepadHandle OpenGamepad(int index)
Definition sdl_compat.h:195
constexpr auto kGamepadButtonX
Definition sdl_compat.h:250
SDL_Keycode GetKeyFromEvent(const SDL_Event &event)
Get keyboard state from SDL event.
Definition sdl_compat.h:115
bool IsGamepadConnected(int index)
Definition sdl_compat.h:216
constexpr auto kGamepadButtonDpadUp
Definition sdl_compat.h:256
bool IsKeyPressed(KeyboardState state, SDL_Scancode scancode)
Check if a key is pressed using the keyboard state.
Definition sdl_compat.h:142
constexpr auto kEventControllerDeviceRemoved
Definition sdl_compat.h:65
bool GetGamepadButton(GamepadHandle gamepad, SDL_GameControllerButton button)
Definition sdl_compat.h:206
void SetRenderVSync(SDL_Renderer *renderer, int interval)
Set vertical sync for the renderer.
Definition sdl_compat.h:289
constexpr auto kGamepadButtonB
Definition sdl_compat.h:249
constexpr auto kKeyDown
Definition sdl_compat.h:101
SDL_Palette * GetSurfacePalette(SDL_Surface *surface)
Get the palette attached to a surface.
Definition sdl_compat.h:375
constexpr auto kKeyD
Definition sdl_compat.h:93
constexpr auto kKeyReturn
Definition sdl_compat.h:98
bool EnsureSurfacePalette256(SDL_Surface *surface)
Ensure the surface has a proper 256-color palette for indexed formats.
Definition sdl_compat.h:454
constexpr auto kKeyS
Definition sdl_compat.h:94
bool RenderTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *srcrect, const SDL_Rect *dstrect)
Render a texture to the current render target.
Definition sdl_compat.h:307
SDL_GameControllerAxis GamepadAxis
Definition sdl_compat.h:246
constexpr auto kGamepadButtonRightShoulder
Definition sdl_compat.h:255
constexpr auto kGamepadButtonStart
Definition sdl_compat.h:253
const Uint8 * KeyboardState
Definition sdl_compat.h:32
void CloseGamepad(GamepadHandle gamepad)
Definition sdl_compat.h:202
constexpr auto kGamepadButtonDpadLeft
Definition sdl_compat.h:258
uint32_t GetDefaultInitFlags()
Get recommended init flags.
Definition sdl_compat.h:663
int GetWindowEventHeight(const SDL_Event &event)
Get window height from resize event data.
Definition sdl_compat.h:634
constexpr auto kGamepadButtonBack
Definition sdl_compat.h:252
constexpr auto kGamepadButtonY
Definition sdl_compat.h:251
void FreeSurface(SDL_Surface *surface)
Free/destroy a surface.
Definition sdl_compat.h:346