Files
Matthew Stanley 3f3cfb7571 Integrate EU RC4 runtime and overlay tooling changes
Import the supplied developer handoff against 03e635e8. Include regional capability controls, texture validation, SHA acceleration with portable fallback, SPU CD/XA correction, and overlay export/staging fixes. Validated with rebuilt EU runtime, guarded AOT audit and focused regressions.
2026-10-21 16:54:05 -07:00

115 lines
4.5 KiB
C++

#pragma once
#include "psx_sdl.h"
#include <cstdlib>
#include <cmath>
/* On Windows/SDL3, borderless stays a normal desktop-sized window. Other
* window managers retain native desktop fullscreen (Wayland owns placement). */
struct PsxWindowFullscreen {
int mode = 0;
int x = 0, y = 0, width = 0, height = 0;
bool maximized = false;
bool bordered = true;
bool resizable = true;
bool cursor_visible = true;
};
static inline int psx_window_fullscreen_set(SDL_Window* window,
PsxWindowFullscreen* state, int mode)
{
if (!window || !state || mode < 0 || mode > 2) return -1;
if (state->mode == mode) return 0;
if (state->mode == 0) {
const auto flags = SDL_GetWindowFlags(window);
state->maximized = (flags & SDL_WINDOW_MAXIMIZED) != 0;
state->bordered = (flags & SDL_WINDOW_BORDERLESS) == 0;
state->resizable = (flags & SDL_WINDOW_RESIZABLE) != 0;
if (state->maximized) {
SDL_RestoreWindow(window);
#if defined(PSX_SDL3)
SDL_SyncWindow(window);
#endif
}
SDL_GetWindowPosition(window, &state->x, &state->y);
SDL_GetWindowSize(window, &state->width, &state->height);
#if defined(PSX_SDL3)
state->cursor_visible = SDL_CursorVisible();
#else
state->cursor_visible = SDL_ShowCursor(SDL_QUERY) == SDL_ENABLE;
#endif
}
SDL_Rect desktop{};
#if defined(PSX_SDL3)
const SDL_DisplayID display = SDL_GetDisplayForWindow(window);
if (mode == 1 && (!display || !SDL_GetDisplayBounds(display, &desktop))) return -1;
SDL_DisplayMode exclusive{};
if (mode == 2) {
const SDL_DisplayMode* current = SDL_GetDesktopDisplayMode(display);
if (!current || !SDL_GetClosestFullscreenDisplayMode(display, current->w,
current->h, current->refresh_rate, true, &exclusive)) return -1;
/* Optional presentation-only mode for an integer cadence (e.g. PAL
* 50 Hz on a 100 Hz panel). Never accept a driver's approximate mode,
* change resolution, or feed this rate into guest video timing. SDL
* restores the desktop mode when exclusive fullscreen is released. */
if (const char *text = std::getenv("PSX_EXCLUSIVE_REFRESH_HZ")) {
const double hz = std::atof(text);
SDL_DisplayMode requested{};
if (hz >= 30.0 && hz <= 1000.0 &&
SDL_GetClosestFullscreenDisplayMode(display, current->w, current->h,
(float)hz, true, &requested) &&
requested.w == current->w && requested.h == current->h &&
std::fabs((double)requested.refresh_rate - hz) <= hz * 0.002)
exclusive = requested;
}
}
if (!SDL_SetWindowFullscreen(window, false)) return -1;
if (!SDL_SetWindowFullscreenMode(window, mode == 2 ? &exclusive : nullptr)) return -1;
#else
const int display = SDL_GetWindowDisplayIndex(window);
if (mode == 1 && (display < 0 || SDL_GetDisplayBounds(display, &desktop) != 0)) return -1;
if (SDL_SetWindowFullscreen(window, 0) != 0) return -1;
#endif
/* Maximized windows can ignore manual geometry; restore before resizing. */
SDL_RestoreWindow(window);
#if defined(PSX_SDL3)
SDL_SyncWindow(window);
#endif
if (mode == 1) {
#if defined(_WIN32) && defined(PSX_SDL3)
SDL_SetWindowBordered(window, SDL_FALSE);
SDL_SetWindowResizable(window, SDL_FALSE);
SDL_SetWindowPosition(window, desktop.x, desktop.y);
SDL_SetWindowSize(window, desktop.w, desktop.h);
SDL_SyncWindow(window);
#elif defined(PSX_SDL3)
if (!SDL_SetWindowFullscreen(window, true)) return -1;
#else
if (SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_DESKTOP) != 0) return -1;
#endif
} else {
SDL_SetWindowBordered(window, state->bordered ? SDL_TRUE : SDL_FALSE);
SDL_SetWindowResizable(window, state->resizable ? SDL_TRUE : SDL_FALSE);
SDL_SetWindowSize(window, state->width, state->height);
SDL_SetWindowPosition(window, state->x, state->y);
if (mode == 2) {
#if defined(PSX_SDL3)
if (!SDL_SetWindowFullscreen(window, true)) return -1;
#else
if (SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN) != 0) return -1;
#endif
} else if (state->maximized) {
SDL_MaximizeWindow(window);
}
}
state->mode = mode;
#if defined(PSX_SDL3)
if (mode || !state->cursor_visible) SDL_HideCursor();
else SDL_ShowCursor();
#else
SDL_ShowCursor(mode || !state->cursor_visible ? SDL_DISABLE : SDL_ENABLE);
#endif
return 0;
}