1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-11-27 22:49:25 +02:00

screen surface is now private member of ScreenHandler instead of global

This commit is contained in:
Ivan Savenko
2025-02-10 17:23:20 +00:00
parent 31e627f128
commit eb7587c000
16 changed files with 85 additions and 40 deletions

View File

@@ -16,8 +16,6 @@ struct SDL_Surface;
extern SDL_Texture * screenTexture; extern SDL_Texture * screenTexture;
extern SDL_Renderer * mainRenderer; extern SDL_Renderer * mainRenderer;
extern SDL_Surface *screen;
/// Notify user about encountered fatal error and terminate the game /// Notify user about encountered fatal error and terminate the game
/// Defined in clientapp EntryPoint /// Defined in clientapp EntryPoint
/// TODO: decide on better location for this method /// TODO: decide on better location for this method

View File

@@ -20,6 +20,7 @@
#include "../CGameInfo.h" #include "../CGameInfo.h"
#include "../adventureMap/AdventureMapInterface.h" #include "../adventureMap/AdventureMapInterface.h"
#include "../render/Canvas.h"
#include "../render/Colors.h" #include "../render/Colors.h"
#include "../render/Graphics.h" #include "../render/Graphics.h"
#include "../render/IFont.h" #include "../render/IFont.h"
@@ -104,21 +105,13 @@ void CGuiHandler::renderFrame()
if (settings["video"]["showfps"].Bool()) if (settings["video"]["showfps"].Bool())
drawFPSCounter(); drawFPSCounter();
SDL_UpdateTexture(screenTexture, nullptr, screen->pixels, screen->pitch); screenHandlerInstance->updateScreenTexture();
}
SDL_RenderClear(mainRenderer);
SDL_RenderCopy(mainRenderer, screenTexture, nullptr, nullptr);
{
boost::mutex::scoped_lock interfaceLock(GH.interfaceMutex);
CCS->curh->render();
windows().onFrameRendered(); windows().onFrameRendered();
CCS->curh->update();
} }
SDL_RenderPresent(mainRenderer); screenHandlerInstance->presetScreenTexture();
framerate().framerateDelay(); // holds a constant FPS framerate().framerateDelay(); // holds a constant FPS
} }
@@ -181,19 +174,12 @@ Point CGuiHandler::screenDimensions() const
void CGuiHandler::drawFPSCounter() void CGuiHandler::drawFPSCounter()
{ {
int scaling = screenHandlerInstance->getScalingFactor(); Canvas target = GH.screenHandler().getScreenCanvas();
int x = 7 * scaling; Rect targetArea(0, screenDimensions().y - 20, 48, 11);
int y = screen->h-20 * scaling;
int width3digitFPSIncludingPadding = 48 * scaling;
int heightFPSTextIncludingPadding = 11 * scaling;
SDL_Rect overlay = { x, y, width3digitFPSIncludingPadding, heightFPSTextIncludingPadding};
uint32_t black = SDL_MapRGB(screen->format, 10, 10, 10);
SDL_FillRect(screen, &overlay, black);
std::string fps = std::to_string(framerate().getFramerate())+" FPS"; std::string fps = std::to_string(framerate().getFramerate())+" FPS";
const auto & font = GH.renderHandler().loadFont(FONT_SMALL); target.drawColor(targetArea, ColorRGBA(10, 10, 10));
font->renderTextLeft(screen, fps, Colors::WHITE, Point(8 * scaling, screen->h-22 * scaling)); target.drawText(targetArea.center(), EFonts::FONT_SMALL, Colors::WHITE, ETextAlignment::CENTER, fps);
} }
bool CGuiHandler::amIGuiThread() bool CGuiHandler::amIGuiThread()

View File

@@ -15,6 +15,7 @@
#include "EventDispatcher.h" #include "EventDispatcher.h"
#include "Shortcut.h" #include "Shortcut.h"
#include "../render/Canvas.h" #include "../render/Canvas.h"
#include "../render/IScreenHandler.h"
#include "../windows/CMessage.h" #include "../windows/CMessage.h"
#include "../CMT.h" #include "../CMT.h"
@@ -238,7 +239,7 @@ void CIntObject::redraw()
} }
else else
{ {
Canvas buffer = Canvas::createFromSurface(screen, CanvasScalingPolicy::AUTO); Canvas buffer = GH.screenHandler().getScreenCanvas();
showAll(buffer); showAll(buffer);
} }
} }

View File

@@ -260,6 +260,11 @@ void CursorHandler::updateSpellcastCursor()
} }
void CursorHandler::render() void CursorHandler::render()
{
cursor->render();
}
void CursorHandler::update()
{ {
if(!showing) if(!showing)
return; return;
@@ -267,7 +272,7 @@ void CursorHandler::render()
if (type == Cursor::Type::SPELLBOOK) if (type == Cursor::Type::SPELLBOOK)
updateSpellcastCursor(); updateSpellcastCursor();
cursor->render(); cursor->update();
} }
void CursorHandler::hide() void CursorHandler::hide()

View File

@@ -179,6 +179,7 @@ public:
Point getPivotOffsetCombat(size_t index); Point getPivotOffsetCombat(size_t index);
void render(); void render();
void update();
void hide(); void hide();
void show(); void show();

View File

@@ -17,6 +17,7 @@
#include "../CMT.h" #include "../CMT.h"
#include "../CGameInfo.h" #include "../CGameInfo.h"
#include "../render/Canvas.h" #include "../render/Canvas.h"
#include "../render/IScreenHandler.h"
#include "../render/Colors.h" #include "../render/Colors.h"
#include "../renderSDL/SDL_Extensions.h" #include "../renderSDL/SDL_Extensions.h"
@@ -108,7 +109,7 @@ void WindowHandler::totalRedrawImpl()
{ {
logGlobal->debug("totalRedraw requested!"); logGlobal->debug("totalRedraw requested!");
Canvas target = Canvas::createFromSurface(screen, CanvasScalingPolicy::AUTO); Canvas target = GH.screenHandler().getScreenCanvas();
for(auto & elem : windowsStack) for(auto & elem : windowsStack)
elem->showAll(target); elem->showAll(target);
@@ -126,7 +127,7 @@ void WindowHandler::simpleRedraw()
void WindowHandler::simpleRedrawImpl() void WindowHandler::simpleRedrawImpl()
{ {
Canvas target = Canvas::createFromSurface(screen, CanvasScalingPolicy::AUTO); Canvas target = GH.screenHandler().getScreenCanvas();
if(!windowsStack.empty()) if(!windowsStack.empty())
windowsStack.back()->show(target); //blit active interface/window windowsStack.back()->show(target); //blit active interface/window

View File

@@ -23,6 +23,7 @@ public:
virtual void setImage(std::shared_ptr<IImage> image, const Point & pivotOffset) = 0; virtual void setImage(std::shared_ptr<IImage> image, const Point & pivotOffset) = 0;
virtual void setCursorPosition( const Point & newPos ) = 0; virtual void setCursorPosition( const Point & newPos ) = 0;
virtual void render() = 0; virtual void render() = 0;
virtual void update() = 0;
virtual void setVisible( bool on) = 0; virtual void setVisible( bool on) = 0;
}; };

View File

@@ -15,6 +15,8 @@ class Point;
class Rect; class Rect;
VCMI_LIB_NAMESPACE_END VCMI_LIB_NAMESPACE_END
class Canvas;
class IScreenHandler class IScreenHandler
{ {
public: public:
@@ -29,6 +31,15 @@ public:
/// Fills screen with black color, erasing any existing content /// Fills screen with black color, erasing any existing content
virtual void clearScreen() = 0; virtual void clearScreen() = 0;
/// Returns canvas that can be used to display objects on screen
virtual Canvas getScreenCanvas() const = 0;
/// Synchronizes internal screen texture. Screen canvas may not be modified during this call
virtual void updateScreenTexture() = 0;
/// Presents screen texture on the screen
virtual void presetScreenTexture() = 0;
/// 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;

View File

@@ -92,3 +92,8 @@ void CursorHardware::render()
{ {
//no-op //no-op
} }
void CursorHardware::update()
{
//no-op
}

View File

@@ -30,6 +30,7 @@ public:
void setImage(std::shared_ptr<IImage> image, const Point & pivotOffset) override; void setImage(std::shared_ptr<IImage> image, const Point & pivotOffset) override;
void setCursorPosition( const Point & newPos ) override; void setCursorPosition( const Point & newPos ) override;
void render() override; void render() override;
void update() override;
void setVisible( bool on) override; void setVisible( bool on) override;
}; };

View File

@@ -21,12 +21,15 @@
#include <SDL_render.h> #include <SDL_render.h>
#include <SDL_events.h> #include <SDL_events.h>
void CursorSoftware::render() void CursorSoftware::update()
{ {
//texture must be updated in the main (renderer) thread, but changes to cursor type may come from other threads //texture must be updated in the main (renderer) thread, but changes to cursor type may come from other threads
if (needUpdate) if (needUpdate)
updateTexture(); updateTexture();
}
void CursorSoftware::render()
{
Point renderPos = pos - pivot; Point renderPos = pos - pivot;
SDL_Rect destRect; SDL_Rect destRect;

View File

@@ -38,6 +38,7 @@ public:
void setImage(std::shared_ptr<IImage> image, const Point & pivotOffset) override; void setImage(std::shared_ptr<IImage> image, const Point & pivotOffset) override;
void setCursorPosition( const Point & newPos ) override; void setCursorPosition( const Point & newPos ) override;
void render() override; void render() override;
void update() override;
void setVisible( bool on) override; void setVisible( bool on) override;
}; };

View File

@@ -211,7 +211,7 @@ SDLImageScaler::SDLImageScaler(SDL_Surface * surf, const Rect & virtualDimension
if (optimizeImage) if (optimizeImage)
{ {
SDLImageOptimizer optimizer(surf, virtualDimensions); SDLImageOptimizer optimizer(surf, virtualDimensions);
optimizer.optimizeSurface(screen); optimizer.optimizeSurface(nullptr);
intermediate = optimizer.acquireResultSurface(); intermediate = optimizer.acquireResultSurface();
virtualDimensionsInput = optimizer.getResultDimensions(); virtualDimensionsInput = optimizer.getResultDimensions();
} }

View File

@@ -71,24 +71,29 @@ void CSDL_Ext::setAlpha(SDL_Surface * bg, int value)
SDL_Surface * CSDL_Ext::newSurface(const Point & dimensions) SDL_Surface * CSDL_Ext::newSurface(const Point & dimensions)
{ {
return newSurface(dimensions, screen); return newSurface(dimensions, nullptr);
} }
SDL_Surface * CSDL_Ext::newSurface(const Point & dimensions, SDL_Surface * mod) //creates new surface, with flags/format same as in surface given SDL_Surface * CSDL_Ext::newSurface(const Point & dimensions, SDL_Surface * mod) //creates new surface, with flags/format same as in surface given
{ {
SDL_Surface * ret = SDL_CreateRGBSurface(0,dimensions.x,dimensions.y,mod->format->BitsPerPixel,mod->format->Rmask,mod->format->Gmask,mod->format->Bmask,mod->format->Amask); SDL_Surface * ret = nullptr;
if (mod != nullptr)
ret = SDL_CreateRGBSurface(0,dimensions.x,dimensions.y,mod->format->BitsPerPixel,mod->format->Rmask,mod->format->Gmask,mod->format->Bmask,mod->format->Amask);
else
ret = SDL_CreateRGBSurfaceWithFormat(0,dimensions.x,dimensions.y,32,SDL_PixelFormatEnum::SDL_PIXELFORMAT_ARGB8888);
if(ret == nullptr) if(ret == nullptr)
{ {
const char * error = SDL_GetError(); const char * error = SDL_GetError();
std::string messagePattern = "Failed to create SDL Surface of size %d x %d, %d bpp. Reason: %s"; std::string messagePattern = "Failed to create SDL Surface of size %d x %d. Reason: %s";
std::string message = boost::str(boost::format(messagePattern) % dimensions.x % dimensions.y % mod->format->BitsPerPixel % error); std::string message = boost::str(boost::format(messagePattern) % dimensions.x % dimensions.y % error);
handleFatalError(message, true); handleFatalError(message, true);
} }
if (mod->format->palette) if (mod && mod->format->palette)
{ {
assert(ret->format->palette); assert(ret->format->palette);
assert(ret->format->palette->ncolors >= mod->format->palette->ncolors); assert(ret->format->palette->ncolors >= mod->format->palette->ncolors);

View File

@@ -11,11 +11,14 @@
#include "StdInc.h" #include "StdInc.h"
#include "ScreenHandler.h" #include "ScreenHandler.h"
#include "../CGameInfo.h"
#include "../CMT.h"
#include "../eventsSDL/NotificationHandler.h" #include "../eventsSDL/NotificationHandler.h"
#include "../gui/CGuiHandler.h" #include "../gui/CGuiHandler.h"
#include "../gui/CursorHandler.h"
#include "../gui/WindowHandler.h" #include "../gui/WindowHandler.h"
#include "../render/Canvas.h"
#include "../renderSDL/SDL_Extensions.h" #include "../renderSDL/SDL_Extensions.h"
#include "CMT.h"
#include "../../lib/CConfigHandler.h" #include "../../lib/CConfigHandler.h"
#include "../../lib/constants/StringConstants.h" #include "../../lib/constants/StringConstants.h"
@@ -34,7 +37,6 @@
static SDL_Window * mainWindow = nullptr; static SDL_Window * mainWindow = nullptr;
SDL_Renderer * mainRenderer = nullptr; SDL_Renderer * mainRenderer = nullptr;
SDL_Texture * screenTexture = nullptr; SDL_Texture * screenTexture = nullptr;
SDL_Surface * screen = nullptr; //main screen surface
static const std::string NAME = GameConstants::VCMI_VERSION; //application name static const std::string NAME = GameConstants::VCMI_VERSION; //application name
static constexpr Point heroes3Resolution = Point(800, 600); static constexpr Point heroes3Resolution = Point(800, 600);
@@ -621,6 +623,24 @@ void ScreenHandler::clearScreen()
SDL_RenderPresent(mainRenderer); SDL_RenderPresent(mainRenderer);
} }
Canvas ScreenHandler::getScreenCanvas() const
{
return Canvas::createFromSurface(screen, CanvasScalingPolicy::AUTO);
}
void ScreenHandler::updateScreenTexture()
{
SDL_UpdateTexture(screenTexture, nullptr, screen->pixels, screen->pitch);
}
void ScreenHandler::presetScreenTexture()
{
SDL_RenderClear(mainRenderer);
SDL_RenderCopy(mainRenderer, screenTexture, nullptr, nullptr);
CCS->curh->render();
SDL_RenderPresent(mainRenderer);
}
std::vector<Point> ScreenHandler::getSupportedResolutions() const std::vector<Point> ScreenHandler::getSupportedResolutions() const
{ {
int displayID = getPreferredDisplayIndex(); int displayID = getPreferredDisplayIndex();

View File

@@ -10,14 +10,14 @@
#pragma once #pragma once
#include "../../lib/Point.h"
#include "../render/IScreenHandler.h"
struct SDL_Texture; struct SDL_Texture;
struct SDL_Window; struct SDL_Window;
struct SDL_Renderer; struct SDL_Renderer;
struct SDL_Surface; struct SDL_Surface;
#include "../../lib/Point.h"
#include "../render/IScreenHandler.h"
enum class EWindowMode enum class EWindowMode
{ {
// game runs in a window that covers part of the screen // game runs in a window that covers part of the screen
@@ -44,6 +44,8 @@ enum class EUpscalingFilter
/// 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 ScreenHandler final : public IScreenHandler class ScreenHandler final : public IScreenHandler
{ {
SDL_Surface * screen = nullptr; //main screen surface
EUpscalingFilter upscalingFilter = EUpscalingFilter::AUTO; EUpscalingFilter upscalingFilter = EUpscalingFilter::AUTO;
/// 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
@@ -114,6 +116,10 @@ public:
int getInterfaceScalingPercentage() const final; int getInterfaceScalingPercentage() const final;
Canvas getScreenCanvas() const final;
void updateScreenTexture() final;
void presetScreenTexture() final;
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<int, int> getSupportedScalingRange() const final; std::tuple<int, int> getSupportedScalingRange() const final;