From bfcc57783caf1126ae115f6214a514999d1ee408 Mon Sep 17 00:00:00 2001 From: Vladimir Olteanu Date: Thu, 5 Aug 2021 00:24:47 +0300 Subject: [PATCH] Remove Surface::{Alloc,Free}, introduce OwnedSurface --- Source/DiabloUI/ttf_render_wrapped.cpp | 2 +- Source/control.cpp | 39 ++++++++++++------------ Source/engine/surface.hpp | 41 ++++++++++++++------------ Source/hwcursor.cpp | 5 ++-- 4 files changed, 45 insertions(+), 42 deletions(-) diff --git a/Source/DiabloUI/ttf_render_wrapped.cpp b/Source/DiabloUI/ttf_render_wrapped.cpp index 019677a96..577f64f53 100644 --- a/Source/DiabloUI/ttf_render_wrapped.cpp +++ b/Source/DiabloUI/ttf_render_wrapped.cpp @@ -43,7 +43,7 @@ SDLSurfaceUniquePtr RenderUTF8_Solid_Wrapped(TTF_Font *font, const char *text, S return {}; } - std::unique_ptr str; + std::unique_ptr str; std::vector strLines; if (wrapLength > 0 && *text != '\0') { const std::size_t strLen = std::strlen(text); diff --git a/Source/control.cpp b/Source/control.cpp index eeb14cac7..07ae2cac8 100644 --- a/Source/control.cpp +++ b/Source/control.cpp @@ -30,6 +30,7 @@ #include "trigs.h" #include "utils/language.h" #include "utils/sdl_geometry.h" +#include "utils/stdcompat/optional.hpp" #include "options.h" #ifdef _DEBUG @@ -80,9 +81,9 @@ Rectangle ChrBtnsRect[4] = { namespace { -Surface pBtmBuff; -Surface pLifeBuff; -Surface pManaBuff; +std::optional pBtmBuff; +std::optional pLifeBuff; +std::optional pManaBuff; std::optional talkButtons; std::optional pDurIcons; std::optional pChrButtons; @@ -384,7 +385,7 @@ void DrawFlaskUpper(const Surface &out, const Surface &sourceBuffer, int offset, DrawFlask(out, sourceBuffer, { 13, 3 }, { PANEL_LEFT + offset, PANEL_TOP - 13 }, emptyPortion); if (emptyPortion < 13) // Draw the filled part of the flask - DrawFlask(out, pBtmBuff, { offset, emptyPortion + 3 }, { PANEL_LEFT + offset, PANEL_TOP - 13 + emptyPortion }, 13 - emptyPortion); + DrawFlask(out, *pBtmBuff, { offset, emptyPortion + 3 }, { PANEL_LEFT + offset, PANEL_TOP - 13 + emptyPortion }, 13 - emptyPortion); } /** @@ -889,31 +890,31 @@ Point GetPanelPosition(UiPanels panel, Point offset) void DrawPanelBox(const Surface &out, SDL_Rect srcRect, Point targetPosition) { - out.BlitFrom(pBtmBuff, srcRect, targetPosition); + out.BlitFrom(*pBtmBuff, srcRect, targetPosition); } void DrawLifeFlaskUpper(const Surface &out) { constexpr int LifeFlaskUpperOffset = 109; - DrawFlaskUpper(out, pLifeBuff, LifeFlaskUpperOffset, Players[MyPlayerId]._pHPPer); + DrawFlaskUpper(out, *pLifeBuff, LifeFlaskUpperOffset, Players[MyPlayerId]._pHPPer); } void DrawManaFlaskUpper(const Surface &out) { constexpr int ManaFlaskUpperOffset = 475; - DrawFlaskUpper(out, pManaBuff, ManaFlaskUpperOffset, Players[MyPlayerId]._pManaPer); + DrawFlaskUpper(out, *pManaBuff, ManaFlaskUpperOffset, Players[MyPlayerId]._pManaPer); } void DrawLifeFlaskLower(const Surface &out) { constexpr int LifeFlaskLowerOffset = 96; - DrawFlaskLower(out, pLifeBuff, LifeFlaskLowerOffset, Players[MyPlayerId]._pHPPer); + DrawFlaskLower(out, *pLifeBuff, LifeFlaskLowerOffset, Players[MyPlayerId]._pHPPer); } void DrawManaFlaskLower(const Surface &out) { constexpr int ManaFlaskLowerOffeset = 464; - DrawFlaskLower(out, pManaBuff, ManaFlaskLowerOffeset, Players[MyPlayerId]._pManaPer); + DrawFlaskLower(out, *pManaBuff, ManaFlaskLowerOffeset, Players[MyPlayerId]._pManaPer); } void control_update_life_mana() @@ -924,9 +925,9 @@ void control_update_life_mana() void InitControlPan() { - pBtmBuff = Surface::Alloc(PANEL_WIDTH, (PANEL_HEIGHT + 16) * (IsChatAvailable() ? 2 : 1)); - pManaBuff = Surface::Alloc(88, 88); - pLifeBuff = Surface::Alloc(88, 88); + pBtmBuff.emplace(PANEL_WIDTH, (PANEL_HEIGHT + 16) * (IsChatAvailable() ? 2 : 1)); + pManaBuff.emplace(88, 88); + pLifeBuff.emplace(88, 88); pChrPanel = LoadCel("Data\\Char.CEL", SPANEL_WIDTH); if (!gbIsHellfire) @@ -934,16 +935,16 @@ void InitControlPan() else pSpellCels = LoadCel("Data\\SpelIcon.CEL", SPLICONLENGTH); SetSpellTrans(RSPLTYPE_SKILL); - CelDrawUnsafeTo(pBtmBuff, { 0, (PANEL_HEIGHT + 16) - 1 }, LoadCel("CtrlPan\\Panel8.CEL", PANEL_WIDTH), 1); + CelDrawUnsafeTo(*pBtmBuff, { 0, (PANEL_HEIGHT + 16) - 1 }, LoadCel("CtrlPan\\Panel8.CEL", PANEL_WIDTH), 1); { const Point bulbsPosition { 0, 87 }; const CelSprite statusPanel = LoadCel("CtrlPan\\P8Bulbs.CEL", 88); - CelDrawUnsafeTo(pLifeBuff, bulbsPosition, statusPanel, 1); - CelDrawUnsafeTo(pManaBuff, bulbsPosition, statusPanel, 2); + CelDrawUnsafeTo(*pLifeBuff, bulbsPosition, statusPanel, 1); + CelDrawUnsafeTo(*pManaBuff, bulbsPosition, statusPanel, 2); } talkflag = false; if (IsChatAvailable()) { - CelDrawUnsafeTo(pBtmBuff, { 0, (PANEL_HEIGHT + 16) * 2 - 1 }, LoadCel("CtrlPan\\TalkPanl.CEL", PANEL_WIDTH), 1); + CelDrawUnsafeTo(*pBtmBuff, { 0, (PANEL_HEIGHT + 16) * 2 - 1 }, LoadCel("CtrlPan\\TalkPanl.CEL", PANEL_WIDTH), 1); multiButtons = LoadCel("CtrlPan\\P8But2.CEL", 33); talkButtons = LoadCel("CtrlPan\\TalkButt.CEL", 61); sgbPlrTalkTbl = 0; @@ -1323,9 +1324,9 @@ void CheckBtnUp() void FreeControlPan() { - pBtmBuff.Free(); - pManaBuff.Free(); - pLifeBuff.Free(); + pBtmBuff = std::nullopt; + pManaBuff = std::nullopt; + pLifeBuff = std::nullopt; pChrPanel = std::nullopt; pSpellCels = std::nullopt; pPanelButtons = std::nullopt; diff --git a/Source/engine/surface.hpp b/Source/engine/surface.hpp index 265170bd0..1ce6016d5 100644 --- a/Source/engine/surface.hpp +++ b/Source/engine/surface.hpp @@ -15,6 +15,7 @@ #include "engine/point.hpp" #include "utils/sdl_geometry.h" +#include "utils/sdl_wrap.h" namespace devilution { @@ -46,25 +47,6 @@ struct Surface { Surface(const Surface &other) = default; Surface &operator=(const Surface &other) = default; - /** - * @brief Allocate a buffer that owns its underlying data. - */ - static Surface Alloc(int width, int height) - { - return Surface(SDL_CreateRGBSurfaceWithFormat(0, width, height, 8, SDL_PIXELFORMAT_INDEX8)); - } - - /** - * @brief Free the underlying data. - * - * Only use this if the buffer owns its data. - */ - void Free() - { - SDL_FreeSurface(this->surface); - this->surface = nullptr; - } - int w() const { return region.w; @@ -172,4 +154,25 @@ struct Surface { void BlitFromSkipColorIndexZero(const Surface &src, SDL_Rect srcRect, Point targetPosition) const; }; +class OwnedSurface : public Surface { + SDLSurfaceUniquePtr pinnedSurface; + +public: + explicit OwnedSurface(SDLSurfaceUniquePtr surface) + : Surface(surface.get()) + , pinnedSurface(std::move(surface)) + { + } + + OwnedSurface(int width, int height) + : OwnedSurface(SDLWrap::CreateRGBSurfaceWithFormat(0, width, height, 8, SDL_PIXELFORMAT_INDEX8)) + { + } + + OwnedSurface(Size size) + : OwnedSurface(size.width, size.height) + { + } +}; + } // namespace devilution diff --git a/Source/hwcursor.cpp b/Source/hwcursor.cpp index 73395be72..0fbd54735 100644 --- a/Source/hwcursor.cpp +++ b/Source/hwcursor.cpp @@ -74,7 +74,7 @@ bool SetHardwareCursor(SDL_Surface *surface, HotpointPosition hotpointPosition) // SDL does not support BlitScaled from 8-bit to RGBA. SDLSurfaceUniquePtr converted { SDL_ConvertSurfaceFormat(surface, SDL_PIXELFORMAT_ARGB8888, 0) }; - SDLSurfaceUniquePtr scaledSurface = SDLWrap::CreateRGBSurfaceWithFormat(0, scaledSize.width, scaledSize.height, 32, SDL_PIXELFORMAT_ARGB8888); + SDLSurfaceUniquePtr scaledSurface = SDLWrap::CreateRGBSurfaceWithFormat(0, scaledSize.width, scaledSize.height, 32, SDL_PIXELFORMAT_ARGB8888); SDL_BlitScaled(converted.get(), nullptr, scaledSurface.get(), nullptr); const Point hotpoint = GetHotpointPosition(*scaledSurface, hotpointPosition); newCursor = SDLCursorUniquePtr { SDL_CreateColorCursor(scaledSurface.get(), hotpoint.x, hotpoint.y) }; @@ -101,7 +101,7 @@ bool SetHardwareCursorFromSprite(int pcurs) if (!IsCursorSizeAllowed(size)) return false; - auto out = Surface::Alloc(size.width, size.height); + OwnedSurface out { size }; SDL_SetSurfacePalette(out.surface, Palette); // Transparent color must not be used in the sprite itself. @@ -112,7 +112,6 @@ bool SetHardwareCursorFromSprite(int pcurs) CelDrawCursor(out, { outlineWidth, size.height - outlineWidth }, pcurs); const bool result = SetHardwareCursor(out.surface, isItem ? HotpointPosition::Center : HotpointPosition::TopLeft); - out.Free(); return result; } #endif