Browse Source

Remove Surface::{Alloc,Free}, introduce OwnedSurface

pull/2638/head
Vladimir Olteanu 5 years ago committed by Anders Jenbo
parent
commit
bfcc57783c
  1. 2
      Source/DiabloUI/ttf_render_wrapped.cpp
  2. 39
      Source/control.cpp
  3. 41
      Source/engine/surface.hpp
  4. 5
      Source/hwcursor.cpp

2
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<char []> str;
std::unique_ptr<char[]> str;
std::vector<char *> strLines;
if (wrapLength > 0 && *text != '\0') {
const std::size_t strLen = std::strlen(text);

39
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<OwnedSurface> pBtmBuff;
std::optional<OwnedSurface> pLifeBuff;
std::optional<OwnedSurface> pManaBuff;
std::optional<CelSprite> talkButtons;
std::optional<CelSprite> pDurIcons;
std::optional<CelSprite> 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;

41
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

5
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

Loading…
Cancel
Save