1#ifndef YAZE_APP_PLATFORM_SDL_COMPAT_H_
2#define YAZE_APP_PLATFORM_SDL_COMPAT_H_
15#include <SDL3/SDL_gamepad.h>
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;
73#include <SDL3/SDL_keycode.h>
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';
85constexpr auto kKeyUp = SDLK_UP;
117 return event.key.key;
119 return event.key.keysym.sym;
130 return SDL_GetScancodeFromKey(key,
nullptr);
132 return SDL_GetScancodeFromKey(key);
145 return state[scancode];
148 return state[scancode] != 0;
161 SDL_JoystickID* joysticks = SDL_GetGamepads(
nullptr);
162 if (joysticks && index < 4) {
163 SDL_JoystickID
id = joysticks[index];
165 return SDL_OpenGamepad(
id);
174 SDL_CloseGamepad(gamepad);
178 return SDL_GetGamepadButton(gamepad, button);
182 return SDL_GetGamepadAxis(gamepad, axis);
187 SDL_JoystickID* joysticks = SDL_GetGamepads(&count);
191 return index < count;
198 if (SDL_IsGameController(index)) {
199 return SDL_GameControllerOpen(index);
206 SDL_GameControllerClose(gamepad);
210 SDL_GameControllerButton button) {
211 return SDL_GameControllerGetButton(gamepad, button) != 0;
215 SDL_GameControllerAxis axis) {
216 return SDL_GameControllerGetAxis(gamepad, axis);
220 return SDL_IsGameController(index);
259 SDL_CONTROLLER_BUTTON_RIGHTSHOULDER;
281 return SDL_CreateRenderer(window,
nullptr);
283 SDL_Renderer* renderer =
284 SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
285 if (renderer ==
nullptr) {
288 SDL_LogWarn(SDL_LOG_CATEGORY_RENDER,
289 "Accelerated renderer unavailable (%s); "
290 "falling back to software rendering",
292 renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_SOFTWARE);
309 SDL_SetRenderVSync(renderer, interval);
310#elif SDL_VERSION_ATLEAST(2, 0, 18)
311 if (renderer !=
nullptr) {
312 SDL_RenderSetVSync(renderer, interval);
329 const SDL_Rect* srcrect,
const SDL_Rect* dstrect) {
331 SDL_FRect src_frect, dst_frect;
332 SDL_FRect* src_ptr =
nullptr;
333 SDL_FRect* dst_ptr =
nullptr;
336 src_frect.x =
static_cast<float>(srcrect->x);
337 src_frect.y =
static_cast<float>(srcrect->y);
338 src_frect.w =
static_cast<float>(srcrect->w);
339 src_frect.h =
static_cast<float>(srcrect->h);
340 src_ptr = &src_frect;
344 dst_frect.x =
static_cast<float>(dstrect->x);
345 dst_frect.y =
static_cast<float>(dstrect->y);
346 dst_frect.w =
static_cast<float>(dstrect->w);
347 dst_frect.h =
static_cast<float>(dstrect->h);
348 dst_ptr = &dst_frect;
351 return SDL_RenderTexture(renderer, texture, src_ptr, dst_ptr);
353 return SDL_RenderCopy(renderer, texture, srcrect, dstrect) == 0;
371 SDL_DestroySurface(surface);
373 SDL_FreeSurface(surface);
384 uint32_t flags = 0) {
389 return SDL_ConvertSurface(surface,
static_cast<SDL_PixelFormat
>(format));
391 return SDL_ConvertSurfaceFormat(surface, format, flags);
402 return SDL_GetSurfacePalette(surface);
404 return surface->format ? surface->format->palette :
nullptr;
416 return surface ?
static_cast<Uint32
>(surface->format)
417 : SDL_PIXELFORMAT_UNKNOWN;
419 return (surface && surface->format) ? surface->format->format
420 : SDL_PIXELFORMAT_UNKNOWN;
427inline Uint32
MapRGB(SDL_Surface* surface, Uint8 r, Uint8 g, Uint8 b) {
431 const SDL_PixelFormatDetails* details =
432 SDL_GetPixelFormatDetails(surface->format);
435 SDL_Palette* palette = SDL_GetSurfacePalette(surface);
436 return SDL_MapRGB(details, palette, r, g, b);
438 return SDL_MapRGB(surface->format, r, g, b);
449 return SDL_CreateSurface(width, height,
static_cast<SDL_PixelFormat
>(format));
451 return SDL_CreateRGBSurfaceWithFormat(0, width, height, depth, format);
465 const SDL_PixelFormatDetails* details =
466 SDL_GetPixelFormatDetails(surface->format);
467 return details ? details->bits_per_pixel : 0;
469 return surface->format ? surface->format->BitsPerPixel : 0;
487 if (existing && existing->ncolors >= 256) {
499 SDL_Palette* new_palette = SDL_CreatePalette(256);
501 SDL_Palette* new_palette = SDL_AllocPalette(256);
504 SDL_Log(
"Warning: Failed to create 256-color palette: %s", SDL_GetError());
509 SDL_Color colors[256];
510 for (
int i = 0; i < 256; i++) {
511 colors[i].r = colors[i].g = colors[i].b =
static_cast<Uint8
>(i);
514 SDL_SetPaletteColors(new_palette, colors, 0, 256);
517 if (SDL_SetSurfacePalette(surface, new_palette) != 0) {
518 SDL_Log(
"Warning: Failed to set surface palette: %s", SDL_GetError());
520 SDL_DestroyPalette(new_palette);
522 SDL_FreePalette(new_palette);
540 const SDL_PixelFormatDetails* details =
541 SDL_GetPixelFormatDetails(surface->format);
542 return details ? details->bytes_per_pixel : 0;
544 return surface->format ? surface->format->BytesPerPixel : 0;
556#define YAZE_SDL_QUIT SDL_EVENT_QUIT
557#define YAZE_SDL_WINDOWEVENT 0
560#define YAZE_SDL_WINDOW_CLOSE SDL_EVENT_WINDOW_CLOSE_REQUESTED
561#define YAZE_SDL_WINDOW_RESIZED SDL_EVENT_WINDOW_RESIZED
562#define YAZE_SDL_WINDOW_SIZE_CHANGED SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED
563#define YAZE_SDL_WINDOW_MINIMIZED SDL_EVENT_WINDOW_MINIMIZED
564#define YAZE_SDL_WINDOW_MAXIMIZED SDL_EVENT_WINDOW_MAXIMIZED
565#define YAZE_SDL_WINDOW_RESTORED SDL_EVENT_WINDOW_RESTORED
566#define YAZE_SDL_WINDOW_SHOWN SDL_EVENT_WINDOW_SHOWN
567#define YAZE_SDL_WINDOW_HIDDEN SDL_EVENT_WINDOW_HIDDEN
568#define YAZE_SDL_WINDOW_EXPOSED SDL_EVENT_WINDOW_EXPOSED
569#define YAZE_SDL_WINDOW_FOCUS_GAINED SDL_EVENT_WINDOW_FOCUS_GAINED
570#define YAZE_SDL_WINDOW_FOCUS_LOST SDL_EVENT_WINDOW_FOCUS_LOST
573#define YAZE_SDL_HAS_INDIVIDUAL_WINDOW_EVENTS 1
578#define YAZE_SDL_QUIT SDL_QUIT
579#define YAZE_SDL_WINDOWEVENT SDL_WINDOWEVENT
582#define YAZE_SDL_WINDOW_CLOSE SDL_WINDOWEVENT_CLOSE
583#define YAZE_SDL_WINDOW_RESIZED SDL_WINDOWEVENT_RESIZED
584#define YAZE_SDL_WINDOW_SIZE_CHANGED SDL_WINDOWEVENT_SIZE_CHANGED
585#define YAZE_SDL_WINDOW_MINIMIZED SDL_WINDOWEVENT_MINIMIZED
586#define YAZE_SDL_WINDOW_MAXIMIZED SDL_WINDOWEVENT_MAXIMIZED
587#define YAZE_SDL_WINDOW_RESTORED SDL_WINDOWEVENT_RESTORED
588#define YAZE_SDL_WINDOW_SHOWN SDL_WINDOWEVENT_SHOWN
589#define YAZE_SDL_WINDOW_HIDDEN SDL_WINDOWEVENT_HIDDEN
590#define YAZE_SDL_WINDOW_EXPOSED SDL_WINDOWEVENT_EXPOSED
591#define YAZE_SDL_WINDOW_FOCUS_GAINED SDL_WINDOWEVENT_FOCUS_GAINED
592#define YAZE_SDL_WINDOW_FOCUS_LOST SDL_WINDOWEVENT_FOCUS_LOST
595#define YAZE_SDL_HAS_INDIVIDUAL_WINDOW_EVENTS 0
609 return event.type == SDL_EVENT_WINDOW_CLOSE_REQUESTED;
611 return event.type == SDL_WINDOWEVENT &&
612 event.window.event == SDL_WINDOWEVENT_CLOSE;
621 return event.type == SDL_EVENT_WINDOW_RESIZED ||
622 event.type == SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED;
624 return event.type == SDL_WINDOWEVENT &&
625 (
event.window.event == SDL_WINDOWEVENT_RESIZED ||
626 event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED);
635 return event.type == SDL_EVENT_WINDOW_MINIMIZED;
637 return event.type == SDL_WINDOWEVENT &&
638 event.window.event == SDL_WINDOWEVENT_MINIMIZED;
647 return event.type == SDL_EVENT_WINDOW_RESTORED;
649 return event.type == SDL_WINDOWEVENT &&
650 event.window.event == SDL_WINDOWEVENT_RESTORED;
658 return event.window.data1;
665 return event.window.data2;
695 return SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_EVENTS;
697 return SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER | SDL_INIT_EVENTS;
709 int depth, Uint32 Rmask, Uint32 Gmask,
710 Uint32 Bmask, Uint32 Amask) {
713 return SDL_CreateSurface(
715 SDL_GetPixelFormatForMasks(depth, Rmask, Gmask, Bmask, Amask));
717 return SDL_CreateRGBSurface(flags, width, height, depth, Rmask, Gmask, Bmask,
727 SDL_DestroySurface(surface);
729 SDL_FreeSurface(surface);
742 return SDL_GetCurrentRenderOutputSize(renderer, w, h);
744 return SDL_GetRendererOutputSize(renderer, w, h);
755 int height,
const SDL_Rect* rect) {
757 return SDL_RenderReadPixels(renderer, rect);
760 SDL_Surface* surface = SDL_CreateRGBSurface(
761 0, width, height, 32, 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000);
765 if (SDL_RenderReadPixels(renderer, rect, SDL_PIXELFORMAT_ARGB8888,
766 surface->pixels, surface->pitch) != 0) {
767 SDL_FreeSurface(surface);
777inline SDL_Surface*
LoadBMP(
const char* file) {
779 return SDL_LoadBMP(file);
781 return SDL_LoadBMP(file);