From 5df03f56e3cb90fd0eedd8a122a96d5d2ba16195 Mon Sep 17 00:00:00 2001 From: Gleb Mazovetskiy Date: Sun, 8 May 2022 12:13:32 +0100 Subject: [PATCH] DiabloUI: Render scrollbar as PCX --- Source/DiabloUI/diabloui.cpp | 25 ++++++++++++++----------- Source/DiabloUI/scrollbar.cpp | 20 +++++++++++--------- Source/DiabloUI/scrollbar.h | 25 ++++++++++++------------- Source/DiabloUI/selgame.cpp | 2 +- Source/DiabloUI/selhero.cpp | 2 +- Source/DiabloUI/settingsmenu.cpp | 2 +- Source/DiabloUI/ui_item.h | 8 ++++---- 7 files changed, 44 insertions(+), 40 deletions(-) diff --git a/Source/DiabloUI/diabloui.cpp b/Source/DiabloUI/diabloui.cpp index 5f5275508..dfabf99c4 100644 --- a/Source/DiabloUI/diabloui.cpp +++ b/Source/DiabloUI/diabloui.cpp @@ -891,33 +891,36 @@ void Render(const UiList *uiList) void Render(const UiScrollbar *uiSb) { + const Surface out = Surface(DiabloUiSurface()); + // Bar background (tiled): { - const int bgYEnd = DownArrowRect(uiSb).y; - int bgY = uiSb->m_rect.y + uiSb->m_arrow->h(); - while (bgY < bgYEnd) { - std::size_t drawH = std::min(bgY + uiSb->m_bg->h(), bgYEnd) - bgY; - DrawArt({ uiSb->m_rect.x, bgY }, uiSb->m_bg, 0, SCROLLBAR_BG_WIDTH, drawH); - bgY += drawH; + const int bgY = uiSb->m_rect.y + uiSb->m_arrow.frameHeight(); + const int bgH = DownArrowRect(uiSb).y - bgY; + const Surface backgroundOut = out.subregion(uiSb->m_rect.x, bgY, SCROLLBAR_BG_WIDTH, bgH); + int y = 0; + while (y < bgH) { + RenderPcxSprite(backgroundOut, uiSb->m_bg, { 0, y }); + y += uiSb->m_bg.height(); } } // Arrows: { const SDL_Rect rect = UpArrowRect(uiSb); - const int frame = static_cast(scrollBarState.upArrowPressed ? ScrollBarArrowFrame_UP_ACTIVE : ScrollBarArrowFrame_UP); - DrawArt({ rect.x, rect.y }, uiSb->m_arrow, frame, rect.w); + const auto frame = static_cast(scrollBarState.upArrowPressed ? ScrollBarArrowFrame_UP_ACTIVE : ScrollBarArrowFrame_UP); + RenderPcxSprite(out.subregion(rect.x, 0, SCROLLBAR_ARROW_WIDTH, out.h()), uiSb->m_arrow.sprite(frame), { 0, rect.y }); } { const SDL_Rect rect = DownArrowRect(uiSb); - const int frame = static_cast(scrollBarState.downArrowPressed ? ScrollBarArrowFrame_DOWN_ACTIVE : ScrollBarArrowFrame_DOWN); - DrawArt({ rect.x, rect.y }, uiSb->m_arrow, frame, rect.w); + const auto frame = static_cast(scrollBarState.downArrowPressed ? ScrollBarArrowFrame_DOWN_ACTIVE : ScrollBarArrowFrame_DOWN); + RenderPcxSprite(out.subregion(rect.x, 0, SCROLLBAR_ARROW_WIDTH, out.h()), uiSb->m_arrow.sprite(frame), { 0, rect.y }); } // Thumb: if (SelectedItemMax > 0) { const SDL_Rect rect = ThumbRect(uiSb, SelectedItem, SelectedItemMax + 1); - DrawArt({ rect.x, rect.y }, uiSb->m_thumb); + RenderPcxSprite(out, uiSb->m_thumb, { rect.x, rect.y }); } } diff --git a/Source/DiabloUI/scrollbar.cpp b/Source/DiabloUI/scrollbar.cpp index 6f0702f51..48d09f2d4 100644 --- a/Source/DiabloUI/scrollbar.cpp +++ b/Source/DiabloUI/scrollbar.cpp @@ -1,23 +1,25 @@ #include "scrollbar.h" +#include "engine/load_pcx.hpp" + namespace devilution { -Art ArtScrollBarBackground; -Art ArtScrollBarThumb; -Art ArtScrollBarArrow; +std::optional ArtScrollBarBackground; +std::optional ArtScrollBarThumb; +std::optional ArtScrollBarArrow; void LoadScrollBar() { - LoadArt("ui_art\\sb_bg.pcx", &ArtScrollBarBackground); - LoadArt("ui_art\\sb_thumb.pcx", &ArtScrollBarThumb); - LoadArt("ui_art\\sb_arrow.pcx", &ArtScrollBarArrow, 4); + ArtScrollBarBackground = LoadPcxAsset("ui_art\\sb_bg.pcx"); + ArtScrollBarThumb = LoadPcxAsset("ui_art\\sb_thumb.pcx"); + ArtScrollBarArrow = LoadPcxSpriteSheetAsset("ui_art\\sb_arrow.pcx", 4); } void UnloadScrollBar() { - ArtScrollBarArrow.Unload(); - ArtScrollBarThumb.Unload(); - ArtScrollBarBackground.Unload(); + ArtScrollBarArrow = std::nullopt; + ArtScrollBarThumb = std::nullopt; + ArtScrollBarBackground = std::nullopt; } } // namespace devilution diff --git a/Source/DiabloUI/scrollbar.h b/Source/DiabloUI/scrollbar.h index bda855d88..30f742448 100644 --- a/Source/DiabloUI/scrollbar.h +++ b/Source/DiabloUI/scrollbar.h @@ -2,14 +2,14 @@ #include -#include "DiabloUI/art.h" #include "DiabloUI/ui_item.h" +#include "engine/pcx_sprite.hpp" namespace devilution { -extern Art ArtScrollBarBackground; -extern Art ArtScrollBarThumb; -extern Art ArtScrollBarArrow; +extern std::optional ArtScrollBarBackground; +extern std::optional ArtScrollBarThumb; +extern std::optional ArtScrollBarArrow; const Uint16 SCROLLBAR_BG_WIDTH = 25; enum ScrollBarArrowFrame : uint8_t { @@ -19,7 +19,6 @@ enum ScrollBarArrowFrame : uint8_t { ScrollBarArrowFrame_DOWN, }; -extern Art ArtScrollBarThumb; const Uint16 SCROLLBAR_ARROW_WIDTH = 25; inline SDL_Rect UpArrowRect(const UiScrollbar *sb) @@ -28,7 +27,7 @@ inline SDL_Rect UpArrowRect(const UiScrollbar *sb) Tmp.x = sb->m_rect.x; Tmp.y = sb->m_rect.y; Tmp.w = SCROLLBAR_ARROW_WIDTH; - Tmp.h = static_cast(sb->m_arrow->h()); + Tmp.h = static_cast(sb->m_arrow.frameHeight()); return Tmp; } @@ -37,23 +36,23 @@ inline SDL_Rect DownArrowRect(const UiScrollbar *sb) { SDL_Rect Tmp; Tmp.x = sb->m_rect.x; - Tmp.y = static_cast(sb->m_rect.y + sb->m_rect.h - sb->m_arrow->h()); + Tmp.y = static_cast(sb->m_rect.y + sb->m_rect.h - sb->m_arrow.frameHeight()); Tmp.w = SCROLLBAR_ARROW_WIDTH, - Tmp.h = static_cast(sb->m_arrow->h()); + Tmp.h = static_cast(sb->m_arrow.frameHeight()); return Tmp; } inline Uint16 BarHeight(const UiScrollbar *sb) { - return sb->m_rect.h - 2 * sb->m_arrow->h(); + return sb->m_rect.h - 2 * sb->m_arrow.frameHeight(); } inline SDL_Rect BarRect(const UiScrollbar *sb) { SDL_Rect Tmp; Tmp.x = sb->m_rect.x; - Tmp.y = static_cast(sb->m_rect.y + sb->m_arrow->h()); + Tmp.y = static_cast(sb->m_rect.y + sb->m_arrow.frameHeight()); Tmp.w = SCROLLBAR_ARROW_WIDTH, Tmp.h = BarHeight(sb); @@ -63,14 +62,14 @@ inline SDL_Rect BarRect(const UiScrollbar *sb) inline SDL_Rect ThumbRect(const UiScrollbar *sb, std::size_t selected_index, std::size_t num_items) { const int THUMB_OFFSET_X = 3; - const int thumb_max_y = BarHeight(sb) - sb->m_thumb->h(); + const int thumb_max_y = BarHeight(sb) - sb->m_thumb.height(); const int thumb_y = static_cast(selected_index * thumb_max_y / (num_items - 1)); SDL_Rect Tmp; Tmp.x = static_cast(sb->m_rect.x + THUMB_OFFSET_X); - Tmp.y = static_cast(sb->m_rect.y + sb->m_arrow->h() + thumb_y); + Tmp.y = static_cast(sb->m_rect.y + sb->m_arrow.frameHeight() + thumb_y); Tmp.w = static_cast(sb->m_rect.w - THUMB_OFFSET_X); - Tmp.h = static_cast(sb->m_thumb->h()); + Tmp.h = static_cast(sb->m_thumb.height()); return Tmp; } diff --git a/Source/DiabloUI/selgame.cpp b/Source/DiabloUI/selgame.cpp index 7e382d8d3..58299a467 100644 --- a/Source/DiabloUI/selgame.cpp +++ b/Source/DiabloUI/selgame.cpp @@ -125,7 +125,7 @@ void UiInitGameSelectionList(string_view search) const Point uiPosition = GetUIRectangle().position; SDL_Rect rectScrollbar = { (Sint16)(uiPosition.x + 590), (Sint16)(uiPosition.y + 244), 25, 178 }; - vecSelGameDialog.push_back(std::make_unique(&ArtScrollBarBackground, &ArtScrollBarThumb, &ArtScrollBarArrow, rectScrollbar)); + vecSelGameDialog.push_back(std::make_unique(PcxSprite { *ArtScrollBarBackground }, PcxSprite { *ArtScrollBarThumb }, PcxSpriteSheet { *ArtScrollBarArrow }, rectScrollbar)); SDL_Rect rect1 = { (Sint16)(uiPosition.x + 24), (Sint16)(uiPosition.y + 161), 590, 35 }; vecSelGameDialog.push_back(std::make_unique(_(ConnectionNames[provider]).c_str(), rect1, UiFlags::AlignCenter | UiFlags::FontSize30 | UiFlags::ColorUiSilver, 3)); diff --git a/Source/DiabloUI/selhero.cpp b/Source/DiabloUI/selhero.cpp index 8a809c692..c1e6574ec 100644 --- a/Source/DiabloUI/selhero.cpp +++ b/Source/DiabloUI/selhero.cpp @@ -495,7 +495,7 @@ void selhero_List_Init() vecSelDlgItems.push_back(std::make_unique(vecSelHeroDlgItems, 6, uiPosition.x + 265, (uiPosition.y + 256), 320, 26, UiFlags::AlignCenter | UiFlags::FontSize24 | UiFlags::ColorUiGold)); SDL_Rect rect2 = { (Sint16)(uiPosition.x + 585), (Sint16)(uiPosition.y + 244), 25, 178 }; - vecSelDlgItems.push_back(std::make_unique(&ArtScrollBarBackground, &ArtScrollBarThumb, &ArtScrollBarArrow, rect2)); + vecSelDlgItems.push_back(std::make_unique(PcxSprite { *ArtScrollBarBackground }, PcxSprite { *ArtScrollBarThumb }, PcxSpriteSheet { *ArtScrollBarArrow }, rect2)); SDL_Rect rect3 = { (Sint16)(uiPosition.x + 239), (Sint16)(uiPosition.y + 429), 120, 35 }; vecSelDlgItems.push_back(std::make_unique(_("OK"), &UiFocusNavigationSelect, rect3, UiFlags::AlignCenter | UiFlags::FontSize30 | UiFlags::ColorUiGold)); diff --git a/Source/DiabloUI/settingsmenu.cpp b/Source/DiabloUI/settingsmenu.cpp index ac42578ea..c452d8278 100644 --- a/Source/DiabloUI/settingsmenu.cpp +++ b/Source/DiabloUI/settingsmenu.cpp @@ -261,7 +261,7 @@ void UiSettingsMenu() string_view titleText = shownMenu == ShownMenuType::Settings ? _("Settings") : selectedOption->GetName(); vecDialog.push_back(std::make_unique(titleText.data(), MakeSdlRect(uiRectangle.position.x, uiRectangle.position.y + 161, uiRectangle.size.width, 35), UiFlags::FontSize30 | UiFlags::ColorUiSilver | UiFlags::AlignCenter, 8)); - vecDialog.push_back(std::make_unique(&ArtScrollBarBackground, &ArtScrollBarThumb, &ArtScrollBarArrow, MakeSdlRect(rectList.position.x + rectList.size.width + 5, rectList.position.y, 25, rectList.size.height))); + vecDialog.push_back(std::make_unique(PcxSprite { *ArtScrollBarBackground }, PcxSprite { *ArtScrollBarThumb }, PcxSpriteSheet { *ArtScrollBarArrow }, MakeSdlRect(rectList.position.x + rectList.size.width + 5, rectList.position.y, 25, rectList.size.height))); vecDialog.push_back(std::make_unique(optionDescription, MakeSdlRect(rectDescription), UiFlags::FontSize12 | UiFlags::ColorUiSilverDark | UiFlags::AlignCenter, 1, IsSmallFontTall() ? 22 : 18)); size_t itemToSelect = 1; diff --git a/Source/DiabloUI/ui_item.h b/Source/DiabloUI/ui_item.h index 6748b75ad..af8157e0d 100644 --- a/Source/DiabloUI/ui_item.h +++ b/Source/DiabloUI/ui_item.h @@ -287,7 +287,7 @@ private: class UiScrollbar : public UiItemBase { public: - UiScrollbar(Art *bg, Art *thumb, Art *arrow, SDL_Rect rect, UiFlags flags = UiFlags::None) + UiScrollbar(PcxSprite bg, PcxSprite thumb, PcxSpriteSheet arrow, SDL_Rect rect, UiFlags flags = UiFlags::None) : UiItemBase(UiType::Scrollbar, rect, flags) , m_bg(bg) , m_thumb(thumb) @@ -296,9 +296,9 @@ public: } // private: - Art *m_bg; - Art *m_thumb; - Art *m_arrow; + PcxSprite m_bg; + PcxSprite m_thumb; + PcxSpriteSheet m_arrow; }; //=============================================================================