From 0c4fc30689bf194f8208345ca6a2d3f5f008d801 Mon Sep 17 00:00:00 2001 From: AloXado320 Date: Tue, 16 Jun 2026 14:44:24 -0500 Subject: [PATCH 1/8] Window adjustments and fixes for all backends --- src/desktop/backends/glfw2.c | 67 ++++++++++++++++-- src/desktop/backends/glfw3.c | 43 ++++++++++-- src/desktop/backends/sdl1.c | 57 ++++++++++++--- src/desktop/backends/sdl2.c | 28 ++++++-- src/desktop/backends/sdl3.c | 130 ++++++++++++++++++++++++++--------- src/desktop/main.c | 7 +- src/desktop/platformdefs.h | 25 +++++++ 7 files changed, 294 insertions(+), 63 deletions(-) diff --git a/src/desktop/backends/glfw2.c b/src/desktop/backends/glfw2.c index f42269da..8a47d59a 100644 --- a/src/desktop/backends/glfw2.c +++ b/src/desktop/backends/glfw2.c @@ -3,6 +3,7 @@ #ifdef _WIN32 #include +#include #endif #ifdef ENABLE_SW_RENDERER @@ -39,9 +40,29 @@ bool platformGetScaledWindowSize(int32_t* outW, int32_t* outH) { return platformGetWindowSize(outW, outH); } +static void platformGetTrueDesktopSize(int* outW, int* outH) { + GLFWvidmode list[256]; + int numModes = glfwGetVideoModes(list, 256); + + if (numModes > 0) { + *outW = list[numModes - 1].Width; + *outH = list[numModes - 1].Height; + } else { + GLFWvidmode mode; + glfwGetDesktopMode(&mode); + *outW = mode.Width; + *outH = mode.Height; + } +} + void platformSetWindowSize(int32_t width, int32_t height) { if (width <= 0 || height <= 0) return; + PLATFORM_CACHE_WINDOW_SIZE(width, height); glfwSetWindowSize(width, height); + + int desktopW, desktopH; + platformGetTrueDesktopSize(&desktopW, &desktopH); + glfwSetWindowPos(((desktopW - width) / 2), ((desktopH - height) / 2)); } void platformGetMousePos(double *xPos, double *yPos) { @@ -139,8 +160,8 @@ static void GLFWCALL mouseButtonCallback(int button, int action) { else if (action == GLFW_RELEASE) RunnerMouse_onButtonUp(g_runner->mouse, gmlButton); } -static int g_last_wheel_pos = 0; static void GLFWCALL scrollCallback(int pos) { + static int g_last_wheel_pos = 0; double yoffset = (double)(pos - g_last_wheel_pos); g_last_wheel_pos = pos; if (g_runner) RunnerMouse_onWheel(g_runner->mouse, yoffset); @@ -151,7 +172,9 @@ bool platformInit(int32_t reqW, int32_t reqH, const char *title, bool headless) fprintf(stderr, "Headless mode is not supported with GLFW 2\n"); return false; } - +#ifdef _WIN32 + timeBeginPeriod(1); +#endif #ifdef GLFW_OPENGL_VERSION_MAJOR if (gfx == SOFTWARE) { glfwOpenWindowHint(GLFW_OPENGL_VERSION_MAJOR, 1); @@ -177,6 +200,9 @@ bool platformInit(int32_t reqW, int32_t reqH, const char *title, bool headless) // Init GLFW if (!glfwInit()) { fprintf(stderr, "Failed to initialize GLFW\n"); +#ifdef _WIN32 + timeEndPeriod(1); +#endif return false; } @@ -196,12 +222,27 @@ bool platformInit(int32_t reqW, int32_t reqH, const char *title, bool headless) } #endif - int window = glfwOpenWindow(reqW, reqH, 8, 8, 8, 8, 24, 8, GLFW_WINDOW); + int desktopW, desktopH; + platformGetTrueDesktopSize(&desktopW, &desktopH); + + int finalW = reqW; + int finalH = reqH; + if (reqW >= desktopW || reqH >= desktopH) { + PLATFORM_GET_BEST_FIT_RES(reqW, reqH, desktopW, desktopH, finalW, finalH); + fprintf(stderr, "Warning: Requested resolution %dx%d is bigger than the screen, adjusting to %dx%d\n", + reqW, reqH, finalW, finalH); + } + + int window = glfwOpenWindow(finalW, finalH, 8, 8, 8, 8, 24, 8, GLFW_WINDOW); if (!window) { fprintf(stderr, "Failed to create GLFW window\n"); glfwTerminate(); +#ifdef _WIN32 + timeEndPeriod(1); +#endif return false; } + glfwSetWindowPos(((desktopW - finalW) / 2), ((desktopH - finalH) / 2)); glfwSetWindowTitle(title); @@ -220,14 +261,27 @@ bool platformInit(int32_t reqW, int32_t reqH, const char *title, bool headless) void platformExit(void) { glfwCloseWindow(); glfwTerminate(); +#ifdef _WIN32 + timeEndPeriod(1); +#endif } +// GLFW2's mouse cursor locks the mouse position when it's invisible on Windows. +// This just makes it visible/invisible as intended. static void platformSetCursor(int32_t cursorType) { // GLFW2 only supports showing/hiding if (cursorType == GML_CR_NONE) { +#ifdef _WIN32 + while (ShowCursor(FALSE) >= 0); +#else glfwDisable(GLFW_MOUSE_CURSOR); +#endif } else { +#ifdef _WIN32 + while (ShowCursor(TRUE) < 0); +#else glfwEnable(GLFW_MOUSE_CURSOR); +#endif } } @@ -269,7 +323,7 @@ void platformSwapBuffers(void) { void *platformGetProcAddress(const char *name) { #ifdef _WIN32 - // glfw2's glfwGetProcAddress is broken on Windows. + // GLFW2's glfwGetProcAddress is broken on Windows. // This just implements it in a way that's fixed so it can be passed to GLAD. void *ret = (void *)wglGetProcAddress(name); // Fallback for driver-specific error codes and legacy OpenGL core functions. @@ -292,7 +346,10 @@ bool platformHandleEvents(void) { } void platformSleepUntil(uint64_t time) { - double remaining = ((int64_t)time - nowNanos()) / 1000000000.0; + int64_t delta = (int64_t)time - nowNanos(); + if (delta <= 0) return; // If the target timestamp is already in the past, skip sleeping + + double remaining = delta / 1000000000.0; if (remaining > 0.002) // glfwSleep takes seconds as a double glfwSleep(remaining - 0.001); diff --git a/src/desktop/backends/glfw3.c b/src/desktop/backends/glfw3.c index a4472f57..a1ba82c1 100644 --- a/src/desktop/backends/glfw3.c +++ b/src/desktop/backends/glfw3.c @@ -5,6 +5,7 @@ #ifdef _WIN32 #include +#include #endif #ifdef ENABLE_SW_RENDERER @@ -57,13 +58,20 @@ bool platformGetScaledWindowSize(int32_t* outW, int32_t* outH) { } void platformSetWindowSize(int32_t width, int32_t height) { - if (width <= 0 || height <= 0) return; - if (!window) return; + if (width <= 0 || height <= 0 || !window) return; + if (glfwGetWindowAttrib(window, GLFW_MAXIMIZED)) return; + PLATFORM_CACHE_WINDOW_SIZE(width, height); + float xs = 1.0f, ys = 1.0f; glfwGetWindowContentScale(window, &xs, &ys); int logicalW, logicalH; framebufferToLogical(xs, ys, width, height, &logicalW, &logicalH); glfwSetWindowSize(window, logicalW, logicalH); + + const GLFWvidmode* mode = glfwGetVideoMode(glfwGetPrimaryMonitor()); + if (mode != NULL) { + glfwSetWindowPos(window, ((mode->width - logicalW) / 2), ((mode->height - logicalH) / 2)); + } } void platformGetMousePos(double *xPos, double *yPos) { @@ -72,7 +80,7 @@ void platformGetMousePos(double *xPos, double *yPos) { } static bool platformGetWindowFocus(void) { - return glfwGetWindowAttrib(window, GLFW_FOCUSED) != 0; + return glfwGetWindowAttrib(window, GLFW_FOCUSED); } static void glfwErrorCallback(int code, const char* description) { @@ -170,10 +178,16 @@ static void scrollCallback(GLFWwindow* window, double xoffset, double yoffset) { } bool platformInit(int32_t reqW, int32_t reqH, const char *title, bool headless) { +#ifdef _WIN32 + timeBeginPeriod(1); +#endif // Init GLFW glfwSetErrorCallback(glfwErrorCallback); if (!glfwInit()) { fprintf(stderr, "Failed to initialize GLFW\n"); +#ifdef _WIN32 + timeEndPeriod(1); +#endif return false; } @@ -224,10 +238,26 @@ bool platformInit(int32_t reqW, int32_t reqH, const char *title, bool headless) if (headless) glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); - window = glfwCreateWindow(reqW, reqH, title, nullptr, nullptr); + int finalW = reqW; + int finalH = reqH; + GLFWmonitor* primaryMonitor = glfwGetPrimaryMonitor(); + if (primaryMonitor) { + int workX, workY, workW, workH; + glfwGetMonitorWorkarea(primaryMonitor, &workX, &workY, &workW, &workH); + if (reqW >= workW || reqH >= workH) { + PLATFORM_GET_BEST_FIT_RES(reqW, reqH, workW, workH, finalW, finalH); + fprintf(stderr, "Warning: Requested resolution %dx%d is bigger than the screen, adjusting to %dx%d\n", + reqW, reqH, finalW, finalH); + } + } + + window = glfwCreateWindow(finalW, finalH, title, nullptr, nullptr); if (!window) { fprintf(stderr, "Failed to create GLFW window\n"); glfwTerminate(); +#ifdef _WIN32 + timeEndPeriod(1); +#endif return false; } @@ -236,7 +266,7 @@ bool platformInit(int32_t reqW, int32_t reqH, const char *title, bool headless) // If we don't do this, the window will be larger than it should be if you are using Wayland fractional scaling // We set the window size AFTER the window creation so we can use glfwGetWindowContentScale - platformSetWindowSize(reqW, reqH); + platformSetWindowSize(finalW, finalH); // Set up keyboard input glfwSetKeyCallback(window, keyCallback); @@ -251,6 +281,9 @@ bool platformInit(int32_t reqW, int32_t reqH, const char *title, bool headless) void platformExit(void) { glfwDestroyWindow(window); glfwTerminate(); +#ifdef _WIN32 + timeEndPeriod(1); +#endif } static void platformSetCursor(int32_t cursorType) { diff --git a/src/desktop/backends/sdl1.c b/src/desktop/backends/sdl1.c index 30b04b54..b60f805f 100644 --- a/src/desktop/backends/sdl1.c +++ b/src/desktop/backends/sdl1.c @@ -41,9 +41,10 @@ bool platformGetScaledWindowSize(int32_t* outW, int32_t* outH) { void platformSetWindowSize(int32_t width, int32_t height) { if (width <= 0 || height <= 0) return; + PLATFORM_CACHE_WINDOW_SIZE(width, height); fbWidth = width; fbHeight = height; - scr = SDL_SetVideoMode(width, height, 0, (gfx == SOFTWARE ? 0 : SDL_OPENGL) | SDL_RESIZABLE); + scr = SDL_SetVideoMode(fbWidth, fbHeight, 0, (gfx == SOFTWARE ? 0 : SDL_OPENGL) | SDL_RESIZABLE); } void platformGetMousePos(double *xPos, double *yPos) { @@ -59,30 +60,58 @@ static bool platformGetWindowFocus(void) { return SDL_GetAppState() & SDL_APPINPUTFOCUS; } +// SDL1.2 redirects stdio messages to stdout.txt and stderr.txt on Windows in SDL_main +// So set the env variable to 0 before it reaches out main so there's no need to set it manually +#ifdef _WIN32 +#if defined(__GNUC__) || defined(__clang__) +__attribute__((constructor)) static void platformDisableRedirect(void) { + SDL_putenv("SDL_STDIO_REDIRECT=0"); +} +#elif defined(_MSC_VER) +static int platformDisableRedirect(void) { + SDL_putenv("SDL_STDIO_REDIRECT=0"); + return 0; +} +#pragma section(".CRT$XCU", read) +__declspec(allocate(".CRT$XCU")) static int (*pDisableRedirect)(void) = platformDisableRedirect; +#endif +#endif + bool platformInit(int32_t reqW, int32_t reqH, const char *title, bool headless) { if (headless && gfx != SOFTWARE) { fprintf(stderr, "Headless mode on SDL 1.2 requires the software renderer!\n"); return false; } + SDL_putenv("SDL_VIDEO_WINDOW_POS=center"); + // Init SDL if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER)) { fprintf(stderr, "Failed to initialize SDL\n"); return false; } - fbWidth = reqW; - fbHeight = reqH; - if(!headless) { + int finalW = reqW; + int finalH = reqH; + const SDL_VideoInfo* info = SDL_GetVideoInfo(); + if (info && (reqW >= info->current_w || reqH >= info->current_h)) { + PLATFORM_GET_BEST_FIT_RES(reqW, reqH, info->current_w, info->current_h, finalW, finalH); + fprintf(stderr, "Warning: Requested resolution %dx%d is bigger than the screen, adjusting to %dx%d\n", + reqW, reqH, finalW, finalH); + } + + fbWidth = finalW; + fbHeight = finalH; + if (!headless) { scr = SDL_SetVideoMode(fbWidth, fbHeight, 0, (gfx == SOFTWARE ? 0 : SDL_OPENGL) | SDL_RESIZABLE); if (!scr && gfx == SOFTWARE) { SDL_Rect** modes = SDL_ListModes(NULL, SDL_FULLSCREEN); if (modes && modes != (SDL_Rect**) -1 && modes[0]) { fprintf(stderr, "Warning: %dx%d unavailable, falling back to %dx%d: %s\n", - reqW, reqH, modes[0]->w, modes[0]->h, SDL_GetError()); - scr = SDL_SetVideoMode(modes[0]->w, modes[0]->h, 0, 0); + fbWidth, fbHeight, modes[0]->w, modes[0]->h, SDL_GetError()); fbWidth = modes[0]->w; fbHeight = modes[0]->h; + scr = SDL_SetVideoMode(fbWidth, fbHeight, 0, 0); } } if (!scr) { @@ -217,21 +246,30 @@ static int32_t SDLMouseButtonToGml(int sdlButton) { bool platformHandleEvents(void) { SDL_Event e; while (SDL_PollEvent(&e)) { + switch (e.type) { + default: + if (InputRecording_isPlaybackActive(globalInputRecording)) continue; + break; + case SDL_VIDEORESIZE: + case SDL_QUIT: + break; + } switch(e.type) { case SDL_KEYDOWN: + // SDL1.2 needs to manually intercept Alt+F4 to exit properly + if (e.key.keysym.sym == SDLK_F4 && (e.key.keysym.mod & KMOD_ALT)) { + return true; + } // During playback, suppress real keyboard input - if (InputRecording_isPlaybackActive(globalInputRecording)) break; RunnerKeyboard_onKeyDown(g_runner->keyboard, SDLKeyToGml(e.key.keysym.sym)); if (e.key.keysym.unicode != 0) RunnerKeyboard_onCharacter(g_runner->keyboard, e.key.keysym.unicode); break; case SDL_KEYUP: // During playback, suppress real keyboard input - if (InputRecording_isPlaybackActive(globalInputRecording)) break; RunnerKeyboard_onKeyUp(g_runner->keyboard, SDLKeyToGml(e.key.keysym.sym)); break; case SDL_MOUSEBUTTONDOWN: - if (InputRecording_isPlaybackActive(globalInputRecording)) break; if (e.button.button == SDL_BUTTON_WHEELUP) { RunnerMouse_onWheel(g_runner->mouse, 1.0); } else if (e.button.button == SDL_BUTTON_WHEELDOWN) { @@ -242,7 +280,6 @@ bool platformHandleEvents(void) { } break; case SDL_MOUSEBUTTONUP: - if (InputRecording_isPlaybackActive(globalInputRecording)) break; if (e.button.button != SDL_BUTTON_WHEELUP && e.button.button != SDL_BUTTON_WHEELDOWN) { int32_t gmlBtn = SDLMouseButtonToGml(e.button.button); if (gmlBtn >= 0) RunnerMouse_onButtonUp(g_runner->mouse, gmlBtn); diff --git a/src/desktop/backends/sdl2.c b/src/desktop/backends/sdl2.c index 91029a63..926ddd41 100644 --- a/src/desktop/backends/sdl2.c +++ b/src/desktop/backends/sdl2.c @@ -60,10 +60,13 @@ static void platformGetWindowScale(float *scale_x, float *scale_y) { void platformSetWindowSize(int32_t width, int32_t height) { if (width <= 0 || height <= 0) return; + if (SDL_GetWindowFlags(window) & SDL_WINDOW_MAXIMIZED) return; + PLATFORM_CACHE_WINDOW_SIZE(width, height); float scale_x, scale_y; platformGetWindowScale(&scale_x, &scale_y); SDL_SetWindowSize(window, (int)(width / scale_x), (int)(height / scale_y)); + SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED); if (gfx == SOFTWARE) scr = SDL_GetWindowSurface(window); @@ -114,25 +117,36 @@ bool platformInit(int reqW, int reqH, const char *title, bool headless) { else flags = (gfx == SOFTWARE ? 0 : SDL_WINDOW_OPENGL) | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI; + int finalW = reqW; + int finalH = reqH; + SDL_Rect usableBounds; + if (SDL_GetDisplayUsableBounds(0, &usableBounds) == 0) { + if (reqW >= usableBounds.w || reqH >= usableBounds.h) { + PLATFORM_GET_BEST_FIT_RES(reqW, reqH, usableBounds.w, usableBounds.h, finalW, finalH); + fprintf(stderr, "Warning: Requested resolution %dx%d is bigger than the screen, adjusting to %dx%d\n", + reqW, reqH, finalW, finalH); + } + } + window = SDL_CreateWindow( title, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, - reqW, reqH, + finalW, finalH, flags ); if (!window && gfx == SOFTWARE) { SDL_DisplayMode mode; if (SDL_GetDisplayMode(0, 0, &mode) == 0) { fprintf(stderr, "Warning: %dx%d unavailable, falling back to %dx%d: %s\n", - reqW, reqH, mode.w, mode.h, SDL_GetError()); - reqW = mode.w; - reqH = mode.h; + finalW, finalH, mode.w, mode.h, SDL_GetError()); + finalW = mode.w; + finalH = mode.h; window = SDL_CreateWindow( title, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, - mode.w, mode.h, + finalW, finalH, flags ); } @@ -151,7 +165,7 @@ bool platformInit(int reqW, int reqH, const char *title, bool headless) { scr = SDL_GetWindowSurface(window); // If we don't do this, the window will be larger than it should be on HiDPI displays. - platformSetWindowSize(reqW, reqH); + platformSetWindowSize(finalW, finalH); return true; } @@ -324,8 +338,10 @@ bool platformHandleEvents(void) { switch (e.type) { default: if (InputRecording_isPlaybackActive(globalInputRecording)) continue; + break; case SDL_WINDOWEVENT: case SDL_QUIT: + break; } switch(e.type) { case SDL_KEYDOWN: diff --git a/src/desktop/backends/sdl3.c b/src/desktop/backends/sdl3.c index eea805e2..001e7e87 100644 --- a/src/desktop/backends/sdl3.c +++ b/src/desktop/backends/sdl3.c @@ -14,7 +14,6 @@ #include "runner_mouse.h" static Runner *g_runner; -static int32_t fbWidth, fbHeight; static SDL_Surface* scr; static SDL_Window *window; static SDL_Gamepad* openControllers[MAX_GAMEPADS]; @@ -45,20 +44,63 @@ void platformSetWindowTitle(const char* title) { bool platformGetWindowSize(int32_t* outW, int32_t* outH) { if (!outW || !outH) return false; - *outW = fbWidth; - *outH = fbHeight; + if (gfx == SOFTWARE) { + if (scr->w <= 0 || scr->h <= 0) return false; + *outW = scr->w; + *outH = scr->h; + } else { + int w = 0; + int h = 0; + SDL_GetWindowSizeInPixels(window, &w, &h); + if (w <= 0 || h <= 0) return false; + *outW = w; + *outH = h; + } return true; } bool platformGetScaledWindowSize(int32_t* outW, int32_t* outH) { - return platformGetWindowSize(outW, outH); + if (!outW || !outH) return false; + int w = 0; + int h = 0; + SDL_GetWindowSize(window, &w, &h); + if (w <= 0 || h <= 0) return false; + *outW = w; + *outH = h; + return true; +} + +static void platformGetWindowScale(float *scale_x, float *scale_y) { + if (!scale_x || !scale_y) return; + int32_t draw_w, draw_h; + int logical_w, logical_h; + platformGetWindowSize(&draw_w, &draw_h); + SDL_GetWindowSize(window, &logical_w, &logical_h); + *scale_x = (logical_w > 0) ? (float)draw_w / logical_w : 1.0f; + *scale_y = (logical_h > 0) ? (float)draw_h / logical_h : 1.0f; } void platformSetWindowSize(int32_t width, int32_t height) { if (width <= 0 || height <= 0) return; - fbWidth = width; - fbHeight = height; - SDL_SetWindowSize(window, width, height); + if (SDL_GetWindowFlags(window) & SDL_WINDOW_MAXIMIZED) return; + PLATFORM_CACHE_WINDOW_SIZE(width, height); + + float scale_x, scale_y; + platformGetWindowScale(&scale_x, &scale_y); + + SDL_SetWindowSize(window, (int)(width / scale_x), (int)(height / scale_y)); + SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED); + SDL_SyncWindow(window); + + // Move the window a bit down so the title bar is visible on large sizes + int top_border, windowX, windowY; + SDL_GetWindowBordersSize(window, &top_border, NULL, NULL, NULL); + SDL_GetWindowPosition(window, &windowX, &windowY); + if (top_border > 0) { + windowY += top_border; + SDL_SetWindowPosition(window, windowX, windowY); + } + if (gfx == SOFTWARE) scr = SDL_GetWindowSurface(window); } @@ -67,8 +109,10 @@ void platformGetMousePos(double *xPos, double *yPos) { if (!xPos || !yPos) return; float mx = 0, my = 0; SDL_GetMouseState(&mx, &my); - *xPos = (double)mx; - *yPos = (double)my; + float scale_x, scale_y; + platformGetWindowScale(&scale_x, &scale_y); + *xPos = (double)mx * scale_x; + *yPos = (double)my * scale_y; } static bool platformGetWindowFocus(void) { @@ -104,13 +148,34 @@ bool platformInit(int reqW, int reqH, const char *title, bool headless) { #endif } - Uint32 flags = (gfx == SOFTWARE ? 0 : SDL_WINDOW_OPENGL) | (headless ? SDL_WINDOW_HIDDEN : SDL_WINDOW_RESIZABLE); - fbWidth = reqW; - fbHeight = reqH; + Uint32 flags; + if (headless) + flags = (gfx == SOFTWARE ? 0 : SDL_WINDOW_OPENGL) | SDL_WINDOW_HIDDEN | SDL_WINDOW_HIGH_PIXEL_DENSITY; + else + flags = (gfx == SOFTWARE ? 0 : SDL_WINDOW_OPENGL) | SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIGH_PIXEL_DENSITY; + + int finalW = reqW; + int finalH = reqH; + int num_displays = 0; + SDL_DisplayID *displays = SDL_GetDisplays(&num_displays); + if (displays && num_displays > 0) { + SDL_DisplayID primaryDisplay = displays[0]; + SDL_Rect usableBounds; + if (SDL_GetDisplayUsableBounds(primaryDisplay, &usableBounds)) { + if (reqW >= usableBounds.w || reqH >= usableBounds.h) { + PLATFORM_GET_BEST_FIT_RES(reqW, reqH, usableBounds.w, usableBounds.h, finalW, finalH); + fprintf(stderr, "Warning: Requested resolution %dx%d is bigger than the screen, adjusting to %dx%d\n", + reqW, reqH, finalW, finalH); + } + } + } + if (displays) + SDL_free(displays); + window = SDL_CreateWindow( title, - fbWidth, - fbHeight, + finalW, + finalH, flags ); if (!window && gfx == SOFTWARE) { @@ -118,13 +183,13 @@ bool platformInit(int reqW, int reqH, const char *title, bool headless) { const SDL_DisplayMode *mode = SDL_GetCurrentDisplayMode(display_id); if (mode != NULL) { fprintf(stderr, "Warning: %dx%d unavailable, falling back to %dx%d: %s\n", - reqW, reqH, mode->w, mode->h, SDL_GetError()); - fbWidth = mode->w; - fbHeight = mode->h; + finalW, finalH, mode->w, mode->h, SDL_GetError()); + finalW = mode->w; + finalH = mode->h; window = SDL_CreateWindow( title, - fbWidth, - fbHeight, + finalW, + finalH, flags ); } @@ -142,6 +207,9 @@ bool platformInit(int reqW, int reqH, const char *title, bool headless) { } else scr = SDL_GetWindowSurface(window); + // If we don't do this, the window will be larger than it should be on HiDPI displays. + platformSetWindowSize(finalW, finalH); + return true; } @@ -339,45 +407,44 @@ static void mapSdl3ToGml(SDL_Gamepad* gp, GamepadSlot* slot) { } bool platformHandleEvents(void) { - bool should_exit = false; SDL_Event e; while (SDL_PollEvent(&e)) { + switch (e.type) { + default: + if (InputRecording_isPlaybackActive(globalInputRecording)) continue; + break; + case SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED: + case SDL_EVENT_QUIT: + break; + } switch(e.type) { case SDL_EVENT_KEY_DOWN: // During playback, suppress real keyboard input - if (InputRecording_isPlaybackActive(globalInputRecording)) break; if (e.key.repeat != 0) break; RunnerKeyboard_onKeyDown(g_runner->keyboard, SDLKeyToGml(e.key.key)); break; case SDL_EVENT_KEY_UP: // During playback, suppress real keyboard input - if (InputRecording_isPlaybackActive(globalInputRecording)) break; RunnerKeyboard_onKeyUp(g_runner->keyboard, SDLKeyToGml(e.key.key)); break; case SDL_EVENT_TEXT_INPUT: // During playback, suppress real keyboard input - if (InputRecording_isPlaybackActive(globalInputRecording)) break; RunnerKeyboard_onCharacter(g_runner->keyboard, utf8_to_codepoint(e.text.text)); break; case SDL_EVENT_MOUSE_BUTTON_DOWN: { - if (InputRecording_isPlaybackActive(globalInputRecording)) break; int32_t gmlBtn = SDLMouseButtonToGml(e.button.button); if (gmlBtn >= 0) RunnerMouse_onButtonDown(g_runner->mouse, gmlBtn); } break; case SDL_EVENT_MOUSE_BUTTON_UP: { - if (InputRecording_isPlaybackActive(globalInputRecording)) break; int32_t gmlBtn = SDLMouseButtonToGml(e.button.button); if (gmlBtn >= 0) RunnerMouse_onButtonUp(g_runner->mouse, gmlBtn); } break; case SDL_EVENT_MOUSE_WHEEL: - if (InputRecording_isPlaybackActive(globalInputRecording)) break; if (e.wheel.y != 0) RunnerMouse_onWheel(g_runner->mouse, (float)e.wheel.y); break; - case SDL_EVENT_WINDOW_RESIZED: - fbWidth = e.window.data1; - fbHeight = e.window.data2; + case SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED: if (gfx == SOFTWARE) scr = SDL_GetWindowSurface(window); break; @@ -406,8 +473,7 @@ bool platformHandleEvents(void) { break; } case SDL_EVENT_QUIT: - should_exit = true; - break; + return true; default: break; } @@ -463,7 +529,7 @@ bool platformHandleEvents(void) { } } - return should_exit; + return false; } void platformSleepUntil(uint64_t time) { diff --git a/src/desktop/main.c b/src/desktop/main.c index 1e635fc0..22351458 100644 --- a/src/desktop/main.c +++ b/src/desktop/main.c @@ -878,8 +878,8 @@ static void onCrashSignal(int sig) { // ===[ MAIN ]=== int main(int argc, char* argv[]) { setbuf(stderr, NULL); -#ifdef _WIN32 - timeBeginPeriod(1); +#if defined(USE_SDL2) || defined(USE_SDL3) + setbuf(stdout, NULL); #endif CommandLineArgs args; @@ -1803,9 +1803,6 @@ int main(int argc, char* argv[]) { arrfree(newArguments); } -#ifdef _WIN32 - timeEndPeriod(1); -#endif printf("Bye! :3\n"); } } diff --git a/src/desktop/platformdefs.h b/src/desktop/platformdefs.h index e45b5c49..777f9ef2 100644 --- a/src/desktop/platformdefs.h +++ b/src/desktop/platformdefs.h @@ -19,6 +19,31 @@ void platformSetWindowSize(int32_t width, int32_t height); void platformSetWindowTitle(const char* title); void platformSleepUntil(uint64_t time); +// Some games call platformSetWindowSize every frame so this avoids redundant resizing +#define PLATFORM_CACHE_WINDOW_SIZE(width, height) \ + do { \ + static int32_t last_width = -1; \ + static int32_t last_height = -1; \ + if (width == last_width && height == last_height) return; \ + last_width = width; \ + last_height = height; \ + } while (0) + +// Some games call an initial resolution larger than the screen so resize properly +#define PLATFORM_GET_BEST_FIT_RES(reqW, reqH, screenW, screenH, finalW, finalH) \ + do { \ + if ((float)(reqW) / (reqH) > (float)(screenW) / (screenH)) { \ + (finalH) = (screenH); \ + (finalW) = (screenW); \ + } else { \ + float scaleX = (float)(screenW) / (reqW); \ + float scaleY = (float)(screenH) / (reqH); \ + float scale = (scaleX < scaleY) ? scaleX : scaleY; \ + (finalW) = (int)((reqW) * scale); \ + (finalH) = (int)((reqH) * scale); \ + } \ + } while(0) + enum GraphicsAPI { SOFTWARE, MODERN_GL, From 3905ddfa56811fd8864fcaaedee4eea608b97fd4 Mon Sep 17 00:00:00 2001 From: AloXado320 Date: Tue, 16 Jun 2026 19:56:21 -0500 Subject: [PATCH 2/8] Fix build for older SDL1 versions --- src/desktop/backends/sdl1.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/desktop/backends/sdl1.c b/src/desktop/backends/sdl1.c index b60f805f..3e558a81 100644 --- a/src/desktop/backends/sdl1.c +++ b/src/desktop/backends/sdl1.c @@ -83,7 +83,9 @@ bool platformInit(int32_t reqW, int32_t reqH, const char *title, bool headless) return false; } +#if SDL_VERSION_ATLEAST(1, 2, 10) // Old SDL1.2: Center pos doesn't matter assuming it's running in low res SDL_putenv("SDL_VIDEO_WINDOW_POS=center"); +#endif // Init SDL if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER)) { @@ -93,12 +95,23 @@ bool platformInit(int32_t reqW, int32_t reqH, const char *title, bool headless) int finalW = reqW; int finalH = reqH; +#if SDL_VERSION_ATLEAST(1, 2, 10) const SDL_VideoInfo* info = SDL_GetVideoInfo(); if (info && (reqW >= info->current_w || reqH >= info->current_h)) { PLATFORM_GET_BEST_FIT_RES(reqW, reqH, info->current_w, info->current_h, finalW, finalH); fprintf(stderr, "Warning: Requested resolution %dx%d is bigger than the screen, adjusting to %dx%d\n", reqW, reqH, finalW, finalH); } +#else + // Old SDL1.2: Set a period appropriate resolution as fallback + int oldW = 1024; + int oldH = 768; + if (reqW >= oldW || reqH >= oldH) { + PLATFORM_GET_BEST_FIT_RES(reqW, reqH, oldW, oldH, finalW, finalH); + fprintf(stderr, "Warning: Requested resolution %dx%d is bigger than the screen, adjusting to %dx%d\n", + reqW, reqH, finalW, finalH); + } +#endif fbWidth = finalW; fbHeight = finalH; From ffd39eab044dafcef8a864a9a0386199e3f81196 Mon Sep 17 00:00:00 2001 From: AloXado320 Date: Tue, 16 Jun 2026 23:46:04 -0500 Subject: [PATCH 3/8] Better screen detection for old SDL1, remove stdio env set --- src/desktop/backends/sdl1.c | 39 +++++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/src/desktop/backends/sdl1.c b/src/desktop/backends/sdl1.c index 3e558a81..2fe7a8a9 100644 --- a/src/desktop/backends/sdl1.c +++ b/src/desktop/backends/sdl1.c @@ -60,21 +60,25 @@ static bool platformGetWindowFocus(void) { return SDL_GetAppState() & SDL_APPINPUTFOCUS; } -// SDL1.2 redirects stdio messages to stdout.txt and stderr.txt on Windows in SDL_main -// So set the env variable to 0 before it reaches out main so there's no need to set it manually -#ifdef _WIN32 -#if defined(__GNUC__) || defined(__clang__) -__attribute__((constructor)) static void platformDisableRedirect(void) { - SDL_putenv("SDL_STDIO_REDIRECT=0"); -} -#elif defined(_MSC_VER) -static int platformDisableRedirect(void) { - SDL_putenv("SDL_STDIO_REDIRECT=0"); - return 0; +#if !SDL_VERSION_ATLEAST(1, 2, 10) +static inline void platformGetTrueDesktopSize(int* outW, int* outH) { + SDL_Rect** modes = SDL_ListModes(NULL, SDL_FULLSCREEN); + if (modes != (SDL_Rect**)0 && modes != (SDL_Rect**)-1) { + int maxHardwareW = 0; + int maxHardwareH = 0; + int i; + + for (i = 0; modes[i]; ++i) { + if (modes[i]->w > maxHardwareW) maxHardwareW = modes[i]->w; + if (modes[i]->h > maxHardwareH) maxHardwareH = modes[i]->h; + } + + if (maxHardwareW > 0 && maxHardwareH > 0) { + if (maxHardwareW < *outW) *outW = maxHardwareW; + if (maxHardwareH < *outH) *outH = maxHardwareH; + } + } } -#pragma section(".CRT$XCU", read) -__declspec(allocate(".CRT$XCU")) static int (*pDisableRedirect)(void) = platformDisableRedirect; -#endif #endif bool platformInit(int32_t reqW, int32_t reqH, const char *title, bool headless) { @@ -103,9 +107,10 @@ bool platformInit(int32_t reqW, int32_t reqH, const char *title, bool headless) reqW, reqH, finalW, finalH); } #else - // Old SDL1.2: Set a period appropriate resolution as fallback - int oldW = 1024; - int oldH = 768; + // Old SDL1.2: Set a default lower res then check if the screen supports it, if not, use the max supported res + int oldW = 800; + int oldH = 600; + platformGetTrueDesktopSize(oldW, oldH); if (reqW >= oldW || reqH >= oldH) { PLATFORM_GET_BEST_FIT_RES(reqW, reqH, oldW, oldH, finalW, finalH); fprintf(stderr, "Warning: Requested resolution %dx%d is bigger than the screen, adjusting to %dx%d\n", From f144c4e2b184b0f3989e9f66791de944e23defc7 Mon Sep 17 00:00:00 2001 From: AloXado320 Date: Wed, 17 Jun 2026 00:37:45 -0500 Subject: [PATCH 4/8] platformdefs: convert macros to inline functions --- src/desktop/backends/glfw2.c | 4 ++-- src/desktop/backends/glfw3.c | 4 ++-- src/desktop/backends/sdl1.c | 6 +++--- src/desktop/backends/sdl2.c | 4 ++-- src/desktop/backends/sdl3.c | 4 ++-- src/desktop/platformdefs.h | 42 ++++++++++++++++++------------------ 6 files changed, 32 insertions(+), 32 deletions(-) diff --git a/src/desktop/backends/glfw2.c b/src/desktop/backends/glfw2.c index 8a47d59a..fe6095cc 100644 --- a/src/desktop/backends/glfw2.c +++ b/src/desktop/backends/glfw2.c @@ -57,7 +57,7 @@ static void platformGetTrueDesktopSize(int* outW, int* outH) { void platformSetWindowSize(int32_t width, int32_t height) { if (width <= 0 || height <= 0) return; - PLATFORM_CACHE_WINDOW_SIZE(width, height); + if (!platformCacheWindowSize(width, height)) return; glfwSetWindowSize(width, height); int desktopW, desktopH; @@ -228,7 +228,7 @@ bool platformInit(int32_t reqW, int32_t reqH, const char *title, bool headless) int finalW = reqW; int finalH = reqH; if (reqW >= desktopW || reqH >= desktopH) { - PLATFORM_GET_BEST_FIT_RES(reqW, reqH, desktopW, desktopH, finalW, finalH); + platformGetBestFitRes(reqW, reqH, desktopW, desktopH, &finalW, &finalH); fprintf(stderr, "Warning: Requested resolution %dx%d is bigger than the screen, adjusting to %dx%d\n", reqW, reqH, finalW, finalH); } diff --git a/src/desktop/backends/glfw3.c b/src/desktop/backends/glfw3.c index a1ba82c1..7fb8c855 100644 --- a/src/desktop/backends/glfw3.c +++ b/src/desktop/backends/glfw3.c @@ -60,7 +60,7 @@ bool platformGetScaledWindowSize(int32_t* outW, int32_t* outH) { void platformSetWindowSize(int32_t width, int32_t height) { if (width <= 0 || height <= 0 || !window) return; if (glfwGetWindowAttrib(window, GLFW_MAXIMIZED)) return; - PLATFORM_CACHE_WINDOW_SIZE(width, height); + if (!platformCacheWindowSize(width, height)) return; float xs = 1.0f, ys = 1.0f; glfwGetWindowContentScale(window, &xs, &ys); @@ -245,7 +245,7 @@ bool platformInit(int32_t reqW, int32_t reqH, const char *title, bool headless) int workX, workY, workW, workH; glfwGetMonitorWorkarea(primaryMonitor, &workX, &workY, &workW, &workH); if (reqW >= workW || reqH >= workH) { - PLATFORM_GET_BEST_FIT_RES(reqW, reqH, workW, workH, finalW, finalH); + platformGetBestFitRes(reqW, reqH, workW, workH, &finalW, &finalH); fprintf(stderr, "Warning: Requested resolution %dx%d is bigger than the screen, adjusting to %dx%d\n", reqW, reqH, finalW, finalH); } diff --git a/src/desktop/backends/sdl1.c b/src/desktop/backends/sdl1.c index 2fe7a8a9..3e1e0b65 100644 --- a/src/desktop/backends/sdl1.c +++ b/src/desktop/backends/sdl1.c @@ -41,7 +41,7 @@ bool platformGetScaledWindowSize(int32_t* outW, int32_t* outH) { void platformSetWindowSize(int32_t width, int32_t height) { if (width <= 0 || height <= 0) return; - PLATFORM_CACHE_WINDOW_SIZE(width, height); + if (!platformCacheWindowSize(width, height)) return; fbWidth = width; fbHeight = height; scr = SDL_SetVideoMode(fbWidth, fbHeight, 0, (gfx == SOFTWARE ? 0 : SDL_OPENGL) | SDL_RESIZABLE); @@ -102,7 +102,7 @@ bool platformInit(int32_t reqW, int32_t reqH, const char *title, bool headless) #if SDL_VERSION_ATLEAST(1, 2, 10) const SDL_VideoInfo* info = SDL_GetVideoInfo(); if (info && (reqW >= info->current_w || reqH >= info->current_h)) { - PLATFORM_GET_BEST_FIT_RES(reqW, reqH, info->current_w, info->current_h, finalW, finalH); + platformGetBestFitRes(reqW, reqH, info->current_w, info->current_h, &finalW, &finalH); fprintf(stderr, "Warning: Requested resolution %dx%d is bigger than the screen, adjusting to %dx%d\n", reqW, reqH, finalW, finalH); } @@ -112,7 +112,7 @@ bool platformInit(int32_t reqW, int32_t reqH, const char *title, bool headless) int oldH = 600; platformGetTrueDesktopSize(oldW, oldH); if (reqW >= oldW || reqH >= oldH) { - PLATFORM_GET_BEST_FIT_RES(reqW, reqH, oldW, oldH, finalW, finalH); + platformGetBestFitRes(reqW, reqH, oldW, oldH, &finalW, &finalH); fprintf(stderr, "Warning: Requested resolution %dx%d is bigger than the screen, adjusting to %dx%d\n", reqW, reqH, finalW, finalH); } diff --git a/src/desktop/backends/sdl2.c b/src/desktop/backends/sdl2.c index 926ddd41..ba00807d 100644 --- a/src/desktop/backends/sdl2.c +++ b/src/desktop/backends/sdl2.c @@ -61,7 +61,7 @@ static void platformGetWindowScale(float *scale_x, float *scale_y) { void platformSetWindowSize(int32_t width, int32_t height) { if (width <= 0 || height <= 0) return; if (SDL_GetWindowFlags(window) & SDL_WINDOW_MAXIMIZED) return; - PLATFORM_CACHE_WINDOW_SIZE(width, height); + if (!platformCacheWindowSize(width, height)) return; float scale_x, scale_y; platformGetWindowScale(&scale_x, &scale_y); @@ -122,7 +122,7 @@ bool platformInit(int reqW, int reqH, const char *title, bool headless) { SDL_Rect usableBounds; if (SDL_GetDisplayUsableBounds(0, &usableBounds) == 0) { if (reqW >= usableBounds.w || reqH >= usableBounds.h) { - PLATFORM_GET_BEST_FIT_RES(reqW, reqH, usableBounds.w, usableBounds.h, finalW, finalH); + platformGetBestFitRes(reqW, reqH, usableBounds.w, usableBounds.h, &finalW, &finalH); fprintf(stderr, "Warning: Requested resolution %dx%d is bigger than the screen, adjusting to %dx%d\n", reqW, reqH, finalW, finalH); } diff --git a/src/desktop/backends/sdl3.c b/src/desktop/backends/sdl3.c index 001e7e87..78697efe 100644 --- a/src/desktop/backends/sdl3.c +++ b/src/desktop/backends/sdl3.c @@ -83,7 +83,7 @@ static void platformGetWindowScale(float *scale_x, float *scale_y) { void platformSetWindowSize(int32_t width, int32_t height) { if (width <= 0 || height <= 0) return; if (SDL_GetWindowFlags(window) & SDL_WINDOW_MAXIMIZED) return; - PLATFORM_CACHE_WINDOW_SIZE(width, height); + if (!platformCacheWindowSize(width, height)) return; float scale_x, scale_y; platformGetWindowScale(&scale_x, &scale_y); @@ -163,7 +163,7 @@ bool platformInit(int reqW, int reqH, const char *title, bool headless) { SDL_Rect usableBounds; if (SDL_GetDisplayUsableBounds(primaryDisplay, &usableBounds)) { if (reqW >= usableBounds.w || reqH >= usableBounds.h) { - PLATFORM_GET_BEST_FIT_RES(reqW, reqH, usableBounds.w, usableBounds.h, finalW, finalH); + platformGetBestFitRes(reqW, reqH, usableBounds.w, usableBounds.h, &finalW, &finalH); fprintf(stderr, "Warning: Requested resolution %dx%d is bigger than the screen, adjusting to %dx%d\n", reqW, reqH, finalW, finalH); } diff --git a/src/desktop/platformdefs.h b/src/desktop/platformdefs.h index 777f9ef2..90e83843 100644 --- a/src/desktop/platformdefs.h +++ b/src/desktop/platformdefs.h @@ -20,29 +20,29 @@ void platformSetWindowTitle(const char* title); void platformSleepUntil(uint64_t time); // Some games call platformSetWindowSize every frame so this avoids redundant resizing -#define PLATFORM_CACHE_WINDOW_SIZE(width, height) \ - do { \ - static int32_t last_width = -1; \ - static int32_t last_height = -1; \ - if (width == last_width && height == last_height) return; \ - last_width = width; \ - last_height = height; \ - } while (0) +static inline bool platformCacheWindowSize(int32_t width, int32_t height) { + static int32_t last_width = -1; + static int32_t last_height = -1; + if (width == last_width && height == last_height) return false; + last_width = width; + last_height = height; + return true; +} // Some games call an initial resolution larger than the screen so resize properly -#define PLATFORM_GET_BEST_FIT_RES(reqW, reqH, screenW, screenH, finalW, finalH) \ - do { \ - if ((float)(reqW) / (reqH) > (float)(screenW) / (screenH)) { \ - (finalH) = (screenH); \ - (finalW) = (screenW); \ - } else { \ - float scaleX = (float)(screenW) / (reqW); \ - float scaleY = (float)(screenH) / (reqH); \ - float scale = (scaleX < scaleY) ? scaleX : scaleY; \ - (finalW) = (int)((reqW) * scale); \ - (finalH) = (int)((reqH) * scale); \ - } \ - } while(0) +static inline void platformGetBestFitRes(int reqW, int reqH, int screenW, int screenH, int *finalW, int *finalH) { + if (!finalW || !finalH) return; + if ((float)reqW / reqH > (float)screenW / screenH) { + *finalH = screenH; + *finalW = screenW; + } else { + float scaleX = (float)screenW / reqW; + float scaleY = (float)screenH / reqH; + float scale = (scaleX < scaleY) ? scaleX : scaleY; + *finalW = (int)(reqW * scale); + *finalH = (int)(reqH * scale); + } +} enum GraphicsAPI { SOFTWARE, From 519892ea48b0bc05f439de406dc998c82f34c32e Mon Sep 17 00:00:00 2001 From: AloXado320 Date: Wed, 17 Jun 2026 00:38:43 -0500 Subject: [PATCH 5/8] Properly fix GLFW2 sleep --- src/desktop/backends/glfw2.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/desktop/backends/glfw2.c b/src/desktop/backends/glfw2.c index fe6095cc..899526ff 100644 --- a/src/desktop/backends/glfw2.c +++ b/src/desktop/backends/glfw2.c @@ -346,10 +346,7 @@ bool platformHandleEvents(void) { } void platformSleepUntil(uint64_t time) { - int64_t delta = (int64_t)time - nowNanos(); - if (delta <= 0) return; // If the target timestamp is already in the past, skip sleeping - - double remaining = delta / 1000000000.0; + double remaining = ((int64_t)time - (int64_t)nowNanos()) / 1000000000.0; if (remaining > 0.002) // glfwSleep takes seconds as a double glfwSleep(remaining - 0.001); From b031c4aa5d4dfc580317ae7a1ca6ace4fa1d9fb4 Mon Sep 17 00:00:00 2001 From: Un1q32 Date: Wed, 17 Jun 2026 21:31:20 -0400 Subject: [PATCH 6/8] Better scaling (#1) * make platformGetWindowScale just return a float there shouldn't be any platforms where scalex != scaley * use the thing * fix * fix sdl3 scaling * fi * is this not scaled??? * just inline --- src/desktop/backends/sdl2.c | 18 +++++++----------- src/desktop/backends/sdl3.c | 37 ++++++++++++++++++------------------- 2 files changed, 25 insertions(+), 30 deletions(-) diff --git a/src/desktop/backends/sdl2.c b/src/desktop/backends/sdl2.c index ba00807d..7ff877ee 100644 --- a/src/desktop/backends/sdl2.c +++ b/src/desktop/backends/sdl2.c @@ -48,14 +48,12 @@ bool platformGetScaledWindowSize(int32_t* outW, int32_t* outH) { return true; } -static void platformGetWindowScale(float *scale_x, float *scale_y) { - if (!scale_x || !scale_y) return; +static float platformGetWindowScale(void) { int32_t draw_w, draw_h; int logical_w, logical_h; platformGetWindowSize(&draw_w, &draw_h); SDL_GetWindowSize(window, &logical_w, &logical_h); - *scale_x = (logical_w > 0) ? (float)draw_w / logical_w : 1.0f; - *scale_y = (logical_h > 0) ? (float)draw_h / logical_h : 1.0f; + return (logical_h > 0) ? (float)draw_h / logical_h : 1.0f; } void platformSetWindowSize(int32_t width, int32_t height) { @@ -63,9 +61,8 @@ void platformSetWindowSize(int32_t width, int32_t height) { if (SDL_GetWindowFlags(window) & SDL_WINDOW_MAXIMIZED) return; if (!platformCacheWindowSize(width, height)) return; - float scale_x, scale_y; - platformGetWindowScale(&scale_x, &scale_y); - SDL_SetWindowSize(window, (int)(width / scale_x), (int)(height / scale_y)); + float scale = platformGetWindowScale(); + SDL_SetWindowSize(window, (int)(width / scale), (int)(height / scale)); SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED); if (gfx == SOFTWARE) @@ -76,10 +73,9 @@ void platformGetMousePos(double *xPos, double *yPos) { if (!xPos || !yPos) return; int mx = 0, my = 0; SDL_GetMouseState(&mx, &my); - float scale_x, scale_y; - platformGetWindowScale(&scale_x, &scale_y); - *xPos = (double)mx * scale_x; - *yPos = (double)my * scale_y; + float scale = platformGetWindowScale(); + *xPos = (double)mx * scale; + *yPos = (double)my * scale; } static bool platformGetWindowFocus(void) { diff --git a/src/desktop/backends/sdl3.c b/src/desktop/backends/sdl3.c index 78697efe..b42439cb 100644 --- a/src/desktop/backends/sdl3.c +++ b/src/desktop/backends/sdl3.c @@ -70,25 +70,14 @@ bool platformGetScaledWindowSize(int32_t* outW, int32_t* outH) { return true; } -static void platformGetWindowScale(float *scale_x, float *scale_y) { - if (!scale_x || !scale_y) return; - int32_t draw_w, draw_h; - int logical_w, logical_h; - platformGetWindowSize(&draw_w, &draw_h); - SDL_GetWindowSize(window, &logical_w, &logical_h); - *scale_x = (logical_w > 0) ? (float)draw_w / logical_w : 1.0f; - *scale_y = (logical_h > 0) ? (float)draw_h / logical_h : 1.0f; -} - void platformSetWindowSize(int32_t width, int32_t height) { if (width <= 0 || height <= 0) return; if (SDL_GetWindowFlags(window) & SDL_WINDOW_MAXIMIZED) return; if (!platformCacheWindowSize(width, height)) return; - float scale_x, scale_y; - platformGetWindowScale(&scale_x, &scale_y); + float scale = SDL_GetWindowPixelDensity(window); - SDL_SetWindowSize(window, (int)(width / scale_x), (int)(height / scale_y)); + SDL_SetWindowSize(window, (int)(width / scale), (int)(height / scale)); SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED); SDL_SyncWindow(window); @@ -109,10 +98,8 @@ void platformGetMousePos(double *xPos, double *yPos) { if (!xPos || !yPos) return; float mx = 0, my = 0; SDL_GetMouseState(&mx, &my); - float scale_x, scale_y; - platformGetWindowScale(&scale_x, &scale_y); - *xPos = (double)mx * scale_x; - *yPos = (double)my * scale_y; + *xPos = (double)mx; + *yPos = (double)my; } static bool platformGetWindowFocus(void) { @@ -162,8 +149,20 @@ bool platformInit(int reqW, int reqH, const char *title, bool headless) { SDL_DisplayID primaryDisplay = displays[0]; SDL_Rect usableBounds; if (SDL_GetDisplayUsableBounds(primaryDisplay, &usableBounds)) { - if (reqW >= usableBounds.w || reqH >= usableBounds.h) { - platformGetBestFitRes(reqW, reqH, usableBounds.w, usableBounds.h, &finalW, &finalH); + /* Open a window so platformGetDisplayScale works */ + window = SDL_CreateWindow(title, 1, 1, SDL_WINDOW_HIDDEN | SDL_WINDOW_HIGH_PIXEL_DENSITY); + float scale = 0; + if (window) { + scale = SDL_GetWindowPixelDensity(window); + SDL_DestroyWindow(window); + window = NULL; + } + if (scale == 0) + scale = 1; + int32_t usableW = usableBounds.w * scale; + int32_t usableH = usableBounds.h * scale; + if (reqW >= usableW || reqH >= usableH) { + platformGetBestFitRes(reqW, reqH, usableW, usableH, &finalW, &finalH); fprintf(stderr, "Warning: Requested resolution %dx%d is bigger than the screen, adjusting to %dx%d\n", reqW, reqH, finalW, finalH); } From 518ef94ac114dab98d235b3ed9c99570fb6dbc8d Mon Sep 17 00:00:00 2001 From: AloXado320 Date: Wed, 17 Jun 2026 20:46:47 -0500 Subject: [PATCH 7/8] Do size correction when resizing again, fix SDL3 window scale --- src/desktop/backends/sdl2.c | 20 ++++++++++++++++--- src/desktop/backends/sdl3.c | 40 ++++++++++++++++++------------------- 2 files changed, 37 insertions(+), 23 deletions(-) diff --git a/src/desktop/backends/sdl2.c b/src/desktop/backends/sdl2.c index 7ff877ee..979b3970 100644 --- a/src/desktop/backends/sdl2.c +++ b/src/desktop/backends/sdl2.c @@ -59,10 +59,24 @@ static float platformGetWindowScale(void) { void platformSetWindowSize(int32_t width, int32_t height) { if (width <= 0 || height <= 0) return; if (SDL_GetWindowFlags(window) & SDL_WINDOW_MAXIMIZED) return; + + // Account for correct size adjustment for multiple monitors + int32_t finalW = width; + int32_t finalH = height; + SDL_Rect usableBounds; + int displayIndex = SDL_GetWindowDisplayIndex(window); + if (displayIndex < 0) displayIndex = 0; + if (SDL_GetDisplayUsableBounds(displayIndex, &usableBounds) == 0) { + if (width > usableBounds.w || height > usableBounds.h) { + platformGetBestFitRes(width, height, usableBounds.w, usableBounds.h, &finalW, &finalH); + } + } + if (!platformCacheWindowSize(width, height)) return; + // Scale window down to account for HIDPI float scale = platformGetWindowScale(); - SDL_SetWindowSize(window, (int)(width / scale), (int)(height / scale)); + SDL_SetWindowSize(window, (int)(finalW / scale), (int)(finalH / scale)); SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED); if (gfx == SOFTWARE) @@ -119,8 +133,8 @@ bool platformInit(int reqW, int reqH, const char *title, bool headless) { if (SDL_GetDisplayUsableBounds(0, &usableBounds) == 0) { if (reqW >= usableBounds.w || reqH >= usableBounds.h) { platformGetBestFitRes(reqW, reqH, usableBounds.w, usableBounds.h, &finalW, &finalH); - fprintf(stderr, "Warning: Requested resolution %dx%d is bigger than the screen, adjusting to %dx%d\n", - reqW, reqH, finalW, finalH); + fprintf(stderr, "Warning: Requested resolution %dx%d is bigger than %dx%d, adjusting to %dx%d\n", + reqW, reqH, usableBounds.w, usableBounds.h, finalW, finalH); } } diff --git a/src/desktop/backends/sdl3.c b/src/desktop/backends/sdl3.c index b42439cb..94e61151 100644 --- a/src/desktop/backends/sdl3.c +++ b/src/desktop/backends/sdl3.c @@ -73,15 +73,27 @@ bool platformGetScaledWindowSize(int32_t* outW, int32_t* outH) { void platformSetWindowSize(int32_t width, int32_t height) { if (width <= 0 || height <= 0) return; if (SDL_GetWindowFlags(window) & SDL_WINDOW_MAXIMIZED) return; - if (!platformCacheWindowSize(width, height)) return; - float scale = SDL_GetWindowPixelDensity(window); + // Account for correct size adjustment for multiple monitors + int32_t finalW = width; + int32_t finalH = height; + SDL_Rect usableBounds; + SDL_DisplayID displayID = SDL_GetDisplayForWindow(window); + if (displayID == 0) displayID = SDL_GetPrimaryDisplay(); + if (SDL_GetDisplayUsableBounds(displayID, &usableBounds)) { + if (width > usableBounds.w || height > usableBounds.h) { + platformGetBestFitRes(width, height, usableBounds.w, usableBounds.h, &finalW, &finalH); + } + } + + if (!platformCacheWindowSize(width, height)) return; - SDL_SetWindowSize(window, (int)(width / scale), (int)(height / scale)); + // No scale here for HIDPI, SDL3 seems to do it internally. + SDL_SetWindowSize(window, finalW, finalH); SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED); SDL_SyncWindow(window); - // Move the window a bit down so the title bar is visible on large sizes + // Move the window a bit down so the title bar is visible on large sizes. int top_border, windowX, windowY; SDL_GetWindowBordersSize(window, &top_border, NULL, NULL, NULL); SDL_GetWindowPosition(window, &windowX, &windowY); @@ -149,22 +161,10 @@ bool platformInit(int reqW, int reqH, const char *title, bool headless) { SDL_DisplayID primaryDisplay = displays[0]; SDL_Rect usableBounds; if (SDL_GetDisplayUsableBounds(primaryDisplay, &usableBounds)) { - /* Open a window so platformGetDisplayScale works */ - window = SDL_CreateWindow(title, 1, 1, SDL_WINDOW_HIDDEN | SDL_WINDOW_HIGH_PIXEL_DENSITY); - float scale = 0; - if (window) { - scale = SDL_GetWindowPixelDensity(window); - SDL_DestroyWindow(window); - window = NULL; - } - if (scale == 0) - scale = 1; - int32_t usableW = usableBounds.w * scale; - int32_t usableH = usableBounds.h * scale; - if (reqW >= usableW || reqH >= usableH) { - platformGetBestFitRes(reqW, reqH, usableW, usableH, &finalW, &finalH); - fprintf(stderr, "Warning: Requested resolution %dx%d is bigger than the screen, adjusting to %dx%d\n", - reqW, reqH, finalW, finalH); + if (reqW >= usableBounds.w || reqH >= usableBounds.h) { + platformGetBestFitRes(reqW, reqH, usableBounds.w, usableBounds.h, &finalW, &finalH); + fprintf(stderr, "Warning: Requested resolution %dx%d is bigger than %dx%d, adjusting to %dx%d\n", + reqW, reqH, usableBounds.w, usableBounds.h, finalW, finalH); } } } From f74a613bceb41c6f5bff707cfdf799350d015955 Mon Sep 17 00:00:00 2001 From: AloXado320 Date: Wed, 17 Jun 2026 20:55:48 -0500 Subject: [PATCH 8/8] Made prints more clear about the max resolution --- src/desktop/backends/glfw2.c | 4 ++-- src/desktop/backends/glfw3.c | 4 ++-- src/desktop/backends/sdl1.c | 8 ++++---- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/desktop/backends/glfw2.c b/src/desktop/backends/glfw2.c index 899526ff..7b3dd67c 100644 --- a/src/desktop/backends/glfw2.c +++ b/src/desktop/backends/glfw2.c @@ -229,8 +229,8 @@ bool platformInit(int32_t reqW, int32_t reqH, const char *title, bool headless) int finalH = reqH; if (reqW >= desktopW || reqH >= desktopH) { platformGetBestFitRes(reqW, reqH, desktopW, desktopH, &finalW, &finalH); - fprintf(stderr, "Warning: Requested resolution %dx%d is bigger than the screen, adjusting to %dx%d\n", - reqW, reqH, finalW, finalH); + fprintf(stderr, "Warning: Requested resolution %dx%d is bigger than %dx%d, adjusting to %dx%d\n", + reqW, reqH, desktopW, desktopH, finalW, finalH); } int window = glfwOpenWindow(finalW, finalH, 8, 8, 8, 8, 24, 8, GLFW_WINDOW); diff --git a/src/desktop/backends/glfw3.c b/src/desktop/backends/glfw3.c index 7fb8c855..433a57c2 100644 --- a/src/desktop/backends/glfw3.c +++ b/src/desktop/backends/glfw3.c @@ -246,8 +246,8 @@ bool platformInit(int32_t reqW, int32_t reqH, const char *title, bool headless) glfwGetMonitorWorkarea(primaryMonitor, &workX, &workY, &workW, &workH); if (reqW >= workW || reqH >= workH) { platformGetBestFitRes(reqW, reqH, workW, workH, &finalW, &finalH); - fprintf(stderr, "Warning: Requested resolution %dx%d is bigger than the screen, adjusting to %dx%d\n", - reqW, reqH, finalW, finalH); + fprintf(stderr, "Warning: Requested resolution %dx%d is bigger than %dx%d, adjusting to %dx%d\n", + reqW, reqH, workW, workH, finalW, finalH); } } diff --git a/src/desktop/backends/sdl1.c b/src/desktop/backends/sdl1.c index 3e1e0b65..4bd2c1a4 100644 --- a/src/desktop/backends/sdl1.c +++ b/src/desktop/backends/sdl1.c @@ -103,8 +103,8 @@ bool platformInit(int32_t reqW, int32_t reqH, const char *title, bool headless) const SDL_VideoInfo* info = SDL_GetVideoInfo(); if (info && (reqW >= info->current_w || reqH >= info->current_h)) { platformGetBestFitRes(reqW, reqH, info->current_w, info->current_h, &finalW, &finalH); - fprintf(stderr, "Warning: Requested resolution %dx%d is bigger than the screen, adjusting to %dx%d\n", - reqW, reqH, finalW, finalH); + fprintf(stderr, "Warning: Requested resolution %dx%d is bigger than %dx%d, adjusting to %dx%d\n", + reqW, reqH, info->current_w, info->current_h, finalW, finalH); } #else // Old SDL1.2: Set a default lower res then check if the screen supports it, if not, use the max supported res @@ -113,8 +113,8 @@ bool platformInit(int32_t reqW, int32_t reqH, const char *title, bool headless) platformGetTrueDesktopSize(oldW, oldH); if (reqW >= oldW || reqH >= oldH) { platformGetBestFitRes(reqW, reqH, oldW, oldH, &finalW, &finalH); - fprintf(stderr, "Warning: Requested resolution %dx%d is bigger than the screen, adjusting to %dx%d\n", - reqW, reqH, finalW, finalH); + fprintf(stderr, "Warning: Requested resolution %dx%d is bigger than %dx%d, adjusting to %dx%d\n", + reqW, reqH, oldW, oldH, finalW, finalH); } #endif