Skip to content

Commit

Permalink
Enable non-resizable windows (SDL2 only)
Browse files Browse the repository at this point in the history
Add a hidden setting to control whether the window is resizable.

Fixes #1512
  • Loading branch information
falbrechtskirchinger committed Jul 10, 2023
1 parent 60499d9 commit d40a26b
Show file tree
Hide file tree
Showing 20 changed files with 88 additions and 38 deletions.
39 changes: 30 additions & 9 deletions extras/videoDrivers/SDL2/VideoSDL2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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, WindowMode windowMode, bool fullscreen)
{
if(!initialized)
return false;
Expand All @@ -116,15 +116,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)
Expand All @@ -133,7 +136,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_)
Expand Down Expand Up @@ -161,7 +166,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;
Expand All @@ -171,12 +176,17 @@ bool VideoSDL2::ResizeScreen(const VideoMode& newSize, bool fullscreen)
SDL_SetWindowFullscreen(window, fullscreen ? SDL_WINDOW_FULLSCREEN : 0);
isFullscreen_ = (SDL_GetWindowFlags(window) & SDL_WINDOW_FULLSCREEN) != 0;
if(!isFullscreen_)
{
MoveWindowToCenter();
}

if(!isFullscreen_ || windowMode != windowMode_)
{
if(!isFullscreen_)
#if SDL_VERSION_ATLEAST(2, 0, 5)
SDL_SetWindowResizable(window, SDL_TRUE);
SDL_SetWindowResizable(window, static_cast<SDL_bool>(windowMode == WindowMode::Resizable));
#endif
MoveWindowToCenter();
}
windowMode_ =
((SDL_GetWindowFlags(window) & SDL_WINDOW_RESIZABLE) != 0 ? WindowMode::Resizable : WindowMode::NonResizable);
}

if(newSize != GetWindowSize())
Expand All @@ -203,6 +213,17 @@ bool VideoSDL2::ResizeScreen(const VideoMode& newSize, bool fullscreen)
}
UpdateCurrentSizes();
}

if(isFullscreen_ != fullscreen || windowMode != windowMode_)
{
if(!isFullscreen_)
#if SDL_VERSION_ATLEAST(2, 0, 5)
SDL_SetWindowResizable(window, static_cast<SDL_bool>(windowMode == WindowMode::Resizable));
#endif
windowMode_ =
((SDL_GetWindowFlags(window) & SDL_WINDOW_RESIZABLE) != 0 ? WindowMode::Resizable : WindowMode::NonResizable);
}

return true;
}

Expand Down
4 changes: 2 additions & 2 deletions extras/videoDrivers/SDL2/VideoSDL2.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
7 changes: 4 additions & 3 deletions extras/videoDrivers/WinAPI/WinAPI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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(' '));
Expand Down
5 changes: 3 additions & 2 deletions extras/videoDrivers/WinAPI/WinAPI.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 2 additions & 0 deletions libs/driver/include/driver/VideoDriver.h
Original file line number Diff line number Diff line change
Expand Up @@ -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; }
Expand All @@ -44,6 +45,7 @@ class VideoDriver : public IVideoDriver
MouseCoords mouse_xy; /// Status der Maus.
std::array<bool, 512> keyboard; /// Status der Tastatur;
bool isFullscreen_; /// Vollbild an/aus?
WindowMode windowMode_; /// Resizable/non-resizable window?
private:
// cached as possibly used often
VideoMode windowSize_;
Expand Down
12 changes: 10 additions & 2 deletions libs/driver/include/driver/VideoInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion libs/s25main/GameManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
5 changes: 5 additions & 0 deletions libs/s25main/Settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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");
Expand Down Expand Up @@ -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);
Expand Down
2 changes: 2 additions & 0 deletions libs/s25main/Settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -61,6 +62,7 @@ class Settings : public Singleton<Settings, SingletonPolicies::WithLongevity>
VideoMode fullscreenSize, windowedSize;
signed short framerate; // <0 for unlimited, 0 for HW Vsync
bool fullscreen;
WindowMode windowMode;
bool vbo;
bool shared_textures;
} video;
Expand Down
2 changes: 1 addition & 1 deletion libs/s25main/WindowManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
2 changes: 1 addition & 1 deletion libs/s25main/desktops/dskBenchmark.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down
2 changes: 1 addition & 1 deletion libs/s25main/desktops/dskOptions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<iwMsgbox>(
_("Sorry!"), _("You need to restart your game to change the screen resolution!"), this,
Expand Down
13 changes: 9 additions & 4 deletions libs/s25main/drivers/VideoDriverWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,15 +92,15 @@ 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)
{
s25util::fatal_error("No video driver selected!");
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;
Expand Down Expand Up @@ -134,15 +134,15 @@ 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)
{
s25util::fatal_error("No video driver selected!");
return false;
}

const bool result = videodriver->ResizeScreen(size, fullscreen);
const bool result = videodriver->ResizeScreen(size, windowMode, fullscreen);
#ifdef _WIN32
if(!videodriver->IsFullscreen())
{
Expand Down Expand Up @@ -487,3 +487,8 @@ bool VideoDriverWrapper::IsFullscreen() const
{
return videodriver->IsFullscreen();
}

WindowMode VideoDriverWrapper::GetWindowMode() const
{
return videodriver->GetWindowMode();
}
6 changes: 4 additions & 2 deletions libs/s25main/drivers/VideoDriverWrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 <memory>
Expand Down Expand Up @@ -35,9 +36,9 @@ class VideoDriverWrapper : public Singleton<VideoDriverWrapper, SingletonPolicie
IVideoDriver* GetDriver() const { return videodriver.get(); }

/// Erstellt das Fenster.
bool CreateScreen(VideoMode size, bool fullscreen);
bool CreateScreen(VideoMode size, WindowMode windowMode, bool fullscreen);
/// Verändert Auflösung, Fenster/Fullscreen
bool ResizeScreen(VideoMode size, bool fullscreen);
bool ResizeScreen(VideoMode size, WindowMode windowMode, bool fullscreen);
/// Viewport (neu) setzen
void RenewViewport();
/// zerstört das Fenster.
Expand Down Expand Up @@ -69,6 +70,7 @@ class VideoDriverWrapper : public Singleton<VideoDriverWrapper, SingletonPolicie
/// Get the renderer size in pixels
Extent GetRenderSize() const;
bool IsFullscreen() const;
WindowMode GetWindowMode() const;

bool IsLeftDown();
bool IsRightDown();
Expand Down
2 changes: 1 addition & 1 deletion libs/s25main/ingameWindows/iwSettings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ iwSettings::~iwSettings()
{
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<iwMsgbox>(
_("Sorry!"), _("You need to restart your game to change the screen resolution!"), this,
Expand Down
8 changes: 5 additions & 3 deletions tests/mockupDrivers/MockupVideoDriver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
5 changes: 3 additions & 2 deletions tests/mockupDrivers/MockupVideoDriver.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion tests/s25Main/UI/testAnimations.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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), WindowMode::Resizable, false);
// Pass the animation
video->tickCount_ += 1100;
dsk->Msg_PaintBefore();
Expand Down
Loading

0 comments on commit d40a26b

Please sign in to comment.