diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index 0465a0ffb..959a0f63e 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -129,6 +129,7 @@ set(libdevilutionx_SRCS DiabloUI/support_lines.cpp DiabloUI/title.cpp panels/charpanel.cpp + panels/info_box.cpp panels/mainpanel.cpp panels/spell_book.cpp panels/spell_icons.cpp diff --git a/Source/diablo.cpp b/Source/diablo.cpp index 4ca17f75b..4c7a5ab8c 100644 --- a/Source/diablo.cpp +++ b/Source/diablo.cpp @@ -52,6 +52,7 @@ #include "nthread.h" #include "objects.h" #include "options.h" +#include "panels/info_box.hpp" #include "panels/spell_book.hpp" #include "panels/spell_list.hpp" #include "pfile.h" @@ -172,6 +173,7 @@ void FreeGame() FreeInvGFX(); FreeGMenu(); FreeQuestText(); + FreeInfoBoxGfx(); FreeStoreMem(); for (auto &player : Players) @@ -982,6 +984,9 @@ void DiabloInit() // Item graphics are loaded early, they already get touched during hero selection. InitItemGFX(); + + // Always available. + LoadSmallSelectionSpinner(); } void DiabloSplash() @@ -1985,15 +1990,17 @@ void LoadGameLevel(bool firstflag, lvl_entry lvldir) if (firstflag) { InitInv(); InitQuestText(); - InitStores(); + InitInfoBoxGfx(); InitAutomapOnce(); InitHelp(); } - SetRndSeed(glSeedTbl[currlevel]); - if (leveltype == DTYPE_TOWN) + if (leveltype == DTYPE_TOWN) { SetupTownStores(); + } else { + FreeStoreMem(); + } IncProgress(); InitAutomap(); diff --git a/Source/engine/render/text_render.cpp b/Source/engine/render/text_render.cpp index 0b5adaf7c..bd02f39db 100644 --- a/Source/engine/render/text_render.cpp +++ b/Source/engine/render/text_render.cpp @@ -25,6 +25,8 @@ namespace devilution { +std::optional pSPentSpn2Cels; + namespace { constexpr char32_t ZWSP = U'\u200B'; // Zero-width space @@ -372,6 +374,11 @@ int DoDrawString(const Surface &out, string_view text, Rectangle rect, Point &ch } // namespace +void LoadSmallSelectionSpinner() +{ + pSPentSpn2Cels = LoadCel("Data\\PentSpn2.CEL", 12); +} + void UnloadFonts(GameFontTables size, text_color color) { uint32_t fontStyle = (color << 24) | (size << 16); diff --git a/Source/engine/render/text_render.hpp b/Source/engine/render/text_render.hpp index 920605fe2..179fba077 100644 --- a/Source/engine/render/text_render.hpp +++ b/Source/engine/render/text_render.hpp @@ -118,8 +118,15 @@ private: std::string formatted_; }; +/** + * @brief Small text selection cursor. + * + * Also used in the stores and the quest log. + */ extern std::optional pSPentSpn2Cels; +void LoadSmallSelectionSpinner(); + void UnloadFonts(GameFontTables size, text_color color); /** diff --git a/Source/error.cpp b/Source/error.cpp index 00149e577..b66cc3658 100644 --- a/Source/error.cpp +++ b/Source/error.cpp @@ -12,6 +12,7 @@ #include "control.h" #include "engine/render/cel_render.hpp" #include "engine/render/text_render.hpp" +#include "panels/info_box.hpp" #include "stores.h" #include "utils/language.h" @@ -113,11 +114,10 @@ const char *const MsgStrings[] = { void InitDiabloMsg(diablo_message e) { - std::string msg = _(MsgStrings[e]); - InitDiabloMsg(msg); + InitDiabloMsg(LanguageTranslate(MsgStrings[e])); } -void InitDiabloMsg(std::string msg) +void InitDiabloMsg(const std::string &msg) { if (DiabloMessages.size() >= MAX_SEND_STR_LEN) return; diff --git a/Source/error.h b/Source/error.h index dac1a69ca..a0a5259ad 100644 --- a/Source/error.h +++ b/Source/error.h @@ -71,7 +71,7 @@ enum diablo_message : uint8_t { }; void InitDiabloMsg(diablo_message e); -void InitDiabloMsg(std::string msg); +void InitDiabloMsg(const std::string &msg); bool IsDiabloMsgAvailable(); void CancelCurrentDiabloMsg(); void ClrDiabloMsg(); diff --git a/Source/items.cpp b/Source/items.cpp index 0a75d8409..3a3bcf3a4 100644 --- a/Source/items.cpp +++ b/Source/items.cpp @@ -29,8 +29,10 @@ #include "lighting.h" #include "missiles.h" #include "options.h" +#include "panels/info_box.hpp" #include "panels/ui_panels.hpp" #include "player.h" +#include "spells.h" #include "stores.h" #include "town.h" #include "utils/language.h" diff --git a/Source/panels/info_box.cpp b/Source/panels/info_box.cpp new file mode 100644 index 000000000..6abfee2d2 --- /dev/null +++ b/Source/panels/info_box.cpp @@ -0,0 +1,22 @@ +#include "panels/info_box.hpp" + +#include "engine/load_cel.hpp" + +namespace devilution { + +std::optional pSTextBoxCels; +std::optional pSTextSlidCels; + +void InitInfoBoxGfx() +{ + pSTextSlidCels = LoadCel("Data\\TextSlid.CEL", 12); + pSTextBoxCels = LoadCel("Data\\TextBox2.CEL", 271); +} + +void FreeInfoBoxGfx() +{ + pSTextBoxCels = std::nullopt; + pSTextSlidCels = std::nullopt; +} + +} // namespace devilution diff --git a/Source/panels/info_box.hpp b/Source/panels/info_box.hpp new file mode 100644 index 000000000..8b541601e --- /dev/null +++ b/Source/panels/info_box.hpp @@ -0,0 +1,25 @@ +#pragma once + +#include "engine/cel_sprite.hpp" +#include "utils/stdcompat/optional.hpp" + +namespace devilution { + +/** + * @brief Info box frame + * + * Used in stores, the quest log, the help window, and the unique item info window. + */ +extern std::optional pSTextBoxCels; + +/** + * @brief Info box scrollbar graphics. + * + * Used in stores and `DrawDiabloMsg`. + */ +extern std::optional pSTextSlidCels; + +void InitInfoBoxGfx(); +void FreeInfoBoxGfx(); + +} // namespace devilution diff --git a/Source/quests.h b/Source/quests.h index 477779528..d198b7d94 100644 --- a/Source/quests.h +++ b/Source/quests.h @@ -13,6 +13,7 @@ #include "gendung.h" #include "monster.h" #include "objdat.h" +#include "panels/info_box.hpp" #include "textdat.h" #include "utils/attributes.h" #include "utils/stdcompat/optional.hpp" diff --git a/Source/stores.cpp b/Source/stores.cpp index ac93481ca..961a6a34e 100644 --- a/Source/stores.cpp +++ b/Source/stores.cpp @@ -17,6 +17,7 @@ #include "init.h" #include "minitext.h" #include "options.h" +#include "panels/info_box.hpp" #include "towners.h" #include "utils/language.h" @@ -24,10 +25,6 @@ namespace devilution { Item golditem; -std::optional pSPentSpn2Cels; -std::optional pSTextBoxCels; -std::optional pSTextSlidCels; - talk_id stextflag; int storenumh; @@ -2282,11 +2279,8 @@ void AddStoreHoldRepair(Item *itm, int8_t i) storenumh++; } -void InitStores() +void SetupTownStores() { - pSPentSpn2Cels = LoadCel("Data\\PentSpn2.CEL", 12); - pSTextBoxCels = LoadCel("Data\\TextBox2.CEL", 271); - pSTextSlidCels = LoadCel("Data\\TextSlid.CEL", 12); ClearSText(0, STORE_LINES); stextflag = STORE_NONE; stextsize = false; @@ -2299,10 +2293,7 @@ void InitStores() boyitem._itype = ItemType::None; boylevel = 0; -} -void SetupTownStores() -{ auto &myPlayer = Players[MyPlayerId]; int l = myPlayer._pLevel / 2; @@ -2325,8 +2316,7 @@ void SetupTownStores() void FreeStoreMem() { - pSTextBoxCels = std::nullopt; - pSTextSlidCels = std::nullopt; + stextflag = STORE_NONE; } void PrintSString(const Surface &out, int margin, int line, const char *text, UiFlags flags, int price) diff --git a/Source/stores.h b/Source/stores.h index 3612388cb..ddfd3e9f2 100644 --- a/Source/stores.h +++ b/Source/stores.h @@ -67,13 +67,6 @@ struct STextStruct { } }; -/** Shop frame graphics */ -extern std::optional pSTextBoxCels; -/** Small text selection cursor */ -extern std::optional pSPentSpn2Cels; -/** Scrollbar graphics */ -extern std::optional pSTextSlidCels; - /** Currently active store */ extern talk_id stextflag; @@ -108,7 +101,6 @@ extern int boylevel; extern Item boyitem; void AddStoreHoldRepair(Item *itm, int8_t i); -void InitStores(); void SetupTownStores(); void FreeStoreMem(); void PrintSString(const Surface &out, int margin, int line, const char *text, UiFlags flags, int price = 0);