From 8a8a47c29ef7d9a3c1f03fc8daaf0bbd7b05544a Mon Sep 17 00:00:00 2001 From: Roman Fomin Date: Mon, 19 Aug 2024 14:05:52 +0700 Subject: [PATCH] don't use SDL_RenderSetLogicalSize (#1847) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix the appearance of thin black bars in widescreen “auto” mode. Thanks to Gendlin. --- src/i_video.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 60 insertions(+), 5 deletions(-) diff --git a/src/i_video.c b/src/i_video.c index 9823b7a3..176c89f6 100644 --- a/src/i_video.c +++ b/src/i_video.c @@ -264,6 +264,9 @@ static void FocusLost(void) #define FocusLost() #endif +static boolean letterboxed; +static void UpdateViewport(void); + // [FG] window event handling from Chocolate Doom 3.0 static void HandleWindowEvent(SDL_WindowEvent *event) @@ -313,6 +316,7 @@ static void HandleWindowEvent(SDL_WindowEvent *event) SDL_GetWindowPosition(screen, &window_x, &window_y); } window_resize = true; + UpdateViewport(); break; case SDL_WINDOWEVENT_MOVED: @@ -413,6 +417,8 @@ static void I_ToggleFullScreen(void) SDL_SetWindowResizable(screen, SDL_TRUE); SDL_SetWindowSize(screen, window_width, window_height); } + + UpdateViewport(); } static void I_ToggleExclusiveFullScreen(void) @@ -662,7 +668,11 @@ static void UpdateRender(void) SDL_LowerBlit(screenbuffer, &blit_rect, argbbuffer, &blit_rect); SDL_UpdateTexture(texture, &blit_rect, argbbuffer->pixels, argbbuffer->pitch); - SDL_RenderClear(renderer); + + if (letterboxed) + { + SDL_RenderClear(renderer); + } if (texture_upscaled) { @@ -1389,15 +1399,60 @@ static void CreateUpscaledTexture(boolean force) SDL_SetTextureScaleMode(texture_upscaled, SDL_ScaleModeLinear); } +static void UpdateViewport(void) +{ + int w, h; + SDL_GetRendererOutputSize(renderer, &w, &h); + + double real_aspect = (double)w / h; + double want_aspect = CurrentAspectRatio(); + + // Clear the scale because we're setting viewport in output coordinates + SDL_RenderSetScale(renderer, 1.0f, 1.0f); + + SDL_Rect viewport = {0}; + + if (fabs(want_aspect - real_aspect) < 0.0001) + { + float scalex = (float)w / video.width; + float scaley = (float)h / actualheight; + viewport.w = w; + viewport.h = h; + SDL_RenderSetViewport(renderer, &viewport); + SDL_RenderSetScale(renderer, scalex, scaley); + letterboxed = false; + return; + } + + float scale; + + letterboxed = true; + + if (want_aspect > real_aspect) + { + scale = (float)w / video.width; + viewport.w = w; + viewport.h = (int)floor(actualheight * scale); + viewport.y = (h - viewport.h) / 2; + } + else + { + scale = (float)h / actualheight; + viewport.h = h; + viewport.w = (int)floor(video.width * scale); + viewport.x = (w - viewport.w) / 2; + } + + SDL_RenderSetViewport(renderer, &viewport); + SDL_RenderSetScale(renderer, scale, scale); +} + static void ResetLogicalSize(void) { blit_rect.w = video.width; blit_rect.h = video.height; - if (SDL_RenderSetLogicalSize(renderer, video.width, actualheight)) - { - I_Printf(VB_ERROR, "Failed to set logical size: %s", SDL_GetError()); - } + UpdateViewport(); if (smooth_scaling) {