1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-08-13 19:54:17 +02:00

Support for changing resolution without game restart

This commit is contained in:
Ivan Savenko
2023-05-04 22:33:25 +03:00
parent 97426a3f7c
commit fd3933e589
10 changed files with 53 additions and 7 deletions

View File

@@ -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().onFullscreenChanged(); GH.windowHandler().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().onFullscreenChanged(); GH.windowHandler().onScreenResize();
} }
#endif #endif
break; break;
@@ -593,8 +593,10 @@ static void handleEvent(SDL_Event & ev)
static void mainLoop() static void mainLoop()
{ {
SettingsListener resChanged = settings.listen["video"]["fullscreen"]; SettingsListener resChanged = settings.listen["video"]["resolution"];
SettingsListener fsChanged = settings.listen["video"]["fullscreen"];
resChanged([](const JsonNode &newState){ CGuiHandler::pushUserEvent(EUserEvent::FULLSCREEN_TOGGLED); }); resChanged([](const JsonNode &newState){ CGuiHandler::pushUserEvent(EUserEvent::FULLSCREEN_TOGGLED); });
fsChanged([](const JsonNode &newState){ CGuiHandler::pushUserEvent(EUserEvent::FULLSCREEN_TOGGLED); });
inGuiThread.reset(new bool(true)); inGuiThread.reset(new bool(true));
assert(GH.mainFPSmng); assert(GH.mainFPSmng);

View File

@@ -799,3 +799,19 @@ void CAdventureMapInterface::hotkeySwitchMapLevel()
{ {
widget->getMapView()->onMapLevelSwitched(); widget->getMapView()->onMapLevelSwitched();
} }
void CAdventureMapInterface::onScreenResize()
{
OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE;
widget.reset();
pos.x = pos.y = 0;
pos.w = GH.screenDimensions().x;
pos.h = GH.screenDimensions().y;
widget = std::make_shared<CAdventureMapWidget>(shortcuts);
widget->setState(EGameState::MAKING_TURN);
widget->getMapView()->onViewMapActivated();
if (isActive())
widget->activate();
}

View File

@@ -87,6 +87,8 @@ protected:
void keyPressed(EShortcut key) override; void keyPressed(EShortcut key) override;
void onScreenResize() override;
public: public:
CAdventureMapInterface(); CAdventureMapInterface();

View File

@@ -811,6 +811,20 @@ IWindowHandler & CGuiHandler::windowHandler()
return *windowHandlerInstance; return *windowHandlerInstance;
} }
void CGuiHandler::onScreenResize()
{
for (auto const & entry : listInt)
{
auto intObject = std::dynamic_pointer_cast<CIntObject>(entry);
if (intObject)
intObject->onScreenResize();
}
totalRedraw();
}
CFramerateManager::CFramerateManager(int newRate) CFramerateManager::CFramerateManager(int newRate)
: rate(0) : rate(0)
, rateticks(0) , rateticks(0)

View File

@@ -160,6 +160,9 @@ public:
void totalRedraw(); //forces total redraw (using showAll), sets a flag, method gets called at the end of the rendering void totalRedraw(); //forces total redraw (using showAll), sets a flag, method gets called at the end of the rendering
void simpleRedraw(); //update only top interface and draw background from buffer, sets a flag, method gets called at the end of the rendering void simpleRedraw(); //update only top interface and draw background from buffer, sets a flag, method gets called at the end of the rendering
/// called whenever user selects different resolution, requiring to center/resize all windows
void onScreenResize();
void pushInt(std::shared_ptr<IShowActivatable> newInt); //deactivate old top interface, activates this one and pushes to the top void pushInt(std::shared_ptr<IShowActivatable> newInt); //deactivate old top interface, activates this one and pushes to the top
template <typename T, typename ... Args> template <typename T, typename ... Args>
void pushIntT(Args && ... args) void pushIntT(Args && ... args)

View File

@@ -294,6 +294,11 @@ void CIntObject::redraw()
} }
} }
void CIntObject::onScreenResize()
{
center(pos, true);
}
const Rect & CIntObject::center( const Rect &r, bool propagate ) const Rect & CIntObject::center( const Rect &r, bool propagate )
{ {
pos.w = r.w; pos.w = r.w;

View File

@@ -160,6 +160,10 @@ public:
//request complete redraw of this object //request complete redraw of this object
void redraw() override; void redraw() override;
/// called only for windows whenever screen size changes
/// default behavior is to re-center, can be overriden
virtual void onScreenResize();
const Rect & center(const Rect &r, bool propagate = true); //sets pos so that r will be in the center of screen, assigns sizes of r to pos, returns new position const Rect & center(const Rect &r, bool propagate = true); //sets pos so that r will be in the center of screen, assigns sizes of r to pos, returns new position
const Rect & center(const Point &p, bool propagate = true); //moves object so that point p will be in its center const Rect & center(const Point &p, bool propagate = true); //moves object so that point p will be in its center
const Rect & center(bool propagate = true); //centers when pos.w and pos.h are set, returns new position const Rect & center(bool propagate = true); //centers when pos.w and pos.h are set, returns new position

View File

@@ -20,7 +20,7 @@ public:
virtual ~IWindowHandler() = default; virtual ~IWindowHandler() = 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 onFullscreenChanged() = 0; virtual void onScreenResize() = 0;
/// De-initializes window state /// De-initializes window state
virtual void close() = 0; virtual void close() = 0;

View File

@@ -306,14 +306,14 @@ SDL_Window * WindowHandler::createWindow()
#endif #endif
} }
void WindowHandler::onFullscreenChanged() void WindowHandler::onScreenResize()
{ {
if(!recreateWindow()) if(!recreateWindow())
{ {
//will return false and report error if video mode is not supported //will return false and report error if video mode is not supported
return; return;
} }
GH.totalRedraw(); GH.onScreenResize();
} }
void WindowHandler::validateSettings() void WindowHandler::validateSettings()

View File

@@ -68,7 +68,7 @@ public:
WindowHandler(); WindowHandler();
/// Updates and potentially recreates target screen to match selected fullscreen status /// Updates and potentially recreates target screen to match selected fullscreen status
void onFullscreenChanged() final; void onScreenResize() final;
/// De-initializes and destroys screen, window and SDL state /// De-initializes and destroys screen, window and SDL state
void close() final; void close() final;