diff --git a/CMake/Assets.cmake b/CMake/Assets.cmake index 48f7578a4..e7fcb79f1 100644 --- a/CMake/Assets.cmake +++ b/CMake/Assets.cmake @@ -44,7 +44,7 @@ set(devilutionx_assets data/boxleftend.clx data/boxmiddle.clx data/boxrightend.clx - data/charbg.pcx + data/charbg.clx data/dirtybuc.clx data/dirtybucp.clx data/healthbox.clx @@ -54,11 +54,11 @@ set(devilutionx_assets data/hinticons.clx data/monstertags.clx data/panel8buc.clx - data/panel8bucp.pcx + data/panel8bucp.clx data/resistance.clx data/stash.clx data/stashnavbtns.clx - data/talkbutton.pcx + data/talkbutton.clx data/xpbar.clx fonts/12-00.bin fonts/12-00.clx diff --git a/Packaging/resources/assets/data/charbg.clx b/Packaging/resources/assets/data/charbg.clx new file mode 100644 index 000000000..a9452ba04 Binary files /dev/null and b/Packaging/resources/assets/data/charbg.clx differ diff --git a/Packaging/resources/assets/data/charbg.pcx b/Packaging/resources/assets/data/charbg.pcx deleted file mode 100644 index aa4be8eca..000000000 Binary files a/Packaging/resources/assets/data/charbg.pcx and /dev/null differ diff --git a/Packaging/resources/assets/data/panel8bucp.clx b/Packaging/resources/assets/data/panel8bucp.clx new file mode 100644 index 000000000..d091cd0b1 Binary files /dev/null and b/Packaging/resources/assets/data/panel8bucp.clx differ diff --git a/Packaging/resources/assets/data/panel8bucp.pcx b/Packaging/resources/assets/data/panel8bucp.pcx deleted file mode 100644 index dccff98d6..000000000 Binary files a/Packaging/resources/assets/data/panel8bucp.pcx and /dev/null differ diff --git a/Packaging/resources/assets/data/talkbutton.clx b/Packaging/resources/assets/data/talkbutton.clx new file mode 100644 index 000000000..79cce47f3 Binary files /dev/null and b/Packaging/resources/assets/data/talkbutton.clx differ diff --git a/Packaging/resources/assets/data/talkbutton.pcx b/Packaging/resources/assets/data/talkbutton.pcx deleted file mode 100644 index a611f69c6..000000000 Binary files a/Packaging/resources/assets/data/talkbutton.pcx and /dev/null differ diff --git a/Source/control.cpp b/Source/control.cpp index 12c2f6739..adf48b57a 100644 --- a/Source/control.cpp +++ b/Source/control.cpp @@ -12,8 +12,6 @@ #include -#include "DiabloUI/art.h" -#include "DiabloUI/art_draw.h" #include "automap.h" #include "controls/modifier_hints.h" #include "controls/plrctrls.h" @@ -638,7 +636,7 @@ void DrawCtrlBtns(const Surface &out) } else { Point position = mainPanelPosition + Displacement { PanBtnPos[i].x, PanBtnPos[i].y + 18 }; ClxDraw(out, position, (*pPanelButtons)[i]); - DrawArt(out, position + Displacement { 4, -18 }, &PanelButtonDown, i); + RenderClxSprite(out, (*PanelButtonDown)[i], position + Displacement { 4, -18 }); } } @@ -1163,14 +1161,14 @@ void DrawTalkPan(const Surface &out) if (WhisperList[i]) { if (TalkButtonsDown[talkBtn]) { ClxDraw(out, talkPanPosition, (*talkButtons)[talkBtn != 0 ? 3 : 2]); - DrawArt(out, talkPanPosition + Displacement { 4, -15 }, &TalkButton, 2); + RenderClxSprite(out, (*TalkButton)[2], talkPanPosition + Displacement { 4, -15 }); } } else { int nCel = talkBtn != 0 ? 1 : 0; if (TalkButtonsDown[talkBtn]) nCel += 4; ClxDraw(out, talkPanPosition, (*talkButtons)[nCel]); - DrawArt(out, talkPanPosition + Displacement { 4, -15 }, &TalkButton, TalkButtonsDown[talkBtn] ? 1 : 0); + RenderClxSprite(out, (*TalkButton)[TalkButtonsDown[talkBtn] ? 1 : 0], talkPanPosition + Displacement { 4, -15 }); } if (player.plractive) { DrawString(out, player._pName, { { x, y + 60 + talkBtn * 18 }, { 204, 0 } }, color); diff --git a/Source/panels/charpanel.cpp b/Source/panels/charpanel.cpp index c530d8cde..14e4b26ff 100644 --- a/Source/panels/charpanel.cpp +++ b/Source/panels/charpanel.cpp @@ -4,8 +4,6 @@ #include -#include "DiabloUI/art.h" -#include "DiabloUI/art_draw.h" #include "control.h" #include "engine/load_clx.hpp" #include "engine/render/clx_render.hpp" @@ -16,6 +14,7 @@ #include "utils/format_int.hpp" #include "utils/language.h" #include "utils/str_cat.hpp" +#include "utils/surface_to_clx.hpp" namespace devilution { @@ -200,24 +199,21 @@ PanelEntry panelEntries[] = { []() { return GetResistInfo(MyPlayer->_pLghtResist); } }, }; -OptionalOwnedClxSpriteList PanelBoxLeft; -OptionalOwnedClxSpriteList PanelBoxMiddle; -OptionalOwnedClxSpriteList PanelBoxRight; -Art PanelFull; +OptionalOwnedClxSpriteList Panel; constexpr int PanelFieldHeight = 24; constexpr int PanelFieldPaddingTop = 3; constexpr int PanelFieldPaddingBottom = 3; constexpr int PanelFieldInnerHeight = PanelFieldHeight - PanelFieldPaddingTop - PanelFieldPaddingBottom; -void DrawPanelField(const Surface &out, Point pos, int len) +void DrawPanelField(const Surface &out, Point pos, int len, ClxSprite left, ClxSprite middle, ClxSprite right) { - RenderClxSprite(out, (*PanelBoxLeft)[0], pos); - pos.x += (*PanelBoxLeft)[0].width(); - len -= (*PanelBoxLeft)[0].width() + (*PanelBoxRight)[0].width(); - RenderClxSprite(out.subregion(pos.x, pos.y, len, (*PanelBoxMiddle)[0].height()), (*PanelBoxMiddle)[0], Point { 0, 0 }); + RenderClxSprite(out, left, pos); + pos.x += left.width(); + len -= left.width() + right.width(); + RenderClxSprite(out.subregion(pos.x, pos.y, len, middle.height()), middle, Point { 0, 0 }); pos.x += len; - RenderClxSprite(out, (*PanelBoxRight)[0], pos); + RenderClxSprite(out, right, pos); } void DrawShadowString(const Surface &out, const PanelEntry &entry) @@ -269,42 +265,45 @@ void DrawStatButtons(const Surface &out) void LoadCharPanel() { - LoadArt("data\\charbg.pcx", &PanelFull); - UpdatePalette(&PanelFull); // PanelFull is being used as a render target - PanelBoxLeft = LoadClx("data\\boxleftend.clx"); - PanelBoxMiddle = LoadClx("data\\boxmiddle.clx"); - PanelBoxRight = LoadClx("data\\boxrightend.clx"); - - const Surface out(PanelFull.surface.get()); - - const bool isSmallFontTall = IsSmallFontTall(); - const int attributeHeadersY = isSmallFontTall ? 112 : 114; - for (unsigned i : AttributeHeaderEntryIndices) { - panelEntries[i].position.y = attributeHeadersY; - } - panelEntries[GoldHeaderEntryIndex].position.y = isSmallFontTall ? 105 : 106; + OptionalOwnedClxSpriteList background = LoadOptionalClx("data\\charbg.clx"); + if (!background) + app_fatal(_("Please update devilutionx.mpq to the latest version")); + OwnedSurface out((*background)[0].width(), (*background)[0].height()); + RenderClxSprite(out, (*background)[0], { 0, 0 }); + background = std::nullopt; + + { + OwnedClxSpriteList boxLeft = LoadClx("data\\boxleftend.clx"); + OwnedClxSpriteList boxMiddle = LoadClx("data\\boxmiddle.clx"); + OwnedClxSpriteList boxRight = LoadClx("data\\boxrightend.clx"); + + const bool isSmallFontTall = IsSmallFontTall(); + const int attributeHeadersY = isSmallFontTall ? 112 : 114; + for (unsigned i : AttributeHeaderEntryIndices) { + panelEntries[i].position.y = attributeHeadersY; + } + panelEntries[GoldHeaderEntryIndex].position.y = isSmallFontTall ? 105 : 106; - for (auto &entry : panelEntries) { - if (entry.statDisplayFunc != nullptr) { - DrawPanelField(out, entry.position, entry.length); + for (auto &entry : panelEntries) { + if (entry.statDisplayFunc != nullptr) { + DrawPanelField(out, entry.position, entry.length, boxLeft[0], boxMiddle[0], boxRight[0]); + } + DrawShadowString(out, entry); } - DrawShadowString(out, entry); } - PanelBoxRight = std::nullopt; - PanelBoxMiddle = std::nullopt; - PanelBoxLeft = std::nullopt; + Panel = SurfaceToClx(out); } void FreeCharPanel() { - PanelFull.Unload(); + Panel = std::nullopt; } void DrawChr(const Surface &out) { Point pos = GetPanelPosition(UiPanels::Character, { 0, 0 }); - DrawArt(out, pos, &PanelFull); + RenderClxSprite(out, (*Panel)[0], pos); for (auto &entry : panelEntries) { if (entry.statDisplayFunc != nullptr) { StyledText tmp = entry.statDisplayFunc(); diff --git a/Source/panels/mainpanel.cpp b/Source/panels/mainpanel.cpp index 520ed6259..f954f15b2 100644 --- a/Source/panels/mainpanel.cpp +++ b/Source/panels/mainpanel.cpp @@ -9,11 +9,13 @@ #include "utils/language.h" #include "utils/sdl_compat.h" #include "utils/sdl_geometry.h" +#include "utils/stdcompat/optional.hpp" +#include "utils/surface_to_clx.hpp" namespace devilution { -Art PanelButtonDown; -Art TalkButton; +OptionalOwnedClxSpriteList PanelButtonDown; +OptionalOwnedClxSpriteList TalkButton; namespace { @@ -40,14 +42,13 @@ void DrawButtonOnPanel(Point position, string_view text, int frame) DrawButtonText(*pBtmBuff, text, { position, { (*PanelButton)[0].width(), 0 } }, UiFlags::ColorButtonface, spacing); } -void RenderMainButton(int buttonId, string_view text, int frame) +void RenderMainButton(const Surface &out, int buttonId, string_view text, int frame) { Point panelPosition { PanBtnPos[buttonId].x + 4, PanBtnPos[buttonId].y + 17 }; DrawButtonOnPanel(panelPosition, text, frame); if (IsChatAvailable()) DrawButtonOnPanel(panelPosition + Displacement { 0, GetMainPanel().size.height + 16 }, text, frame); - const Surface out(PanelButtonDown.surface.get()); Point position { 0, 19 * buttonId }; int spacing = 2; int width = std::min(GetLineWidth(text, GameFont12, spacing), (*PanelButton)[0].width()); @@ -56,58 +57,66 @@ void RenderMainButton(int buttonId, string_view text, int frame) width = std::min(GetLineWidth(text, GameFont12, spacing), (*PanelButton)[0].width()); } RenderClxSprite(out.subregion(position.x + ((*PanelButton)[0].width() - width) / 2, position.y + 9, width, out.h() - position.y - 9), (*PanelButtonDownGrime)[frame], { 0, 0 }); - DrawButtonText(out, text, { position + Displacement { 0, 2 }, { PanelButtonDown.w(), 0 } }, UiFlags::ColorButtonpushed, spacing); -} - -void DrawTalkButton(int buttonId) -{ - string_view text = _("voice"); - Point position { 176, GetMainPanel().size.height + 101 + 18 * buttonId }; - DrawArt(*pBtmBuff, position, &TalkButton); - int width = std::min(GetLineWidth(text, GameFont12, 1), (*PanelButton)[0].width()); - RenderClxSprite(pBtmBuff->subregion(position.x + (TalkButton.w() - width) / 2, position.y + 6, width, 9), (*PanelButtonGrime)[1], { 0, 0 }); - DrawButtonText(*pBtmBuff, text, { position, { TalkButton.w(), 0 } }, UiFlags::ColorButtonface); + DrawButtonText(out, text, { position + Displacement { 0, 2 }, { out.w(), 0 } }, UiFlags::ColorButtonpushed, spacing); } } // namespace void LoadMainPanel() { - LoadArt("data\\panel8bucp.pcx", &PanelButtonDown, 6); - PanelButton = LoadClx("data\\panel8buc.clx"); - PanelButtonGrime = LoadClx("data\\dirtybuc.clx"); - PanelButtonDownGrime = LoadClx("data\\dirtybucp.clx"); - - // Load palette to render targets - UpdatePalette(&PanelButtonDown); - if (SDLC_SetSurfaceColors(pBtmBuff->surface, PalSurface->format->palette) <= -1) - ErrSdl(); - - RenderMainButton(0, _("char"), 0); - RenderMainButton(1, _("quests"), 1); - RenderMainButton(2, _("map"), 1); - RenderMainButton(3, _("menu"), 0); - RenderMainButton(4, _("inv"), 1); - RenderMainButton(5, _("spells"), 0); + std::optional out; + constexpr uint16_t NumButtonSprites = 6; + { + OptionalOwnedClxSpriteList background = LoadOptionalClx("data\\panel8bucp.clx"); + if (!background) + app_fatal(_("Please update devilutionx.mpq to the latest version")); + out.emplace((*background)[0].width(), (*background)[0].height() * NumButtonSprites); + RenderClxSprite(*out, (*background)[0], { 0, 0 }); + } - if (IsChatAvailable()) { - LoadArt("data\\talkbutton.pcx", &TalkButton, 3); - UpdatePalette(&TalkButton); + PanelButton = LoadOptionalClx("data\\panel8buc.clx"); + PanelButtonGrime = LoadOptionalClx("data\\dirtybuc.clx"); + PanelButtonDownGrime = LoadOptionalClx("data\\dirtybucp.clx"); + + RenderMainButton(*out, 0, _("char"), 0); + RenderMainButton(*out, 1, _("quests"), 1); + RenderMainButton(*out, 2, _("map"), 1); + RenderMainButton(*out, 3, _("menu"), 0); + RenderMainButton(*out, 4, _("inv"), 1); + RenderMainButton(*out, 5, _("spells"), 0); + PanelButtonDown = SurfaceToClx(*out, NumButtonSprites); + out = std::nullopt; - // Must be done before adding the text to TalkButton - DrawTalkButton(0); - DrawTalkButton(1); - DrawTalkButton(2); + if (IsChatAvailable()) { + OptionalOwnedClxSpriteList talkButton = LoadClx("data\\talkbutton.clx"); + const int talkButtonWidth = (*talkButton)[0].width(); + const int talkButtonHeight = (*talkButton)[0].height(); + constexpr uint16_t NumTalkButtonSprites = 3; + + // Render the empty button to pBtmBuff. + string_view text = _("voice"); + const int textWidth = GetLineWidth(text, GameFont12, 1); + for (size_t i = 0; i < 3; ++i) { + Point position { 176, static_cast(GetMainPanel().size.height + 101 + 18 * i) }; + RenderClxSprite(*pBtmBuff, (*talkButton)[0], position); + int width = std::min(textWidth, (*PanelButton)[0].width()); + RenderClxSprite(pBtmBuff->subregion(position.x + (talkButtonWidth - width) / 2, position.y + 6, width, 9), (*PanelButtonGrime)[1], { 0, 0 }); + DrawButtonText(*pBtmBuff, text, { position, { talkButtonWidth, 0 } }, UiFlags::ColorButtonface); + } + + OwnedSurface talkSurface(talkButtonWidth, talkButtonHeight * NumTalkButtonSprites); + RenderClxSprite(talkSurface, (*talkButton)[0], { 0, 0 }); + talkButton = std::nullopt; - const Surface talkSurface(TalkButton.surface.get()); int muteWidth = GetLineWidth(_("mute"), GameFont12, 2); - RenderClxSprite(talkSurface.subregion((TalkButton.w() - muteWidth) / 2, 6, muteWidth, 9), (*PanelButtonGrime)[1], { 0, 0 }); - DrawButtonText(talkSurface, _("mute"), { { 0, 0 }, { TalkButton.w(), 0 } }, UiFlags::ColorButtonface); - RenderClxSprite(talkSurface.subregion((TalkButton.w() - muteWidth) / 2, 23, muteWidth, 9), (*PanelButtonGrime)[1], { 0, 0 }); - DrawButtonText(talkSurface, _("mute"), { { 0, 17 }, { TalkButton.w(), 0 } }, UiFlags::ColorButtonpushed); + RenderClxSprite(talkSurface.subregion((talkButtonWidth - muteWidth) / 2, 6, muteWidth, 9), (*PanelButtonGrime)[1], { 0, 0 }); + DrawButtonText(talkSurface, _("mute"), { { 0, 0 }, { talkButtonWidth, 0 } }, UiFlags::ColorButtonface); + RenderClxSprite(talkSurface.subregion((talkButtonWidth - muteWidth) / 2, 23, muteWidth, 9), (*PanelButtonGrime)[1], { 0, 0 }); + DrawButtonText(talkSurface, _("mute"), { { 0, 17 }, { talkButtonWidth, 0 } }, UiFlags::ColorButtonpushed); int voiceWidth = GetLineWidth(_("voice"), GameFont12, 2); - RenderClxSprite(talkSurface.subregion((TalkButton.w() - voiceWidth) / 2, 39, voiceWidth, 9), (*PanelButtonGrime)[1], { 0, 0 }); - DrawButtonText(talkSurface, _("voice"), { { 0, 33 }, { TalkButton.w(), 0 } }, UiFlags::ColorButtonpushed); + RenderClxSprite(talkSurface.subregion((talkButtonWidth - voiceWidth) / 2, 39, voiceWidth, 9), (*PanelButtonGrime)[1], { 0, 0 }); + DrawButtonText(talkSurface, _("voice"), { { 0, 33 }, { talkButtonWidth, 0 } }, UiFlags::ColorButtonpushed); + TalkButton = SurfaceToClx(talkSurface, NumTalkButtonSprites); } UnloadFonts(GameFont12, ColorButtonface); @@ -120,8 +129,8 @@ void LoadMainPanel() void FreeMainPanel() { - PanelButtonDown.Unload(); - TalkButton.Unload(); + TalkButton = std::nullopt; + PanelButtonDown = std::nullopt; } } // namespace devilution diff --git a/Source/panels/mainpanel.hpp b/Source/panels/mainpanel.hpp index 1877f2e69..893ebeff3 100644 --- a/Source/panels/mainpanel.hpp +++ b/Source/panels/mainpanel.hpp @@ -1,14 +1,12 @@ -#pragma once - -#include "DiabloUI/art.h" -#include "DiabloUI/art_draw.h" - -namespace devilution { - -extern Art PanelButtonDown; -extern Art TalkButton; - -void LoadMainPanel(); -void FreeMainPanel(); - -} // namespace devilution +#pragma once + +#include "engine/clx_sprite.hpp" +namespace devilution { + +extern OptionalOwnedClxSpriteList PanelButtonDown; +extern OptionalOwnedClxSpriteList TalkButton; + +void LoadMainPanel(); +void FreeMainPanel(); + +} // namespace devilution