1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-01-26 03:52:01 +02:00

Rename & cleanup of WindowHandler -> ScreenHandler

This commit is contained in:
Ivan Savenko 2023-05-08 13:22:01 +03:00
parent 29b10f0436
commit e26b18c139
8 changed files with 107 additions and 88 deletions

View File

@ -24,7 +24,7 @@
#include "gui/NotificationHandler.h" #include "gui/NotificationHandler.h"
#include "ClientCommandManager.h" #include "ClientCommandManager.h"
#include "windows/CMessage.h" #include "windows/CMessage.h"
#include "render/IWindowHandler.h" #include "render/IScreenHandler.h"
#include "../lib/filesystem/Filesystem.h" #include "../lib/filesystem/Filesystem.h"
#include "../lib/CConsoleHandler.h" #include "../lib/CConsoleHandler.h"
@ -348,7 +348,7 @@ int main(int argc, char * argv[])
{ {
if(!vm.count("battle") && !vm.count("nointro") && settings["video"]["showIntro"].Bool()) if(!vm.count("battle") && !vm.count("nointro") && settings["video"]["showIntro"].Bool())
playIntro(); playIntro();
GH.windowHandler().clearScreen(); GH.screenHandler().clearScreen();
} }
@ -547,7 +547,7 @@ static void handleEvent(SDL_Event & ev)
case EUserEvent::FULLSCREEN_TOGGLED: case EUserEvent::FULLSCREEN_TOGGLED:
{ {
boost::unique_lock<boost::recursive_mutex> lock(*CPlayerInterface::pim); boost::unique_lock<boost::recursive_mutex> lock(*CPlayerInterface::pim);
GH.windowHandler().onScreenResize(); GH.screenHandler().onScreenResize();
break; break;
} }
default: default:
@ -564,7 +564,7 @@ static void handleEvent(SDL_Event & ev)
#ifndef VCMI_IOS #ifndef VCMI_IOS
{ {
boost::unique_lock<boost::recursive_mutex> lock(*CPlayerInterface::pim); boost::unique_lock<boost::recursive_mutex> lock(*CPlayerInterface::pim);
GH.windowHandler().onScreenResize(); GH.screenHandler().onScreenResize();
} }
#endif #endif
break; break;
@ -651,7 +651,7 @@ static void quitApplication()
boost::this_thread::sleep(boost::posix_time::milliseconds(750));//??? boost::this_thread::sleep(boost::posix_time::milliseconds(750));//???
if(!settings["session"]["headless"].Bool()) if(!settings["session"]["headless"].Bool())
GH.windowHandler().close(); GH.screenHandler().close();
if(logConfig != nullptr) if(logConfig != nullptr)
{ {

View File

@ -76,7 +76,7 @@ set(client_SRCS
renderSDL/SDLImage.cpp renderSDL/SDLImage.cpp
renderSDL/SDLImageLoader.cpp renderSDL/SDLImageLoader.cpp
renderSDL/SDLRWwrapper.cpp renderSDL/SDLRWwrapper.cpp
renderSDL/WindowHandler.cpp renderSDL/ScreenHandler.cpp
renderSDL/SDL_Extensions.cpp renderSDL/SDL_Extensions.cpp
widgets/Buttons.cpp widgets/Buttons.cpp
@ -206,7 +206,7 @@ set(client_HEADERS
render/IFont.h render/IFont.h
render/IImage.h render/IImage.h
render/IImageLoader.h render/IImageLoader.h
render/IWindowHandler.h render/IScreenHandler.h
renderSDL/CBitmapFont.h renderSDL/CBitmapFont.h
renderSDL/CBitmapHanFont.h renderSDL/CBitmapHanFont.h
@ -216,7 +216,7 @@ set(client_HEADERS
renderSDL/SDLImage.h renderSDL/SDLImage.h
renderSDL/SDLImageLoader.h renderSDL/SDLImageLoader.h
renderSDL/SDLRWwrapper.h renderSDL/SDLRWwrapper.h
renderSDL/WindowHandler.h renderSDL/ScreenHandler.h
renderSDL/SDL_Extensions.h renderSDL/SDL_Extensions.h
renderSDL/SDL_PixelAccess.h renderSDL/SDL_PixelAccess.h

View File

@ -18,7 +18,7 @@
#include "../CGameInfo.h" #include "../CGameInfo.h"
#include "../render/Colors.h" #include "../render/Colors.h"
#include "../renderSDL/SDL_Extensions.h" #include "../renderSDL/SDL_Extensions.h"
#include "../renderSDL/WindowHandler.h" #include "../renderSDL/ScreenHandler.h"
#include "../CMT.h" #include "../CMT.h"
#include "../CPlayerInterface.h" #include "../CPlayerInterface.h"
#include "../battle/BattleInterface.h" #include "../battle/BattleInterface.h"
@ -98,7 +98,7 @@ void CGuiHandler::processLists(const ui16 activityFlag, std::function<void (std:
void CGuiHandler::init() void CGuiHandler::init()
{ {
windowHandlerInstance = std::make_unique<WindowHandler>(); screenHandlerInstance = std::make_unique<ScreenHandler>();
shortcutsHandlerInstance = std::make_unique<ShortcutHandler>(); shortcutsHandlerInstance = std::make_unique<ShortcutHandler>();
mainFPSmng = new CFramerateManager(settings["video"]["targetfps"].Integer()); mainFPSmng = new CFramerateManager(settings["video"]["targetfps"].Integer());
@ -806,9 +806,9 @@ void CGuiHandler::pushUserEvent(EUserEvent usercode, void * userdata)
SDL_PushEvent(&event); SDL_PushEvent(&event);
} }
IWindowHandler & CGuiHandler::windowHandler() IScreenHandler & CGuiHandler::screenHandler()
{ {
return *windowHandlerInstance; return *screenHandlerInstance;
} }
void CGuiHandler::onScreenResize() void CGuiHandler::onScreenResize()

View File

@ -29,7 +29,7 @@ class CIntObject;
class IUpdateable; class IUpdateable;
class IShowActivatable; class IShowActivatable;
class IShowable; class IShowable;
class IWindowHandler; class IScreenHandler;
// TODO: event handling need refactoring // TODO: event handling need refactoring
enum class EUserEvent enum class EUserEvent
@ -96,7 +96,7 @@ private:
CIntObjectList doubleClickInterested; CIntObjectList doubleClickInterested;
CIntObjectList textInterested; CIntObjectList textInterested;
std::unique_ptr<IWindowHandler> windowHandlerInstance; std::unique_ptr<IScreenHandler> screenHandlerInstance;
void handleMouseButtonClick(CIntObjectList & interestedObjs, MouseButton btn, bool isPressed); void handleMouseButtonClick(CIntObjectList & interestedObjs, MouseButton btn, bool isPressed);
void processLists(const ui16 activityFlag, std::function<void (std::list<CIntObject*> *)> cb); void processLists(const ui16 activityFlag, std::function<void (std::list<CIntObject*> *)> cb);
@ -137,7 +137,7 @@ public:
/// moves mouse pointer into specified position inside vcmi window /// moves mouse pointer into specified position inside vcmi window
void moveCursorToPosition(const Point & position); void moveCursorToPosition(const Point & position);
IWindowHandler & windowHandler(); IScreenHandler & screenHandler();
IUpdateable *curInt; IUpdateable *curInt;

View File

@ -1,5 +1,5 @@
/* /*
* IWindowHandler.h, part of VCMI engine * IScreenHandler.h, part of VCMI engine
* *
* Authors: listed in file AUTHORS in main folder * Authors: listed in file AUTHORS in main folder
* *
@ -14,10 +14,10 @@ VCMI_LIB_NAMESPACE_BEGIN
class Point; class Point;
VCMI_LIB_NAMESPACE_END VCMI_LIB_NAMESPACE_END
class IWindowHandler class IScreenHandler
{ {
public: public:
virtual ~IWindowHandler() = default; virtual ~IScreenHandler() = default;
/// Updates window state after fullscreen state has been changed in settings /// Updates window state after fullscreen state has been changed in settings
virtual void onScreenResize() = 0; virtual void onScreenResize() = 0;
@ -31,6 +31,6 @@ public:
/// Returns list of resolutions supported by current screen /// Returns list of resolutions supported by current screen
virtual std::vector<Point> getSupportedResolutions() const = 0; virtual std::vector<Point> getSupportedResolutions() const = 0;
/// Returns <min, max> range of possible values for screen scaling /// Returns <min, max> range of possible values for screen scaling percentage
virtual std::tuple<double, double> getSupportedScalingRange() const = 0; virtual std::tuple<int, int> getSupportedScalingRange() const = 0;
}; };

View File

@ -1,5 +1,5 @@
/* /*
* WindowHandler.cpp, part of VCMI engine * ScreenHandler.cpp, part of VCMI engine
* *
* Authors: listed in file AUTHORS in main folder * Authors: listed in file AUTHORS in main folder
* *
@ -9,7 +9,7 @@
*/ */
#include "StdInc.h" #include "StdInc.h"
#include "WindowHandler.h" #include "ScreenHandler.h"
#include "../../lib/CConfigHandler.h" #include "../../lib/CConfigHandler.h"
#include "../gui/CGuiHandler.h" #include "../gui/CGuiHandler.h"
@ -23,6 +23,7 @@
#include <SDL.h> #include <SDL.h>
// TODO: should be made into a private members of ScreenHandler
SDL_Window * mainWindow = nullptr; SDL_Window * mainWindow = nullptr;
SDL_Renderer * mainRenderer = nullptr; SDL_Renderer * mainRenderer = nullptr;
SDL_Texture * screenTexture = nullptr; SDL_Texture * screenTexture = nullptr;
@ -33,7 +34,7 @@ SDL_Surface * screenBuf = screen; //points to screen (if only advmapint is prese
static const std::string NAME_AFFIX = "client"; static const std::string NAME_AFFIX = "client";
static const std::string NAME = GameConstants::VCMI_VERSION + std::string(" (") + NAME_AFFIX + ')'; //application name static const std::string NAME = GameConstants::VCMI_VERSION + std::string(" (") + NAME_AFFIX + ')'; //application name
std::tuple<double, double> WindowHandler::getSupportedScalingRange() const std::tuple<int, int> ScreenHandler::getSupportedScalingRange() const
{ {
// H3 resolution, any resolution smaller than that is not correctly supported // H3 resolution, any resolution smaller than that is not correctly supported
static const Point minResolution = {800, 600}; static const Point minResolution = {800, 600};
@ -48,22 +49,22 @@ std::tuple<double, double> WindowHandler::getSupportedScalingRange() const
return { minimalScaling, maximalScaling }; return { minimalScaling, maximalScaling };
} }
Point WindowHandler::getPreferredLogicalResolution() const Point ScreenHandler::getPreferredLogicalResolution() const
{ {
Point renderResolution = getPreferredRenderingResolution(); Point renderResolution = getPreferredRenderingResolution();
auto [minimalScaling, maximalScaling] = getSupportedScalingRange(); auto [minimalScaling, maximalScaling] = getSupportedScalingRange();
double userScaling = settings["video"]["resolution"]["scaling"].Float(); int userScaling = settings["video"]["resolution"]["scaling"].Integer();
double scaling = std::clamp(userScaling, minimalScaling, maximalScaling); int scaling = std::clamp(userScaling, minimalScaling, maximalScaling);
Point logicalResolution = renderResolution * 100.0 / scaling; Point logicalResolution = renderResolution * 100.0 / scaling;
return logicalResolution; return logicalResolution;
} }
Point WindowHandler::getPreferredRenderingResolution() const Point ScreenHandler::getPreferredRenderingResolution() const
{ {
if (getPreferredWindowMode() == EWindowMode::FULLSCREEN_WINDOWED) if (getPreferredWindowMode() == EWindowMode::FULLSCREEN_BORDERLESS_WINDOWED)
{ {
SDL_Rect bounds; SDL_Rect bounds;
SDL_GetDisplayBounds(getPreferredDisplayIndex(), &bounds); SDL_GetDisplayBounds(getPreferredDisplayIndex(), &bounds);
@ -79,7 +80,7 @@ Point WindowHandler::getPreferredRenderingResolution() const
} }
} }
int WindowHandler::getPreferredDisplayIndex() const int ScreenHandler::getPreferredDisplayIndex() const
{ {
#ifdef VCMI_MOBILE #ifdef VCMI_MOBILE
// Assuming no multiple screens on Android / ios? // Assuming no multiple screens on Android / ios?
@ -92,11 +93,11 @@ int WindowHandler::getPreferredDisplayIndex() const
#endif #endif
} }
EWindowMode WindowHandler::getPreferredWindowMode() const EWindowMode ScreenHandler::getPreferredWindowMode() const
{ {
#ifdef VCMI_MOBILE #ifdef VCMI_MOBILE
// On Android / ios game will always render to screen size // On Android / ios game will always render to screen size
return EWindowMode::FULLSCREEN_WINDOWED; return EWindowMode::FULLSCREEN_BORDERLESS_WINDOWED;
#else #else
const JsonNode & video = settings["video"]; const JsonNode & video = settings["video"];
bool fullscreen = video["fullscreen"].Bool(); bool fullscreen = video["fullscreen"].Bool();
@ -106,13 +107,13 @@ EWindowMode WindowHandler::getPreferredWindowMode() const
return EWindowMode::WINDOWED; return EWindowMode::WINDOWED;
if (realFullscreen) if (realFullscreen)
return EWindowMode::FULLSCREEN_TRUE; return EWindowMode::FULLSCREEN_EXCLUSIVE;
else else
return EWindowMode::FULLSCREEN_WINDOWED; return EWindowMode::FULLSCREEN_BORDERLESS_WINDOWED;
#endif #endif
} }
WindowHandler::WindowHandler() ScreenHandler::ScreenHandler()
{ {
#ifdef VCMI_WINDOWS #ifdef VCMI_WINDOWS
// set VCMI as "per-monitor DPI awareness". This completely disables any DPI-scaling by system. // set VCMI as "per-monitor DPI awareness". This completely disables any DPI-scaling by system.
@ -145,36 +146,34 @@ WindowHandler::WindowHandler()
#endif // VCMI_ANDROID #endif // VCMI_ANDROID
validateSettings(); validateSettings();
recreateWindow(); recreateWindowAndScreenBuffers();
} }
bool WindowHandler::recreateWindow() void ScreenHandler::recreateWindowAndScreenBuffers()
{ {
destroyScreen(); destroyScreenBuffers();
if(mainWindow == nullptr) if(mainWindow == nullptr)
initializeRenderer(); initializeWindow();
else else
updateFullscreenState(); updateWindowState();
initializeScreen(); initializeScreenBuffers();
if(!settings["session"]["headless"].Bool() && settings["general"]["notifications"].Bool()) if(!settings["session"]["headless"].Bool() && settings["general"]["notifications"].Bool())
{ {
NotificationHandler::init(mainWindow); NotificationHandler::init(mainWindow);
} }
return true;
} }
void WindowHandler::updateFullscreenState() void ScreenHandler::updateWindowState()
{ {
#if !defined(VCMI_MOBILE) #if !defined(VCMI_MOBILE)
int displayIndex = getPreferredDisplayIndex(); int displayIndex = getPreferredDisplayIndex();
switch(getPreferredWindowMode()) switch(getPreferredWindowMode())
{ {
case EWindowMode::FULLSCREEN_TRUE: case EWindowMode::FULLSCREEN_EXCLUSIVE:
{ {
SDL_SetWindowFullscreen(mainWindow, SDL_WINDOW_FULLSCREEN); SDL_SetWindowFullscreen(mainWindow, SDL_WINDOW_FULLSCREEN);
@ -190,7 +189,7 @@ void WindowHandler::updateFullscreenState()
return; return;
} }
case EWindowMode::FULLSCREEN_WINDOWED: case EWindowMode::FULLSCREEN_BORDERLESS_WINDOWED:
{ {
SDL_SetWindowFullscreen(mainWindow, SDL_WINDOW_FULLSCREEN_DESKTOP); SDL_SetWindowFullscreen(mainWindow, SDL_WINDOW_FULLSCREEN_DESKTOP);
SDL_SetWindowPosition(mainWindow, SDL_WINDOWPOS_UNDEFINED_DISPLAY(displayIndex), SDL_WINDOWPOS_UNDEFINED_DISPLAY(displayIndex)); SDL_SetWindowPosition(mainWindow, SDL_WINDOWPOS_UNDEFINED_DISPLAY(displayIndex), SDL_WINDOWPOS_UNDEFINED_DISPLAY(displayIndex));
@ -208,7 +207,7 @@ void WindowHandler::updateFullscreenState()
#endif #endif
} }
void WindowHandler::initializeRenderer() void ScreenHandler::initializeWindow()
{ {
mainWindow = createWindow(); mainWindow = createWindow();
@ -227,7 +226,7 @@ void WindowHandler::initializeRenderer()
logGlobal->info("Created renderer %s", info.name); logGlobal->info("Created renderer %s", info.name);
} }
void WindowHandler::initializeScreen() void ScreenHandler::initializeScreenBuffers()
{ {
#ifdef VCMI_ENDIAN_BIG #ifdef VCMI_ENDIAN_BIG
int bmask = 0xff000000; int bmask = 0xff000000;
@ -277,7 +276,7 @@ void WindowHandler::initializeScreen()
clearScreen(); clearScreen();
} }
SDL_Window * WindowHandler::createWindowImpl(Point dimensions, int flags, bool center) SDL_Window * ScreenHandler::createWindowImpl(Point dimensions, int flags, bool center)
{ {
int displayIndex = getPreferredDisplayIndex(); int displayIndex = getPreferredDisplayIndex();
int positionFlags = center ? SDL_WINDOWPOS_CENTERED_DISPLAY(displayIndex) : SDL_WINDOWPOS_UNDEFINED_DISPLAY(displayIndex); int positionFlags = center ? SDL_WINDOWPOS_CENTERED_DISPLAY(displayIndex) : SDL_WINDOWPOS_UNDEFINED_DISPLAY(displayIndex);
@ -285,17 +284,17 @@ SDL_Window * WindowHandler::createWindowImpl(Point dimensions, int flags, bool c
return SDL_CreateWindow(NAME.c_str(), positionFlags, positionFlags, dimensions.x, dimensions.y, flags); return SDL_CreateWindow(NAME.c_str(), positionFlags, positionFlags, dimensions.x, dimensions.y, flags);
} }
SDL_Window * WindowHandler::createWindow() SDL_Window * ScreenHandler::createWindow()
{ {
#ifndef VCMI_MOBILE #ifndef VCMI_MOBILE
Point dimensions = getPreferredRenderingResolution(); Point dimensions = getPreferredRenderingResolution();
switch(getPreferredWindowMode()) switch(getPreferredWindowMode())
{ {
case EWindowMode::FULLSCREEN_TRUE: case EWindowMode::FULLSCREEN_EXCLUSIVE:
return createWindowImpl(dimensions, SDL_WINDOW_FULLSCREEN, false); return createWindowImpl(dimensions, SDL_WINDOW_FULLSCREEN, false);
case EWindowMode::FULLSCREEN_WINDOWED: case EWindowMode::FULLSCREEN_BORDERLESS_WINDOWED:
return createWindowImpl(Point(), SDL_WINDOW_FULLSCREEN_DESKTOP, false); return createWindowImpl(Point(), SDL_WINDOW_FULLSCREEN_DESKTOP, false);
case EWindowMode::WINDOWED: case EWindowMode::WINDOWED:
@ -325,17 +324,13 @@ SDL_Window * WindowHandler::createWindow()
#endif #endif
} }
void WindowHandler::onScreenResize() void ScreenHandler::onScreenResize()
{ {
if(!recreateWindow()) recreateWindowAndScreenBuffers();
{
//will return false and report error if video mode is not supported
return;
}
GH.onScreenResize(); GH.onScreenResize();
} }
void WindowHandler::validateSettings() void ScreenHandler::validateSettings()
{ {
#if !defined(VCMI_MOBILE) #if !defined(VCMI_MOBILE)
{ {
@ -368,14 +363,29 @@ void WindowHandler::validateSettings()
} }
} }
if (getPreferredWindowMode() == EWindowMode::FULLSCREEN_TRUE) if (getPreferredWindowMode() == EWindowMode::FULLSCREEN_EXCLUSIVE)
{ {
// TODO: check that display supports selected resolution auto legalOptions = getSupportedResolutions();
Point selectedResolution = getPreferredRenderingResolution();
if(!vstd::contains(legalOptions, selectedResolution))
{
// resolution selected for fullscreen mode is not supported by display
// try to find current display resolution and use it instead as "reasonable default"
SDL_DisplayMode mode;
if (SDL_GetDesktopDisplayMode(getPreferredDisplayIndex(), &mode) == 0)
{
Settings writer = settings.write["video"]["resolution"];
writer["width"].Float() = mode.w;
writer["height"].Float() = mode.h;
}
}
} }
#endif #endif
} }
int WindowHandler::getPreferredRenderingDriver() const int ScreenHandler::getPreferredRenderingDriver() const
{ {
int result = -1; int result = -1;
const JsonNode & video = settings["video"]; const JsonNode & video = settings["video"];
@ -403,9 +413,10 @@ int WindowHandler::getPreferredRenderingDriver() const
return result; return result;
} }
void WindowHandler::destroyScreen() void ScreenHandler::destroyScreenBuffers()
{ {
screenBuf = nullptr; //it`s a link - just nullify // screenBuf is not a separate surface, but points to either screen or screen2 - just set to null
screenBuf = nullptr;
if(nullptr != screen2) if(nullptr != screen2)
{ {
@ -426,7 +437,7 @@ void WindowHandler::destroyScreen()
} }
} }
void WindowHandler::destroyWindow() void ScreenHandler::destroyWindow()
{ {
if(nullptr != mainRenderer) if(nullptr != mainRenderer)
{ {
@ -441,32 +452,32 @@ void WindowHandler::destroyWindow()
} }
} }
void WindowHandler::close() void ScreenHandler::close()
{ {
if(settings["general"]["notifications"].Bool()) if(settings["general"]["notifications"].Bool())
NotificationHandler::destroy(); NotificationHandler::destroy();
destroyScreen(); destroyScreenBuffers();
destroyWindow(); destroyWindow();
SDL_Quit(); SDL_Quit();
} }
void WindowHandler::clearScreen() void ScreenHandler::clearScreen()
{ {
SDL_SetRenderDrawColor(mainRenderer, 0, 0, 0, 255); SDL_SetRenderDrawColor(mainRenderer, 0, 0, 0, 255);
SDL_RenderClear(mainRenderer); SDL_RenderClear(mainRenderer);
SDL_RenderPresent(mainRenderer); SDL_RenderPresent(mainRenderer);
} }
std::vector<Point> WindowHandler::getSupportedResolutions() const std::vector<Point> ScreenHandler::getSupportedResolutions() const
{ {
int displayID = SDL_GetWindowDisplayIndex(mainWindow); int displayID = SDL_GetWindowDisplayIndex(mainWindow);
return getSupportedResolutions(displayID); return getSupportedResolutions(displayID);
} }
std::vector<Point> WindowHandler::getSupportedResolutions( int displayIndex) const std::vector<Point> ScreenHandler::getSupportedResolutions( int displayIndex) const
{ {
//TODO: check this method on iOS / Android //NOTE: this method is never called on Android/iOS, only on desktop systems
std::vector<Point> result; std::vector<Point> result;
@ -488,6 +499,7 @@ std::vector<Point> WindowHandler::getSupportedResolutions( int displayIndex) con
return left.x * left.y < right.x * right.y; return left.x * left.y < right.x * right.y;
}); });
// erase potential duplicates, e.g. resolutions with different framerate / bits per pixel
result.erase(boost::unique(result).end(), result.end()); result.erase(boost::unique(result).end(), result.end());
return result; return result;

View File

@ -1,5 +1,5 @@
/* /*
* WindowHandler.h, part of VCMI engine * ScreenHandler.h, part of VCMI engine
* *
* Authors: listed in file AUTHORS in main folder * Authors: listed in file AUTHORS in main folder
* *
@ -16,7 +16,7 @@ struct SDL_Renderer;
struct SDL_Surface; struct SDL_Surface;
#include "../../lib/Point.h" #include "../../lib/Point.h"
#include "../render/IWindowHandler.h" #include "../render/IScreenHandler.h"
enum class EWindowMode enum class EWindowMode
{ {
@ -24,13 +24,13 @@ enum class EWindowMode
WINDOWED, WINDOWED,
// game runs in a 'window' that always covers entire screen and uses unmodified desktop resolution // game runs in a 'window' that always covers entire screen and uses unmodified desktop resolution
// The only mode that is available on mobile devices // The only mode that is available on mobile devices
FULLSCREEN_WINDOWED, FULLSCREEN_BORDERLESS_WINDOWED,
// game runs in a fullscreen mode with resolution selected by player // game runs in a fullscreen mode with resolution selected by player
FULLSCREEN_TRUE FULLSCREEN_EXCLUSIVE
}; };
/// This class is responsible for management of game window and its main rendering surface /// This class is responsible for management of game window and its main rendering surface
class WindowHandler : public IWindowHandler class ScreenHandler : public IScreenHandler
{ {
/// Dimensions of target surfaces/textures, this value is what game logic views as screen size /// Dimensions of target surfaces/textures, this value is what game logic views as screen size
Point getPreferredLogicalResolution() const; Point getPreferredLogicalResolution() const;
@ -53,19 +53,26 @@ class WindowHandler : public IWindowHandler
/// Creates SDL window using OS-specific settings & user-specific config /// Creates SDL window using OS-specific settings & user-specific config
SDL_Window * createWindow(); SDL_Window * createWindow();
void initializeRenderer(); /// Manages window and SDL renderer
void initializeScreen(); void initializeWindow();
void updateFullscreenState();
bool recreateWindow();
void destroyScreen();
void destroyWindow(); void destroyWindow();
/// Manages surfaces & textures used for
void initializeScreenBuffers();
void destroyScreenBuffers();
/// Updates state (e.g. position) of game window after resolution/fullscreen change
void updateWindowState();
/// Initializes or reiniitalizes all screen state
void recreateWindowAndScreenBuffers();
/// Performs validation of settings and updates them to valid values if necessary
void validateSettings(); void validateSettings();
public: public:
/// Creates and initializes screen, window and SDL state /// Creates and initializes screen, window and SDL state
WindowHandler(); ScreenHandler();
/// Updates and potentially recreates target screen to match selected fullscreen status /// Updates and potentially recreates target screen to match selected fullscreen status
void onScreenResize() final; void onScreenResize() final;
@ -78,5 +85,5 @@ public:
std::vector<Point> getSupportedResolutions() const final; std::vector<Point> getSupportedResolutions() const final;
std::vector<Point> getSupportedResolutions(int displayIndex) const; std::vector<Point> getSupportedResolutions(int displayIndex) const;
std::tuple<double, double> getSupportedScalingRange() const final; std::tuple<int, int> getSupportedScalingRange() const final;
}; };

View File

@ -22,7 +22,7 @@
#include "CPlayerInterface.h" #include "CPlayerInterface.h"
#include "windows/GUIClasses.h" #include "windows/GUIClasses.h"
#include "CServerHandler.h" #include "CServerHandler.h"
#include "render/IWindowHandler.h" #include "render/IScreenHandler.h"
static void setIntSetting(std::string group, std::string field, int value) static void setIntSetting(std::string group, std::string field, int value)
@ -183,7 +183,7 @@ GeneralOptionsTab::GeneralOptionsTab()
void GeneralOptionsTab::selectGameResolution() void GeneralOptionsTab::selectGameResolution()
{ {
supportedResolutions = GH.windowHandler().getSupportedResolutions(); supportedResolutions = GH.screenHandler().getSupportedResolutions();
std::vector<std::string> items; std::vector<std::string> items;
size_t currentResolutionIndex = 0; size_t currentResolutionIndex = 0;
@ -232,10 +232,10 @@ void GeneralOptionsTab::selectGameScaling()
{ {
supportedScaling.clear(); supportedScaling.clear();
auto [minimalScaling, maximalScaling] = GH.windowHandler().getSupportedScalingRange(); auto [minimalScaling, maximalScaling] = GH.screenHandler().getSupportedScalingRange();
for (int i = 0; i <= static_cast<int>(maximalScaling); i += 10) for (int i = 0; i <= maximalScaling; i += 10)
{ {
if (i >= static_cast<int>(minimalScaling)) if (i >= minimalScaling)
supportedScaling.push_back(i); supportedScaling.push_back(i);
} }