diff --git a/Source/controls/modifier_hints.cpp b/Source/controls/modifier_hints.cpp index 7ee509dda..b1cec39a1 100644 --- a/Source/controls/modifier_hints.cpp +++ b/Source/controls/modifier_hints.cpp @@ -12,13 +12,12 @@ #include "engine/render/clx_render.hpp" #include "engine/render/text_render.hpp" #include "options.h" +#include "panels/spell_book.hpp" #include "panels/spell_icons.hpp" #include "utils/language.h" namespace devilution { -extern OptionalOwnedClxSpriteList pSBkIconCels; - namespace { /** Vertical distance between text lines. */ @@ -140,7 +139,11 @@ void DrawSpellsCircleMenuHint(const Surface &out, const Point &origin) } SetSpellTrans(splType); - DrawSpellCel(out, spellIconPositions[slot], *pSBkIconCels, SpellITbl[splId]); +#ifdef UNPACKED_MPQS + DrawSpellCel(out, spellIconPositions[slot], (*pSBkIconsForeground)[SpellITbl[splId]], (*pSBkIconsBackground)[0]); +#else + DrawSpellCel(out, spellIconPositions[slot], (*pSBkIconCels)[SpellITbl[splId]]); +#endif RenderClxSprite(out, (*hintBox)[0], hintBoxPositions[slot]); } } diff --git a/Source/panels/spell_book.cpp b/Source/panels/spell_book.cpp index 99fcdabea..5afd309ca 100644 --- a/Source/panels/spell_book.cpp +++ b/Source/panels/spell_book.cpp @@ -6,6 +6,7 @@ #include "engine/backbuffer_state.hpp" #include "engine/clx_sprite.hpp" #include "engine/load_cel.hpp" +#include "engine/load_clx.hpp" #include "engine/rectangle.hpp" #include "engine/render/clx_render.hpp" #include "engine/render/text_render.hpp" @@ -18,11 +19,14 @@ #include "utils/language.h" #include "utils/stdcompat/optional.hpp" -#define SPLICONLAST (gbIsHellfire ? 51 : 42) - namespace devilution { +#ifdef UNPACKED_MPQS +OptionalOwnedClxSpriteList pSBkIconsBackground; +OptionalOwnedClxSpriteList pSBkIconsForeground; +#else OptionalOwnedClxSpriteList pSBkIconCels; +#endif namespace { @@ -84,7 +88,12 @@ void InitSpellBook() { pSpellBkCel = LoadCel("data\\spellbk", static_cast(SidePanelSize.width)); pSBkBtnCel = LoadCel("data\\spellbkb", gbIsHellfire ? 61 : 76); +#ifdef UNPACKED_MPQS + pSBkIconsBackground = LoadClx("data\\spelli2_bg.clx"); + pSBkIconsForeground = LoadClx("data\\spelli2_fg.clx"); +#else pSBkIconCels = LoadCel("data\\spelli2", 37); +#endif Player &player = *MyPlayer; if (player._pClass == HeroClass::Warrior) { @@ -104,9 +113,14 @@ void InitSpellBook() void FreeSpellBook() { - pSpellBkCel = std::nullopt; - pSBkBtnCel = std::nullopt; +#ifdef UNPACKED_MPQS + pSBkIconsForeground = std::nullopt; + pSBkIconsBackground = std::nullopt; +#else pSBkIconCels = std::nullopt; +#endif + pSBkBtnCel = std::nullopt; + pSpellBkCel = std::nullopt; } void DrawSpellBook(const Surface &out) @@ -135,10 +149,18 @@ void DrawSpellBook(const Surface &out) spell_type st = GetSBookTrans(sn, true); SetSpellTrans(st); const Point spellCellPosition = GetPanelPosition(UiPanels::Spell, { 11, yp + SpellBookDescription.height }); - DrawSpellCel(out, spellCellPosition, *pSBkIconCels, SpellITbl[sn]); +#ifdef UNPACKED_MPQS + DrawSpellCel(out, spellCellPosition, (*pSBkIconsForeground)[SpellITbl[sn]], (*pSBkIconsBackground)[0]); +#else + DrawSpellCel(out, spellCellPosition, (*pSBkIconCels)[SpellITbl[sn]]); +#endif if (sn == player._pRSpell && st == player._pRSplType) { SetSpellTrans(RSPLTYPE_SKILL); - DrawSpellCel(out, spellCellPosition, *pSBkIconCels, SPLICONLAST); +#ifdef UNPACKED_MPQS + DrawSpellBorder(out, spellCellPosition, (*pSBkIconsForeground)[SpellITbl[sn]]); +#else + DrawSpellBorder(out, spellCellPosition, (*pSBkIconCels)[SpellITbl[sn]]); +#endif } const Point line0 { 0, yp + textPaddingTop }; diff --git a/Source/panels/spell_book.hpp b/Source/panels/spell_book.hpp index 2a9aeaa39..119cfa4f7 100644 --- a/Source/panels/spell_book.hpp +++ b/Source/panels/spell_book.hpp @@ -1,9 +1,17 @@ #pragma once +#include "engine/clx_sprite.hpp" #include "engine/surface.hpp" namespace devilution { +#ifdef UNPACKED_MPQS +extern OptionalOwnedClxSpriteList pSBkIconsBackground; +extern OptionalOwnedClxSpriteList pSBkIconsForeground; +#else +extern OptionalOwnedClxSpriteList pSBkIconCels; +#endif + void InitSpellBook(); void FreeSpellBook(); void CheckSBook(); diff --git a/Source/panels/spell_icons.cpp b/Source/panels/spell_icons.cpp index 93bf92308..63bf494be 100644 --- a/Source/panels/spell_icons.cpp +++ b/Source/panels/spell_icons.cpp @@ -1,6 +1,7 @@ #include "panels/spell_icons.hpp" #include "engine/load_cel.hpp" +#include "engine/load_clx.hpp" #include "engine/palette.h" #include "engine/render/clx_render.hpp" #include "init.h" @@ -9,7 +10,13 @@ namespace devilution { namespace { +#ifdef UNPACKED_MPQS +OptionalOwnedClxSpriteList pSpellIconsBackground; +OptionalOwnedClxSpriteList pSpellIconsForeground; +#else OptionalOwnedClxSpriteList pSpellCels; +#endif + uint8_t SplTransTbl[256]; } // namespace @@ -70,26 +77,74 @@ const char SpellITbl[] = { void LoadSpellIcons() { - if (!gbIsHellfire) + if (!gbIsHellfire) { +#ifdef UNPACKED_MPQS + pSpellIconsForeground = LoadClx("ctrlpan\\spelicon_fg.clx"); + pSpellIconsBackground = LoadClx("ctrlpan\\spelicon_bg.clx"); +#else pSpellCels = LoadCel("ctrlpan\\spelicon", SPLICONLENGTH); - else +#endif + } else { +#ifdef UNPACKED_MPQS + pSpellIconsForeground = LoadClx("data\\spelicon_fg.clx"); + pSpellIconsBackground = LoadClx("data\\spelicon_bg.clx"); +#else pSpellCels = LoadCel("data\\spelicon", SPLICONLENGTH); +#endif + } SetSpellTrans(RSPLTYPE_SKILL); } void FreeSpellIcons() { +#ifdef UNPACKED_MPQS + pSpellIconsBackground = std::nullopt; + pSpellIconsForeground = std::nullopt; +#else pSpellCels = std::nullopt; +#endif } void DrawSpellCel(const Surface &out, Point position, int nCel) { - DrawSpellCel(out, position, *pSpellCels, nCel); +#ifdef UNPACKED_MPQS + DrawSpellCel(out, position, (*pSpellIconsForeground)[nCel], (*pSpellIconsBackground)[0]); +#else + DrawSpellCel(out, position, (*pSpellCels)[nCel]); +#endif +} + +#ifdef UNPACKED_MPQS +void DrawSpellCel(const Surface &out, Point position, ClxSprite sprite, ClxSprite background) +{ + ClxDrawTRN(out, position, background, SplTransTbl); + ClxDrawTRN(out, position, sprite, SplTransTbl); +} +#else +void DrawSpellCel(const Surface &out, Point position, ClxSprite sprite) +{ + ClxDrawTRN(out, position, sprite, SplTransTbl); } +#endif -void DrawSpellCel(const Surface &out, Point position, const OwnedClxSpriteList &sprite, int nCel) +void DrawSpellBorder(const Surface &out, Point position, ClxSprite sprite) { - ClxDrawTRN(out, position, sprite[nCel], SplTransTbl); + const uint8_t color = SplTransTbl[PAL8_YELLOW + 2]; + const size_t width = sprite.width(); + const size_t height = sprite.height(); + position.y -= static_cast(height); + uint8_t *buf = &out[position]; + std::memset(buf, color, width); + buf += out.pitch(); + std::memset(buf, color, width); + for (size_t i = 4; i < sprite.height(); ++i) { + buf[0] = buf[1] = color; + buf[width - 2] = buf[width - 1] = color; + buf += out.pitch(); + } + std::memset(buf, color, width); + buf += out.pitch(); + std::memset(buf, color, width); } void SetSpellTrans(spell_type t) diff --git a/Source/panels/spell_icons.hpp b/Source/panels/spell_icons.hpp index 871ea57b5..9f6f1d73b 100644 --- a/Source/panels/spell_icons.hpp +++ b/Source/panels/spell_icons.hpp @@ -25,9 +25,14 @@ void DrawSpellCel(const Surface &out, Point position, int nCel); * @param out Output buffer. * @param position Buffer coordinates. * @param sprite Icons sprite sheet. - * @param nCel Index of the cel frame to draw. 0 based. */ -void DrawSpellCel(const Surface &out, Point position, const OwnedClxSpriteList &sprite, int nCel); +#ifdef UNPACKED_MPQS +void DrawSpellCel(const Surface &out, Point position, ClxSprite sprite, ClxSprite background); +#else +void DrawSpellCel(const Surface &out, Point position, ClxSprite sprite); +#endif + +void DrawSpellBorder(const Surface &out, Point position, ClxSprite sprite); void SetSpellTrans(spell_type t);