From b881468c041cf2c2d3be9bf865624f02a678c9d9 Mon Sep 17 00:00:00 2001 From: Gleb Mazovetskiy Date: Tue, 9 Aug 2022 12:22:52 +0100 Subject: [PATCH] Difficulty indicator improvements (#5224) * Difficulty indicator improvements 1. Clean up positioning code. 2. Do not show for non-save portraits. 3. Remove `vecDifficultyIndicators` - render the items on the fly instead --- Source/DiabloUI/button.cpp | 12 +-- Source/DiabloUI/button.h | 2 +- Source/DiabloUI/diabloui.cpp | 168 +++++++++++++++++------------------ Source/DiabloUI/diabloui.h | 1 + Source/DiabloUI/scrollbar.h | 73 +++++++-------- Source/DiabloUI/selhero.cpp | 29 +++--- 6 files changed, 141 insertions(+), 144 deletions(-) diff --git a/Source/DiabloUI/button.cpp b/Source/DiabloUI/button.cpp index 3f27aa5ac..1e0d770e4 100644 --- a/Source/DiabloUI/button.cpp +++ b/Source/DiabloUI/button.cpp @@ -34,17 +34,17 @@ ClxSprite ButtonSprite(bool pressed) return (*ButtonSprites)[pressed ? 1 : 0]; } -void RenderButton(UiButton *button) +void RenderButton(const UiButton &button) { - const Surface &out = Surface(DiabloUiSurface()).subregion(button->m_rect.x, button->m_rect.y, button->m_rect.w, button->m_rect.h); - RenderClxSprite(out, ButtonSprite(button->IsPressed()), { 0, 0 }); + const Surface &out = Surface(DiabloUiSurface()).subregion(button.m_rect.x, button.m_rect.y, button.m_rect.w, button.m_rect.h); + RenderClxSprite(out, ButtonSprite(button.IsPressed()), { 0, 0 }); - Rectangle textRect { { 0, 0 }, { button->m_rect.w, button->m_rect.h } }; - if (!button->IsPressed()) { + Rectangle textRect { { 0, 0 }, { button.m_rect.w, button.m_rect.h } }; + if (!button.IsPressed()) { --textRect.position.y; } - DrawString(out, button->GetText(), textRect, UiFlags::AlignCenter | UiFlags::FontSizeDialog | UiFlags::ColorDialogWhite); + DrawString(out, button.GetText(), textRect, UiFlags::AlignCenter | UiFlags::FontSizeDialog | UiFlags::ColorDialogWhite); } bool HandleMouseEventButton(const SDL_Event &event, UiButton *button) diff --git a/Source/DiabloUI/button.h b/Source/DiabloUI/button.h index 91b46b0bd..d8801f63b 100644 --- a/Source/DiabloUI/button.h +++ b/Source/DiabloUI/button.h @@ -11,7 +11,7 @@ const Uint16 DialogButtonHeight = 28; void LoadDialogButtonGraphics(); void FreeDialogButtonGraphics(); ClxSprite ButtonSprite(bool pressed); -void RenderButton(UiButton *button); +void RenderButton(const UiButton &button); bool HandleMouseEventButton(const SDL_Event &event, UiButton *button); void HandleGlobalMouseUpButton(UiButton *button); diff --git a/Source/DiabloUI/diabloui.cpp b/Source/DiabloUI/diabloui.cpp index e1ea1d863..3686ed782 100644 --- a/Source/DiabloUI/diabloui.cpp +++ b/Source/DiabloUI/diabloui.cpp @@ -563,8 +563,8 @@ void LoadUiGFX() } else { ArtLogo = LoadPcxSpriteList("ui_art\\smlogo.pcx", /*numFrames=*/15, /*transparentColor=*/250); } - DifficultyIndicator[0] = LoadPcx("ui_art\\radio1.pcx"); - DifficultyIndicator[1] = LoadPcx("ui_art\\radio3.pcx"); + DifficultyIndicator[0] = LoadPcx("ui_art\\radio1.pcx", /*transparentColor=*/0); + DifficultyIndicator[1] = LoadPcx("ui_art\\radio3.pcx", /*transparentColor=*/0); ArtFocus[FOCUS_SMALL] = LoadPcxSpriteList("ui_art\\focus16.pcx", /*numFrames=*/8, /*transparentColor=*/250); ArtFocus[FOCUS_MED] = LoadPcxSpriteList("ui_art\\focus.pcx", /*numFrames=*/8, /*transparentColor=*/250); ArtFocus[FOCUS_BIG] = LoadPcxSpriteList("ui_art\\focus42.pcx", /*numFrames=*/8, /*transparentColor=*/250); @@ -793,75 +793,75 @@ void UiPollAndRender(std::function eventHandler) namespace { -void Render(const UiText *uiText) +void Render(const UiText &uiText) { const Surface &out = Surface(DiabloUiSurface()); - DrawString(out, uiText->GetText(), MakeRectangle(uiText->m_rect), uiText->GetFlags() | UiFlags::FontSizeDialog); + DrawString(out, uiText.GetText(), MakeRectangle(uiText.m_rect), uiText.GetFlags() | UiFlags::FontSizeDialog); } -void Render(const UiArtText *uiArtText) +void Render(const UiArtText &uiArtText) { const Surface &out = Surface(DiabloUiSurface()); - DrawString(out, uiArtText->GetText(), MakeRectangle(uiArtText->m_rect), uiArtText->GetFlags(), uiArtText->GetSpacing(), uiArtText->GetLineHeight()); + DrawString(out, uiArtText.GetText(), MakeRectangle(uiArtText.m_rect), uiArtText.GetFlags(), uiArtText.GetSpacing(), uiArtText.GetLineHeight()); } -void Render(const UiImageClx *uiImage) +void Render(const UiImageClx &uiImage) { - ClxSprite sprite = uiImage->sprite(); - int x = uiImage->m_rect.x; - if (uiImage->isCentered()) { - x += GetCenterOffset(sprite.width(), uiImage->m_rect.w); + ClxSprite sprite = uiImage.sprite(); + int x = uiImage.m_rect.x; + if (uiImage.isCentered()) { + x += GetCenterOffset(sprite.width(), uiImage.m_rect.w); } - RenderClxSprite(Surface(DiabloUiSurface()), sprite, { x, uiImage->m_rect.y }); + RenderClxSprite(Surface(DiabloUiSurface()), sprite, { x, uiImage.m_rect.y }); } -void Render(const UiImageAnimatedClx *uiImage) +void Render(const UiImageAnimatedClx &uiImage) { - ClxSprite sprite = uiImage->sprite(GetAnimationFrame(uiImage->numFrames())); - int x = uiImage->m_rect.x; - if (uiImage->isCentered()) { - x += GetCenterOffset(sprite.width(), uiImage->m_rect.w); + ClxSprite sprite = uiImage.sprite(GetAnimationFrame(uiImage.numFrames())); + int x = uiImage.m_rect.x; + if (uiImage.isCentered()) { + x += GetCenterOffset(sprite.width(), uiImage.m_rect.w); } - RenderClxSprite(Surface(DiabloUiSurface()), sprite, { x, uiImage->m_rect.y }); + RenderClxSprite(Surface(DiabloUiSurface()), sprite, { x, uiImage.m_rect.y }); } -void Render(const UiArtTextButton *uiButton) +void Render(const UiArtTextButton &uiButton) { const Surface &out = Surface(DiabloUiSurface()); - DrawString(out, uiButton->GetText(), MakeRectangle(uiButton->m_rect), uiButton->GetFlags()); + DrawString(out, uiButton.GetText(), MakeRectangle(uiButton.m_rect), uiButton.GetFlags()); } -void Render(const UiList *uiList) +void Render(const UiList &uiList) { const Surface &out = Surface(DiabloUiSurface()); - for (std::size_t i = listOffset; i < uiList->m_vecItems.size() && (i - listOffset) < ListViewportSize; ++i) { - SDL_Rect rect = uiList->itemRect(i - listOffset); - const UiListItem *item = uiList->GetItem(i); + for (std::size_t i = listOffset; i < uiList.m_vecItems.size() && (i - listOffset) < ListViewportSize; ++i) { + SDL_Rect rect = uiList.itemRect(i - listOffset); + const UiListItem &item = *uiList.GetItem(i); if (i == SelectedItem) DrawSelector(rect); Rectangle rectangle = MakeRectangle(rect); - if (item->args.empty()) - DrawString(out, item->m_text, rectangle, uiList->GetFlags() | item->uiFlags, uiList->GetSpacing()); + if (item.args.empty()) + DrawString(out, item.m_text, rectangle, uiList.GetFlags() | item.uiFlags, uiList.GetSpacing()); else - DrawStringWithColors(out, item->m_text, item->args, rectangle, uiList->GetFlags() | item->uiFlags, uiList->GetSpacing()); + DrawStringWithColors(out, item.m_text, item.args, rectangle, uiList.GetFlags() | item.uiFlags, uiList.GetSpacing()); } } -void Render(const UiScrollbar *uiSb) +void Render(const UiScrollbar &uiSb) { const Surface out = Surface(DiabloUiSurface()); // Bar background (tiled): { - const int bgY = uiSb->m_rect.y + uiSb->m_arrow[0].height(); + const int bgY = uiSb.m_rect.y + uiSb.m_arrow[0].height(); const int bgH = DownArrowRect(uiSb).y - bgY; - const Surface backgroundOut = out.subregion(uiSb->m_rect.x, bgY, SCROLLBAR_BG_WIDTH, bgH); + const Surface backgroundOut = out.subregion(uiSb.m_rect.x, bgY, ScrollBarBgWidth, bgH); int y = 0; while (y < bgH) { - RenderClxSprite(backgroundOut, uiSb->m_bg, { 0, y }); - y += uiSb->m_bg.height(); + RenderClxSprite(backgroundOut, uiSb.m_bg, { 0, y }); + y += uiSb.m_bg.height(); } } @@ -869,65 +869,30 @@ void Render(const UiScrollbar *uiSb) { const SDL_Rect rect = UpArrowRect(uiSb); const auto frame = static_cast(scrollBarState.upArrowPressed ? ScrollBarArrowFrame_UP_ACTIVE : ScrollBarArrowFrame_UP); - RenderClxSprite(out.subregion(rect.x, 0, SCROLLBAR_ARROW_WIDTH, out.h()), uiSb->m_arrow[frame], { 0, rect.y }); + RenderClxSprite(out.subregion(rect.x, 0, ScrollBarArrowWidth, out.h()), uiSb.m_arrow[frame], { 0, rect.y }); } { const SDL_Rect rect = DownArrowRect(uiSb); const auto frame = static_cast(scrollBarState.downArrowPressed ? ScrollBarArrowFrame_DOWN_ACTIVE : ScrollBarArrowFrame_DOWN); - RenderClxSprite(out.subregion(rect.x, 0, SCROLLBAR_ARROW_WIDTH, out.h()), uiSb->m_arrow[frame], { 0, rect.y }); + RenderClxSprite(out.subregion(rect.x, 0, ScrollBarArrowWidth, out.h()), uiSb.m_arrow[frame], { 0, rect.y }); } // Thumb: if (SelectedItemMax > 0) { const SDL_Rect rect = ThumbRect(uiSb, SelectedItem, SelectedItemMax + 1); - RenderClxSprite(out, uiSb->m_thumb, { rect.x, rect.y }); + RenderClxSprite(out, uiSb.m_thumb, { rect.x, rect.y }); } } -void Render(const UiEdit *uiEdit) +void Render(const UiEdit &uiEdit) { - DrawSelector(uiEdit->m_rect); + DrawSelector(uiEdit.m_rect); // To simulate padding we inset the region used to draw text in an edit control - Rectangle rect = MakeRectangle(uiEdit->m_rect).inset({ 43, 1 }); + Rectangle rect = MakeRectangle(uiEdit.m_rect).inset({ 43, 1 }); const Surface &out = Surface(DiabloUiSurface()); - DrawString(out, uiEdit->m_value, rect, uiEdit->GetFlags() | UiFlags::TextCursor); -} - -void RenderItem(UiItemBase *item) -{ - if (item->IsHidden()) - return; - switch (item->GetType()) { - case UiType::Text: - Render(static_cast(item)); - break; - case UiType::ArtText: - Render(static_cast(item)); - break; - case UiType::ImageClx: - Render(static_cast(item)); - break; - case UiType::ImageAnimatedClx: - Render(static_cast(item)); - break; - case UiType::ArtTextButton: - Render(static_cast(item)); - break; - case UiType::Button: - RenderButton(static_cast(item)); - break; - case UiType::List: - Render(static_cast(item)); - break; - case UiType::Scrollbar: - Render(static_cast(item)); - break; - case UiType::Edit: - Render(static_cast(item)); - break; - } + DrawString(out, uiEdit.m_value, rect, uiEdit.GetFlags() | UiFlags::TextCursor); } bool HandleMouseEventArtTextButton(const SDL_Event &event, const UiArtTextButton *uiButton) @@ -989,18 +954,18 @@ bool HandleMouseEventScrollBar(const SDL_Event &event, const UiScrollbar *uiSb) if (event.button.button != SDL_BUTTON_LEFT) return false; if (event.type == SDL_MOUSEBUTTONUP) { - if (scrollBarState.upArrowPressed && IsInsideRect(event, UpArrowRect(uiSb))) { + if (scrollBarState.upArrowPressed && IsInsideRect(event, UpArrowRect(*uiSb))) { UiFocusUp(); return true; } - if (scrollBarState.downArrowPressed && IsInsideRect(event, DownArrowRect(uiSb))) { + if (scrollBarState.downArrowPressed && IsInsideRect(event, DownArrowRect(*uiSb))) { UiFocusDown(); return true; } } else if (event.type == SDL_MOUSEBUTTONDOWN) { - if (IsInsideRect(event, BarRect(uiSb))) { + if (IsInsideRect(event, BarRect(*uiSb))) { // Scroll up or down based on thumb position. - const SDL_Rect thumbRect = ThumbRect(uiSb, SelectedItem, SelectedItemMax + 1); + const SDL_Rect thumbRect = ThumbRect(*uiSb, SelectedItem, SelectedItemMax + 1); if (event.button.y < thumbRect.y) { UiFocusPageUp(); } else if (event.button.y > thumbRect.y + thumbRect.h) { @@ -1008,11 +973,11 @@ bool HandleMouseEventScrollBar(const SDL_Event &event, const UiScrollbar *uiSb) } return true; } - if (IsInsideRect(event, UpArrowRect(uiSb))) { + if (IsInsideRect(event, UpArrowRect(*uiSb))) { scrollBarState.upArrowPressed = true; return true; } - if (IsInsideRect(event, DownArrowRect(uiSb))) { + if (IsInsideRect(event, DownArrowRect(*uiSb))) { scrollBarState.downArrowPressed = true; return true; } @@ -1047,16 +1012,51 @@ void LoadPalInMem(const SDL_Color *pPal) } } +void UiRenderItem(const UiItemBase &item) +{ + if (item.IsHidden()) + return; + switch (item.GetType()) { + case UiType::Text: + Render(static_cast(item)); + break; + case UiType::ArtText: + Render(static_cast(item)); + break; + case UiType::ImageClx: + Render(static_cast(item)); + break; + case UiType::ImageAnimatedClx: + Render(static_cast(item)); + break; + case UiType::ArtTextButton: + Render(static_cast(item)); + break; + case UiType::Button: + RenderButton(static_cast(item)); + break; + case UiType::List: + Render(static_cast(item)); + break; + case UiType::Scrollbar: + Render(static_cast(item)); + break; + case UiType::Edit: + Render(static_cast(item)); + break; + } +} + void UiRenderItems(const std::vector &items) { - for (const auto &item : items) - RenderItem(item); + for (const UiItemBase *item : items) + UiRenderItem(*item); } void UiRenderItems(const std::vector> &items) { - for (const auto &item : items) - RenderItem(item.get()); + for (const std::unique_ptr &item : items) + UiRenderItem(*item); } bool UiItemMouseEvents(SDL_Event *event, const std::vector &items) diff --git a/Source/DiabloUI/diabloui.h b/Source/DiabloUI/diabloui.h index 7032e095f..52aeed533 100644 --- a/Source/DiabloUI/diabloui.h +++ b/Source/DiabloUI/diabloui.h @@ -104,6 +104,7 @@ void UiFocusNavigationYesNo(); void UiInitList(void (*fnFocus)(int value), void (*fnSelect)(int value), void (*fnEsc)(), const std::vector> &items, bool wraps = false, void (*fnFullscreen)() = nullptr, bool (*fnYesNo)() = nullptr, size_t selectedItem = 0); void UiClearScreen(); void UiPollAndRender(std::function eventHandler = nullptr); +void UiRenderItem(const UiItemBase &item); void UiRenderItems(const std::vector &items); void UiRenderItems(const std::vector> &items); void UiInitList_clear(); diff --git a/Source/DiabloUI/scrollbar.h b/Source/DiabloUI/scrollbar.h index ed6a34676..1bfddcfac 100644 --- a/Source/DiabloUI/scrollbar.h +++ b/Source/DiabloUI/scrollbar.h @@ -4,13 +4,14 @@ #include "DiabloUI/ui_item.h" #include "engine/clx_sprite.hpp" +#include "utils/sdl_geometry.h" namespace devilution { extern OptionalOwnedClxSpriteList ArtScrollBarBackground; extern OptionalOwnedClxSpriteList ArtScrollBarThumb; extern OptionalOwnedClxSpriteList ArtScrollBarArrow; -const Uint16 SCROLLBAR_BG_WIDTH = 25; +constexpr Uint16 ScrollBarBgWidth = 25; enum ScrollBarArrowFrame : uint8_t { ScrollBarArrowFrame_UP_ACTIVE, @@ -19,59 +20,51 @@ enum ScrollBarArrowFrame : uint8_t { ScrollBarArrowFrame_DOWN, }; -const Uint16 SCROLLBAR_ARROW_WIDTH = 25; +constexpr Uint16 ScrollBarArrowWidth = 25; -inline SDL_Rect UpArrowRect(const UiScrollbar *sb) +inline SDL_Rect UpArrowRect(const UiScrollbar &bar) { - SDL_Rect Tmp; - Tmp.x = sb->m_rect.x; - Tmp.y = sb->m_rect.y; - Tmp.w = SCROLLBAR_ARROW_WIDTH; - Tmp.h = static_cast(sb->m_arrow[0].height()); - - return Tmp; + return MakeSdlRect( + bar.m_rect.x, + bar.m_rect.y, + ScrollBarArrowWidth, + bar.m_arrow[0].height()); } -inline SDL_Rect DownArrowRect(const UiScrollbar *sb) +inline SDL_Rect DownArrowRect(const UiScrollbar &bar) { - SDL_Rect Tmp; - Tmp.x = sb->m_rect.x; - Tmp.y = static_cast(sb->m_rect.y + sb->m_rect.h - sb->m_arrow[0].height()); - Tmp.w = SCROLLBAR_ARROW_WIDTH, - Tmp.h = static_cast(sb->m_arrow[0].height()); - - return Tmp; + return MakeSdlRect( + bar.m_rect.x, + bar.m_rect.y + bar.m_rect.h - bar.m_arrow[0].height(), + ScrollBarArrowWidth, + bar.m_arrow[0].height()); } -inline Uint16 BarHeight(const UiScrollbar *sb) +inline Uint16 BarHeight(const UiScrollbar &bar) { - return sb->m_rect.h - 2 * sb->m_arrow[0].height(); + return bar.m_rect.h - 2 * bar.m_arrow[0].height(); } -inline SDL_Rect BarRect(const UiScrollbar *sb) +inline SDL_Rect BarRect(const UiScrollbar &bar) { - SDL_Rect Tmp; - Tmp.x = sb->m_rect.x; - Tmp.y = static_cast(sb->m_rect.y + sb->m_arrow[0].height()); - Tmp.w = SCROLLBAR_ARROW_WIDTH, - Tmp.h = BarHeight(sb); - - return Tmp; + return MakeSdlRect( + bar.m_rect.x, + bar.m_rect.y + bar.m_arrow[0].height(), + ScrollBarArrowWidth, + BarHeight(bar)); } -inline SDL_Rect ThumbRect(const UiScrollbar *sb, std::size_t selected_index, std::size_t num_items) +inline SDL_Rect ThumbRect(const UiScrollbar &bar, size_t selectedIndex, size_t numItems) { - const int THUMB_OFFSET_X = 3; - 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[0].height() + thumb_y); - Tmp.w = static_cast(sb->m_rect.w - THUMB_OFFSET_X); - Tmp.h = static_cast(sb->m_thumb.height()); - - return Tmp; + constexpr int ThumbOffsetX = 3; + const int thumbMaxY = BarHeight(bar) - bar.m_thumb.height(); + const int thumbY = static_cast(selectedIndex * thumbMaxY / (numItems - 1)); + + return MakeSdlRect( + bar.m_rect.x + ThumbOffsetX, + bar.m_rect.y + bar.m_arrow[0].height() + thumbY, + bar.m_rect.w - ThumbOffsetX, + bar.m_thumb.height()); } void LoadScrollBar(); diff --git a/Source/DiabloUI/selhero.cpp b/Source/DiabloUI/selhero.cpp index 146230625..44ac2c9a1 100644 --- a/Source/DiabloUI/selhero.cpp +++ b/Source/DiabloUI/selhero.cpp @@ -39,12 +39,11 @@ char textStats[6][4]; const char *title = ""; _selhero_selections selhero_result; bool selhero_navigateYesNo; -bool selhero_deleteEnabled; +bool selhero_isSavegame; std::vector> vecSelHeroDialog; std::vector> vecSelHeroDlgItems; std::vector> vecSelDlgItems; -std::vector> vecDifficultyIndicators; UiImageClx *SELHERO_DIALOG_HERO_IMG; @@ -62,7 +61,7 @@ const char *SelheroGenerateName(HeroClass heroClass); void SelheroUiFocusNavigationYesNo() { - if (selhero_deleteEnabled) + if (selhero_isSavegame) UiFocusNavigationYesNo(); } @@ -71,7 +70,6 @@ void SelheroFree() ArtBackground = std::nullopt; vecSelHeroDialog.clear(); - vecDifficultyIndicators.clear(); vecSelDlgItems.clear(); vecSelHeroDlgItems.clear(); @@ -87,13 +85,18 @@ void SelheroSetStats() CopyUtf8(textStats[3], StrCat(selhero_heroInfo.dexterity), sizeof(textStats[3])); CopyUtf8(textStats[4], StrCat(selhero_heroInfo.vitality), sizeof(textStats[4])); CopyUtf8(textStats[5], StrCat(selhero_heroInfo.saveNumber), sizeof(textStats[5])); +} - const Point uiPosition = GetUIRectangle().position; - vecDifficultyIndicators.clear(); - SDL_Rect rect = MakeSdlRect(uiPosition.x + 28, uiPosition.y + 198, 12, 12); +void RenderDifficultyIndicators() +{ + if (!selhero_isSavegame) + return; + const uint16_t width = (*DifficultyIndicator[0])[0].width(); + const uint16_t height = (*DifficultyIndicator[0])[0].height(); + SDL_Rect rect = MakeSdlRect(SELHERO_DIALOG_HERO_IMG->m_rect.x, SELHERO_DIALOG_HERO_IMG->m_rect.y - height - 2, width, height); for (int i = 0; i <= DIFF_LAST; i++) { - vecDifficultyIndicators.push_back(std::make_unique(*DifficultyIndicator[i < selhero_heroInfo.herorank ? 0 : 1], rect, UiFlags::None)); - rect.x += 12; + UiRenderItem(UiImageClx((*DifficultyIndicator[i < selhero_heroInfo.herorank ? 0 : 1])[0], rect, UiFlags::None)); + rect.x += width; } } @@ -116,7 +119,7 @@ void SelheroListFocus(int value) memcpy(&selhero_heroInfo, &selhero_heros[index], sizeof(selhero_heroInfo)); SelheroSetStats(); SELLIST_DIALOG_DELETE_BUTTON->SetFlags(baseFlags | UiFlags::ColorUiGold); - selhero_deleteEnabled = true; + selhero_isSavegame = true; return; } @@ -124,12 +127,12 @@ void SelheroListFocus(int value) for (char *textStat : textStats) strcpy(textStat, "--"); SELLIST_DIALOG_DELETE_BUTTON->SetFlags(baseFlags | UiFlags::ColorUiSilver | UiFlags::ElementDisabled); - selhero_deleteEnabled = false; + selhero_isSavegame = false; } bool SelheroListDeleteYesNo() { - selhero_navigateYesNo = selhero_deleteEnabled; + selhero_navigateYesNo = selhero_isSavegame; return selhero_navigateYesNo; } @@ -564,7 +567,7 @@ static void UiSelHeroDialog( while (!selhero_endMenu && !selhero_navigateYesNo) { UiClearScreen(); UiRenderItems(vecSelHeroDialog); - UiRenderItems(vecDifficultyIndicators); + RenderDifficultyIndicators(); UiPollAndRender(); } SelheroFree();