From 9cd000895daa645f858327a350089c96fc6bca65 Mon Sep 17 00:00:00 2001 From: Florian Albrechtskirchinger Date: Mon, 10 Jul 2023 06:01:46 +0200 Subject: [PATCH] Enable non-resizable windows (SDL2 only) Add a hidden setting to control whether the window is resizable. Fixes #1512 --- extras/videoDrivers/SDL2/VideoSDL2.cpp | 51 ++++++----- extras/videoDrivers/SDL2/VideoSDL2.h | 4 +- extras/videoDrivers/WinAPI/WinAPI.cpp | 29 +++--- extras/videoDrivers/WinAPI/WinAPI.h | 6 +- libs/driver/include/driver/VideoDriver.h | 9 +- libs/driver/include/driver/VideoInterface.h | 90 ++++++++++++++++++- libs/driver/src/VideoDriver.cpp | 2 +- libs/s25main/GameManager.cpp | 8 +- libs/s25main/Settings.cpp | 14 ++- libs/s25main/Settings.h | 3 +- libs/s25main/WindowManager.cpp | 11 +-- libs/s25main/desktops/dskBenchmark.cpp | 2 +- libs/s25main/desktops/dskOptions.cpp | 17 ++-- libs/s25main/drivers/VideoDriverWrapper.cpp | 18 +++- libs/s25main/drivers/VideoDriverWrapper.h | 7 +- libs/s25main/ingameWindows/iwSettings.cpp | 19 ++-- tests/mockupDrivers/MockupVideoDriver.cpp | 8 +- tests/mockupDrivers/MockupVideoDriver.h | 4 +- tests/s25Main/UI/testAnimations.cpp | 2 +- tests/s25Main/UI/testVideoDriver.cpp | 4 +- .../UI/uiHelper/uiHelper/uiHelpers.cpp | 2 +- 21 files changed, 222 insertions(+), 88 deletions(-) diff --git a/extras/videoDrivers/SDL2/VideoSDL2.cpp b/extras/videoDrivers/SDL2/VideoSDL2.cpp index afd519c10..683ed5da8 100644 --- a/extras/videoDrivers/SDL2/VideoSDL2.cpp +++ b/extras/videoDrivers/SDL2/VideoSDL2.cpp @@ -91,7 +91,7 @@ void VideoSDL2::UpdateCurrentSizes() SetNewSize(VideoMode(w, h), Extent(w2, h2)); } -bool VideoSDL2::CreateScreen(const std::string& title, const VideoMode& size, bool fullscreen) +bool VideoSDL2::CreateScreen(const std::string& title, const VideoMode& size, DisplayMode displayMode) { if(!initialized) return false; @@ -113,19 +113,20 @@ bool VideoSDL2::CreateScreen(const std::string& title, const VideoMode& size, bo CHECK_SDL(SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8)); CHECK_SDL(SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1)); - int wndPos = SDL_WINDOWPOS_CENTERED; - + const int wndPos = SDL_WINDOWPOS_CENTERED; + const auto fullscreen = (displayMode & DisplayMode::Fullscreen) != DisplayMode::None; + const auto resizable = (displayMode & DisplayMode::Resizable) != DisplayMode::None; const auto requestedSize = fullscreen ? FindClosestVideoMode(size) : size; + const unsigned commonFlags = SDL_WINDOW_OPENGL | (resizable ? SDL_WINDOW_RESIZABLE : 0); + const unsigned fullscreenFlag = (fullscreen ? SDL_WINDOW_FULLSCREEN : 0); window = SDL_CreateWindow(title.c_str(), wndPos, wndPos, requestedSize.width, requestedSize.height, - SDL_WINDOW_OPENGL | (fullscreen ? SDL_WINDOW_FULLSCREEN : SDL_WINDOW_RESIZABLE)); + commonFlags | fullscreenFlag); // Fallback to non-fullscreen if(!window && fullscreen) - { - window = SDL_CreateWindow(title.c_str(), wndPos, wndPos, requestedSize.width, requestedSize.height, - SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE); - } + window = + SDL_CreateWindow(title.c_str(), wndPos, wndPos, requestedSize.width, requestedSize.height, commonFlags); if(!window) { @@ -133,10 +134,12 @@ bool VideoSDL2::CreateScreen(const std::string& title, const VideoMode& size, bo return false; } - isFullscreen_ = (SDL_GetWindowFlags(window) & SDL_WINDOW_FULLSCREEN) != 0; + const auto flags = SDL_GetWindowFlags(window); + SetFullscreenFlag((flags & SDL_WINDOW_FULLSCREEN) != 0); + SetResizableFlag((flags & SDL_WINDOW_RESIZABLE) != 0); UpdateCurrentSizes(); - if(!isFullscreen_) + if(!IsFullscreen()) MoveWindowToCenter(); SDL_Surface* iconSurf = @@ -161,27 +164,34 @@ bool VideoSDL2::CreateScreen(const std::string& title, const VideoMode& size, bo return true; } -bool VideoSDL2::ResizeScreen(const VideoMode& newSize, bool fullscreen) +bool VideoSDL2::ResizeScreen(const VideoMode& newSize, DisplayMode displayMode) { if(!initialized) return false; - if(isFullscreen_ != fullscreen) + const auto fullscreen = (displayMode & DisplayMode::Fullscreen) != DisplayMode::None; + const auto resizable = (displayMode & DisplayMode::Resizable) != DisplayMode::None; + + if(IsFullscreen() != fullscreen) { SDL_SetWindowFullscreen(window, fullscreen ? SDL_WINDOW_FULLSCREEN : 0); - isFullscreen_ = (SDL_GetWindowFlags(window) & SDL_WINDOW_FULLSCREEN) != 0; - if(!isFullscreen_) - { + SetFullscreenFlag((SDL_GetWindowFlags(window) & SDL_WINDOW_FULLSCREEN) != 0); + if(!IsFullscreen()) + MoveWindowToCenter(); + } + + if(displayMode_ != displayMode) + { + if(!IsFullscreen()) #if SDL_VERSION_ATLEAST(2, 0, 5) - SDL_SetWindowResizable(window, SDL_TRUE); + SDL_SetWindowResizable(window, static_cast(resizable)); #endif - MoveWindowToCenter(); - } + SetResizableFlag((SDL_GetWindowFlags(window) & SDL_WINDOW_RESIZABLE) != 0); } if(newSize != GetWindowSize()) { - if(isFullscreen_) + if(IsFullscreen()) { auto const targetMode = FindClosestVideoMode(newSize); SDL_DisplayMode target; @@ -203,6 +213,7 @@ bool VideoSDL2::ResizeScreen(const VideoMode& newSize, bool fullscreen) } UpdateCurrentSizes(); } + return true; } @@ -265,7 +276,7 @@ bool VideoSDL2::MessageLoop() { case SDL_WINDOWEVENT_RESIZED: { - isFullscreen_ = (SDL_GetWindowFlags(window) & SDL_WINDOW_FULLSCREEN) != 0; + SetFullscreenFlag((SDL_GetWindowFlags(window) & SDL_WINDOW_FULLSCREEN) != 0); VideoMode newSize(ev.window.data1, ev.window.data2); if(newSize != GetWindowSize()) { diff --git a/extras/videoDrivers/SDL2/VideoSDL2.h b/extras/videoDrivers/SDL2/VideoSDL2.h index 0a34be639..0c03184cf 100644 --- a/extras/videoDrivers/SDL2/VideoSDL2.h +++ b/extras/videoDrivers/SDL2/VideoSDL2.h @@ -24,8 +24,8 @@ class VideoSDL2 final : public VideoDriver bool Initialize() override; - bool CreateScreen(const std::string& title, const VideoMode& size, bool fullscreen) override; - bool ResizeScreen(const VideoMode& newSize, bool fullscreen) override; + bool CreateScreen(const std::string& title, const VideoMode& size, DisplayMode displayMode) override; + bool ResizeScreen(const VideoMode& newSize, DisplayMode displayMode) override; void DestroyScreen() override; diff --git a/extras/videoDrivers/WinAPI/WinAPI.cpp b/extras/videoDrivers/WinAPI/WinAPI.cpp index 8b43cb086..9e829966f 100644 --- a/extras/videoDrivers/WinAPI/WinAPI.cpp +++ b/extras/videoDrivers/WinAPI/WinAPI.cpp @@ -129,26 +129,25 @@ void VideoWinAPI::CleanUp() /** * Erstellt das Fenster mit entsprechenden Werten. * - * @param[in] width Breite des Fensters - * @param[in] height Höhe des Fensters - * @param[in] fullscreen Vollbildmodus ja oder nein + * @param[in] width Breite des Fensters + * @param[in] height Höhe des Fensters + * @param[in] displayMode Fullscreen on/off, window resizable? * * @return @p true bei Erfolg, @p false bei Fehler * * @bug Hardwarecursor ist bei Fenstermodus sichtbar, * Cursor deaktivieren ist fehlerhaft */ -bool VideoWinAPI::CreateScreen(const std::string& title, const VideoMode& newSize, bool fullscreen) +bool VideoWinAPI::CreateScreen(const std::string& title, const VideoMode& newSize, DisplayMode displayMode) { if(!initialized) return false; - if(!RegisterAndCreateWindow(title, newSize, fullscreen)) + if(!RegisterAndCreateWindow(title, newSize, displayMode)) return false; - if(fullscreen && !MakeFullscreen(GetWindowSize())) + if(bitset::isSet(displayMode, DisplayMode::Fullscreen) && !MakeFullscreen(GetWindowSize())) return false; - isFullscreen_ = fullscreen; if(!InitOGL()) return false; @@ -174,30 +173,31 @@ bool VideoWinAPI::CreateScreen(const std::string& title, const VideoMode& newSiz * * @todo Vollbildmodus ggf. wechseln */ -bool VideoWinAPI::ResizeScreen(const VideoMode& newSize, bool fullscreen) +bool VideoWinAPI::ResizeScreen(const VideoMode& newSize, DisplayMode displayMode) { if(!initialized || !isWindowResizable) return false; - if(isFullscreen_ == fullscreen && newSize == GetWindowSize()) + const auto fullscreen = bitset::isSet(displayMode, DisplayMode::Fullscreen); + if(IsFullscreen() == fullscreen && newSize == GetWindowSize()) return true; ShowWindow(screen, SW_HIDE); VideoMode windowSize = fullscreen ? FindClosestVideoMode(newSize) : newSize; // Try to switch full screen first - if(isFullscreen_ && !fullscreen) + if(IsFullscreen() && !fullscreen) { if(ChangeDisplaySettings(nullptr, 0) != DISP_CHANGE_SUCCESSFUL) return false; - } else if(isFullscreen_ || fullscreen) + } else if(IsFullscreen() || fullscreen) { if(!MakeFullscreen(windowSize)) return false; } // Fensterstyle ggf. ändern - std::pair style = GetStyleFlags(isFullscreen_); + std::pair style = GetStyleFlags(IsFullscreen()); SetWindowLongPtr(screen, GWL_STYLE, style.first); SetWindowLongPtr(screen, GWL_EXSTYLE, style.second); @@ -253,7 +253,7 @@ RECT VideoWinAPI::CalculateWindowRect(bool fullscreen, VideoMode& size) const return wRect; } -bool VideoWinAPI::RegisterAndCreateWindow(const std::string& title, const VideoMode& wndSize, bool fullscreen) +bool VideoWinAPI::RegisterAndCreateWindow(const std::string& title, const VideoMode& wndSize, DisplayMode displayMode) { std::wstring wTitle = boost::nowide::widen(title); windowClassName = wTitle.substr(0, wTitle.find(' ')); @@ -275,6 +275,7 @@ bool VideoWinAPI::RegisterAndCreateWindow(const std::string& title, const VideoM return false; // Create window + const auto fullscreen = bitset::isSet(displayMode, DisplayMode::Fullscreen); auto adjWindowSize = fullscreen ? FindClosestVideoMode(wndSize) : wndSize; RECT wRect = CalculateWindowRect(fullscreen, adjWindowSize); @@ -405,7 +406,7 @@ void VideoWinAPI::DestroyScreen() UnregisterClassW(windowClassName.c_str(), GetModuleHandle(nullptr)); - isFullscreen_ = false; + displayMode_ = bitset::set(displayMode_, DisplayMode::Fullscreen, false); } /** diff --git a/extras/videoDrivers/WinAPI/WinAPI.h b/extras/videoDrivers/WinAPI/WinAPI.h index 408e4097e..62bfe2f5b 100644 --- a/extras/videoDrivers/WinAPI/WinAPI.h +++ b/extras/videoDrivers/WinAPI/WinAPI.h @@ -30,10 +30,10 @@ class VideoWinAPI final : public VideoDriver bool Initialize() override; /// Erstellt das Fenster mit entsprechenden Werten. - bool CreateScreen(const std::string& title, const VideoMode& newSize, bool fullscreen) override; + bool CreateScreen(const std::string& title, const VideoMode& newSize, DisplayMode displayMode) override; /// Erstellt oder verändert das Fenster mit entsprechenden Werten. - bool ResizeScreen(const VideoMode& newSize, bool fullscreen) override; + bool ResizeScreen(const VideoMode& newSize, DisplayMode displayMode) override; /// Schliesst das Fenster. void DestroyScreen() override; @@ -66,7 +66,7 @@ class VideoWinAPI final : public VideoDriver std::pair GetStyleFlags(bool fullscreen) const; /// Calculate the rect for the window and adjusts the (usable) size if required RECT CalculateWindowRect(bool fullscreen, VideoMode& size) const; - bool RegisterAndCreateWindow(const std::string& title, const VideoMode& wndSize, bool fullscreen); + bool RegisterAndCreateWindow(const std::string& title, const VideoMode& wndSize, DisplayMode displayMode); bool InitOGL(); static bool MakeFullscreen(const VideoMode& resolution); diff --git a/libs/driver/include/driver/VideoDriver.h b/libs/driver/include/driver/VideoDriver.h index 9d2860219..2f801b44b 100644 --- a/libs/driver/include/driver/VideoDriver.h +++ b/libs/driver/include/driver/VideoDriver.h @@ -29,7 +29,9 @@ class VideoDriver : public IVideoDriver VideoMode GetWindowSize() const override final { return windowSize_; } Extent GetRenderSize() const override final { return renderSize_; } - bool IsFullscreen() const override final { return isFullscreen_; } + DisplayMode GetDisplayMode() const override final { return displayMode_; } + bool IsFullscreen() const override final { return bitset::isSet(displayMode_, DisplayMode::Fullscreen); } + bool IsResizable() const override final { return bitset::isSet(displayMode_, DisplayMode::Fullscreen); } /// prüft auf Initialisierung. bool IsInitialized() const override final { return initialized; } @@ -39,11 +41,14 @@ class VideoDriver : public IVideoDriver VideoMode FindClosestVideoMode(const VideoMode& mode) const; void SetNewSize(VideoMode windowSize, Extent renderSize); + void SetFullscreenFlag(bool fullscreen) { displayMode_ = fullscreen ? (displayMode_ | DisplayMode::Fullscreen) : (displayMode_ & ~DisplayMode::Fullscreen); } + void SetResizableFlag(bool resizable) { displayMode_ = bitset::set(displayMode_, DisplayMode::Resizable, resizable); } + VideoDriverLoaderInterface* CallBack; /// Das DriverCallback für Rückmeldungen. bool initialized; /// Initialisierungsstatus. MouseCoords mouse_xy; /// Status der Maus. std::array keyboard; /// Status der Tastatur; - bool isFullscreen_; /// Vollbild an/aus? + DisplayMode displayMode_; /// Fullscreen/resizable? private: // cached as possibly used often VideoMode windowSize_; diff --git a/libs/driver/include/driver/VideoInterface.h b/libs/driver/include/driver/VideoInterface.h index 04cf639bb..bd10bcc98 100644 --- a/libs/driver/include/driver/VideoInterface.h +++ b/libs/driver/include/driver/VideoInterface.h @@ -8,12 +8,96 @@ #include "Point.h" #include "VideoMode.h" #include "exportImport.h" +// #include "s25util/enumUtils.h" #include +#include #include /// Function type for loading OpenGL methods using OpenGL_Loader_Proc = void* (*)(const char*); +template +struct IsBitset : std::false_type +{}; + +template +using IsValidBitset = + std::integral_constant::value && std::is_unsigned>::value>; + +template::value, int> = 0> +constexpr auto operator~(Enum val) noexcept +{ + using T = std::underlying_type_t; + return Enum(~static_cast(val)); +} + +template::value, int> = 0> +constexpr auto operator&(Enum lhs, Enum rhs) noexcept +{ + using T = std::underlying_type_t; + return Enum(static_cast(lhs) & static_cast(rhs)); +} + +template::value, int> = 0> +constexpr auto operator|(Enum lhs, Enum rhs) noexcept +{ + using T = std::underlying_type_t; + return Enum(static_cast(lhs) | static_cast(rhs)); +} + +template::value, int> = 0> +constexpr auto operator^(Enum lhs, Enum rhs) noexcept +{ + using T = std::underlying_type_t; + return Enum(static_cast(lhs) ^ static_cast(rhs)); +} + +template::value, int> = 0> +constexpr auto operator&=(Enum& lhs, Enum rhs) noexcept +{ + lhs = lhs & rhs; + return lhs; +} + +template::value, int> = 0> +constexpr auto operator|=(Enum& lhs, Enum rhs) noexcept +{ + lhs = lhs | rhs; + return lhs; +} + +template::value, int> = 0> +constexpr auto operator^=(Enum& lhs, Enum rhs) noexcept +{ + lhs = lhs ^ rhs; + return lhs; +} + +namespace bitset { +template::value, int> = 0> +constexpr bool isSet(Enum val, Enum flag) +{ + return (val & flag) != Enum(0); +} + +template::value, int> = 0> +[[nodiscard]] constexpr Enum set(Enum val, Enum flag, bool state) +{ + return state ? (val | flag) : (val & ~flag); +} +} // namespace bitset + +enum class DisplayMode : unsigned +{ + None, + Fullscreen = (1 << 0), + Resizable = (1 << 1) +}; + +template<> +struct IsBitset : std::true_type +{}; + class BOOST_SYMBOL_VISIBLE IVideoDriver { public: @@ -25,9 +109,9 @@ class BOOST_SYMBOL_VISIBLE IVideoDriver virtual bool Initialize() = 0; /// Erstellt das Fenster mit entsprechenden Werten. - virtual bool CreateScreen(const std::string& title, const VideoMode& newSize, bool fullscreen) = 0; + virtual bool CreateScreen(const std::string& title, const VideoMode& newSize, DisplayMode displayMode) = 0; - virtual bool ResizeScreen(const VideoMode& newSize, bool fullscreen) = 0; + virtual bool ResizeScreen(const VideoMode& newSize, DisplayMode displayMode) = 0; /// Schliesst das Fenster. virtual void DestroyScreen() = 0; @@ -61,7 +145,9 @@ class BOOST_SYMBOL_VISIBLE IVideoDriver virtual VideoMode GetWindowSize() const = 0; /// Get the size of the render region in pixels virtual Extent GetRenderSize() const = 0; + virtual DisplayMode GetDisplayMode() const = 0; virtual bool IsFullscreen() const = 0; + virtual bool IsResizable() const = 0; /// Get state of the modifier keys virtual KeyEvent GetModKeyState() const = 0; diff --git a/libs/driver/src/VideoDriver.cpp b/libs/driver/src/VideoDriver.cpp index fc1c37991..1992530f0 100644 --- a/libs/driver/src/VideoDriver.cpp +++ b/libs/driver/src/VideoDriver.cpp @@ -17,7 +17,7 @@ IVideoDriver::~IVideoDriver() = default; * @param[in] CallBack DriverCallback für Rückmeldungen. */ VideoDriver::VideoDriver(VideoDriverLoaderInterface* CallBack) - : CallBack(CallBack), initialized(false), isFullscreen_(false), renderSize_(0, 0) + : CallBack(CallBack), initialized(false), displayMode_(DisplayMode::Resizable), renderSize_(0, 0) { std::fill(keyboard.begin(), keyboard.end(), false); } diff --git a/libs/s25main/GameManager.cpp b/libs/s25main/GameManager.cpp index 6d3cce356..17b38b589 100644 --- a/libs/s25main/GameManager.cpp +++ b/libs/s25main/GameManager.cpp @@ -12,6 +12,7 @@ #include "desktops/dskLobby.h" #include "desktops/dskMainMenu.h" #include "desktops/dskSplash.h" +#include "driver/VideoInterface.h" #include "drivers/AudioDriverWrapper.h" #include "drivers/VideoDriverWrapper.h" #include "files.h" @@ -48,9 +49,10 @@ bool GameManager::Start() } // Fenster erstellen - const auto screenSize = - settings_.video.fullscreen ? settings_.video.fullscreenSize : settings_.video.windowedSize; //-V807 - if(!videoDriver_.CreateScreen(screenSize, settings_.video.fullscreen)) + const auto screenSize = (settings_.video.displayMode & DisplayMode::Fullscreen) != DisplayMode::None ? + settings_.video.fullscreenSize : + settings_.video.windowedSize; //-V807 + if(!videoDriver_.CreateScreen(screenSize, settings_.video.displayMode)) return false; videoDriver_.setTargetFramerate(settings_.video.framerate); videoDriver_.SetMouseWarping(settings_.global.smartCursor); diff --git a/libs/s25main/Settings.cpp b/libs/s25main/Settings.cpp index 6b9e7e6c0..06bec87de 100644 --- a/libs/s25main/Settings.cpp +++ b/libs/s25main/Settings.cpp @@ -6,6 +6,7 @@ #include "DrawPoint.h" #include "RTTR_Version.h" #include "RttrConfig.h" +#include "driver/VideoInterface.h" #include "drivers/AudioDriverWrapper.h" #include "drivers/VideoDriverWrapper.h" #include "files.h" @@ -84,11 +85,12 @@ void Settings::LoadDefaults() { video.fullscreenSize = VIDEODRIVER.GetWindowSize(); video.windowedSize = VIDEODRIVER.IsFullscreen() ? VideoMode(800, 600) : video.fullscreenSize; - video.fullscreen = VIDEODRIVER.IsFullscreen(); + video.displayMode = (VIDEODRIVER.IsFullscreen() ? DisplayMode::Fullscreen : DisplayMode::None) + | (VIDEODRIVER.IsResizable() ? DisplayMode::Resizable : DisplayMode::None); } else { video.windowedSize = video.fullscreenSize = VideoMode(800, 600); - video.fullscreen = false; + video.displayMode = DisplayMode::Resizable; } video.framerate = 0; // Special value for HW vsync video.vbo = true; @@ -223,7 +225,10 @@ void Settings::Load() video.windowedSize.height = iniVideo->getIntValue("windowed_height"); video.fullscreenSize.width = iniVideo->getIntValue("fullscreen_width"); video.fullscreenSize.height = iniVideo->getIntValue("fullscreen_height"); - video.fullscreen = iniVideo->getBoolValue("fullscreen"); + const auto fullscreen = iniVideo->getBoolValue("fullscreen"); + const auto resizable = iniVideo->getValue("resizable", true); + video.displayMode = (fullscreen ? DisplayMode::Fullscreen : DisplayMode::None) + | (resizable ? DisplayMode::Resizable : DisplayMode::None); video.framerate = iniVideo->getValue("framerate", 0); video.vbo = iniVideo->getBoolValue("vbo"); video.shared_textures = iniVideo->getBoolValue("shared_textures"); @@ -401,7 +406,8 @@ void Settings::Save() iniVideo->setValue("fullscreen_height", video.fullscreenSize.height); iniVideo->setValue("windowed_width", video.windowedSize.width); iniVideo->setValue("windowed_height", video.windowedSize.height); - iniVideo->setValue("fullscreen", video.fullscreen); + iniVideo->setValue("fullscreen", (video.displayMode & DisplayMode::Fullscreen) != DisplayMode::None); + iniVideo->setValue("resizable", (video.displayMode & DisplayMode::Resizable) != DisplayMode::None); iniVideo->setValue("framerate", video.framerate); iniVideo->setValue("vbo", video.vbo); iniVideo->setValue("shared_textures", video.shared_textures); diff --git a/libs/s25main/Settings.h b/libs/s25main/Settings.h index a435a3242..8f60c257d 100644 --- a/libs/s25main/Settings.h +++ b/libs/s25main/Settings.h @@ -5,6 +5,7 @@ #pragma once #include "DrawPoint.h" +#include "driver/VideoInterface.h" #include "driver/VideoMode.h" #include "s25util/ProxySettings.h" #include "s25util/Singleton.h" @@ -60,7 +61,7 @@ class Settings : public Singleton { VideoMode fullscreenSize, windowedSize; signed short framerate; // <0 for unlimited, 0 for HW Vsync - bool fullscreen; + DisplayMode displayMode; bool vbo; bool shared_textures; } video; diff --git a/libs/s25main/WindowManager.cpp b/libs/s25main/WindowManager.cpp index 2baa01803..dd7fc8444 100644 --- a/libs/s25main/WindowManager.cpp +++ b/libs/s25main/WindowManager.cpp @@ -10,6 +10,7 @@ #include "Window.h" #include "commonDefines.h" #include "desktops/Desktop.h" +#include "driver/VideoInterface.h" #include "drivers/ScreenResizeEvent.h" #include "drivers/VideoDriverWrapper.h" #include "files.h" @@ -600,10 +601,10 @@ void WindowManager::Msg_KeyDown(const KeyEvent& ke) if(ke.alt && (ke.kt == KeyType::Return)) { // Switch Fullscreen/Windowed - const auto newScreenSize = - !SETTINGS.video.fullscreen ? SETTINGS.video.fullscreenSize : SETTINGS.video.windowedSize; //-V807 - VIDEODRIVER.ResizeScreen(newScreenSize, !SETTINGS.video.fullscreen); - SETTINGS.video.fullscreen = VIDEODRIVER.IsFullscreen(); + SETTINGS.video.displayMode ^= DisplayMode::Fullscreen; + const auto isFullscreen = (SETTINGS.video.displayMode & DisplayMode::Fullscreen) != DisplayMode::None; + const auto newScreenSize = isFullscreen ? SETTINGS.video.fullscreenSize : SETTINGS.video.windowedSize; //-V807 + VIDEODRIVER.ResizeScreen(newScreenSize, SETTINGS.video.displayMode); } else if(ke.kt == KeyType::Print) TakeScreenshot(); else @@ -632,7 +633,7 @@ void WindowManager::Msg_ScreenResize(const Extent& newSize) curRenderSize = sr.newSize; // Don't change fullscreen size (only in menu) - if(!SETTINGS.video.fullscreen) + if(!bitset::isSet(SETTINGS.video.displayMode, DisplayMode::Fullscreen)) SETTINGS.video.windowedSize = VIDEODRIVER.GetWindowSize(); // ist unser Desktop gültig? diff --git a/libs/s25main/desktops/dskBenchmark.cpp b/libs/s25main/desktops/dskBenchmark.cpp index a65982f72..f6eb86ea9 100644 --- a/libs/s25main/desktops/dskBenchmark.cpp +++ b/libs/s25main/desktops/dskBenchmark.cpp @@ -131,7 +131,7 @@ void dskBenchmark::Msg_PaintAfter() void dskBenchmark::SetActive(bool activate) { if(!IsActive() && activate) - VIDEODRIVER.ResizeScreen(VideoMode(1600, 900), false); + VIDEODRIVER.ResizeScreen(VideoMode(1600, 900), DisplayMode::Resizable); dskMenuBase::SetActive(activate); } diff --git a/libs/s25main/desktops/dskOptions.cpp b/libs/s25main/desktops/dskOptions.cpp index 633c691ea..b51644e4f 100644 --- a/libs/s25main/desktops/dskOptions.cpp +++ b/libs/s25main/desktops/dskOptions.cpp @@ -379,7 +379,8 @@ dskOptions::dskOptions() : Desktop(LOADER.GetImageN("setup013", 0)) } // "Vollbild" setzen - groupGrafik->GetCtrl(ID_grpFullscreen)->SetSelection(SETTINGS.video.fullscreen); //-V807 + groupGrafik->GetCtrl(ID_grpFullscreen) + ->SetSelection(bitset::isSet(SETTINGS.video.displayMode, DisplayMode::Fullscreen)); //-V807 // "Limit Framerate" füllen auto* cbFrameRate = groupGrafik->GetCtrl(ID_cbFramerate); @@ -502,7 +503,9 @@ void dskOptions::Msg_Group_OptionGroupChange(const unsigned /*group_id*/, const switch(ctrl_id) { case ID_grpIpv6: SETTINGS.server.ipv6 = enabled; break; - case ID_grpFullscreen: SETTINGS.video.fullscreen = enabled; break; + case ID_grpFullscreen: + SETTINGS.video.displayMode = bitset::set(SETTINGS.video.displayMode, DisplayMode::Fullscreen, enabled); + break; case ID_grpVBO: SETTINGS.video.vbo = enabled; break; case ID_grpOptTextures: SETTINGS.video.shared_textures = enabled; break; case ID_grpMusic: @@ -570,12 +573,12 @@ void dskOptions::Msg_ButtonClick(const unsigned ctrl_id) SETTINGS.Save(); - if((SETTINGS.video.fullscreen && SETTINGS.video.fullscreenSize != VIDEODRIVER.GetWindowSize()) //-V807 - || SETTINGS.video.fullscreen != VIDEODRIVER.IsFullscreen()) + const auto fullscreen = bitset::isSet(SETTINGS.video.displayMode, DisplayMode::Fullscreen); + if((fullscreen && SETTINGS.video.fullscreenSize != VIDEODRIVER.GetWindowSize()) //-V807 + || fullscreen != VIDEODRIVER.IsFullscreen()) { - const auto screenSize = - SETTINGS.video.fullscreen ? SETTINGS.video.fullscreenSize : SETTINGS.video.windowedSize; - if(!VIDEODRIVER.ResizeScreen(screenSize, SETTINGS.video.fullscreen)) + const auto screenSize = fullscreen ? SETTINGS.video.fullscreenSize : SETTINGS.video.windowedSize; + if(!VIDEODRIVER.ResizeScreen(screenSize, SETTINGS.video.displayMode)) { WINDOWMANAGER.Show(std::make_unique( _("Sorry!"), _("You need to restart your game to change the screen resolution!"), this, diff --git a/libs/s25main/drivers/VideoDriverWrapper.cpp b/libs/s25main/drivers/VideoDriverWrapper.cpp index c58a0534c..8a4bed3ae 100644 --- a/libs/s25main/drivers/VideoDriverWrapper.cpp +++ b/libs/s25main/drivers/VideoDriverWrapper.cpp @@ -92,7 +92,7 @@ void VideoDriverWrapper::UnloadDriver() * * @return Bei Erfolg @p true ansonsten @p false */ -bool VideoDriverWrapper::CreateScreen(const VideoMode size, const bool fullscreen) +bool VideoDriverWrapper::CreateScreen(const VideoMode size, const DisplayMode displayMode) { if(!videodriver) { @@ -100,7 +100,7 @@ bool VideoDriverWrapper::CreateScreen(const VideoMode size, const bool fullscree return false; } - if(!videodriver->CreateScreen(rttr::version::GetTitle(), size, fullscreen)) + if(!videodriver->CreateScreen(rttr::version::GetTitle(), size, displayMode)) { s25util::fatal_error("Could not create window!"); return false; @@ -134,7 +134,7 @@ bool VideoDriverWrapper::CreateScreen(const VideoMode size, const bool fullscree * * @return Bei Erfolg @p true ansonsten @p false */ -bool VideoDriverWrapper::ResizeScreen(const VideoMode size, const bool fullscreen) +bool VideoDriverWrapper::ResizeScreen(const VideoMode size, const DisplayMode displayMode) { if(!videodriver) { @@ -142,7 +142,7 @@ bool VideoDriverWrapper::ResizeScreen(const VideoMode size, const bool fullscree return false; } - const bool result = videodriver->ResizeScreen(size, fullscreen); + const bool result = videodriver->ResizeScreen(size, displayMode); #ifdef _WIN32 if(!videodriver->IsFullscreen()) { @@ -483,7 +483,17 @@ Extent VideoDriverWrapper::GetRenderSize() const return videodriver->GetRenderSize(); } +DisplayMode VideoDriverWrapper::GetDisplayMode() const +{ + return videodriver->GetDisplayMode(); +} + bool VideoDriverWrapper::IsFullscreen() const { return videodriver->IsFullscreen(); } + +bool VideoDriverWrapper::IsResizable() const +{ + return videodriver->IsResizable(); +} diff --git a/libs/s25main/drivers/VideoDriverWrapper.h b/libs/s25main/drivers/VideoDriverWrapper.h index 80b530145..5a278bafe 100644 --- a/libs/s25main/drivers/VideoDriverWrapper.h +++ b/libs/s25main/drivers/VideoDriverWrapper.h @@ -7,6 +7,7 @@ #include "DriverWrapper.h" #include "Point.h" #include "driver/KeyEvent.h" +#include "driver/VideoInterface.h" #include "driver/VideoMode.h" #include "s25util/Singleton.h" #include @@ -35,9 +36,9 @@ class VideoDriverWrapper : public Singleton(3); - optiongroup->SetSelection((SETTINGS.video.fullscreen ? 1 : 2)); //-V807 + + optiongroup->SetSelection((bitset::isSet(SETTINGS.video.displayMode, DisplayMode::Fullscreen) ? 1 : 2)); //-V807 VIDEODRIVER.ListVideoModes(video_modes); // "Auflösung" @@ -63,12 +65,12 @@ iwSettings::~iwSettings() auto* SizeCombo = GetCtrl(0); SETTINGS.video.fullscreenSize = video_modes[SizeCombo->GetSelection().get()]; - if((SETTINGS.video.fullscreen && SETTINGS.video.fullscreenSize != VIDEODRIVER.GetWindowSize()) - || SETTINGS.video.fullscreen != VIDEODRIVER.IsFullscreen()) + const auto fullscreen = bitset::isSet(SETTINGS.video.displayMode, DisplayMode::Fullscreen); + if((fullscreen && SETTINGS.video.fullscreenSize != VIDEODRIVER.GetWindowSize()) + || fullscreen != VIDEODRIVER.IsFullscreen()) { - const auto screenSize = - SETTINGS.video.fullscreen ? SETTINGS.video.fullscreenSize : SETTINGS.video.windowedSize; - if(!VIDEODRIVER.ResizeScreen(screenSize, SETTINGS.video.fullscreen)) + const auto screenSize = fullscreen ? SETTINGS.video.fullscreenSize : SETTINGS.video.windowedSize; + if(!VIDEODRIVER.ResizeScreen(screenSize, SETTINGS.video.displayMode)) { WINDOWMANAGER.Show(std::make_unique( _("Sorry!"), _("You need to restart your game to change the screen resolution!"), this, @@ -85,7 +87,10 @@ void iwSettings::Msg_OptionGroupChange(const unsigned ctrl_id, const unsigned se { switch(ctrl_id) { - case 3: SETTINGS.video.fullscreen = (selection == 1); break; + case 3: + SETTINGS.video.displayMode = + bitset::set(SETTINGS.video.displayMode, DisplayMode::Fullscreen, (selection == 1)); + break; } } diff --git a/tests/mockupDrivers/MockupVideoDriver.cpp b/tests/mockupDrivers/MockupVideoDriver.cpp index 7b239109f..a962e24cf 100644 --- a/tests/mockupDrivers/MockupVideoDriver.cpp +++ b/tests/mockupDrivers/MockupVideoDriver.cpp @@ -29,16 +29,16 @@ bool MockupVideoDriver::Initialize() return true; } -bool MockupVideoDriver::CreateScreen(const std::string&, const VideoMode& newSize, bool fullscreen) +bool MockupVideoDriver::CreateScreen(const std::string&, const VideoMode& newSize, DisplayMode displayMode) { - ResizeScreen(newSize, fullscreen); + ResizeScreen(newSize, displayMode); return true; } -bool MockupVideoDriver::ResizeScreen(const VideoMode& newSize, bool fullscreen) +bool MockupVideoDriver::ResizeScreen(const VideoMode& newSize, DisplayMode displayMode) { SetNewSize(newSize, Extent(newSize.width, newSize.height)); - isFullscreen_ = fullscreen; + displayMode_ = displayMode; return true; } diff --git a/tests/mockupDrivers/MockupVideoDriver.h b/tests/mockupDrivers/MockupVideoDriver.h index 2f24ccaf4..df3cb4678 100644 --- a/tests/mockupDrivers/MockupVideoDriver.h +++ b/tests/mockupDrivers/MockupVideoDriver.h @@ -13,8 +13,8 @@ class MockupVideoDriver : public VideoDriver ~MockupVideoDriver() override; const char* GetName() const override; bool Initialize() override; - bool CreateScreen(const std::string& title, const VideoMode& newSize, bool fullscreen) override; - bool ResizeScreen(const VideoMode& newSize, bool fullscreen) override; + bool CreateScreen(const std::string& title, const VideoMode& newSize, DisplayMode displayMode) override; + bool ResizeScreen(const VideoMode& newSize, DisplayMode displayMode) override; void DestroyScreen() override {} bool SwapBuffers() override { return true; } bool MessageLoop() override; diff --git a/tests/s25Main/UI/testAnimations.cpp b/tests/s25Main/UI/testAnimations.cpp index e460de15c..ef8d2c26e 100644 --- a/tests/s25Main/UI/testAnimations.cpp +++ b/tests/s25Main/UI/testAnimations.cpp @@ -681,7 +681,7 @@ BOOST_AUTO_TEST_CASE(MoveAniScale) video->tickCount_ += 1; dsk->Msg_PaintBefore(); // Resize the screen and test that the final position got updated too - VIDEODRIVER.ResizeScreen(VideoMode(1024, 768), false); + VIDEODRIVER.ResizeScreen(VideoMode(1024, 768), DisplayMode::Resizable); // Pass the animation video->tickCount_ += 1100; dsk->Msg_PaintBefore(); diff --git a/tests/s25Main/UI/testVideoDriver.cpp b/tests/s25Main/UI/testVideoDriver.cpp index a86a5b2a7..8fb22642c 100644 --- a/tests/s25Main/UI/testVideoDriver.cpp +++ b/tests/s25Main/UI/testVideoDriver.cpp @@ -66,7 +66,7 @@ BOOST_FIXTURE_TEST_CASE(CreateAndDestroyTextures, uiHelper::Fixture) { rttr::test::LogAccessor logAcc; VIDEODRIVER.DestroyScreen(); - VIDEODRIVER.CreateScreen(VideoMode(800, 600), false); + VIDEODRIVER.CreateScreen(VideoMode(800, 600), DisplayMode::Resizable); logAcc.clearLog(); } @@ -87,7 +87,7 @@ BOOST_FIXTURE_TEST_CASE(CreateAndDestroyTextures, uiHelper::Fixture) { rttr::test::LogAccessor logAcc; - VIDEODRIVER.CreateScreen(VideoMode(800, 600), false); + VIDEODRIVER.CreateScreen(VideoMode(800, 600), DisplayMode::Resizable); logAcc.clearLog(); } glGenTextures = rttrOglMock2::glGenTextures; diff --git a/tests/s25Main/UI/uiHelper/uiHelper/uiHelpers.cpp b/tests/s25Main/UI/uiHelper/uiHelper/uiHelpers.cpp index f019bd2f9..9434a77f0 100644 --- a/tests/s25Main/UI/uiHelper/uiHelper/uiHelpers.cpp +++ b/tests/s25Main/UI/uiHelper/uiHelper/uiHelpers.cpp @@ -28,7 +28,7 @@ void initGUITests() rttr::test::LogAccessor logAcc; VIDEODRIVER.LoadDriver(new MockupVideoDriver(&WINDOWMANAGER)); RTTR_REQUIRE_LOG_CONTAINS("Mockup Video Driver", false); - VIDEODRIVER.CreateScreen(VideoMode(800, 600), false); + VIDEODRIVER.CreateScreen(VideoMode(800, 600), DisplayMode::Resizable); BOOST_TEST_CHECKPOINT("Load dummy files"); LOADER.LoadDummyGUIFiles(); BOOST_TEST_CHECKPOINT("Switch to Desktop");