From 86bf5424e3d32bbb7ef4eefe3f32d22de288ef20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20M=C3=BCller?= Date: Sun, 28 Apr 2024 13:28:52 +0200 Subject: [PATCH 1/2] Revert screen mode config variables when change not accepted When changing the screen width, height or refresh rate config variables to 0 or negative values, which are not allowed by the backend, automatically revert the config variables to the actual values again to ensure that the config variables stay in sync with the state of the window. This fixes the client crashing in the graphics settings when setting the screen width and height to 0 via the console, which causes a division by zero when calculating the aspect ratio. --- src/engine/client/client.cpp | 4 ++-- src/engine/client/graphics_threaded.cpp | 19 ++++++++++++++++--- src/engine/client/graphics_threaded.h | 3 ++- src/engine/graphics.h | 3 ++- src/game/client/components/menus_settings.cpp | 2 +- 5 files changed, 23 insertions(+), 8 deletions(-) diff --git a/src/engine/client/client.cpp b/src/engine/client/client.cpp index 5a872fd22..09ad70a54 100644 --- a/src/engine/client/client.cpp +++ b/src/engine/client/client.cpp @@ -3943,7 +3943,7 @@ void CClient::SwitchWindowScreen(int Index) g_Config.m_GfxScreenHeight = CurMode.m_WindowHeight; g_Config.m_GfxScreenRefreshRate = CurMode.m_RefreshRate; - Graphics()->Resize(g_Config.m_GfxScreenWidth, g_Config.m_GfxScreenHeight, g_Config.m_GfxScreenRefreshRate); + Graphics()->ResizeToScreen(); SetWindowParams(IsFullscreen, IsBorderless); } @@ -4032,7 +4032,7 @@ void CClient::ConchainWindowResize(IConsole::IResult *pResult, void *pUserData, pfnCallback(pResult, pCallbackUserData); if(pSelf->Graphics() && pResult->NumArguments()) { - pSelf->Graphics()->Resize(g_Config.m_GfxScreenWidth, g_Config.m_GfxScreenHeight, g_Config.m_GfxScreenRefreshRate); + pSelf->Graphics()->ResizeToScreen(); } } diff --git a/src/engine/client/graphics_threaded.cpp b/src/engine/client/graphics_threaded.cpp index cb66672bb..eced478e8 100644 --- a/src/engine/client/graphics_threaded.cpp +++ b/src/engine/client/graphics_threaded.cpp @@ -2664,15 +2664,15 @@ void CGraphics_Threaded::Move(int x, int y) PropChangedListener(); } -void CGraphics_Threaded::Resize(int w, int h, int RefreshRate) +bool CGraphics_Threaded::Resize(int w, int h, int RefreshRate) { #if defined(CONF_VIDEORECORDER) if(IVideo::Current() && IVideo::Current()->IsRecording()) - return; + return false; #endif if(WindowWidth() == w && WindowHeight() == h && RefreshRate == m_ScreenRefreshRate) - return; + return false; // if the size is changed manually, only set the window resize, a window size changed event is triggered anyway if(m_pBackend->ResizeWindow(w, h, RefreshRate)) @@ -2680,7 +2680,20 @@ void CGraphics_Threaded::Resize(int w, int h, int RefreshRate) CVideoMode CurMode; m_pBackend->GetCurrentVideoMode(CurMode, m_ScreenHiDPIScale, g_Config.m_GfxDesktopWidth, g_Config.m_GfxDesktopHeight, g_Config.m_GfxScreen); GotResized(w, h, RefreshRate); + return true; } + return false; +} + +void CGraphics_Threaded::ResizeToScreen() +{ + if(Resize(g_Config.m_GfxScreenWidth, g_Config.m_GfxScreenHeight, g_Config.m_GfxScreenRefreshRate)) + return; + + // Revert config variables if the change was not accepted + g_Config.m_GfxScreenWidth = ScreenWidth(); + g_Config.m_GfxScreenHeight = ScreenHeight(); + g_Config.m_GfxScreenRefreshRate = m_ScreenRefreshRate; } void CGraphics_Threaded::GotResized(int w, int h, int RefreshRate) diff --git a/src/engine/client/graphics_threaded.h b/src/engine/client/graphics_threaded.h index 8d55ff37b..cd1113759 100644 --- a/src/engine/client/graphics_threaded.h +++ b/src/engine/client/graphics_threaded.h @@ -1237,7 +1237,8 @@ public: void SetWindowParams(int FullscreenMode, bool IsBorderless) override; bool SetWindowScreen(int Index) override; void Move(int x, int y) override; - void Resize(int w, int h, int RefreshRate) override; + bool Resize(int w, int h, int RefreshRate) override; + void ResizeToScreen() override; void GotResized(int w, int h, int RefreshRate) override; void UpdateViewport(int X, int Y, int W, int H, bool ByResize) override; void AddWindowResizeListener(WINDOW_RESIZE_FUNC pFunc) override; diff --git a/src/engine/graphics.h b/src/engine/graphics.h index b96214698..cfd4d8e2c 100644 --- a/src/engine/graphics.h +++ b/src/engine/graphics.h @@ -295,7 +295,8 @@ public: virtual bool SetMultiSampling(uint32_t ReqMultiSamplingCount, uint32_t &MultiSamplingCountBackend) = 0; virtual int GetWindowScreen() = 0; virtual void Move(int x, int y) = 0; - virtual void Resize(int w, int h, int RefreshRate) = 0; + virtual bool Resize(int w, int h, int RefreshRate) = 0; + virtual void ResizeToScreen() = 0; virtual void GotResized(int w, int h, int RefreshRate) = 0; virtual void UpdateViewport(int X, int Y, int W, int H, bool ByResize) = 0; diff --git a/src/game/client/components/menus_settings.cpp b/src/game/client/components/menus_settings.cpp index b7ea979fe..0413df639 100644 --- a/src/game/client/components/menus_settings.cpp +++ b/src/game/client/components/menus_settings.cpp @@ -1567,7 +1567,7 @@ void CMenus::RenderSettingsGraphics(CUIRect MainView) g_Config.m_GfxScreenWidth = s_aModes[NewSelected].m_WindowWidth; g_Config.m_GfxScreenHeight = s_aModes[NewSelected].m_WindowHeight; g_Config.m_GfxScreenRefreshRate = s_aModes[NewSelected].m_RefreshRate; - Graphics()->Resize(g_Config.m_GfxScreenWidth, g_Config.m_GfxScreenHeight, g_Config.m_GfxScreenRefreshRate); + Graphics()->ResizeToScreen(); } // switches From e4dddb95ce175e2150b86fe07801647cd55a822a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20M=C3=BCller?= Date: Sun, 28 Apr 2024 13:36:32 +0200 Subject: [PATCH 2/2] Update screen index config variable after moving window The wrong screen was shown in the settings when moving the window to another screen while in windowed mode. --- src/engine/client/backend_sdl.cpp | 1 + src/engine/client/client.cpp | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/engine/client/backend_sdl.cpp b/src/engine/client/backend_sdl.cpp index 51031af66..1de4f34c2 100644 --- a/src/engine/client/backend_sdl.cpp +++ b/src/engine/client/backend_sdl.cpp @@ -1539,6 +1539,7 @@ bool CGraphicsBackend_SDL_GL::UpdateDisplayMode(int Index) return false; } + g_Config.m_GfxScreen = Index; g_Config.m_GfxDesktopWidth = DisplayMode.w; g_Config.m_GfxDesktopHeight = DisplayMode.h; diff --git a/src/engine/client/client.cpp b/src/engine/client/client.cpp index 09ad70a54..1fdb2c274 100644 --- a/src/engine/client/client.cpp +++ b/src/engine/client/client.cpp @@ -3929,8 +3929,10 @@ void CClient::SwitchWindowScreen(int Index) int IsFullscreen = g_Config.m_GfxFullscreen; int IsBorderless = g_Config.m_GfxBorderless; - if(Graphics()->SetWindowScreen(Index)) - g_Config.m_GfxScreen = Index; + if(!Graphics()->SetWindowScreen(Index)) + { + return; + } SetWindowParams(3, false); // prevent DDNet to get stretch on monitors