diff --git a/extras/videoDrivers/SDL2/VideoSDL2.cpp b/extras/videoDrivers/SDL2/VideoSDL2.cpp index afd519c10..492440e24 100644 --- a/extras/videoDrivers/SDL2/VideoSDL2.cpp +++ b/extras/videoDrivers/SDL2/VideoSDL2.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #ifdef _WIN32 @@ -91,7 +92,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, WindowMode windowMode, bool fullscreen) { if(!initialized) return false; @@ -116,15 +117,18 @@ bool VideoSDL2::CreateScreen(const std::string& title, const VideoMode& size, bo int wndPos = SDL_WINDOWPOS_CENTERED; const auto requestedSize = fullscreen ? FindClosestVideoMode(size) : size; + unsigned commonFlags = SDL_WINDOW_OPENGL; + unsigned fullscreenFlags = (fullscreen ? SDL_WINDOW_FULLSCREEN : 0); + unsigned windowFlags = (windowMode == WindowMode::Resizable ? SDL_WINDOW_RESIZABLE : 0); window = SDL_CreateWindow(title.c_str(), wndPos, wndPos, requestedSize.width, requestedSize.height, - SDL_WINDOW_OPENGL | (fullscreen ? SDL_WINDOW_FULLSCREEN : SDL_WINDOW_RESIZABLE)); + commonFlags | fullscreenFlags | windowFlags); // 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); + commonFlags | windowFlags); } if(!window) @@ -133,7 +137,9 @@ 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); + isFullscreen_ = (flags & SDL_WINDOW_FULLSCREEN) != 0; + windowMode_ = ((flags & SDL_WINDOW_RESIZABLE) != 0 ? WindowMode::Resizable : WindowMode::NonResizable); UpdateCurrentSizes(); if(!isFullscreen_) @@ -161,7 +167,7 @@ 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, WindowMode windowMode, bool fullscreen) { if(!initialized) return false; @@ -172,9 +178,6 @@ bool VideoSDL2::ResizeScreen(const VideoMode& newSize, bool fullscreen) isFullscreen_ = (SDL_GetWindowFlags(window) & SDL_WINDOW_FULLSCREEN) != 0; if(!isFullscreen_) { -#if SDL_VERSION_ATLEAST(2, 0, 5) - SDL_SetWindowResizable(window, SDL_TRUE); -#endif MoveWindowToCenter(); } } @@ -203,6 +206,17 @@ bool VideoSDL2::ResizeScreen(const VideoMode& newSize, bool fullscreen) } UpdateCurrentSizes(); } + + if(windowMode != windowMode_) + { + if(!isFullscreen_) +#if SDL_VERSION_ATLEAST(2, 0, 5) + SDL_SetWindowResizable(window, static_cast(windowMode == WindowMode::Resizable)); +#endif + windowMode_ = + ((SDL_GetWindowFlags(window) & SDL_WINDOW_RESIZABLE) != 0 ? WindowMode::Resizable : WindowMode::NonResizable); + } + return true; } diff --git a/extras/videoDrivers/SDL2/VideoSDL2.h b/extras/videoDrivers/SDL2/VideoSDL2.h index 0a34be639..f16e522ce 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, WindowMode windowMode, bool fullscreen) override; + bool ResizeScreen(const VideoMode& newSize, WindowMode windowMode, bool fullscreen) override; void DestroyScreen() override; diff --git a/extras/videoDrivers/WinAPI/WinAPI.cpp b/extras/videoDrivers/WinAPI/WinAPI.cpp index 8b43cb086..b9bb0615b 100644 --- a/extras/videoDrivers/WinAPI/WinAPI.cpp +++ b/extras/videoDrivers/WinAPI/WinAPI.cpp @@ -138,7 +138,8 @@ void VideoWinAPI::CleanUp() * @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, WindowMode /* windowMode */, + bool fullscreen) { if(!initialized) return false; @@ -174,7 +175,7 @@ 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, WindowMode /* windowMode */, bool fullscreen) { if(!initialized || !isWindowResizable) return false; @@ -253,7 +254,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, WindowMode windowMode) { std::wstring wTitle = boost::nowide::widen(title); windowClassName = wTitle.substr(0, wTitle.find(' ')); diff --git a/extras/videoDrivers/WinAPI/WinAPI.h b/extras/videoDrivers/WinAPI/WinAPI.h index 408e4097e..0e92240b1 100644 --- a/extras/videoDrivers/WinAPI/WinAPI.h +++ b/extras/videoDrivers/WinAPI/WinAPI.h @@ -30,10 +30,11 @@ 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, WindowMode windowMode, + bool fullscreen) override; /// Erstellt oder verändert das Fenster mit entsprechenden Werten. - bool ResizeScreen(const VideoMode& newSize, bool fullscreen) override; + bool ResizeScreen(const VideoMode& newSize, WindowMode windowMode, bool fullscreen) override; /// Schliesst das Fenster. void DestroyScreen() override; diff --git a/libs/driver/include/driver/VideoDriver.h b/libs/driver/include/driver/VideoDriver.h index 9d2860219..13e97a101 100644 --- a/libs/driver/include/driver/VideoDriver.h +++ b/libs/driver/include/driver/VideoDriver.h @@ -30,6 +30,7 @@ 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_; } + WindowMode GetWindowMode() const override final { return windowMode_; } /// prüft auf Initialisierung. bool IsInitialized() const override final { return initialized; } @@ -44,6 +45,7 @@ class VideoDriver : public IVideoDriver MouseCoords mouse_xy; /// Status der Maus. std::array keyboard; /// Status der Tastatur; bool isFullscreen_; /// Vollbild an/aus? + WindowMode windowMode_; /// Resizable/non-resizable window? 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..ae32609ea 100644 --- a/libs/driver/include/driver/VideoInterface.h +++ b/libs/driver/include/driver/VideoInterface.h @@ -14,6 +14,12 @@ /// Function type for loading OpenGL methods using OpenGL_Loader_Proc = void* (*)(const char*); +enum class WindowMode +{ + Resizable, + NonResizable, +}; + class BOOST_SYMBOL_VISIBLE IVideoDriver { public: @@ -25,9 +31,10 @@ 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, WindowMode windowMode, + bool fullscreen) = 0; - virtual bool ResizeScreen(const VideoMode& newSize, bool fullscreen) = 0; + virtual bool ResizeScreen(const VideoMode& newSize, WindowMode windowMode, bool fullscreen) = 0; /// Schliesst das Fenster. virtual void DestroyScreen() = 0; @@ -62,6 +69,7 @@ class BOOST_SYMBOL_VISIBLE IVideoDriver /// Get the size of the render region in pixels virtual Extent GetRenderSize() const = 0; virtual bool IsFullscreen() const = 0; + virtual WindowMode GetWindowMode() const = 0; /// Get state of the modifier keys virtual KeyEvent GetModKeyState() const = 0; diff --git a/libs/s25main/GameManager.cpp b/libs/s25main/GameManager.cpp index 6d3cce356..4293a9cba 100644 --- a/libs/s25main/GameManager.cpp +++ b/libs/s25main/GameManager.cpp @@ -50,7 +50,7 @@ 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)) + if(!videoDriver_.CreateScreen(screenSize, settings_.video.windowMode, settings_.video.fullscreen)) 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..a48afeb77 100644 --- a/libs/s25main/Settings.cpp +++ b/libs/s25main/Settings.cpp @@ -85,10 +85,12 @@ void Settings::LoadDefaults() video.fullscreenSize = VIDEODRIVER.GetWindowSize(); video.windowedSize = VIDEODRIVER.IsFullscreen() ? VideoMode(800, 600) : video.fullscreenSize; video.fullscreen = VIDEODRIVER.IsFullscreen(); + video.windowMode = VIDEODRIVER.GetWindowMode(); } else { video.windowedSize = video.fullscreenSize = VideoMode(800, 600); video.fullscreen = false; + video.windowMode = WindowMode::Resizable; } video.framerate = 0; // Special value for HW vsync video.vbo = true; @@ -224,6 +226,8 @@ void Settings::Load() video.fullscreenSize.width = iniVideo->getIntValue("fullscreen_width"); video.fullscreenSize.height = iniVideo->getIntValue("fullscreen_height"); video.fullscreen = iniVideo->getBoolValue("fullscreen"); + const auto resizable = iniVideo->getValue("resizable_window", true); + video.windowMode = (resizable ? WindowMode::Resizable : WindowMode::NonResizable); video.framerate = iniVideo->getValue("framerate", 0); video.vbo = iniVideo->getBoolValue("vbo"); video.shared_textures = iniVideo->getBoolValue("shared_textures"); @@ -402,6 +406,7 @@ void Settings::Save() iniVideo->setValue("windowed_width", video.windowedSize.width); iniVideo->setValue("windowed_height", video.windowedSize.height); iniVideo->setValue("fullscreen", video.fullscreen); + iniVideo->setValue("resizable_window", video.windowMode == WindowMode::Resizable); 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..01267b87d 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" @@ -61,6 +62,7 @@ class Settings : public Singleton VideoMode fullscreenSize, windowedSize; signed short framerate; // <0 for unlimited, 0 for HW Vsync bool fullscreen; + WindowMode windowMode; bool vbo; bool shared_textures; } video; diff --git a/libs/s25main/WindowManager.cpp b/libs/s25main/WindowManager.cpp index e92a582f7..74ca28c00 100644 --- a/libs/s25main/WindowManager.cpp +++ b/libs/s25main/WindowManager.cpp @@ -602,7 +602,7 @@ void WindowManager::Msg_KeyDown(const KeyEvent& ke) // Switch Fullscreen/Windowed const auto newScreenSize = !SETTINGS.video.fullscreen ? SETTINGS.video.fullscreenSize : SETTINGS.video.windowedSize; //-V807 - VIDEODRIVER.ResizeScreen(newScreenSize, !SETTINGS.video.fullscreen); + VIDEODRIVER.ResizeScreen(newScreenSize, SETTINGS.video.windowMode, !SETTINGS.video.fullscreen); SETTINGS.video.fullscreen = VIDEODRIVER.IsFullscreen(); } else if(ke.kt == KeyType::Print) TakeScreenshot(); diff --git a/libs/s25main/desktops/dskBenchmark.cpp b/libs/s25main/desktops/dskBenchmark.cpp index a65982f72..e5a3ea62f 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), WindowMode::Resizable, false); dskMenuBase::SetActive(activate); } diff --git a/libs/s25main/desktops/dskOptions.cpp b/libs/s25main/desktops/dskOptions.cpp index 633c691ea..3a78e6433 100644 --- a/libs/s25main/desktops/dskOptions.cpp +++ b/libs/s25main/desktops/dskOptions.cpp @@ -575,7 +575,7 @@ void dskOptions::Msg_ButtonClick(const unsigned ctrl_id) { const auto screenSize = SETTINGS.video.fullscreen ? SETTINGS.video.fullscreenSize : SETTINGS.video.windowedSize; - if(!VIDEODRIVER.ResizeScreen(screenSize, SETTINGS.video.fullscreen)) + if(!VIDEODRIVER.ResizeScreen(screenSize, SETTINGS.video.windowMode, SETTINGS.video.fullscreen)) { 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..ba7678877 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 WindowMode windowMode, const bool fullscreen) { 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, windowMode, fullscreen)) { 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 WindowMode windowMode, const bool fullscreen) { 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, windowMode, fullscreen); #ifdef _WIN32 if(!videodriver->IsFullscreen()) { @@ -487,3 +487,8 @@ bool VideoDriverWrapper::IsFullscreen() const { return videodriver->IsFullscreen(); } + +WindowMode VideoDriverWrapper::GetWindowMode() const +{ + return videodriver->GetWindowMode(); +} diff --git a/libs/s25main/drivers/VideoDriverWrapper.h b/libs/s25main/drivers/VideoDriverWrapper.h index 80b530145..e2d19c6c8 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( _("Sorry!"), _("You need to restart your game to change the screen resolution!"), this, diff --git a/tests/mockupDrivers/MockupVideoDriver.cpp b/tests/mockupDrivers/MockupVideoDriver.cpp index 7b239109f..8bd56e133 100644 --- a/tests/mockupDrivers/MockupVideoDriver.cpp +++ b/tests/mockupDrivers/MockupVideoDriver.cpp @@ -29,16 +29,18 @@ 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, WindowMode windowMode, + bool fullscreen) { - ResizeScreen(newSize, fullscreen); + ResizeScreen(newSize, windowMode, fullscreen); return true; } -bool MockupVideoDriver::ResizeScreen(const VideoMode& newSize, bool fullscreen) +bool MockupVideoDriver::ResizeScreen(const VideoMode& newSize, WindowMode windowMode, bool fullscreen) { SetNewSize(newSize, Extent(newSize.width, newSize.height)); isFullscreen_ = fullscreen; + windowMode_ = windowMode; return true; } diff --git a/tests/mockupDrivers/MockupVideoDriver.h b/tests/mockupDrivers/MockupVideoDriver.h index 2f24ccaf4..6cce2fd1e 100644 --- a/tests/mockupDrivers/MockupVideoDriver.h +++ b/tests/mockupDrivers/MockupVideoDriver.h @@ -13,8 +13,9 @@ 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, WindowMode windowMode, + bool fullscreen) override; + bool ResizeScreen(const VideoMode& newSize, WindowMode windowMode, bool fullscreen) override; void DestroyScreen() override {} bool SwapBuffers() override { return true; } bool MessageLoop() override;