mirror of
https://github.com/RetroPortingToolKit/psxrecomp
synced 2026-10-26 02:11:36 -04:00
3f3cfb7571
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.
115 lines
4.5 KiB
C++
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;
|
|
}
|