diff --git a/CMakeLists.txt b/CMakeLists.txt index 2df68c68a..8d923cadd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -403,6 +403,7 @@ set(libdevilutionx_SRCS Source/engine/render/cl2_render.cpp Source/engine/render/dun_render.cpp Source/engine/render/text_render.cpp + Source/engine/surface.cpp Source/qol/autopickup.cpp Source/qol/common.cpp Source/qol/monhealthbar.cpp diff --git a/Source/DiabloUI/art_draw.cpp b/Source/DiabloUI/art_draw.cpp index 01e572c18..e60905af5 100644 --- a/Source/DiabloUI/art_draw.cpp +++ b/Source/DiabloUI/art_draw.cpp @@ -36,7 +36,7 @@ void DrawArt(Sint16 screenX, Sint16 screenY, Art *art, int nFrame, Uint16 srcW, ErrSdl(); } -void DrawArt(const CelOutputBuffer &out, Sint16 screenX, Sint16 screenY, Art *art, int nFrame, Uint16 srcW, Uint16 srcH) +void DrawArt(const Surface &out, Sint16 screenX, Sint16 screenY, Art *art, int nFrame, Uint16 srcW, Uint16 srcH) { if (screenY >= gnScreenHeight || screenX >= gnScreenWidth || art->surface == nullptr) return; diff --git a/Source/DiabloUI/art_draw.h b/Source/DiabloUI/art_draw.h index 4a4801882..f70bdb2a7 100644 --- a/Source/DiabloUI/art_draw.h +++ b/Source/DiabloUI/art_draw.h @@ -7,7 +7,7 @@ namespace devilution { void DrawArt(Sint16 screenX, Sint16 screenY, Art *art, int nFrame = 0, Uint16 srcW = 0, Uint16 srcH = 0); -void DrawArt(const CelOutputBuffer &out, Sint16 screenX, Sint16 screenY, Art *art, int nFrame = 0, Uint16 srcW = 0, Uint16 srcH = 0); +void DrawArt(const Surface &out, Sint16 screenX, Sint16 screenY, Art *art, int nFrame = 0, Uint16 srcW = 0, Uint16 srcH = 0); void DrawAnimatedArt(Art *art, int screenX, int screenY); diff --git a/Source/automap.cpp b/Source/automap.cpp index aba390590..9d74ae1e2 100644 --- a/Source/automap.cpp +++ b/Source/automap.cpp @@ -55,7 +55,7 @@ enum MapFlags : uint8_t { // clang-format on }; -void DrawDiamond(const CelOutputBuffer &out, Point center, uint8_t color) +void DrawDiamond(const Surface &out, Point center, uint8_t color) { const Point left { center.x - AmLine16, center.y }; const Point top { center.x, center.y - AmLine8 }; @@ -67,14 +67,14 @@ void DrawDiamond(const CelOutputBuffer &out, Point center, uint8_t color) DrawMapLineNE(out, bottom, AmLine8, color); } -void DrawMapVerticalDoor(const CelOutputBuffer &out, Point center) +void DrawMapVerticalDoor(const Surface &out, Point center) { DrawMapLineNE(out, { center.x + AmLine8, center.y - AmLine4 }, AmLine4, MapColorsDim); DrawMapLineNE(out, { center.x - AmLine16, center.y + AmLine8 }, AmLine4, MapColorsDim); DrawDiamond(out, center, MapColorsBright); } -void DrawMapHorizontalDoor(const CelOutputBuffer &out, Point center) +void DrawMapHorizontalDoor(const Surface &out, Point center) { DrawMapLineSE(out, { center.x - AmLine16, center.y - AmLine8 }, AmLine4, MapColorsDim); DrawMapLineSE(out, { center.x + AmLine8, center.y + AmLine4 }, AmLine4, MapColorsDim); @@ -84,7 +84,7 @@ void DrawMapHorizontalDoor(const CelOutputBuffer &out, Point center) /** * @brief Renders the given automap shape at the specified screen coordinates. */ -void DrawAutomapTile(const CelOutputBuffer &out, Point center, uint16_t automapType) +void DrawAutomapTile(const Surface &out, Point center, uint16_t automapType) { uint8_t flags = automapType >> 8; @@ -207,7 +207,7 @@ void DrawAutomapTile(const CelOutputBuffer &out, Point center, uint16_t automapT } } -void SearchAutomapItem(const CelOutputBuffer &out) +void SearchAutomapItem(const Surface &out) { auto &myPlayer = plr[myplr]; Point tile = myPlayer.position.tile; @@ -253,7 +253,7 @@ void SearchAutomapItem(const CelOutputBuffer &out) /** * @brief Renders an arrow on the automap, centered on and facing the direction of the player. */ -void DrawAutomapPlr(const CelOutputBuffer &out, int playerId) +void DrawAutomapPlr(const Surface &out, int playerId) { int playerColor = MapColorsPlayer + (8 * playerId) % 128; @@ -380,7 +380,7 @@ uint16_t GetAutomapType(Point map, bool view) /** * @brief Renders game info, such as the name of the current level, and in multi player the name of the game and the game password. */ -void DrawAutomapText(const CelOutputBuffer &out) +void DrawAutomapText(const Surface &out) { char desc[256]; Point linePosition { 8, 20 }; @@ -532,7 +532,7 @@ void AutomapZoomOut() AmLine4 = AmLine8 / 2; } -void DrawAutomap(const CelOutputBuffer &out) +void DrawAutomap(const Surface &out) { if (leveltype == DTYPE_TOWN) { DrawAutomapText(out); diff --git a/Source/automap.h b/Source/automap.h index cd0e93aef..ed893d299 100644 --- a/Source/automap.h +++ b/Source/automap.h @@ -75,7 +75,7 @@ void AutomapZoomOut(); /** * @brief Renders the automap to the given buffer. */ -void DrawAutomap(const CelOutputBuffer &out); +void DrawAutomap(const Surface &out); /** * @brief Marks the given coordinate as within view on the automap. diff --git a/Source/capture.cpp b/Source/capture.cpp index cd7fdc37c..fac4143df 100644 --- a/Source/capture.cpp +++ b/Source/capture.cpp @@ -112,7 +112,7 @@ static BYTE *CaptureEnc(BYTE *src, BYTE *dst, int width) * @param buf Buffer * @return True if successful, else false */ -static bool CapturePix(const CelOutputBuffer &buf, std::ofstream *out) +static bool CapturePix(const Surface &buf, std::ofstream *out) { int width = buf.w(); std::unique_ptr pBuffer { new BYTE[2 * width] }; @@ -175,7 +175,7 @@ void CaptureScreen() RedPalette(); lock_buf(2); - const CelOutputBuffer &buf = GlobalBackBuffer(); + const Surface &buf = GlobalBackBuffer(); success = CaptureHdr(buf.w(), buf.h(), outStream); if (success) { success = CapturePix(buf, outStream); diff --git a/Source/control.cpp b/Source/control.cpp index 038af7652..394cb072c 100644 --- a/Source/control.cpp +++ b/Source/control.cpp @@ -33,9 +33,9 @@ namespace devilution { namespace { -CelOutputBuffer pBtmBuff; -CelOutputBuffer pLifeBuff; -CelOutputBuffer pManaBuff; +Surface pBtmBuff; +Surface pLifeBuff; +Surface pManaBuff; std::optional pTalkBtns; std::optional pDurIcons; std::optional pChrButtons; @@ -233,7 +233,7 @@ spell_id SpellPages[6][7] = { * @param cel The CEL sprite * @param nCel Index of the cel frame to draw. 0 based. */ -static void DrawSpellCel(const CelOutputBuffer &out, Point position, const CelSprite &cel, int nCel) +static void DrawSpellCel(const Surface &out, Point position, const CelSprite &cel, int nCel) { CelDrawLightTo(out, position, cel, nCel, SplTransTbl); } @@ -298,7 +298,7 @@ void SetSpellTrans(spell_type t) /** * Sets the spell frame to draw and its position then draws it. */ -static void DrawSpell(const CelOutputBuffer &out) +static void DrawSpell(const Surface &out) { auto &myPlayer = plr[myplr]; spell_id spl = myPlayer._pRSpell; @@ -320,7 +320,7 @@ static void DrawSpell(const CelOutputBuffer &out) DrawSpellCel(out, position, *pSpellCels, nCel); } -static void PrintSBookHotkey(const CelOutputBuffer &out, Point position, const std::string &text) +static void PrintSBookHotkey(const Surface &out, Point position, const std::string &text) { // Align the hot key text with the top-right corner of the spell icon position += Displacement { SPLICONLENGTH - (GetLineWidth(text.c_str()) + 5), 17 - SPLICONLENGTH }; @@ -331,7 +331,7 @@ static void PrintSBookHotkey(const CelOutputBuffer &out, Point position, const s DrawString(out, text.c_str(), position, UIS_SILVER); } -void DrawSpellList(const CelOutputBuffer &out) +void DrawSpellList(const Surface &out) { int c; int s; @@ -542,7 +542,7 @@ void ClearPanel() pinfoflag = false; } -void DrawPanelBox(const CelOutputBuffer &out, SDL_Rect srcRect, Point targetPosition) +void DrawPanelBox(const Surface &out, SDL_Rect srcRect, Point targetPosition) { out.BlitFrom(pBtmBuff, srcRect, targetPosition); } @@ -557,7 +557,7 @@ void DrawPanelBox(const CelOutputBuffer &out, SDL_Rect srcRect, Point targetPosi * @param y0 Top of the flask cel section to draw. * @param y1 Bottom of the flask cel section to draw. */ -static void DrawFlaskTop(const CelOutputBuffer &out, Point position, const CelOutputBuffer &celBuf, int y0, int y1) +static void DrawFlaskTop(const Surface &out, Point position, const Surface &celBuf, int y0, int y1) { out.BlitFrom(celBuf, SDL_Rect { 0, static_cast(y0), celBuf.w(), y1 - y0 }, position); } @@ -572,13 +572,13 @@ static void DrawFlaskTop(const CelOutputBuffer &out, Point position, const CelOu * @param targetPosition Target buffer coordinate. * @param h How many lines of the source buffer that will be copied. */ -static void DrawFlask(const CelOutputBuffer &out, const CelOutputBuffer &celBuf, Point sourcePosition, Point targetPosition, int h) +static void DrawFlask(const Surface &out, const Surface &celBuf, Point sourcePosition, Point targetPosition, int h) { constexpr int FlaskWidth = 59; out.BlitFromSkipColorIndexZero(celBuf, MakeSdlRect(sourcePosition.x, sourcePosition.y, FlaskWidth, h), targetPosition); } -void DrawLifeFlask(const CelOutputBuffer &out) +void DrawLifeFlask(const Surface &out) { auto &myPlayer = plr[myplr]; @@ -595,7 +595,7 @@ void DrawLifeFlask(const CelOutputBuffer &out) } } -void UpdateLifeFlask(const CelOutputBuffer &out) +void UpdateLifeFlask(const Surface &out) { auto &myPlayer = plr[myplr]; @@ -611,7 +611,7 @@ void UpdateLifeFlask(const CelOutputBuffer &out) DrawPanelBox(out, { 96, 85 - filled, 88, filled }, { 96 + PANEL_X, PANEL_Y + 69 - filled }); } -void DrawManaFlask(const CelOutputBuffer &out) +void DrawManaFlask(const Surface &out) { int filled = plr[myplr]._pManaPer; if (filled > 80) @@ -636,7 +636,7 @@ void control_update_life_mana() myPlayer.UpdateHitPointPercentage(); } -void UpdateManaFlask(const CelOutputBuffer &out) +void UpdateManaFlask(const Surface &out) { auto &myPlayer = plr[myplr]; @@ -657,9 +657,9 @@ void UpdateManaFlask(const CelOutputBuffer &out) void InitControlPan() { - pBtmBuff = CelOutputBuffer::Alloc(PANEL_WIDTH, (PANEL_HEIGHT + 16) * (gbIsMultiplayer ? 2 : 1)); - pManaBuff = CelOutputBuffer::Alloc(88, 88); - pLifeBuff = CelOutputBuffer::Alloc(88, 88); + pBtmBuff = Surface::Alloc(PANEL_WIDTH, (PANEL_HEIGHT + 16) * (gbIsMultiplayer ? 2 : 1)); + pManaBuff = Surface::Alloc(88, 88); + pLifeBuff = Surface::Alloc(88, 88); pChrPanel = LoadCel("Data\\Char.CEL", SPANEL_WIDTH); if (!gbIsHellfire) @@ -742,13 +742,13 @@ void InitControlPan() initialDropGoldIndex = 0; } -void DrawCtrlPan(const CelOutputBuffer &out) +void DrawCtrlPan(const Surface &out) { DrawPanelBox(out, { 0, sgbPlrTalkTbl + 16, PANEL_WIDTH, PANEL_HEIGHT }, { PANEL_X, PANEL_Y }); DrawInfoBox(out); } -void DrawCtrlBtns(const CelOutputBuffer &out) +void DrawCtrlBtns(const Surface &out) { for (int i = 0; i < 6; i++) { if (!panbtns[i]) @@ -1083,7 +1083,7 @@ void FreeControlPan() pGBoxBuff = std::nullopt; } -static void PrintInfo(const CelOutputBuffer &out) +static void PrintInfo(const Surface &out) { if (talkflag) return; @@ -1104,7 +1104,7 @@ static void PrintInfo(const CelOutputBuffer &out) } } -void DrawInfoBox(const CelOutputBuffer &out) +void DrawInfoBox(const Surface &out) { DrawPanelBox(out, { 177, 62, 288, 60 }, { PANEL_X + 177, PANEL_Y + 46 }); if (!panelflag && !trigflag && pcursinvitem == -1 && !spselflag) { @@ -1167,7 +1167,7 @@ void DrawInfoBox(const CelOutputBuffer &out) PrintInfo(out); } -void DrawChr(const CelOutputBuffer &out) +void DrawChr(const Surface &out) { uint32_t style = UIS_SILVER; char chrstr[64]; @@ -1387,7 +1387,7 @@ void ReleaseLvlBtn() lvlbtndown = false; } -void DrawLevelUpIcon(const CelOutputBuffer &out) +void DrawLevelUpIcon(const Surface &out) { if (stextflag == STORE_NONE) { int nCel = lvlbtndown ? 3 : 2; @@ -1476,7 +1476,7 @@ void ReleaseChrBtns(bool addAllStatPoints) } } -static int DrawDurIcon4Item(const CelOutputBuffer &out, ItemStruct *pItem, int x, int c) +static int DrawDurIcon4Item(const Surface &out, ItemStruct *pItem, int x, int c) { if (pItem->isEmpty()) return x; @@ -1510,7 +1510,7 @@ static int DrawDurIcon4Item(const CelOutputBuffer &out, ItemStruct *pItem, int x return x - 32 - 8; } -void DrawDurIcon(const CelOutputBuffer &out) +void DrawDurIcon(const Surface &out) { bool hasRoomBetweenPanels = gnScreenWidth >= PANEL_WIDTH + 16 + (32 + 8 + 32 + 8 + 32 + 8 + 32) + 16; bool hasRoomUnderPanels = gnScreenHeight >= SPANEL_HEIGHT + PANEL_HEIGHT + 16 + 32 + 16; @@ -1533,7 +1533,7 @@ void DrawDurIcon(const CelOutputBuffer &out) DrawDurIcon4Item(out, &myPlayer.InvBody[INVLOC_HAND_RIGHT], x, 0); } -void RedBack(const CelOutputBuffer &out) +void RedBack(const Surface &out) { uint8_t *dst = out.begin(); uint8_t *tbl = &pLightTbl[4608]; @@ -1546,7 +1546,7 @@ void RedBack(const CelOutputBuffer &out) } } -static void PrintSBookStr(const CelOutputBuffer &out, Point position, const char *text) +static void PrintSBookStr(const Surface &out, Point position, const char *text) { DrawString(out, text, { RIGHT_PANEL_X + SPLICONLENGTH + position.x, position.y, 222, 0 }, UIS_SILVER); } @@ -1578,7 +1578,7 @@ spell_type GetSBookTrans(spell_id ii, bool townok) return st; } -void DrawSpellBook(const CelOutputBuffer &out) +void DrawSpellBook(const Surface &out) { CelDrawTo(out, { RIGHT_PANEL_X, 351 }, *pSpellBkCel, 1); if (gbIsHellfire && sbooktab < 5) { @@ -1670,7 +1670,7 @@ void CheckSBook() } } -void DrawGoldSplit(const CelOutputBuffer &out, int amount) +void DrawGoldSplit(const Surface &out, int amount) { const int dialogX = RIGHT_PANEL_X + 30; @@ -1773,7 +1773,7 @@ void control_remove_gold(int pnum, int goldIndex) dropGoldValue = 0; } -void DrawTalkPan(const CelOutputBuffer &out) +void DrawTalkPan(const Surface &out) { if (!talkflag) return; diff --git a/Source/control.h b/Source/control.h index a002b5879..11333d843 100644 --- a/Source/control.h +++ b/Source/control.h @@ -63,45 +63,45 @@ inline bool CanPanelsCoverView() return gnScreenWidth <= PANEL_WIDTH && gnScreenHeight <= SPANEL_HEIGHT + PANEL_HEIGHT; } -void DrawSpellList(const CelOutputBuffer &out); +void DrawSpellList(const Surface &out); void SetSpell(); void SetSpeedSpell(int slot); void ToggleSpell(int slot); void AddPanelString(const char *str); void ClearPanel(); -void DrawPanelBox(const CelOutputBuffer &out, SDL_Rect srcRect, Point targetPosition); +void DrawPanelBox(const Surface &out, SDL_Rect srcRect, Point targetPosition); /** * Draws the top dome of the life flask (that part that protrudes out of the control panel). * First it draws the empty flask cel and then draws the filled part on top if needed. */ -void DrawLifeFlask(const CelOutputBuffer &out); +void DrawLifeFlask(const Surface &out); /** * Controls the drawing of the area of the life flask within the control panel. * First sets the fill amount then draws the empty flask cel portion then the filled * flask portion. */ -void UpdateLifeFlask(const CelOutputBuffer &out); +void UpdateLifeFlask(const Surface &out); -void DrawManaFlask(const CelOutputBuffer &out); +void DrawManaFlask(const Surface &out); void control_update_life_mana(); /** * Controls the drawing of the area of the life flask within the control panel. * Also for some reason draws the current right mouse button spell. */ -void UpdateManaFlask(const CelOutputBuffer &out); +void UpdateManaFlask(const Surface &out); void InitControlPan(); -void DrawCtrlPan(const CelOutputBuffer &out); +void DrawCtrlPan(const Surface &out); /** * Draws the control panel buttons in their current state. If the button is in the default * state draw it from the panel cel(extract its sub-rect). Else draw it from the buttons cel. */ -void DrawCtrlBtns(const CelOutputBuffer &out); +void DrawCtrlBtns(const Surface &out); void DoSpeedBook(); void DoPanBtn(); @@ -114,21 +114,21 @@ void FreeControlPan(); /** * Sets a string to be drawn in the info box and then draws it. */ -void DrawInfoBox(const CelOutputBuffer &out); -void DrawChr(const CelOutputBuffer &out); +void DrawInfoBox(const Surface &out); +void DrawChr(const Surface &out); void CheckLvlBtn(); void ReleaseLvlBtn(); -void DrawLevelUpIcon(const CelOutputBuffer &out); +void DrawLevelUpIcon(const Surface &out); void CheckChrBtns(); void ReleaseChrBtns(bool addAllStatPoints); -void DrawDurIcon(const CelOutputBuffer &out); -void RedBack(const CelOutputBuffer &out); -void DrawSpellBook(const CelOutputBuffer &out); +void DrawDurIcon(const Surface &out); +void RedBack(const Surface &out); +void DrawSpellBook(const Surface &out); void CheckSBook(); -void DrawGoldSplit(const CelOutputBuffer &out, int amount); +void DrawGoldSplit(const Surface &out, int amount); void control_drop_gold(char vkey); void control_remove_gold(int pnum, int goldIndex); -void DrawTalkPan(const CelOutputBuffer &out); +void DrawTalkPan(const Surface &out); bool control_check_talk_btn(); void control_release_talk_btn(); void control_type_message(); diff --git a/Source/controls/modifier_hints.cpp b/Source/controls/modifier_hints.cpp index 94094624d..bd994d1f6 100644 --- a/Source/controls/modifier_hints.cpp +++ b/Source/controls/modifier_hints.cpp @@ -104,7 +104,7 @@ uint16_t CircleMenuHintTextColor(bool active) * @param hint Struct describing the text to draw and the dimensions of the layout. * @param origin Top left corner of the layout (relative to the output buffer). */ -void DrawCircleMenuHint(const CelOutputBuffer &out, const CircleMenuHint &hint, const Point &origin) +void DrawCircleMenuHint(const Surface &out, const CircleMenuHint &hint, const Point &origin) { DrawString(out, hint.top, origin + Displacement { hint.xMid - hint.topW / 2, 0 }, CircleMenuHintTextColor(IsTopActive(hint))); @@ -114,7 +114,7 @@ void DrawCircleMenuHint(const CelOutputBuffer &out, const CircleMenuHint &hint, DrawString(out, hint.bottom, origin + Displacement { hint.xMid - hint.bottomW / 2, LineHeight * 2 }, CircleMenuHintTextColor(IsBottomActive(hint))); } -void DrawStartModifierMenu(const CelOutputBuffer &out) +void DrawStartModifierMenu(const Surface &out) { if (!start_modifier_active) return; @@ -124,7 +124,7 @@ void DrawStartModifierMenu(const CelOutputBuffer &out) DrawCircleMenuHint(out, Buttons, { PANEL_LEFT + PANEL_WIDTH - Buttons.Width() - CircleMarginX, PANEL_TOP - CircleTop }); } -void DrawSelectModifierMenu(const CelOutputBuffer &out) +void DrawSelectModifierMenu(const Surface &out) { if (!select_modifier_active) return; @@ -138,7 +138,7 @@ void DrawSelectModifierMenu(const CelOutputBuffer &out) } // namespace -void DrawControllerModifierHints(const CelOutputBuffer &out) +void DrawControllerModifierHints(const Surface &out) { DrawStartModifierMenu(out); DrawSelectModifierMenu(out); diff --git a/Source/controls/modifier_hints.h b/Source/controls/modifier_hints.h index bf9376834..87edba29e 100644 --- a/Source/controls/modifier_hints.h +++ b/Source/controls/modifier_hints.h @@ -4,6 +4,6 @@ namespace devilution { -void DrawControllerModifierHints(const CelOutputBuffer &out); +void DrawControllerModifierHints(const Surface &out); } // namespace devilution diff --git a/Source/cursor.cpp b/Source/cursor.cpp index 42164ab6b..4115ec973 100644 --- a/Source/cursor.cpp +++ b/Source/cursor.cpp @@ -187,7 +187,7 @@ void NewCursor(int cursId) } } -void CelDrawCursor(const CelOutputBuffer &out, Point position, int cursId) +void CelDrawCursor(const Surface &out, Point position, int cursId) { const auto &sprite = GetInvItemSprite(cursId); const int frame = GetInvItemFrame(cursId); diff --git a/Source/cursor.h b/Source/cursor.h index 20f3dd725..b2cd67ea6 100644 --- a/Source/cursor.h +++ b/Source/cursor.h @@ -60,7 +60,7 @@ inline bool IsItemSprite(int cursId) return cursId >= CURSOR_FIRSTITEM; } -void CelDrawCursor(const CelOutputBuffer &out, Point position, int cursId); +void CelDrawCursor(const Surface &out, Point position, int cursId); /** Returns the sprite for the given inventory index. */ const CelSprite &GetInvItemSprite(int i); diff --git a/Source/doom.cpp b/Source/doom.cpp index 19637babe..c62dfaf81 100644 --- a/Source/doom.cpp +++ b/Source/doom.cpp @@ -52,7 +52,7 @@ void doom_close() DoomCel = std::nullopt; } -void doom_draw(const CelOutputBuffer &out) +void doom_draw(const Surface &out) { if (!DoomFlag) { return; diff --git a/Source/doom.h b/Source/doom.h index 31627a1a7..b15cd66c8 100644 --- a/Source/doom.h +++ b/Source/doom.h @@ -15,6 +15,6 @@ extern int DoomQuestState; int doom_get_frame_from_time(); void doom_init(); void doom_close(); -void doom_draw(const CelOutputBuffer &out); +void doom_draw(const Surface &out); } // namespace devilution diff --git a/Source/dx.cpp b/Source/dx.cpp index d3414dc92..b96171170 100644 --- a/Source/dx.cpp +++ b/Source/dx.cpp @@ -160,14 +160,14 @@ void unlock_buf(int idx) // NOLINT(misc-unused-parameters) UnlockBufPriv(); } -CelOutputBuffer GlobalBackBuffer() +Surface GlobalBackBuffer() { if (sgdwLockCount == 0) { Log("WARNING: Trying to obtain GlobalBackBuffer() without holding a lock"); - return CelOutputBuffer(); + return Surface(); } - return CelOutputBuffer(pal_surface, SDL_Rect { 0, 0, gnScreenWidth, gnScreenHeight }); + return Surface(pal_surface, SDL_Rect { 0, 0, gnScreenWidth, gnScreenHeight }); } void dx_cleanup() diff --git a/Source/dx.h b/Source/dx.h index c815b4484..54211be0c 100644 --- a/Source/dx.h +++ b/Source/dx.h @@ -12,7 +12,7 @@ namespace devilution { /** Whether we render directly to the screen surface, i.e. `pal_surface == GetOutputSurface()` */ extern bool RenderDirectlyToOutputSurface; -CelOutputBuffer GlobalBackBuffer(); +Surface GlobalBackBuffer(); void dx_init(); void lock_buf(int idx); diff --git a/Source/engine.cpp b/Source/engine.cpp index b053b5571..045d23ac7 100644 --- a/Source/engine.cpp +++ b/Source/engine.cpp @@ -20,53 +20,7 @@ namespace devilution { -namespace { - -template -void BufferBlit(const CelOutputBuffer &src, SDL_Rect srcRect, const CelOutputBuffer &dst, Point dstPosition) -{ - // We do not use `SDL_BlitSurface` here because the palettes may be different objects - // and SDL would attempt to map them. - - dst.Clip(&srcRect, &dstPosition); - if (srcRect.w <= 0 || srcRect.h <= 0) - return; - - const std::uint8_t *srcBuf = src.at(srcRect.x, srcRect.y); - const auto srcPitch = src.pitch(); - std::uint8_t *dstBuf = &dst[dstPosition]; - const auto dstPitch = dst.pitch(); - - for (unsigned h = srcRect.h; h != 0; --h) { - if (SkipColorIndexZero) { - for (unsigned w = srcRect.w; w != 0; --w) { - if (*srcBuf != 0) - *dstBuf = *srcBuf; - ++srcBuf, ++dstBuf; - } - srcBuf += srcPitch - srcRect.w; - dstBuf += dstPitch - srcRect.w; - } else { - std::memcpy(dstBuf, srcBuf, srcRect.w); - srcBuf += srcPitch; - dstBuf += dstPitch; - } - } -} - -} // namespace - -void CelOutputBuffer::BlitFrom(const CelOutputBuffer &src, SDL_Rect srcRect, Point targetPosition) const -{ - BufferBlit(src, srcRect, *this, targetPosition); -} - -void CelOutputBuffer::BlitFromSkipColorIndexZero(const CelOutputBuffer &src, SDL_Rect srcRect, Point targetPosition) const -{ - BufferBlit(src, srcRect, *this, targetPosition); -} - -void DrawHorizontalLine(const CelOutputBuffer &out, Point from, int width, std::uint8_t colorIndex) +void DrawHorizontalLine(const Surface &out, Point from, int width, std::uint8_t colorIndex) { if (from.y < 0 || from.y >= out.h() || from.x >= out.w() || width <= 0 || from.x + width <= 0) return; @@ -79,12 +33,12 @@ void DrawHorizontalLine(const CelOutputBuffer &out, Point from, int width, std:: return UnsafeDrawHorizontalLine(out, from, width, colorIndex); } -void UnsafeDrawHorizontalLine(const CelOutputBuffer &out, Point from, int width, std::uint8_t colorIndex) +void UnsafeDrawHorizontalLine(const Surface &out, Point from, int width, std::uint8_t colorIndex) { std::memset(&out[from], colorIndex, width); } -void DrawVerticalLine(const CelOutputBuffer &out, Point from, int height, std::uint8_t colorIndex) +void DrawVerticalLine(const Surface &out, Point from, int height, std::uint8_t colorIndex) { if (from.x < 0 || from.x >= out.w() || from.y >= out.h() || height <= 0 || from.y + height <= 0) return; @@ -97,7 +51,7 @@ void DrawVerticalLine(const CelOutputBuffer &out, Point from, int height, std::u return UnsafeDrawVerticalLine(out, from, height, colorIndex); } -void UnsafeDrawVerticalLine(const CelOutputBuffer &out, Point from, int height, std::uint8_t colorIndex) +void UnsafeDrawVerticalLine(const Surface &out, Point from, int height, std::uint8_t colorIndex) { auto *dst = &out[from]; const auto pitch = out.pitch(); @@ -107,7 +61,7 @@ void UnsafeDrawVerticalLine(const CelOutputBuffer &out, Point from, int height, } } -static void DrawHalfTransparentBlendedRectTo(const CelOutputBuffer &out, int sx, int sy, int width, int height) +static void DrawHalfTransparentBlendedRectTo(const Surface &out, int sx, int sy, int width, int height) { BYTE *pix = out.at(sx, sy); @@ -120,7 +74,7 @@ static void DrawHalfTransparentBlendedRectTo(const CelOutputBuffer &out, int sx, } } -static void DrawHalfTransparentStippledRectTo(const CelOutputBuffer &out, int sx, int sy, int width, int height) +static void DrawHalfTransparentStippledRectTo(const Surface &out, int sx, int sy, int width, int height) { BYTE *pix = out.at(sx, sy); @@ -134,7 +88,7 @@ static void DrawHalfTransparentStippledRectTo(const CelOutputBuffer &out, int sx } } -void DrawHalfTransparentRectTo(const CelOutputBuffer &out, int sx, int sy, int width, int height) +void DrawHalfTransparentRectTo(const Surface &out, int sx, int sy, int width, int height) { if (sx + width < 0) return; diff --git a/Source/engine.h b/Source/engine.h index ee378a0da..29bff58b2 100644 --- a/Source/engine.h +++ b/Source/engine.h @@ -35,6 +35,7 @@ #include "appfat.h" #include "engine/point.hpp" #include "engine/size.hpp" +#include "engine/surface.hpp" #include "miniwin/miniwin.h" #include "utils/stdcompat/cstddef.hpp" @@ -67,174 +68,6 @@ bool IsNoneOf(const V &v, X x, Xs... xs) return IsNoneOf(v, x) && IsNoneOf(v, xs...); } -struct CelOutputBuffer { - // 8-bit palletized surface. - SDL_Surface *surface; - SDL_Rect region; - - CelOutputBuffer() - : surface(NULL) - , region(SDL_Rect { 0, 0, 0, 0 }) - { - } - - explicit CelOutputBuffer(SDL_Surface *surface) - : surface(surface) - , region(SDL_Rect { 0, 0, (Uint16)surface->w, (Uint16)surface->h }) - { - } - - CelOutputBuffer(SDL_Surface *surface, SDL_Rect region) - : surface(surface) - , region(region) - { - } - - CelOutputBuffer(const CelOutputBuffer &other) - : surface(other.surface) - , region(other.region) - { - } - - void operator=(const CelOutputBuffer &other) - { - surface = other.surface; - region = other.region; - } - - /** - * @brief Allocate a buffer that owns its underlying data. - */ - static CelOutputBuffer Alloc(std::size_t width, std::size_t height) - { - return CelOutputBuffer(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 = NULL; - } - - int w() const - { - return region.w; - } - int h() const - { - return region.h; - } - - std::uint8_t &operator[](Point p) const - { - return *at(p.x, p.y); - } - - uint8_t *at(int x, int y) const - { - return static_cast(surface->pixels) + region.x + x + surface->pitch * (region.y + y); - } - - uint8_t *begin() const - { - return at(0, 0); - } - uint8_t *end() const - { - return at(0, region.h); - } - - /** - * @brief Set the value of a single pixel if it is in bounds. - * @param point Target buffer coordinate - * @param col Color index from current palette - */ - void SetPixel(Point position, std::uint8_t col) const - { - if (InBounds(position)) - (*this)[position] = col; - } - - /** - * @brief Line width of the raw underlying byte buffer. - * May be wider than its logical width (for power-of-2 alignment). - */ - int pitch() const - { - return surface->pitch; - } - - bool InBounds(Point position) const - { - return position.x >= 0 && position.y >= 0 && position.x < region.w && position.y < region.h; - } - - /** - * @brief Returns a subregion of the given buffer. - */ - CelOutputBuffer subregion(Sint16 x, Sint16 y, Uint16 w, Uint16 h) const - { - // In SDL1 SDL_Rect x and y are Sint16. Cast explicitly to avoid a compiler warning. - using CoordType = decltype(SDL_Rect {}.x); - return CelOutputBuffer( - surface, - SDL_Rect { - static_cast(region.x + x), - static_cast(region.y + y), - w, h }); - } - - /** - * @brief Returns a buffer that starts at `y` of height `h`. - */ - CelOutputBuffer subregionY(Sint16 y, Sint16 h) const - { - SDL_Rect subregion = region; - subregion.y += y; - subregion.h = h; - return CelOutputBuffer(surface, subregion); - } - - /** - * @brief Clips srcRect and targetPosition to this output buffer. - */ - void Clip(SDL_Rect *srcRect, Point *targetPosition) const - { - if (targetPosition->x < 0) { - srcRect->x -= targetPosition->x; - srcRect->w += targetPosition->x; - targetPosition->x = 0; - } - if (targetPosition->y < 0) { - srcRect->y -= targetPosition->y; - srcRect->h += targetPosition->y; - targetPosition->y = 0; - } - if (targetPosition->x + srcRect->w > region.w) { - srcRect->w = region.w - targetPosition->x; - } - if (targetPosition->y + srcRect->h > region.h) { - srcRect->h = region.h - targetPosition->y; - } - } - - /** - * @brief Copies the `srcRect` portion of the given buffer to this buffer at `targetPosition`. - */ - void BlitFrom(const CelOutputBuffer &src, SDL_Rect srcRect, Point targetPosition) const; - - /** - * @brief Copies the `srcRect` portion of the given buffer to this buffer at `targetPosition`. - * Source pixels with index 0 are not copied. - */ - void BlitFromSkipColorIndexZero(const CelOutputBuffer &src, SDL_Rect srcRect, Point targetPosition) const; -}; - /** * @brief Draw a horizontal line segment in the target buffer (left to right) * @param out Target buffer @@ -242,10 +75,10 @@ struct CelOutputBuffer { * @param width * @param colorIndex Color index from current palette */ -void DrawHorizontalLine(const CelOutputBuffer &out, Point from, int width, std::uint8_t colorIndex); +void DrawHorizontalLine(const Surface &out, Point from, int width, std::uint8_t colorIndex); /** Same as DrawHorizontalLine but without bounds clipping. */ -void UnsafeDrawHorizontalLine(const CelOutputBuffer &out, Point from, int width, std::uint8_t colorIndex); +void UnsafeDrawHorizontalLine(const Surface &out, Point from, int width, std::uint8_t colorIndex); /** * @brief Draw a vertical line segment in the target buffer (top to bottom) @@ -254,10 +87,10 @@ void UnsafeDrawHorizontalLine(const CelOutputBuffer &out, Point from, int width, * @param height * @param colorIndex Color index from current palette */ -void DrawVerticalLine(const CelOutputBuffer &out, Point from, int height, std::uint8_t colorIndex); +void DrawVerticalLine(const Surface &out, Point from, int height, std::uint8_t colorIndex); /** Same as DrawVerticalLine but without bounds clipping. */ -void UnsafeDrawVerticalLine(const CelOutputBuffer &out, Point from, int height, std::uint8_t colorIndex); +void UnsafeDrawVerticalLine(const Surface &out, Point from, int height, std::uint8_t colorIndex); /** * Draws a half-transparent rectangle by blacking out odd pixels on odd lines, @@ -270,7 +103,7 @@ void UnsafeDrawVerticalLine(const CelOutputBuffer &out, Point from, int height, * @param width Rectangle width * @param height Rectangle height */ -void DrawHalfTransparentRectTo(const CelOutputBuffer &out, int sx, int sy, int width, int height); +void DrawHalfTransparentRectTo(const Surface &out, int sx, int sy, int width, int height); /** * @brief Calculate the best fit direction between two points diff --git a/Source/engine/render/automap_render.cpp b/Source/engine/render/automap_render.cpp index 97b2b39c9..605f0821b 100644 --- a/Source/engine/render/automap_render.cpp +++ b/Source/engine/render/automap_render.cpp @@ -19,7 +19,7 @@ enum class DirectionY { }; template -void DrawMapLine(const CelOutputBuffer &out, Point from, int height, std::uint8_t colorIndex) +void DrawMapLine(const Surface &out, Point from, int height, std::uint8_t colorIndex) { while (height-- > 0) { out.SetPixel({ from.x, from.y + 1 }, 0); @@ -35,7 +35,7 @@ void DrawMapLine(const CelOutputBuffer &out, Point from, int height, std::uint8_ } template -void DrawMapLineSteep(const CelOutputBuffer &out, Point from, int width, std::uint8_t colorIndex) +void DrawMapLineSteep(const Surface &out, Point from, int width, std::uint8_t colorIndex) { while (width-- > 0) { out.SetPixel(from, colorIndex); @@ -49,42 +49,42 @@ void DrawMapLineSteep(const CelOutputBuffer &out, Point from, int width, std::ui } // namespace -void DrawMapLineNE(const CelOutputBuffer &out, Point from, int height, std::uint8_t colorIndex) +void DrawMapLineNE(const Surface &out, Point from, int height, std::uint8_t colorIndex) { DrawMapLine(out, from, height, colorIndex); } -void DrawMapLineSE(const CelOutputBuffer &out, Point from, int height, std::uint8_t colorIndex) +void DrawMapLineSE(const Surface &out, Point from, int height, std::uint8_t colorIndex) { DrawMapLine(out, from, height, colorIndex); } -void DrawMapLineNW(const CelOutputBuffer &out, Point from, int height, std::uint8_t colorIndex) +void DrawMapLineNW(const Surface &out, Point from, int height, std::uint8_t colorIndex) { DrawMapLine(out, from, height, colorIndex); } -void DrawMapLineSW(const CelOutputBuffer &out, Point from, int height, std::uint8_t colorIndex) +void DrawMapLineSW(const Surface &out, Point from, int height, std::uint8_t colorIndex) { DrawMapLine(out, from, height, colorIndex); } -void DrawMapLineSteepNE(const CelOutputBuffer &out, Point from, int width, std::uint8_t colorIndex) +void DrawMapLineSteepNE(const Surface &out, Point from, int width, std::uint8_t colorIndex) { DrawMapLineSteep(out, from, width, colorIndex); } -void DrawMapLineSteepSE(const CelOutputBuffer &out, Point from, int width, std::uint8_t colorIndex) +void DrawMapLineSteepSE(const Surface &out, Point from, int width, std::uint8_t colorIndex) { DrawMapLineSteep(out, from, width, colorIndex); } -void DrawMapLineSteepNW(const CelOutputBuffer &out, Point from, int width, std::uint8_t colorIndex) +void DrawMapLineSteepNW(const Surface &out, Point from, int width, std::uint8_t colorIndex) { DrawMapLineSteep(out, from, width, colorIndex); } -void DrawMapLineSteepSW(const CelOutputBuffer &out, Point from, int width, std::uint8_t colorIndex) +void DrawMapLineSteepSW(const Surface &out, Point from, int width, std::uint8_t colorIndex) { DrawMapLineSteep(out, from, width, colorIndex); } diff --git a/Source/engine/render/automap_render.hpp b/Source/engine/render/automap_render.hpp index d8ff87c70..8cbf87098 100644 --- a/Source/engine/render/automap_render.hpp +++ b/Source/engine/render/automap_render.hpp @@ -22,7 +22,7 @@ namespace devilution { * * The end point is at `{ from.x + 2 * height + 1, from.y - height }`. */ -void DrawMapLineNE(const CelOutputBuffer &out, Point from, int height, std::uint8_t colorIndex); +void DrawMapLineNE(const Surface &out, Point from, int height, std::uint8_t colorIndex); /** * @brief Draw a line in the target buffer from the given point towards south east at an `atan(1/2)` angle. @@ -31,7 +31,7 @@ void DrawMapLineNE(const CelOutputBuffer &out, Point from, int height, std::uint * * The end point is at `{ from.x + 2 * height + 1, from.y + height }`. */ -void DrawMapLineSE(const CelOutputBuffer &out, Point from, int height, std::uint8_t colorIndex); +void DrawMapLineSE(const Surface &out, Point from, int height, std::uint8_t colorIndex); /** * @brief Draw a line in the target buffer from the given point towards north west at an `atan(1/2)` angle. @@ -40,7 +40,7 @@ void DrawMapLineSE(const CelOutputBuffer &out, Point from, int height, std::uint * * The end point is at `{ from.x - 2 * height + 1, from.y - height }`. */ -void DrawMapLineNW(const CelOutputBuffer &out, Point from, int height, std::uint8_t colorIndex); +void DrawMapLineNW(const Surface &out, Point from, int height, std::uint8_t colorIndex); /** * @brief Draw a line in the target buffer from the given point towards south west at an `atan(1/2)` angle. @@ -49,7 +49,7 @@ void DrawMapLineNW(const CelOutputBuffer &out, Point from, int height, std::uint * * The end point is at `{ from.x - 2 * height + 1, from.y + height }`. */ -void DrawMapLineSW(const CelOutputBuffer &out, Point from, int height, std::uint8_t colorIndex); +void DrawMapLineSW(const Surface &out, Point from, int height, std::uint8_t colorIndex); /** * @brief Draw a line in the target buffer from the given point towards north east at an `atan(1/2)` angle. @@ -58,7 +58,7 @@ void DrawMapLineSW(const CelOutputBuffer &out, Point from, int height, std::uint * * The end point is at `{ from.x + width + 1, from.y - 2 * width }`. */ -void DrawMapLineSteepNE(const CelOutputBuffer &out, Point from, int width, std::uint8_t colorIndex); +void DrawMapLineSteepNE(const Surface &out, Point from, int width, std::uint8_t colorIndex); /** * @brief Draw a line in the target buffer from the given point towards south east at an `atan(2)` angle. @@ -67,7 +67,7 @@ void DrawMapLineSteepNE(const CelOutputBuffer &out, Point from, int width, std:: * * The end point is at `{ from.x + width + 1, from.y + 2 * width }`. */ -void DrawMapLineSteepSE(const CelOutputBuffer &out, Point from, int width, std::uint8_t colorIndex); +void DrawMapLineSteepSE(const Surface &out, Point from, int width, std::uint8_t colorIndex); /** * @brief Draw a line in the target buffer from the given point towards north west at an `atan(1/2)` angle. @@ -76,7 +76,7 @@ void DrawMapLineSteepSE(const CelOutputBuffer &out, Point from, int width, std:: * * The end point is at `{ from.x - (width + 1), from.y - 2 * width }`. */ -void DrawMapLineSteepNW(const CelOutputBuffer &out, Point from, int width, std::uint8_t colorIndex); +void DrawMapLineSteepNW(const Surface &out, Point from, int width, std::uint8_t colorIndex); /** * @brief Draw a line in the target buffer from the given point towards south west at an `atan(1/2)` angle. @@ -85,6 +85,6 @@ void DrawMapLineSteepNW(const CelOutputBuffer &out, Point from, int width, std:: * * The end point is at `{ from.x - (width + 1), from.y + 2 * width }`. */ -void DrawMapLineSteepSW(const CelOutputBuffer &out, Point from, int width, std::uint8_t colorIndex); +void DrawMapLineSteepSW(const Surface &out, Point from, int width, std::uint8_t colorIndex); } // namespace devilution diff --git a/Source/engine/render/cel_render.cpp b/Source/engine/render/cel_render.cpp index 556eb0df4..1b35b0911 100644 --- a/Source/engine/render/cel_render.cpp +++ b/Source/engine/render/cel_render.cpp @@ -48,7 +48,7 @@ constexpr auto NullLineEndFn = []() {}; /** Renders a CEL with only vertical clipping to the output buffer. */ template -DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void RenderCelClipY(const CelOutputBuffer &out, Point position, const byte *src, std::size_t srcSize, std::size_t srcWidth, +DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void RenderCelClipY(const Surface &out, Point position, const byte *src, std::size_t srcSize, std::size_t srcWidth, const RenderLine &renderLine, const LineEndFn &lineEndFn) { const auto *srcEnd = src + srcSize; @@ -84,7 +84,7 @@ DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void RenderCelClipY(const CelOutputBuffer &o /** Renders a CEL with both horizontal and vertical clipping to the output buffer. */ template DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void RenderCelClipXY( // NOLINT(readability-function-cognitive-complexity) - const CelOutputBuffer &out, Point position, const byte *src, std::size_t srcSize, std::size_t srcWidth, ClipX clipX, + const Surface &out, Point position, const byte *src, std::size_t srcSize, std::size_t srcWidth, ClipX clipX, const RenderLine &renderLine, const LineEndFn &lineEndFn) { const auto *srcEnd = src + srcSize; @@ -164,7 +164,7 @@ DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void RenderCelClipXY( // NOLINT(readability- template DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void RenderCel( - const CelOutputBuffer &out, Point position, const byte *src, std::size_t srcSize, std::size_t srcWidth, + const Surface &out, Point position, const byte *src, std::size_t srcSize, std::size_t srcWidth, const RenderLine &renderLine, const LineEndFn &lineEndFn) { const ClipX clipX = CalculateClipX(position.x, srcWidth, out); @@ -177,7 +177,7 @@ DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void RenderCel( } } -void RenderCelWithLightTable(const CelOutputBuffer &out, Point position, const byte *src, std::size_t srcSize, std::size_t srcWidth, const std::uint8_t *tbl) +void RenderCelWithLightTable(const Surface &out, Point position, const byte *src, std::size_t srcSize, std::size_t srcWidth, const std::uint8_t *tbl) { RenderCel( out, position, src, srcSize, srcWidth, [tbl](std::uint8_t *dst, const std::uint8_t *src, std::size_t w) { @@ -303,7 +303,7 @@ std::uint8_t *RenderCelOutlinePixels( template const byte *RenderCelOutlineRowClipped( // NOLINT(readability-function-cognitive-complexity,misc-no-recursion) - const CelOutputBuffer &out, Point position, const byte *src, ClipX clipX, std::uint8_t color) + const Surface &out, Point position, const byte *src, ClipX clipX, std::uint8_t color) { std::int_fast16_t remainingWidth = clipX.width; std::uint8_t v; @@ -353,7 +353,7 @@ const byte *RenderCelOutlineRowClipped( // NOLINT(readability-function-cognitive } template -void RenderCelOutlineClippedY(const CelOutputBuffer &out, Point position, const byte *src, std::size_t srcSize, // NOLINT(readability-function-cognitive-complexity) +void RenderCelOutlineClippedY(const Surface &out, Point position, const byte *src, std::size_t srcSize, // NOLINT(readability-function-cognitive-complexity) std::size_t srcWidth, std::uint8_t color) { const auto *srcEnd = src + srcSize; @@ -409,7 +409,7 @@ void RenderCelOutlineClippedY(const CelOutputBuffer &out, Point position, const } template -void RenderCelOutlineClippedXY(const CelOutputBuffer &out, Point position, const byte *src, std::size_t srcSize, // NOLINT(readability-function-cognitive-complexity) +void RenderCelOutlineClippedXY(const Surface &out, Point position, const byte *src, std::size_t srcSize, // NOLINT(readability-function-cognitive-complexity) std::size_t srcWidth, std::uint8_t color) { const auto *srcEnd = src + srcSize; @@ -514,7 +514,7 @@ void RenderCelOutlineClippedXY(const CelOutputBuffer &out, Point position, const } template -void RenderCelOutline(const CelOutputBuffer &out, Point position, const byte *src, std::size_t srcSize, +void RenderCelOutline(const Surface &out, Point position, const byte *src, std::size_t srcSize, std::size_t srcWidth, std::uint8_t color) { if (position.x > 0 && position.x + static_cast(srcWidth) < static_cast(out.w())) { @@ -531,7 +531,7 @@ void RenderCelOutline(const CelOutputBuffer &out, Point position, const byte *sr * @param pRLEBytes CEL pixel stream (run-length encoded) * @param nDataSize Size of CEL in bytes */ -void CelBlitSafeTo(const CelOutputBuffer &out, Point position, const byte *pRLEBytes, int nDataSize, int nWidth) +void CelBlitSafeTo(const Surface &out, Point position, const byte *pRLEBytes, int nDataSize, int nWidth) { assert(pRLEBytes != nullptr); RenderCel(out, position, pRLEBytes, nDataSize, nWidth, RenderLineMemcpy, NullLineEndFn); @@ -544,7 +544,7 @@ void CelBlitSafeTo(const CelOutputBuffer &out, Point position, const byte *pRLEB * @param pRLEBytes CEL pixel stream (run-length encoded) * @param nDataSize Size of CEL in bytes */ -void CelBlitLightTransSafeTo(const CelOutputBuffer &out, Point position, const byte *pRLEBytes, int nDataSize, int nWidth) +void CelBlitLightTransSafeTo(const Surface &out, Point position, const byte *pRLEBytes, int nDataSize, int nWidth) { assert(pRLEBytes != nullptr); const std::uint8_t *tbl = &pLightTbl[light_table_index * 256]; @@ -571,7 +571,7 @@ void CelBlitLightTransSafeTo(const CelOutputBuffer &out, Point position, const b * @param nWidth Width of sprite * @param tbl Palette translation table */ -void CelBlitLightBlendedSafeTo(const CelOutputBuffer &out, Point position, const byte *pRLEBytes, int nDataSize, int nWidth, const uint8_t *tbl) +void CelBlitLightBlendedSafeTo(const Surface &out, Point position, const byte *pRLEBytes, int nDataSize, int nWidth, const uint8_t *tbl) { assert(pRLEBytes != nullptr); if (tbl == nullptr) @@ -595,7 +595,7 @@ void CelBlitLightBlendedSafeTo(const CelOutputBuffer &out, Point position, const * @param nDataSize Size of CEL in bytes * @param tbl Palette translation table */ -void CelBlitLightSafeTo(const CelOutputBuffer &out, Point position, const byte *pRLEBytes, int nDataSize, int nWidth, uint8_t *tbl) +void CelBlitLightSafeTo(const Surface &out, Point position, const byte *pRLEBytes, int nDataSize, int nWidth, uint8_t *tbl) { assert(pRLEBytes != nullptr); if (tbl == nullptr) @@ -605,14 +605,14 @@ void CelBlitLightSafeTo(const CelOutputBuffer &out, Point position, const byte * } // namespace -void CelDrawTo(const CelOutputBuffer &out, Point position, const CelSprite &cel, int frame) +void CelDrawTo(const Surface &out, Point position, const CelSprite &cel, int frame) { int nDataSize; const auto *pRLEBytes = CelGetFrame(cel.Data(), frame, &nDataSize); CelBlitSafeTo(out, position, pRLEBytes, nDataSize, cel.Width(frame)); } -void CelClippedDrawTo(const CelOutputBuffer &out, Point position, const CelSprite &cel, int frame) +void CelClippedDrawTo(const Surface &out, Point position, const CelSprite &cel, int frame) { int nDataSize; const auto *pRLEBytes = CelGetFrameClipped(cel.Data(), frame, &nDataSize); @@ -620,7 +620,7 @@ void CelClippedDrawTo(const CelOutputBuffer &out, Point position, const CelSprit CelBlitSafeTo(out, position, pRLEBytes, nDataSize, cel.Width(frame)); } -void CelDrawLightTo(const CelOutputBuffer &out, Point position, const CelSprite &cel, int frame, uint8_t *tbl) +void CelDrawLightTo(const Surface &out, Point position, const CelSprite &cel, int frame, uint8_t *tbl) { int nDataSize; const auto *pRLEBytes = CelGetFrame(cel.Data(), frame, &nDataSize); @@ -631,7 +631,7 @@ void CelDrawLightTo(const CelOutputBuffer &out, Point position, const CelSprite CelBlitSafeTo(out, position, pRLEBytes, nDataSize, cel.Width(frame)); } -void CelClippedDrawLightTo(const CelOutputBuffer &out, Point position, const CelSprite &cel, int frame) +void CelClippedDrawLightTo(const Surface &out, Point position, const CelSprite &cel, int frame) { int nDataSize; const auto *pRLEBytes = CelGetFrameClipped(cel.Data(), frame, &nDataSize); @@ -642,14 +642,14 @@ void CelClippedDrawLightTo(const CelOutputBuffer &out, Point position, const Cel CelBlitSafeTo(out, position, pRLEBytes, nDataSize, cel.Width(frame)); } -void CelDrawLightRedTo(const CelOutputBuffer &out, Point position, const CelSprite &cel, int frame) +void CelDrawLightRedTo(const Surface &out, Point position, const CelSprite &cel, int frame) { int nDataSize; const auto *pRLEBytes = CelGetFrameClipped(cel.Data(), frame, &nDataSize); RenderCelWithLightTable(out, position, pRLEBytes, nDataSize, cel.Width(frame), GetLightTable(1)); } -void CelDrawItem(const ItemStruct &item, const CelOutputBuffer &out, Point position, const CelSprite &cel, int frame) +void CelDrawItem(const ItemStruct &item, const Surface &out, Point position, const CelSprite &cel, int frame) { bool usable = item._iStatFlag; if (!usable) { @@ -659,14 +659,14 @@ void CelDrawItem(const ItemStruct &item, const CelOutputBuffer &out, Point posit } } -void CelClippedDrawSafeTo(const CelOutputBuffer &out, Point position, const CelSprite &cel, int frame) +void CelClippedDrawSafeTo(const Surface &out, Point position, const CelSprite &cel, int frame) { int nDataSize; const auto *pRLEBytes = CelGetFrameClipped(cel.Data(), frame, &nDataSize); CelBlitSafeTo(out, position, pRLEBytes, nDataSize, cel.Width(frame)); } -void CelClippedBlitLightTransTo(const CelOutputBuffer &out, Point position, const CelSprite &cel, int frame) +void CelClippedBlitLightTransTo(const Surface &out, Point position, const CelSprite &cel, int frame) { int nDataSize; const byte *pRLEBytes = CelGetFrameClipped(cel.Data(), frame, &nDataSize); @@ -682,21 +682,21 @@ void CelClippedBlitLightTransTo(const CelOutputBuffer &out, Point position, cons CelBlitSafeTo(out, position, pRLEBytes, nDataSize, cel.Width(frame)); } -void CelDrawLightRedSafeTo(const CelOutputBuffer &out, Point position, const CelSprite &cel, int frame) +void CelDrawLightRedSafeTo(const Surface &out, Point position, const CelSprite &cel, int frame) { int nDataSize; const auto *pRLEBytes = CelGetFrameClipped(cel.Data(), frame, &nDataSize); RenderCelWithLightTable(out, position, pRLEBytes, nDataSize, cel.Width(frame), GetLightTable(1)); } -void CelDrawUnsafeTo(const CelOutputBuffer &out, Point position, const CelSprite &cel, int frame) +void CelDrawUnsafeTo(const Surface &out, Point position, const CelSprite &cel, int frame) { int nDataSize; const auto *pRLEBytes = CelGetFrame(cel.Data(), frame, &nDataSize); RenderCelClipY(out, position, pRLEBytes, nDataSize, cel.Width(frame), RenderLineMemcpy, NullLineEndFn); } -void CelBlitOutlineTo(const CelOutputBuffer &out, uint8_t col, Point position, const CelSprite &cel, int frame, bool skipColorIndexZero) +void CelBlitOutlineTo(const Surface &out, uint8_t col, Point position, const CelSprite &cel, int frame, bool skipColorIndexZero) { int nDataSize; const byte *src = CelGetFrameClipped(cel.Data(), frame, &nDataSize); diff --git a/Source/engine/render/cel_render.hpp b/Source/engine/render/cel_render.hpp index 16f1fd435..6aa62456f 100644 --- a/Source/engine/render/cel_render.hpp +++ b/Source/engine/render/cel_render.hpp @@ -27,7 +27,7 @@ std::pair MeasureSolidHorizontalBounds(const CelSprite &cel, int frame * @param cel CEL sprite * @param frame CEL frame number */ -void CelDrawTo(const CelOutputBuffer &out, Point position, const CelSprite &cel, int frame); +void CelDrawTo(const Surface &out, Point position, const CelSprite &cel, int frame); /** * @briefBlit CEL sprite to the given buffer, does not perform bounds-checking. @@ -36,7 +36,7 @@ void CelDrawTo(const CelOutputBuffer &out, Point position, const CelSprite &cel, * @param cel CEL sprite * @param frame CEL frame number */ -void CelDrawUnsafeTo(const CelOutputBuffer &out, Point position, const CelSprite &cel, int frame); +void CelDrawUnsafeTo(const Surface &out, Point position, const CelSprite &cel, int frame); /** * @brief Same as CelDrawTo but with the option to skip parts of the top and bottom of the sprite @@ -45,7 +45,7 @@ void CelDrawUnsafeTo(const CelOutputBuffer &out, Point position, const CelSprite * @param cel CEL sprite * @param frame CEL frame number */ -void CelClippedDrawTo(const CelOutputBuffer &out, Point position, const CelSprite &cel, int frame); +void CelClippedDrawTo(const Surface &out, Point position, const CelSprite &cel, int frame); /** * @brief Blit CEL sprite, and apply lighting, to the back buffer at the given coordinates @@ -54,7 +54,7 @@ void CelClippedDrawTo(const CelOutputBuffer &out, Point position, const CelSprit * @param cel CEL sprite * @param frame CEL frame number */ -void CelDrawLightTo(const CelOutputBuffer &out, Point position, const CelSprite &cel, int frame, uint8_t *tbl); +void CelDrawLightTo(const Surface &out, Point position, const CelSprite &cel, int frame, uint8_t *tbl); /** * @brief Same as CelDrawLightTo but with the option to skip parts of the top and bottom of the sprite @@ -63,7 +63,7 @@ void CelDrawLightTo(const CelOutputBuffer &out, Point position, const CelSprite * @param cel CEL sprite * @param frame CEL frame number */ -void CelClippedDrawLightTo(const CelOutputBuffer &out, Point position, const CelSprite &cel, int frame); +void CelClippedDrawLightTo(const Surface &out, Point position, const CelSprite &cel, int frame); /** * @brief Same as CelBlitLightTransSafeTo @@ -72,7 +72,7 @@ void CelClippedDrawLightTo(const CelOutputBuffer &out, Point position, const Cel * @param cel CEL sprite * @param frame CEL frame number */ -void CelClippedBlitLightTransTo(const CelOutputBuffer &out, Point position, const CelSprite &cel, int frame); +void CelClippedBlitLightTransTo(const Surface &out, Point position, const CelSprite &cel, int frame); /** * @brief Blit CEL sprite, and apply lighting, to the back buffer at the given coordinates, translated to a red hue @@ -81,7 +81,7 @@ void CelClippedBlitLightTransTo(const CelOutputBuffer &out, Point position, cons * @param cel CEL sprite * @param frame CEL frame number */ -void CelDrawLightRedTo(const CelOutputBuffer &out, Point position, const CelSprite &cel, int frame); +void CelDrawLightRedTo(const Surface &out, Point position, const CelSprite &cel, int frame); /** * @brief Blit item's CEL sprite recolored red if not usable, normal if usable @@ -91,7 +91,7 @@ void CelDrawLightRedTo(const CelOutputBuffer &out, Point position, const CelSpri * @param cel CEL sprite * @param frame CEL frame number */ -void CelDrawItem(const ItemStruct &item, const CelOutputBuffer &out, Point position, const CelSprite &cel, int frame); +void CelDrawItem(const ItemStruct &item, const Surface &out, Point position, const CelSprite &cel, int frame); /** * @brief Same as CelClippedDrawTo but checks for drawing outside the buffer @@ -100,7 +100,7 @@ void CelDrawItem(const ItemStruct &item, const CelOutputBuffer &out, Point posit * @param cel CEL sprite * @param frame CEL frame number */ -void CelClippedDrawSafeTo(const CelOutputBuffer &out, Point position, const CelSprite &cel, int frame); +void CelClippedDrawSafeTo(const Surface &out, Point position, const CelSprite &cel, int frame); /** * @brief Same as CelDrawLightRedTo but checks for drawing outside the buffer @@ -109,7 +109,7 @@ void CelClippedDrawSafeTo(const CelOutputBuffer &out, Point position, const CelS * @param cel CEL sprite * @param frame CEL frame number */ -void CelDrawLightRedSafeTo(const CelOutputBuffer &out, Point position, const CelSprite &cel, int frame); +void CelDrawLightRedSafeTo(const Surface &out, Point position, const CelSprite &cel, int frame); /** * @brief Blit a solid colder shape one pixel larger than the given sprite shape, to the target buffer at the given coordianates @@ -120,6 +120,6 @@ void CelDrawLightRedSafeTo(const CelOutputBuffer &out, Point position, const Cel * @param frame CEL frame number * @param skipColorIndexZero If true, color in index 0 will be treated as transparent (these are typically used for shadows in sprites) */ -void CelBlitOutlineTo(const CelOutputBuffer &out, uint8_t col, Point position, const CelSprite &cel, int frame, bool skipColorIndexZero = true); +void CelBlitOutlineTo(const Surface &out, uint8_t col, Point position, const CelSprite &cel, int frame, bool skipColorIndexZero = true); } // namespace devilution diff --git a/Source/engine/render/cl2_render.cpp b/Source/engine/render/cl2_render.cpp index bcfc953b0..229b497f9 100644 --- a/Source/engine/render/cl2_render.cpp +++ b/Source/engine/render/cl2_render.cpp @@ -93,7 +93,7 @@ DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT const byte *SkipRestOfCl2Line( /** Renders a CL2 sprite with only vertical clipping to the output buffer. */ template DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void RenderCl2ClipY( - const CelOutputBuffer &out, Point position, const byte *src, std::size_t srcSize, std::size_t srcWidth, + const Surface &out, Point position, const byte *src, std::size_t srcSize, std::size_t srcWidth, const RenderPixels &renderPixels, const RenderFill &renderFill) { const auto *srcEnd = src + srcSize; @@ -146,7 +146,7 @@ DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void RenderCl2ClipY( /** Renders a CEL with both horizontal and vertical clipping to the output buffer. */ template DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void RenderCl2ClipXY( // NOLINT(readability-function-cognitive-complexity) - const CelOutputBuffer &out, Point position, const byte *src, std::size_t srcSize, std::size_t srcWidth, ClipX clipX, + const Surface &out, Point position, const byte *src, std::size_t srcSize, std::size_t srcWidth, ClipX clipX, const RenderPixels &renderPixels, const RenderFill &renderFill) { const auto *srcEnd = src + srcSize; @@ -249,7 +249,7 @@ DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void RenderCl2ClipXY( // NOLINT(readability- template DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void RenderCl2( - const CelOutputBuffer &out, Point position, const byte *src, std::size_t srcSize, std::size_t srcWidth, + const Surface &out, Point position, const byte *src, std::size_t srcSize, std::size_t srcWidth, const RenderPixels &renderPixels, const RenderFill &renderFill) { const ClipX clipX = CalculateClipX(position.x, srcWidth, out); @@ -271,7 +271,7 @@ DVL_ALWAYS_INLINE DVL_ATTRIBUTE_HOT void RenderCl2( * @param nDataSize Size of CL2 in bytes * @param nWidth Width of sprite */ -void Cl2BlitSafe(const CelOutputBuffer &out, int sx, int sy, const byte *pRLEBytes, int nDataSize, int nWidth) +void Cl2BlitSafe(const Surface &out, int sx, int sy, const byte *pRLEBytes, int nDataSize, int nWidth) { RenderCl2( out, { sx, sy }, pRLEBytes, nDataSize, nWidth, @@ -303,7 +303,7 @@ void Cl2BlitSafe(const CelOutputBuffer &out, int sx, int sy, const byte *pRLEByt * @param nWidth With of CL2 sprite * @param pTable Light color table */ -void Cl2BlitLightSafe(const CelOutputBuffer &out, int sx, int sy, const byte *pRLEBytes, int nDataSize, int nWidth, uint8_t *pTable) +void Cl2BlitLightSafe(const Surface &out, int sx, int sy, const byte *pRLEBytes, int nDataSize, int nWidth, uint8_t *pTable) { RenderCl2( out, { sx, sy }, pRLEBytes, nDataSize, nWidth, @@ -467,7 +467,7 @@ std::uint8_t *RenderCl2OutlinePixels( template const byte *RenderCl2OutlineRowClipped( // NOLINT(readability-function-cognitive-complexity) - const CelOutputBuffer &out, Point position, const byte *src, std::size_t srcWidth, + const Surface &out, Point position, const byte *src, std::size_t srcWidth, ClipX clipX, std::uint8_t color, SkipSize &skipSize) { std::int_fast16_t remainingWidth = clipX.width; @@ -556,7 +556,7 @@ const byte *RenderCl2OutlineRowClipped( // NOLINT(readability-function-cognitive return src; } -void RenderCl2OutlineClippedY(const CelOutputBuffer &out, Point position, const byte *src, std::size_t srcSize, // NOLINT(readability-function-cognitive-complexity) +void RenderCl2OutlineClippedY(const Surface &out, Point position, const byte *src, std::size_t srcSize, // NOLINT(readability-function-cognitive-complexity) std::size_t srcWidth, std::uint8_t color) { const auto *srcEnd = src + srcSize; @@ -613,7 +613,7 @@ void RenderCl2OutlineClippedY(const CelOutputBuffer &out, Point position, const } } -void RenderCl2OutlineClippedXY(const CelOutputBuffer &out, Point position, const byte *src, std::size_t srcSize, // NOLINT(readability-function-cognitive-complexity) +void RenderCl2OutlineClippedXY(const Surface &out, Point position, const byte *src, std::size_t srcSize, // NOLINT(readability-function-cognitive-complexity) std::size_t srcWidth, std::uint8_t color) { const auto *srcEnd = src + srcSize; @@ -718,7 +718,7 @@ void RenderCl2OutlineClippedXY(const CelOutputBuffer &out, Point position, const } } -void RenderCl2Outline(const CelOutputBuffer &out, Point position, const byte *src, std::size_t srcSize, +void RenderCl2Outline(const Surface &out, Point position, const byte *src, std::size_t srcSize, std::size_t srcWidth, std::uint8_t color) { if (position.x > 0 && position.x + static_cast(srcWidth) < static_cast(out.w())) { @@ -763,7 +763,7 @@ void Cl2ApplyTrans(byte *p, const std::array &ttbl, int nCel) } } -void Cl2Draw(const CelOutputBuffer &out, int sx, int sy, const CelSprite &cel, int frame) +void Cl2Draw(const Surface &out, int sx, int sy, const CelSprite &cel, int frame) { assert(frame > 0); @@ -773,7 +773,7 @@ void Cl2Draw(const CelOutputBuffer &out, int sx, int sy, const CelSprite &cel, i Cl2BlitSafe(out, sx, sy, pRLEBytes, nDataSize, cel.Width(frame)); } -void Cl2DrawOutline(const CelOutputBuffer &out, uint8_t col, int sx, int sy, const CelSprite &cel, int frame) +void Cl2DrawOutline(const Surface &out, uint8_t col, int sx, int sy, const CelSprite &cel, int frame) { assert(frame > 0); @@ -783,7 +783,7 @@ void Cl2DrawOutline(const CelOutputBuffer &out, uint8_t col, int sx, int sy, con RenderCl2Outline(out, { sx, sy }, pRLEBytes, nDataSize, cel.Width(frame), col); } -void Cl2DrawLightTbl(const CelOutputBuffer &out, int sx, int sy, const CelSprite &cel, int frame, char light) +void Cl2DrawLightTbl(const Surface &out, int sx, int sy, const CelSprite &cel, int frame, char light) { assert(frame > 0); @@ -792,7 +792,7 @@ void Cl2DrawLightTbl(const CelOutputBuffer &out, int sx, int sy, const CelSprite Cl2BlitLightSafe(out, sx, sy, pRLEBytes, nDataSize, cel.Width(frame), GetLightTable(light)); } -void Cl2DrawLight(const CelOutputBuffer &out, int sx, int sy, const CelSprite &cel, int frame) +void Cl2DrawLight(const Surface &out, int sx, int sy, const CelSprite &cel, int frame) { assert(frame > 0); diff --git a/Source/engine/render/cl2_render.hpp b/Source/engine/render/cl2_render.hpp index 7c3c6b981..f92f082c8 100644 --- a/Source/engine/render/cl2_render.hpp +++ b/Source/engine/render/cl2_render.hpp @@ -30,7 +30,7 @@ void Cl2ApplyTrans(byte *p, const std::array &ttbl, int nCel); * @param pCelBuff CL2 buffer * @param nCel CL2 frame number */ -void Cl2Draw(const CelOutputBuffer &out, int sx, int sy, const CelSprite &cel, int frame); +void Cl2Draw(const Surface &out, int sx, int sy, const CelSprite &cel, int frame); /** * @brief Blit a solid colder shape one pixel larger than the given sprite shape, to the given buffer at the given coordianates @@ -41,7 +41,7 @@ void Cl2Draw(const CelOutputBuffer &out, int sx, int sy, const CelSprite &cel, i * @param pCelBuff CL2 buffer * @param nCel CL2 frame number */ -void Cl2DrawOutline(const CelOutputBuffer &out, uint8_t col, int sx, int sy, const CelSprite &cel, int frame); +void Cl2DrawOutline(const Surface &out, uint8_t col, int sx, int sy, const CelSprite &cel, int frame); /** * @brief Blit CL2 sprite, and apply a given lighting, to the given buffer at the given coordianates @@ -52,7 +52,7 @@ void Cl2DrawOutline(const CelOutputBuffer &out, uint8_t col, int sx, int sy, con * @param nCel CL2 frame number * @param light Light shade to use */ -void Cl2DrawLightTbl(const CelOutputBuffer &out, int sx, int sy, const CelSprite &cel, int frame, char light); +void Cl2DrawLightTbl(const Surface &out, int sx, int sy, const CelSprite &cel, int frame, char light); /** * @brief Blit CL2 sprite, and apply lighting, to the given buffer at the given coordinates @@ -62,6 +62,6 @@ void Cl2DrawLightTbl(const CelOutputBuffer &out, int sx, int sy, const CelSprite * @param pCelBuff CL2 buffer * @param nCel CL2 frame number */ -void Cl2DrawLight(const CelOutputBuffer &out, int sx, int sy, const CelSprite &cel, int frame); +void Cl2DrawLight(const Surface &out, int sx, int sy, const CelSprite &cel, int frame); } // namespace devilution diff --git a/Source/engine/render/common_impl.h b/Source/engine/render/common_impl.h index 88ec7f3ee..a782ff29b 100644 --- a/Source/engine/render/common_impl.h +++ b/Source/engine/render/common_impl.h @@ -29,7 +29,7 @@ struct ClipX { std::int_fast16_t width; }; -inline ClipX CalculateClipX(std::int_fast16_t x, std::size_t w, const CelOutputBuffer &out) +inline ClipX CalculateClipX(std::int_fast16_t x, std::size_t w, const Surface &out) { ClipX clip; clip.left = static_cast(x < 0 ? -x : 0); diff --git a/Source/engine/render/dun_render.cpp b/Source/engine/render/dun_render.cpp index 3084eb3d5..bec17b632 100644 --- a/Source/engine/render/dun_render.cpp +++ b/Source/engine/render/dun_render.cpp @@ -606,7 +606,7 @@ struct Clip { std::int_fast16_t height; }; -Clip CalculateClip(std::int_fast16_t x, std::int_fast16_t y, std::int_fast16_t w, std::int_fast16_t h, const CelOutputBuffer &out) +Clip CalculateClip(std::int_fast16_t x, std::int_fast16_t y, std::int_fast16_t w, std::int_fast16_t h, const Surface &out) { Clip clip; clip.top = y + 1 < h ? h - (y + 1) : 0; @@ -1375,7 +1375,7 @@ void RenderBlackTileFull(std::uint8_t *dst, int dstPitch) } // namespace -void RenderTile(const CelOutputBuffer &out, int x, int y) +void RenderTile(const Surface &out, int x, int y) { const auto tile = static_cast((level_cel_block & 0x7000) >> 12); const auto *mask = GetMask(tile); @@ -1432,7 +1432,7 @@ void RenderTile(const CelOutputBuffer &out, int x, int y) } } -void world_draw_black_tile(const CelOutputBuffer &out, int sx, int sy) +void world_draw_black_tile(const Surface &out, int sx, int sy) { #ifdef DEBUG_RENDER_OFFSET_X sx += DEBUG_RENDER_OFFSET_X; diff --git a/Source/engine/render/dun_render.hpp b/Source/engine/render/dun_render.hpp index 8469e894b..260d4d35e 100644 --- a/Source/engine/render/dun_render.hpp +++ b/Source/engine/render/dun_render.hpp @@ -15,7 +15,7 @@ namespace devilution { * @param x Target buffer coordinate * @param y Target buffer coordinate */ -void RenderTile(const CelOutputBuffer &out, int x, int y); +void RenderTile(const Surface &out, int x, int y); /** * @brief Render a black 64x31 tile ◆ @@ -23,6 +23,6 @@ void RenderTile(const CelOutputBuffer &out, int x, int y); * @param sx Target buffer coordinate (left corner of the tile) * @param sy Target buffer coordinate (bottom corner of the tile) */ -void world_draw_black_tile(const CelOutputBuffer &out, int sx, int sy); +void world_draw_black_tile(const Surface &out, int sx, int sy); } // namespace devilution diff --git a/Source/engine/render/text_render.cpp b/Source/engine/render/text_render.cpp index e3a1e588f..aebbfe916 100644 --- a/Source/engine/render/text_render.cpp +++ b/Source/engine/render/text_render.cpp @@ -137,7 +137,7 @@ uint8_t fontColorTableGold[256]; uint8_t fontColorTableBlue[256]; uint8_t fontColorTableRed[256]; -void DrawChar(const CelOutputBuffer &out, Point position, GameFontTables size, int nCel, text_color color) +void DrawChar(const Surface &out, Point position, GameFontTables size, int nCel, text_color color) { switch (color) { case ColorWhite: @@ -269,9 +269,9 @@ void WordWrapGameString(char *text, size_t width, GameFontTables size, int spaci } /** - * @todo replace Rectangle with cropped CelOutputBuffer + * @todo replace Rectangle with cropped Surface */ -int DrawString(const CelOutputBuffer &out, const char *text, const Rectangle &rect, uint16_t flags, int spacing, int lineHeight, bool drawTextCursor) +int DrawString(const Surface &out, const char *text, const Rectangle &rect, uint16_t flags, int spacing, int lineHeight, bool drawTextCursor) { GameFontTables size = GameFontSmall; if ((flags & UIS_MED) != 0) diff --git a/Source/engine/render/text_render.hpp b/Source/engine/render/text_render.hpp index 213528ef4..6a9efb486 100644 --- a/Source/engine/render/text_render.hpp +++ b/Source/engine/render/text_render.hpp @@ -58,7 +58,7 @@ void WordWrapGameString(char *text, size_t width, GameFontTables size = GameFont * @param drawTextCursor Whether to draw an animated cursor sprite at the end of the text (default is to display nothing). * @return The number of characters rendered, including characters "drawn" outside the buffer. */ -int DrawString(const CelOutputBuffer &out, const char *text, const Rectangle &rect, uint16_t flags = 0, int spacing = 1, int lineHeight = -1, bool drawTextCursor = false); +int DrawString(const Surface &out, const char *text, const Rectangle &rect, uint16_t flags = 0, int spacing = 1, int lineHeight = -1, bool drawTextCursor = false); /** * @brief Draws a line of text at the given position relative to the origin of the output buffer. @@ -78,7 +78,7 @@ int DrawString(const CelOutputBuffer &out, const char *text, const Rectangle &re * @param drawTextCursor Whether to draw an animated cursor sprite at the end of the text (default is to display nothing). * @return The number of characters rendered (could be less than the string length if it wrapped past the bottom of the buffer). */ -inline int DrawString(const CelOutputBuffer &out, const char *text, const Point &position, uint16_t flags = 0, int spacing = 1, int lineHeight = -1, bool drawTextCursor = false) +inline int DrawString(const Surface &out, const char *text, const Point &position, uint16_t flags = 0, int spacing = 1, int lineHeight = -1, bool drawTextCursor = false) { return DrawString(out, text, { position.x, position.y, out.w() - position.x, 0 }, flags, spacing, lineHeight, drawTextCursor); } diff --git a/Source/engine/surface.cpp b/Source/engine/surface.cpp new file mode 100644 index 000000000..5e023efee --- /dev/null +++ b/Source/engine/surface.cpp @@ -0,0 +1,53 @@ +#include "engine/surface.hpp" + +#include + +namespace devilution { + +namespace { + +template +void SurfaceBlit(const Surface &src, SDL_Rect srcRect, const Surface &dst, Point dstPosition) +{ + // We do not use `SDL_BlitSurface` here because the palettes may be different objects + // and SDL would attempt to map them. + + dst.Clip(&srcRect, &dstPosition); + if (srcRect.w <= 0 || srcRect.h <= 0) + return; + + const std::uint8_t *srcBuf = src.at(srcRect.x, srcRect.y); + const auto srcPitch = src.pitch(); + std::uint8_t *dstBuf = &dst[dstPosition]; + const auto dstPitch = dst.pitch(); + + for (unsigned h = srcRect.h; h != 0; --h) { + if (SkipColorIndexZero) { + for (unsigned w = srcRect.w; w != 0; --w) { + if (*srcBuf != 0) + *dstBuf = *srcBuf; + ++srcBuf, ++dstBuf; + } + srcBuf += srcPitch - srcRect.w; + dstBuf += dstPitch - srcRect.w; + } else { + std::memcpy(dstBuf, srcBuf, srcRect.w); + srcBuf += srcPitch; + dstBuf += dstPitch; + } + } +} + +} // namespace + +void Surface::BlitFrom(const Surface &src, SDL_Rect srcRect, Point targetPosition) const +{ + SurfaceBlit(src, srcRect, *this, targetPosition); +} + +void Surface::BlitFromSkipColorIndexZero(const Surface &src, SDL_Rect srcRect, Point targetPosition) const +{ + SurfaceBlit(src, srcRect, *this, targetPosition); +} + +} // namespace devilution diff --git a/Source/engine/surface.hpp b/Source/engine/surface.hpp new file mode 100644 index 000000000..40ba4149f --- /dev/null +++ b/Source/engine/surface.hpp @@ -0,0 +1,175 @@ +#pragma once + +#include +#include + +#include + +#if SDL_VERSION_ATLEAST(2, 0, 0) +#include +#include +#else +#include +#include "utils/sdl2_to_1_2_backports.h" +#endif + +#include "engine/point.hpp" +#include "utils/sdl_geometry.h" + +namespace devilution { + +/** + * @brief 8-bit surface. + */ +struct Surface { + SDL_Surface *surface; + SDL_Rect region; + + Surface() + : surface(nullptr) + , region(SDL_Rect { 0, 0, 0, 0 }) + { + } + + explicit Surface(SDL_Surface *surface) + : surface(surface) + , region(MakeSdlRect(0, 0, surface->w, surface->h)) + { + } + + Surface(SDL_Surface *surface, SDL_Rect region) + : surface(surface) + , region(region) + { + } + + Surface(const Surface &other) = default; + Surface& operator=(const Surface &other) = default; + + /** + * @brief Allocate a buffer that owns its underlying data. + */ + static Surface Alloc(std::size_t width, std::size_t 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; + } + int h() const + { + return region.h; + } + + std::uint8_t &operator[](Point p) const + { + return *at(p.x, p.y); + } + + std::uint8_t *at(int x, int y) const + { + return static_cast(surface->pixels) + region.x + x + surface->pitch * (region.y + y); + } + + std::uint8_t *begin() const + { + return at(0, 0); + } + std::uint8_t *end() const + { + return at(0, region.h); + } + + /** + * @brief Set the value of a single pixel if it is in bounds. + * @param point Target buffer coordinate + * @param col Color index from current palette + */ + void SetPixel(Point position, std::uint8_t col) const + { + if (InBounds(position)) + (*this)[position] = col; + } + + /** + * @brief Line width of the raw underlying byte buffer. + * May be wider than its logical width (for power-of-2 alignment). + */ + int pitch() const + { + return surface->pitch; + } + + bool InBounds(Point position) const + { + return position.x >= 0 && position.y >= 0 && position.x < region.w && position.y < region.h; + } + + /** + * @brief Returns a subregion of the given buffer. + */ + Surface subregion(int x, int y, int w, int h) const + { + return Surface(surface, MakeSdlRect(region.x + x, region.y + y, w, h)); + } + + /** + * @brief Returns a buffer that starts at `y` of height `h`. + */ + Surface subregionY(int y, int h) const + { + SDL_Rect subregion = region; + subregion.y += static_cast(y); + subregion.h = static_cast(h); + return Surface(surface, subregion); + } + + /** + * @brief Clips srcRect and targetPosition to this output buffer. + */ + void Clip(SDL_Rect *srcRect, Point *targetPosition) const + { + if (targetPosition->x < 0) { + srcRect->x -= targetPosition->x; + srcRect->w += targetPosition->x; + targetPosition->x = 0; + } + if (targetPosition->y < 0) { + srcRect->y -= targetPosition->y; + srcRect->h += targetPosition->y; + targetPosition->y = 0; + } + if (targetPosition->x + srcRect->w > region.w) { + srcRect->w = region.w - targetPosition->x; + } + if (targetPosition->y + srcRect->h > region.h) { + srcRect->h = region.h - targetPosition->y; + } + } + + /** + * @brief Copies the `srcRect` portion of the given buffer to this buffer at `targetPosition`. + */ + void BlitFrom(const Surface &src, SDL_Rect srcRect, Point targetPosition) const; + + /** + * @brief Copies the `srcRect` portion of the given buffer to this buffer at `targetPosition`. + * Source pixels with index 0 are not copied. + */ + void BlitFromSkipColorIndexZero(const Surface &src, SDL_Rect srcRect, Point targetPosition) const; +}; + +} // namespace devilution diff --git a/Source/error.cpp b/Source/error.cpp index 40f6b4fba..20ad06e40 100644 --- a/Source/error.cpp +++ b/Source/error.cpp @@ -107,7 +107,7 @@ void ClrDiabloMsg() #define DIALOG_Y ((gnScreenHeight - PANEL_HEIGHT) / 2 - 18) -void DrawDiabloMsg(const CelOutputBuffer &out) +void DrawDiabloMsg(const Surface &out) { CelDrawTo(out, { PANEL_X + 101, DIALOG_Y }, *pSTextSlidCels, 1); CelDrawTo(out, { PANEL_X + 527, DIALOG_Y }, *pSTextSlidCels, 4); diff --git a/Source/error.h b/Source/error.h index d6b395fc6..a9d989880 100644 --- a/Source/error.h +++ b/Source/error.h @@ -74,6 +74,6 @@ extern diablo_message msgflag; void InitDiabloMsg(diablo_message e); void ClrDiabloMsg(); -void DrawDiabloMsg(const CelOutputBuffer &out); +void DrawDiabloMsg(const Surface &out); } // namespace devilution diff --git a/Source/gmenu.cpp b/Source/gmenu.cpp index 6fe263155..2308aa77d 100644 --- a/Source/gmenu.cpp +++ b/Source/gmenu.cpp @@ -35,7 +35,7 @@ void (*gmenu_current_option)(); TMenuItem *sgpCurrentMenu; int sgCurrentMenuIdx; -void gmenu_draw_pause(const CelOutputBuffer &out) +void gmenu_draw_pause(const Surface &out) { if (currlevel != 0) RedBack(out); @@ -145,7 +145,7 @@ void gmenu_set_items(TMenuItem *pItem, void (*gmFunc)()) GmenuUpDown(true); } -static void GmenuClearBuffer(const CelOutputBuffer &out, int x, int y, int width, int height) +static void GmenuClearBuffer(const Surface &out, int x, int y, int width, int height) { BYTE *i = out.at(x, y); while ((height--) != 0) { @@ -162,7 +162,7 @@ static int GmenuGetLfont(TMenuItem *pItem) return GetLineWidth(_(pItem->pszStr), GameFontBig, 2); } -static void GmenuDrawMenuItem(const CelOutputBuffer &out, TMenuItem *pItem, int y) +static void GmenuDrawMenuItem(const Surface &out, TMenuItem *pItem, int y) { int w = GmenuGetLfont(pItem); if ((pItem->dwFlags & GMENU_SLIDER) != 0) { @@ -194,7 +194,7 @@ static void GameMenuMove() GmenuUpDown(moveDir.y == AxisDirectionY_DOWN); } -void gmenu_draw(const CelOutputBuffer &out) +void gmenu_draw(const Surface &out) { if (sgpCurrentMenu != nullptr) { GameMenuMove(); diff --git a/Source/gmenu.h b/Source/gmenu.h index 3c0cd452c..c1dcd9fc6 100644 --- a/Source/gmenu.h +++ b/Source/gmenu.h @@ -22,12 +22,12 @@ struct TMenuItem { extern TMenuItem *sgpCurrentMenu; -void gmenu_draw_pause(const CelOutputBuffer &out); +void gmenu_draw_pause(const Surface &out); void FreeGMenu(); void gmenu_init_menu(); bool gmenu_is_active(); void gmenu_set_items(TMenuItem *pItem, void (*gmFunc)()); -void gmenu_draw(const CelOutputBuffer &out); +void gmenu_draw(const Surface &out); bool gmenu_presskeys(int vkey); bool gmenu_on_mouse_move(); bool gmenu_left_mouse(bool isDown); diff --git a/Source/help.cpp b/Source/help.cpp index c1632bea6..2855e88c7 100644 --- a/Source/help.cpp +++ b/Source/help.cpp @@ -115,7 +115,7 @@ void InitHelp() } } -void DrawHelp(const CelOutputBuffer &out) +void DrawHelp(const Surface &out) { DrawSTextHelp(); DrawQTextBack(out); diff --git a/Source/help.h b/Source/help.h index cf2b4c569..524e28fc5 100644 --- a/Source/help.h +++ b/Source/help.h @@ -12,7 +12,7 @@ namespace devilution { extern bool helpflag; void InitHelp(); -void DrawHelp(const CelOutputBuffer &out); +void DrawHelp(const Surface &out); void DisplayHelp(); void HelpScrollUp(); void HelpScrollDown(); diff --git a/Source/hwcursor.cpp b/Source/hwcursor.cpp index 87d7deb41..50b0ec85e 100644 --- a/Source/hwcursor.cpp +++ b/Source/hwcursor.cpp @@ -79,7 +79,7 @@ bool SetHardwareCursorFromSprite(int pcurs) size.width += 2 * outlineWidth; size.height += 2 * outlineWidth; - auto out = CelOutputBuffer::Alloc(size.width, size.height); + auto out = Surface::Alloc(size.width, size.height); SDL_SetSurfacePalette(out.surface, palette); // Transparent color must not be used in the sprite itself. diff --git a/Source/interfac.cpp b/Source/interfac.cpp index 08a985935..0ddd1de8c 100644 --- a/Source/interfac.cpp +++ b/Source/interfac.cpp @@ -169,7 +169,7 @@ static void InitCutscene(interface_mode uMsg) static void DrawCutscene() { lock_buf(1); - const CelOutputBuffer &out = GlobalBackBuffer(); + const Surface &out = GlobalBackBuffer(); DrawArt(out, PANEL_X - (ArtCutsceneWidescreen.w() - PANEL_WIDTH) / 2, UI_OFFSET_Y, &ArtCutsceneWidescreen); CelDrawTo(out, { PANEL_X, 480 - 1 + UI_OFFSET_Y }, *sgpBackCel, 1); diff --git a/Source/inv.cpp b/Source/inv.cpp index e625789e3..238ba351e 100644 --- a/Source/inv.cpp +++ b/Source/inv.cpp @@ -164,7 +164,7 @@ void InitInv() drawsbarflag = false; } -static void InvDrawSlotBack(const CelOutputBuffer &out, Point targetPosition, Size size) +static void InvDrawSlotBack(const Surface &out, Point targetPosition, Size size) { SDL_Rect srcRect = MakeSdlRect(0, 0, size.width, size.height); out.Clip(&srcRect, &targetPosition); @@ -188,7 +188,7 @@ static void InvDrawSlotBack(const CelOutputBuffer &out, Point targetPosition, Si } } -void DrawInv(const CelOutputBuffer &out) +void DrawInv(const Surface &out) { CelDrawTo(out, { RIGHT_PANEL_X, 351 }, *pInvCels, 1); @@ -297,7 +297,7 @@ void DrawInv(const CelOutputBuffer &out) } } -void DrawInvBelt(const CelOutputBuffer &out) +void DrawInvBelt(const Surface &out) { if (talkflag) { return; diff --git a/Source/inv.h b/Source/inv.h index 34634cae9..434ac1c82 100644 --- a/Source/inv.h +++ b/Source/inv.h @@ -91,9 +91,9 @@ void InitInv(); /** * @brief Render the inventory panel to the given buffer. */ -void DrawInv(const CelOutputBuffer &out); +void DrawInv(const Surface &out); -void DrawInvBelt(const CelOutputBuffer &out); +void DrawInvBelt(const Surface &out); bool AutoEquipEnabled(const PlayerStruct &player, const ItemStruct &item); bool AutoEquip(int playerId, const ItemStruct &item, bool persistItem = true); bool AutoPlaceItemInInventory(PlayerStruct &player, const ItemStruct &item, bool persistItem = false); diff --git a/Source/items.cpp b/Source/items.cpp index 005e70495..ee2b25270 100644 --- a/Source/items.cpp +++ b/Source/items.cpp @@ -3641,13 +3641,13 @@ void PrintItemPower(char plidx, ItemStruct *x) } } -static void DrawUTextBack(const CelOutputBuffer &out) +static void DrawUTextBack(const Surface &out) { CelDrawTo(out, { RIGHT_PANEL_X - SPANEL_WIDTH + 24, 327 }, *pSTextBoxCels, 1); DrawHalfTransparentRectTo(out, RIGHT_PANEL_X - SPANEL_WIDTH + 27, 28, 265, 297); } -static void DrawULine(const CelOutputBuffer &out, int y) +static void DrawULine(const Surface &out, int y) { BYTE *src = out.at(26 + RIGHT_PANEL - SPANEL_WIDTH, 25); BYTE *dst = out.at(26 + RIGHT_PANEL_X - SPANEL_WIDTH, y * 12 + 38); @@ -3656,7 +3656,7 @@ static void DrawULine(const CelOutputBuffer &out, int y) memcpy(dst, src, 267); // BUGFIX: should be 267 (fixed) } -void DrawUniqueInfo(const CelOutputBuffer &out) +void DrawUniqueInfo(const Surface &out) { if ((chrflag || questlog) && gnScreenWidth < SPANEL_WIDTH * 3) { return; diff --git a/Source/items.h b/Source/items.h index 420783063..53c94da91 100644 --- a/Source/items.h +++ b/Source/items.h @@ -450,7 +450,7 @@ void DoRepair(int pnum, int cii); void DoRecharge(int pnum, int cii); void DoOil(int pnum, int cii); void PrintItemPower(char plidx, ItemStruct *x); -void DrawUniqueInfo(const CelOutputBuffer &out); +void DrawUniqueInfo(const Surface &out); void PrintItemDetails(ItemStruct *x); void PrintItemDur(ItemStruct *x); void UseItem(int p, item_misc_id Mid, spell_id spl); diff --git a/Source/minitext.cpp b/Source/minitext.cpp index d406562f3..08ec13a70 100644 --- a/Source/minitext.cpp +++ b/Source/minitext.cpp @@ -96,7 +96,7 @@ int CalculateTextPosition() /** * @brief Draw the current text in the quest dialog window */ -void DrawQTextContent(const CelOutputBuffer &out) +void DrawQTextContent(const Surface &out) { int y = CalculateTextPosition(); @@ -155,13 +155,13 @@ void InitQTextMsg(_speech_id m) PlaySFX(alltext[m].sfxnr); } -void DrawQTextBack(const CelOutputBuffer &out) +void DrawQTextBack(const Surface &out) { CelDrawTo(out, { PANEL_X + 24, 327 + UI_OFFSET_Y }, *pTextBoxCels, 1); DrawHalfTransparentRectTo(out, PANEL_X + 27, UI_OFFSET_Y + 28, 585, 297); } -void DrawQText(const CelOutputBuffer &out) +void DrawQText(const Surface &out) { DrawQTextBack(out); DrawQTextContent(out.subregionY(UI_OFFSET_Y + 49, 260)); diff --git a/Source/minitext.h b/Source/minitext.h index 190b54efb..ab811c5de 100644 --- a/Source/minitext.h +++ b/Source/minitext.h @@ -19,11 +19,11 @@ void InitQTextMsg(_speech_id m); /** * @brief Draw the quest dialog window decoration and background. */ -void DrawQTextBack(const CelOutputBuffer &out); +void DrawQTextBack(const Surface &out); /** * @brief Draw the quest dialog window text. */ -void DrawQText(const CelOutputBuffer &out); +void DrawQText(const Surface &out); } // namespace devilution diff --git a/Source/plrmsg.cpp b/Source/plrmsg.cpp index 42641b1be..15e89ed69 100644 --- a/Source/plrmsg.cpp +++ b/Source/plrmsg.cpp @@ -93,7 +93,7 @@ void InitPlrMsg() plr_msg_slot = 0; } -static void PrintPlrMsg(const CelOutputBuffer &out, int x, int y, int width, char *text, uint16_t style) +static void PrintPlrMsg(const Surface &out, int x, int y, int width, char *text, uint16_t style) { int length = strlen(text); for (int i = 0; i < length; i++) { @@ -104,7 +104,7 @@ static void PrintPlrMsg(const CelOutputBuffer &out, int x, int y, int width, cha DrawString(out, text, { x, y, width, 0 }, style, 1, 10); } -void DrawPlrMsg(const CelOutputBuffer &out) +void DrawPlrMsg(const Surface &out) { int i; DWORD x = 10; diff --git a/Source/plrmsg.h b/Source/plrmsg.h index b8963aab7..3b6d563d2 100644 --- a/Source/plrmsg.h +++ b/Source/plrmsg.h @@ -24,6 +24,6 @@ size_t EventPlrMsg(const char *pszFmt, ...); void SendPlrMsg(int pnum, const char *pszStr); void ClearPlrMsg(); void InitPlrMsg(); -void DrawPlrMsg(const CelOutputBuffer &out); +void DrawPlrMsg(const Surface &out); } // namespace devilution diff --git a/Source/qol/common.h b/Source/qol/common.h index a0a60aee1..c4a1d75ab 100644 --- a/Source/qol/common.h +++ b/Source/qol/common.h @@ -9,7 +9,7 @@ namespace devilution { -struct CelOutputBuffer; +struct Surface; /** * @brief Prints integer into buffer, using ',' as thousands separator. diff --git a/Source/qol/itemlabels.cpp b/Source/qol/itemlabels.cpp index 4b66fd807..17872bae9 100644 --- a/Source/qol/itemlabels.cpp +++ b/Source/qol/itemlabels.cpp @@ -103,14 +103,14 @@ bool IsMouseOverGameArea() return true; } -void FillRect(const CelOutputBuffer &out, int x, int y, int width, int height, Uint8 col) +void FillRect(const Surface &out, int x, int y, int width, int height, Uint8 col) { for (int j = 0; j < height; j++) { DrawHorizontalLine(out, { x, y + j }, width, col); } } -void DrawItemNameLabels(const CelOutputBuffer &out) +void DrawItemNameLabels(const Surface &out) { isLabelHighlighted = false; diff --git a/Source/qol/itemlabels.h b/Source/qol/itemlabels.h index 15425b76d..04b8821bd 100644 --- a/Source/qol/itemlabels.h +++ b/Source/qol/itemlabels.h @@ -14,6 +14,6 @@ void AltPressed(bool pressed); bool IsItemLabelHighlighted(); bool IsHighlightingLabelsEnabled(); void AddItemToLabelQueue(int id, int x, int y); -void DrawItemNameLabels(const CelOutputBuffer &out); +void DrawItemNameLabels(const Surface &out); } // namespace devilution diff --git a/Source/qol/monhealthbar.cpp b/Source/qol/monhealthbar.cpp index 7bd59603f..91e6eae59 100644 --- a/Source/qol/monhealthbar.cpp +++ b/Source/qol/monhealthbar.cpp @@ -45,7 +45,7 @@ void FreeMonsterHealthBar() resistance.Unload(); } -void DrawMonsterHealthBar(const CelOutputBuffer &out) +void DrawMonsterHealthBar(const Surface &out) { if (!sgOptions.Gameplay.bEnemyHealthBar) return; diff --git a/Source/qol/monhealthbar.h b/Source/qol/monhealthbar.h index 3ea0015db..f988c612c 100644 --- a/Source/qol/monhealthbar.h +++ b/Source/qol/monhealthbar.h @@ -7,11 +7,11 @@ namespace devilution { -struct CelOutputBuffer; +struct Surface; void InitMonsterHealthBar(); void FreeMonsterHealthBar(); -void DrawMonsterHealthBar(const CelOutputBuffer &out); +void DrawMonsterHealthBar(const Surface &out); } // namespace devilution diff --git a/Source/qol/xpbar.cpp b/Source/qol/xpbar.cpp index 18f00bc4a..eeccc78f5 100644 --- a/Source/qol/xpbar.cpp +++ b/Source/qol/xpbar.cpp @@ -31,14 +31,14 @@ constexpr int BackHeight = 9; Art xpbarArt; -void DrawBar(const CelOutputBuffer &out, int x, int y, int width, const ColorGradient &gradient) +void DrawBar(const Surface &out, int x, int y, int width, const ColorGradient &gradient) { UnsafeDrawHorizontalLine(out, { x, y + 1 }, width, gradient[gradient.size() * 3 / 4 - 1]); UnsafeDrawHorizontalLine(out, { x, y + 2 }, width, gradient[gradient.size() - 1]); UnsafeDrawHorizontalLine(out, { x, y + 3 }, width, gradient[gradient.size() / 2 - 1]); } -void DrawEndCap(const CelOutputBuffer &out, Point point, int idx, const ColorGradient &gradient) +void DrawEndCap(const Surface &out, Point point, int idx, const ColorGradient &gradient) { out.SetPixel({ point.x, point.y + 1 }, gradient[idx * 3 / 4]); out.SetPixel({ point.x, point.y + 2 }, gradient[idx]); @@ -65,7 +65,7 @@ void FreeXPBar() xpbarArt.Unload(); } -void DrawXPBar(const CelOutputBuffer &out) +void DrawXPBar(const Surface &out) { if (!sgOptions.Gameplay.bExperienceBar) return; diff --git a/Source/qol/xpbar.h b/Source/qol/xpbar.h index 47c1309ae..2502f6297 100644 --- a/Source/qol/xpbar.h +++ b/Source/qol/xpbar.h @@ -7,12 +7,12 @@ namespace devilution { -struct CelOutputBuffer; +struct Surface; void InitXPBar(); void FreeXPBar(); -void DrawXPBar(const CelOutputBuffer &out); +void DrawXPBar(const Surface &out); bool CheckXPBarInfo(); } // namespace devilution diff --git a/Source/quests.cpp b/Source/quests.cpp index 0d67bf990..ac9ed4c66 100644 --- a/Source/quests.cpp +++ b/Source/quests.cpp @@ -701,7 +701,7 @@ void ResyncQuests() } } -static void PrintQLString(const CelOutputBuffer &out, int x, int line, const char *str) +static void PrintQLString(const Surface &out, int x, int line, const char *str) { int width = GetLineWidth(str); int sx = x + std::max((257 - width) / 2, 0); @@ -715,7 +715,7 @@ static void PrintQLString(const CelOutputBuffer &out, int x, int line, const cha } } -void DrawQuestLog(const CelOutputBuffer &out) +void DrawQuestLog(const Surface &out) { DrawString(out, _("Quest Log"), { 32, 44, 257, 0 }, UIS_CENTER); CelDrawTo(out, { 0, 351 }, *pQLogCel, 1); diff --git a/Source/quests.h b/Source/quests.h index cf097905f..e2567d094 100644 --- a/Source/quests.h +++ b/Source/quests.h @@ -88,7 +88,7 @@ void LoadPWaterPalette(); void UpdatePWaterPalette(); void ResyncMPQuests(); void ResyncQuests(); -void DrawQuestLog(const CelOutputBuffer &out); +void DrawQuestLog(const Surface &out); void StartQuestlog(); void QuestlogUp(); void QuestlogDown(); diff --git a/Source/scrollrt.cpp b/Source/scrollrt.cpp index b60036e95..cbd19500f 100644 --- a/Source/scrollrt.cpp +++ b/Source/scrollrt.cpp @@ -176,7 +176,7 @@ static void BlitCursor(BYTE *dst, std::uint32_t dstPitch, BYTE *src, std::uint32 /** * @brief Remove the cursor from the buffer */ -static void UndrawCursor(const CelOutputBuffer &out) +static void UndrawCursor(const Surface &out) { if (sgdwCursWdt == 0) { return; @@ -199,7 +199,7 @@ static bool ShouldShowCursor() /** * @brief Save the content behind the cursor to a temporary buffer, then draw the cursor. */ -static void DrawCursor(const CelOutputBuffer &out) +static void DrawCursor(const Surface &out) { if (pcurs <= CURSOR_NONE || cursW == 0 || cursH == 0 || !ShouldShowCursor()) { return; @@ -240,7 +240,7 @@ static void DrawCursor(const CelOutputBuffer &out) * @param sy Output buffer coordinate * @param pre Is the sprite in the background */ -void DrawMissilePrivate(const CelOutputBuffer &out, MissileStruct *m, int sx, int sy, bool pre) +void DrawMissilePrivate(const Surface &out, MissileStruct *m, int sx, int sy, bool pre) { if (m->_miPreFlag != pre || !m->_miDrawFlag) return; @@ -276,7 +276,7 @@ void DrawMissilePrivate(const CelOutputBuffer &out, MissileStruct *m, int sx, in * @param sy Output buffer coordinate * @param pre Is the sprite in the background */ -void DrawMissile(const CelOutputBuffer &out, int x, int y, int sx, int sy, bool pre) +void DrawMissile(const Surface &out, int x, int y, int sx, int sy, bool pre) { int i; MissileStruct *m; @@ -308,7 +308,7 @@ void DrawMissile(const CelOutputBuffer &out, int x, int y, int sx, int sy, bool * @param my Output buffer coordinate * @param m Id of monster */ -static void DrawMonster(const CelOutputBuffer &out, int x, int y, int mx, int my, int m) +static void DrawMonster(const Surface &out, int x, int y, int mx, int my, int m) { if (m < 0 || m >= MAXMONSTERS) { Log("Draw Monster: tried to draw illegal monster {}", m); @@ -360,7 +360,7 @@ static void DrawMonster(const CelOutputBuffer &out, int x, int y, int mx, int my /** * @brief Helper for rendering a specific player icon (Mana Shield or Reflect) */ -static void DrawPlayerIconHelper(const CelOutputBuffer &out, int pnum, missile_graphic_id missileGraphicId, int x, int y, bool lighting) +static void DrawPlayerIconHelper(const Surface &out, int pnum, missile_graphic_id missileGraphicId, int x, int y, bool lighting) { x += CalculateWidth2(plr[pnum].AnimInfo.pCelSprite->Width()) - misfiledata[missileGraphicId].mAnimWidth2[0]; @@ -390,7 +390,7 @@ static void DrawPlayerIconHelper(const CelOutputBuffer &out, int pnum, missile_g * @param sy Output buffer coordinate * @param lighting Should lighting be applied */ -static void DrawPlayerIcons(const CelOutputBuffer &out, int pnum, int x, int y, bool lighting) +static void DrawPlayerIcons(const Surface &out, int pnum, int x, int y, bool lighting) { if (plr[pnum].pManaShield) DrawPlayerIconHelper(out, pnum, MFILE_MANASHLD, x, y, lighting); @@ -410,7 +410,7 @@ static void DrawPlayerIcons(const CelOutputBuffer &out, int pnum, int x, int y, * @param nCel frame * @param nWidth width */ -static void DrawPlayer(const CelOutputBuffer &out, int pnum, int x, int y, int px, int py) +static void DrawPlayer(const Surface &out, int pnum, int x, int y, int px, int py) { if ((dFlags[x][y] & BFLAG_LIT) == 0 && !plr[myplr]._pInfraFlag && leveltype != DTYPE_TOWN) { return; @@ -477,7 +477,7 @@ static void DrawPlayer(const CelOutputBuffer &out, int pnum, int x, int y, int p * @param sx Output buffer coordinate * @param sy Output buffer coordinate */ -void DrawDeadPlayer(const CelOutputBuffer &out, int x, int y, int sx, int sy) +void DrawDeadPlayer(const Surface &out, int x, int y, int sx, int sy) { dFlags[x][y] &= ~BFLAG_DEAD_PLAYER; @@ -501,7 +501,7 @@ void DrawDeadPlayer(const CelOutputBuffer &out, int x, int y, int sx, int sy) * @param oy Output buffer coordinate * @param pre Is the sprite in the background */ -static void DrawObject(const CelOutputBuffer &out, int x, int y, int ox, int oy, bool pre) +static void DrawObject(const Surface &out, int x, int y, int ox, int oy, bool pre) { if (dObject[x][y] == 0 || light_table_index >= lightmax) return; @@ -550,7 +550,7 @@ static void DrawObject(const CelOutputBuffer &out, int x, int y, int ox, int oy, } } -static void DrawDungeon(const CelOutputBuffer & /*out*/, int /*sx*/, int /*sy*/, int /*dx*/, int /*dy*/); +static void DrawDungeon(const Surface & /*out*/, int /*sx*/, int /*sy*/, int /*dx*/, int /*dy*/); /** * @brief Render a cell @@ -560,7 +560,7 @@ static void DrawDungeon(const CelOutputBuffer & /*out*/, int /*sx*/, int /*sy*/, * @param sx Target buffer coordinate * @param sy Target buffer coordinate */ -static void DrawCell(const CelOutputBuffer &out, int x, int y, int sx, int sy) +static void DrawCell(const Surface &out, int x, int y, int sx, int sy) { MICROS *pMap = &dpiece_defs_map_2[x][y]; level_piece_id = dPiece[x][y]; @@ -590,7 +590,7 @@ static void DrawCell(const CelOutputBuffer &out, int x, int y, int sx, int sy) * @param sx Target buffer coordinate * @param sy Target buffer coordinate */ -static void DrawFloor(const CelOutputBuffer &out, int x, int y, int sx, int sy) +static void DrawFloor(const Surface &out, int x, int y, int sx, int sy) { cel_transparency_active = false; light_table_index = dLight[x][y]; @@ -616,7 +616,7 @@ static void DrawFloor(const CelOutputBuffer &out, int x, int y, int sx, int sy) * @param sy Output buffer coordinate * @param pre Is the sprite in the background */ -static void DrawItem(const CelOutputBuffer &out, int x, int y, int sx, int sy, bool pre) +static void DrawItem(const Surface &out, int x, int y, int sx, int sy, bool pre) { int8_t bItem = dItem[x][y]; @@ -659,7 +659,7 @@ static void DrawItem(const CelOutputBuffer &out, int x, int y, int sx, int sy, b * @param sx Output buffer coordinate * @param sy Output buffer coordinate */ -static void DrawMonsterHelper(const CelOutputBuffer &out, int x, int y, int oy, int sx, int sy) +static void DrawMonsterHelper(const Surface &out, int x, int y, int oy, int sx, int sy) { int mi = dMonster[x][y + oy]; mi = mi > 0 ? mi - 1 : -(mi + 1); @@ -716,7 +716,7 @@ static void DrawMonsterHelper(const CelOutputBuffer &out, int x, int y, int oy, * @param sx Output buffer coordinate * @param sy Output buffer coordinate */ -static void DrawPlayerHelper(const CelOutputBuffer &out, int x, int y, int sx, int sy) +static void DrawPlayerHelper(const Surface &out, int x, int y, int sx, int sy) { int p = dPlayer[x][y]; p = p > 0 ? p - 1 : -(p + 1); @@ -745,7 +745,7 @@ static void DrawPlayerHelper(const CelOutputBuffer &out, int x, int y, int sx, i * @param dx Target buffer coordinate * @param dy Target buffer coordinate */ -static void DrawDungeon(const CelOutputBuffer &out, int sx, int sy, int dx, int dy) +static void DrawDungeon(const Surface &out, int sx, int sy, int dx, int dy) { assert((DWORD)sx < MAXDUNX); assert((DWORD)sy < MAXDUNY); @@ -858,7 +858,7 @@ static void DrawDungeon(const CelOutputBuffer &out, int sx, int sy, int dx, int * @param rows Number of rows * @param columns Tile in a row */ -static void DrawFloor(const CelOutputBuffer &out, int x, int y, int sx, int sy, int rows, int columns) +static void DrawFloor(const Surface &out, int x, int y, int sx, int sy, int rows, int columns) { for (int i = 0; i < rows; i++) { for (int j = 0; j < columns; j++) { @@ -907,7 +907,7 @@ static void DrawFloor(const CelOutputBuffer &out, int x, int y, int sx, int sy, * @param rows Number of rows * @param columns Tile in a row */ -static void DrawTileContent(const CelOutputBuffer &out, int x, int y, int sx, int sy, int rows, int columns) +static void DrawTileContent(const Surface &out, int x, int y, int sx, int sy, int rows, int columns) { // Keep evaluating until MicroTiles can't affect screen rows += MicroTileLen; @@ -955,7 +955,7 @@ static void DrawTileContent(const CelOutputBuffer &out, int x, int y, int sx, in /** * @brief Scale up the top left part of the buffer 2x. */ -static void Zoom(const CelOutputBuffer &out) +static void Zoom(const Surface &out) { int viewport_width = out.w(); int viewport_offset_x = 0; @@ -1153,10 +1153,10 @@ void CalcViewportGeometry() * @param x Center of view in dPiece coordinate * @param y Center of view in dPiece coordinate */ -static void DrawGame(const CelOutputBuffer &full_out, int x, int y) +static void DrawGame(const Surface &full_out, int x, int y) { // Limit rendering to the view area - const CelOutputBuffer &out = zoomflag + const Surface &out = zoomflag ? full_out.subregionY(0, gnViewportHeight) : full_out.subregionY(0, (gnViewportHeight + 1) / 2); @@ -1255,9 +1255,9 @@ static void DrawGame(const CelOutputBuffer &full_out, int x, int y) } // DevilutionX extension. -extern void DrawControllerModifierHints(const CelOutputBuffer &out); +extern void DrawControllerModifierHints(const Surface &out); -void DrawView(const CelOutputBuffer &out, int StartX, int StartY) +void DrawView(const Surface &out, int StartX, int StartY) { DrawGame(out, StartX, StartY); if (AutomapActive) { @@ -1428,7 +1428,7 @@ void EnableFrameCount() /** * @brief Display the current average FPS over 1 sec */ -static void DrawFPS(const CelOutputBuffer &out) +static void DrawFPS(const Surface &out) { char String[12]; @@ -1581,7 +1581,7 @@ void DrawAndBlit() force_redraw = 0; lock_buf(0); - const CelOutputBuffer &out = GlobalBackBuffer(); + const Surface &out = GlobalBackBuffer(); UndrawCursor(out); nthread_UpdateProgressToNextGameTick(); diff --git a/Source/scrollrt.h b/Source/scrollrt.h index 4e4ff9a1c..cec5a3225 100644 --- a/Source/scrollrt.h +++ b/Source/scrollrt.h @@ -58,7 +58,7 @@ void CalcViewportGeometry(); * @param StartX Center of view in dPiece coordinate * @param StartY Center of view in dPiece coordinate */ -void DrawView(const CelOutputBuffer &out, int StartX, int StartY); +void DrawView(const Surface &out, int StartX, int StartY); void ClearScreenBuffer(); #ifdef _DEBUG diff --git a/Source/stores.cpp b/Source/stores.cpp index 3629f856e..25eb6e651 100644 --- a/Source/stores.cpp +++ b/Source/stores.cpp @@ -75,13 +75,13 @@ const char *const TownerNames[] = { "Wirt" }; -void DrawSTextBack(const CelOutputBuffer &out) +void DrawSTextBack(const Surface &out) { CelDrawTo(out, { PANEL_X + 320 + 24, 327 + UI_OFFSET_Y }, *pSTextBoxCels, 1); DrawHalfTransparentRectTo(out, PANEL_X + 347, UI_OFFSET_Y + 28, 265, 297); } -void DrawSSlider(const CelOutputBuffer &out, int y1, int y2) +void DrawSSlider(const Surface &out, int y1, int y2) { int yd1 = y1 * 12 + 44 + UI_OFFSET_Y; int yd2 = y2 * 12 + 44 + UI_OFFSET_Y; @@ -2221,7 +2221,7 @@ void FreeStoreMem() pSTextSlidCels = std::nullopt; } -static void DrawSelector(const CelOutputBuffer &out, const Rectangle &rect, const char *text, uint16_t flags) +static void DrawSelector(const Surface &out, const Rectangle &rect, const char *text, uint16_t flags) { int lineWidth = GetLineWidth(text); @@ -2238,7 +2238,7 @@ static void DrawSelector(const CelOutputBuffer &out, const Rectangle &rect, cons CelDrawTo(out, { x2, rect.position.y + 1 }, *pSPentSpn2Cels, PentSpn2Spin()); } -void PrintSString(const CelOutputBuffer &out, int margin, int line, const char *text, uint16_t flags, int price) +void PrintSString(const Surface &out, int margin, int line, const char *text, uint16_t flags, int price) { int sx = PANEL_X + 32 + margin; if (!stextsize) { @@ -2266,7 +2266,7 @@ void PrintSString(const CelOutputBuffer &out, int margin, int line, const char * } } -void DrawSLine(const CelOutputBuffer &out, int y) +void DrawSLine(const Surface &out, int y) { int sx = 26; int sy = y * 12; @@ -2403,7 +2403,7 @@ void StartStore(talk_id s) stextflag = s; } -void DrawSText(const CelOutputBuffer &out) +void DrawSText(const Surface &out) { int i; diff --git a/Source/stores.h b/Source/stores.h index 3a0ce65ad..5981689f9 100644 --- a/Source/stores.h +++ b/Source/stores.h @@ -98,12 +98,12 @@ void AddStoreHoldRepair(ItemStruct *itm, int i); void InitStores(); void SetupTownStores(); void FreeStoreMem(); -void PrintSString(const CelOutputBuffer &out, int margin, int line, const char *text, uint16_t flags, int price = 0); -void DrawSLine(const CelOutputBuffer &out, int y); +void PrintSString(const Surface &out, int margin, int line, const char *text, uint16_t flags, int price = 0); +void DrawSLine(const Surface &out, int y); void DrawSTextHelp(); void ClearSText(int s, int e); void StartStore(talk_id s); -void DrawSText(const CelOutputBuffer &out); +void DrawSText(const Surface &out); void STextESC(); void STextUp(); void STextDown();