Evil hack to work around SDL bug 4700.

Check if we're in the requested mode after the fullscreen window was
created. If not: Try to switch again in the requested mode by calling
SDL_SetWindowDisplayMode(). If that's successfull set the new window
size with SDL_SetWindowSize(). That shouldn't be necessary, at least to
SDLs crappy doku, but without the subsequent SDL_GetWindowDisplayMode()
call fails with 'Invalid Window'. Use that call to check if we're now
in the requested mode. If yes, process. If not abort and trigger the
fallback magic. It'll set `r_mode 4` and `vid_fullscreen 0`.

Caveat: In the worst case this will switch the display mode 3 times.
To create the window, to work around the bug and to set a refresh rate.
No problem for flat panels, but my unforgotten Trinitron CRT would
have cried in pain.
This commit is contained in:
Yamagi Burmeister 2019-07-04 17:13:34 +02:00
parent 890d708085
commit 6db1203f22

View file

@ -96,9 +96,9 @@ CreateSDLWindow(int flags, int w, int h)
(or was) an SDL bug were SDL switched into the wrong mode
without giving an error code. See the bug report for details:
https://bugzilla.libsdl.org/show_bug.cgi?id=4700 */
SDL_DisplayMode mode;
SDL_DisplayMode real_mode;
if (SDL_GetWindowDisplayMode(window, &mode) != 0)
if (SDL_GetWindowDisplayMode(window, &real_mode) != 0)
{
SDL_DestroyWindow(window);
window = NULL;
@ -108,16 +108,55 @@ CreateSDLWindow(int flags, int w, int h)
return false;
}
if ((mode.w != w) || (mode.h != h))
if ((real_mode.w != w) || (real_mode.h != h))
{
Com_Printf("Current display mode isn't requested display mode\n");
Com_Printf("Likely SDL bug #4700, trying to work around it\n");
/* Mkay, try to hack around that. */
SDL_DisplayMode wanted_mode = {};
wanted_mode.w = w;
wanted_mode.h = h;
if (SDL_SetWindowDisplayMode(window, &wanted_mode) != 0)
{
SDL_DestroyWindow(window);
window = NULL;
Com_Printf("Current display mode isn't requested display mode\n");
Com_Printf("Can't force resolution to %ix%i: %s\n", w, h, SDL_GetError());
return false;
}
/* The SDL doku says, that SDL_SetWindowSize() shouldn't be
used on fullscreen windows. But at least in my test with
SDL 2.0.9 the subsequent SDL_GetWindowDisplayMode() fails
if I don't call it. */
SDL_SetWindowSize(window, wanted_mode.w, wanted_mode.h);
if (SDL_GetWindowDisplayMode(window, &real_mode) != 0)
{
SDL_DestroyWindow(window);
window = NULL;
Com_Printf("Can't get display mode: %s\n", SDL_GetError());
return false;
}
if ((real_mode.w != w) || (real_mode.h != h))
{
SDL_DestroyWindow(window);
window = NULL;
Com_Printf("Can't get display mode: %s\n", SDL_GetError());
return false;
}
}
/* Normally SDL stays at desktop refresh rate or chooses
something sane. Some player may want to override that. */
if (flags & SDL_WINDOW_FULLSCREEN)
@ -125,7 +164,7 @@ CreateSDLWindow(int flags, int w, int h)
if (vid_rate->value > 0)
{
SDL_DisplayMode closest_mode;
SDL_DisplayMode requested_mode = mode;
SDL_DisplayMode requested_mode = real_mode;
requested_mode.refresh_rate = (int)vid_rate->value;