2 changed files with 196 additions and 196 deletions
@ -1,187 +1,187 @@ |
|||||||
#include "selstart.h" |
#include "selstart.h" |
||||||
|
|
||||||
#include "DiabloUI/diabloui.h" |
#include "DiabloUI/diabloui.h" |
||||||
#include "DiabloUI/scrollbar.h" |
#include "DiabloUI/scrollbar.h" |
||||||
#include "control.h" |
#include "control.h" |
||||||
#include "engine/render/text_render.hpp" |
#include "engine/render/text_render.hpp" |
||||||
#include "hwcursor.hpp" |
#include "hwcursor.hpp" |
||||||
#include "options.h" |
#include "options.h" |
||||||
#include "utils/language.h" |
#include "utils/language.h" |
||||||
|
|
||||||
namespace devilution { |
namespace devilution { |
||||||
namespace { |
namespace { |
||||||
|
|
||||||
bool endMenu = false; |
bool endMenu = false; |
||||||
bool recreateUI = false; |
bool recreateUI = false; |
||||||
|
|
||||||
std::vector<std::unique_ptr<UiListItem>> vecDialogItems; |
std::vector<std::unique_ptr<UiListItem>> vecDialogItems; |
||||||
std::vector<std::unique_ptr<UiItemBase>> vecDialog; |
std::vector<std::unique_ptr<UiItemBase>> vecDialog; |
||||||
std::vector<OptionEntryBase *> vecOptions; |
std::vector<OptionEntryBase *> vecOptions; |
||||||
|
|
||||||
char optionDescription[256]; |
char optionDescription[256]; |
||||||
|
|
||||||
Rectangle rectDescription; |
Rectangle rectDescription; |
||||||
|
|
||||||
enum class SpecialMenuEntry { |
enum class SpecialMenuEntry { |
||||||
None = -1, |
None = -1, |
||||||
PreviousMenu = -2, |
PreviousMenu = -2, |
||||||
SwitchGame = -3, |
SwitchGame = -3, |
||||||
ToggleSpawn = -4, |
ToggleSpawn = -4, |
||||||
}; |
}; |
||||||
|
|
||||||
bool IsValidEntry(OptionEntryBase *pOptionEntry) |
bool IsValidEntry(OptionEntryBase *pOptionEntry) |
||||||
{ |
{ |
||||||
return HasNoneOf(pOptionEntry->GetFlags(), OptionEntryFlags::Invisible | (gbIsHellfire ? OptionEntryFlags::OnlyDiablo : OptionEntryFlags::OnlyHellfire)); |
return HasNoneOf(pOptionEntry->GetFlags(), OptionEntryFlags::Invisible | (gbIsHellfire ? OptionEntryFlags::OnlyDiablo : OptionEntryFlags::OnlyHellfire)); |
||||||
} |
} |
||||||
|
|
||||||
std::vector<DrawStringFormatArg> CreateDrawStringFormatArgForEntry(OptionEntryBase *pEntry) |
std::vector<DrawStringFormatArg> CreateDrawStringFormatArgForEntry(OptionEntryBase *pEntry) |
||||||
{ |
{ |
||||||
return std::vector<DrawStringFormatArg> { |
return std::vector<DrawStringFormatArg> { |
||||||
{ pEntry->GetName().data(), UiFlags::ColorUiGold }, |
{ pEntry->GetName().data(), UiFlags::ColorUiGold }, |
||||||
{ pEntry->GetValueDescription().data(), UiFlags::ColorUiSilver } |
{ pEntry->GetValueDescription().data(), UiFlags::ColorUiSilver } |
||||||
}; |
}; |
||||||
} |
} |
||||||
|
|
||||||
void ItemFocused(int value) |
void ItemFocused(int value) |
||||||
{ |
{ |
||||||
auto &vecItem = vecDialogItems[value]; |
auto &vecItem = vecDialogItems[value]; |
||||||
optionDescription[0] = '\0'; |
optionDescription[0] = '\0'; |
||||||
if (vecItem->m_value < 0) { |
if (vecItem->m_value < 0) { |
||||||
return; |
return; |
||||||
} |
} |
||||||
auto *pOption = vecOptions[vecItem->m_value]; |
auto *pOption = vecOptions[vecItem->m_value]; |
||||||
auto paragraphs = WordWrapString(pOption->GetDescription(), rectDescription.size.width, GameFont12, 1); |
auto paragraphs = WordWrapString(pOption->GetDescription(), rectDescription.size.width, GameFont12, 1); |
||||||
strncpy(optionDescription, paragraphs.c_str(), sizeof(optionDescription)); |
strncpy(optionDescription, paragraphs.c_str(), sizeof(optionDescription)); |
||||||
} |
} |
||||||
|
|
||||||
void ItemSelected(int value) |
void ItemSelected(int value) |
||||||
{ |
{ |
||||||
auto &vecItem = vecDialogItems[value]; |
auto &vecItem = vecDialogItems[value]; |
||||||
if (vecItem->m_value < 0) { |
if (vecItem->m_value < 0) { |
||||||
auto specialMenuEntry = static_cast<SpecialMenuEntry>(vecItem->m_value); |
auto specialMenuEntry = static_cast<SpecialMenuEntry>(vecItem->m_value); |
||||||
switch (specialMenuEntry) { |
switch (specialMenuEntry) { |
||||||
case SpecialMenuEntry::None: |
case SpecialMenuEntry::None: |
||||||
break; |
break; |
||||||
case SpecialMenuEntry::PreviousMenu: |
case SpecialMenuEntry::PreviousMenu: |
||||||
endMenu = true; |
endMenu = true; |
||||||
break; |
break; |
||||||
case SpecialMenuEntry::SwitchGame: |
case SpecialMenuEntry::SwitchGame: |
||||||
gbIsHellfire = !gbIsHellfire; |
gbIsHellfire = !gbIsHellfire; |
||||||
endMenu = true; |
endMenu = true; |
||||||
recreateUI = true; |
recreateUI = true; |
||||||
break; |
break; |
||||||
case SpecialMenuEntry::ToggleSpawn: |
case SpecialMenuEntry::ToggleSpawn: |
||||||
gbIsSpawn = !gbIsSpawn; |
gbIsSpawn = !gbIsSpawn; |
||||||
UiSetSpawned(gbIsSpawn); |
UiSetSpawned(gbIsSpawn); |
||||||
endMenu = true; |
endMenu = true; |
||||||
recreateUI = true; |
recreateUI = true; |
||||||
break; |
break; |
||||||
} |
} |
||||||
return; |
return; |
||||||
} |
} |
||||||
|
|
||||||
auto *pOption = vecOptions[vecItem->m_value]; |
auto *pOption = vecOptions[vecItem->m_value]; |
||||||
switch (pOption->GetType()) { |
switch (pOption->GetType()) { |
||||||
case OptionEntryType::Boolean: { |
case OptionEntryType::Boolean: { |
||||||
auto *pOptionBoolean = static_cast<OptionEntryBoolean *>(pOption); |
auto *pOptionBoolean = static_cast<OptionEntryBoolean *>(pOption); |
||||||
pOptionBoolean->SetValue(!**pOptionBoolean); |
pOptionBoolean->SetValue(!**pOptionBoolean); |
||||||
} break; |
} break; |
||||||
case OptionEntryType::List: { |
case OptionEntryType::List: { |
||||||
auto *pOptionList = static_cast<OptionEntryListBase *>(pOption); |
auto *pOptionList = static_cast<OptionEntryListBase *>(pOption); |
||||||
size_t nextIndex = pOptionList->GetActiveListIndex() + 1; |
size_t nextIndex = pOptionList->GetActiveListIndex() + 1; |
||||||
if (nextIndex >= pOptionList->GetListSize()) |
if (nextIndex >= pOptionList->GetListSize()) |
||||||
nextIndex = 0; |
nextIndex = 0; |
||||||
pOptionList->SetActiveListIndex(nextIndex); |
pOptionList->SetActiveListIndex(nextIndex); |
||||||
} break; |
} break; |
||||||
} |
} |
||||||
vecDialogItems[value]->args.clear(); |
vecDialogItems[value]->args.clear(); |
||||||
for (auto &arg : CreateDrawStringFormatArgForEntry(pOption)) |
for (auto &arg : CreateDrawStringFormatArgForEntry(pOption)) |
||||||
vecDialogItems[value]->args.push_back(arg); |
vecDialogItems[value]->args.push_back(arg); |
||||||
} |
} |
||||||
|
|
||||||
void EscPressed() |
void EscPressed() |
||||||
{ |
{ |
||||||
endMenu = true; |
endMenu = true; |
||||||
} |
} |
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
void UiSettingsMenu() |
void UiSettingsMenu() |
||||||
{ |
{ |
||||||
endMenu = false; |
endMenu = false; |
||||||
|
|
||||||
do { |
do { |
||||||
LoadBackgroundArt("ui_art\\black.pcx"); |
LoadBackgroundArt("ui_art\\black.pcx"); |
||||||
LoadScrollBar(); |
LoadScrollBar(); |
||||||
UiAddBackground(&vecDialog); |
UiAddBackground(&vecDialog); |
||||||
UiAddLogo(&vecDialog); |
UiAddLogo(&vecDialog); |
||||||
|
|
||||||
Rectangle rectList = { { PANEL_LEFT + 50, (UI_OFFSET_Y + 204) }, { 540, 208 } }; |
Rectangle rectList = { { PANEL_LEFT + 50, (UI_OFFSET_Y + 204) }, { 540, 208 } }; |
||||||
rectDescription = { { PANEL_LEFT + 24, rectList.position.y + rectList.size.height + 20 }, { 590, 35 } }; |
rectDescription = { { PANEL_LEFT + 24, rectList.position.y + rectList.size.height + 20 }, { 590, 35 } }; |
||||||
|
|
||||||
optionDescription[0] = '\0'; |
optionDescription[0] = '\0'; |
||||||
|
|
||||||
const char *titleText = _("Settings"); |
const char *titleText = _("Settings"); |
||||||
vecDialog.push_back(std::make_unique<UiArtText>(titleText, MakeSdlRect(PANEL_LEFT, UI_OFFSET_Y + 161, PANEL_WIDTH, 35), UiFlags::FontSize30 | UiFlags::ColorUiSilver | UiFlags::AlignCenter, 8)); |
vecDialog.push_back(std::make_unique<UiArtText>(titleText, MakeSdlRect(PANEL_LEFT, UI_OFFSET_Y + 161, PANEL_WIDTH, 35), UiFlags::FontSize30 | UiFlags::ColorUiSilver | UiFlags::AlignCenter, 8)); |
||||||
vecDialog.push_back(std::make_unique<UiScrollbar>(&ArtScrollBarBackground, &ArtScrollBarThumb, &ArtScrollBarArrow, MakeSdlRect(rectList.position.x + rectList.size.width + 5, rectList.position.y, 25, rectList.size.height))); |
vecDialog.push_back(std::make_unique<UiScrollbar>(&ArtScrollBarBackground, &ArtScrollBarThumb, &ArtScrollBarArrow, MakeSdlRect(rectList.position.x + rectList.size.width + 5, rectList.position.y, 25, rectList.size.height))); |
||||||
vecDialog.push_back(std::make_unique<UiArtText>(optionDescription, MakeSdlRect(rectDescription), UiFlags::FontSize12 | UiFlags::ColorUiSilverDark | UiFlags::AlignCenter, 1)); |
vecDialog.push_back(std::make_unique<UiArtText>(optionDescription, MakeSdlRect(rectDescription), UiFlags::FontSize12 | UiFlags::ColorUiSilverDark | UiFlags::AlignCenter, 1)); |
||||||
|
|
||||||
if (diabdat_mpq && hellfire_mpq) |
if (diabdat_mpq && hellfire_mpq) |
||||||
vecDialogItems.push_back(std::make_unique<UiListItem>(gbIsHellfire ? _("Switch to Diablo") : _("Switch to Hellfire"), static_cast<int>(SpecialMenuEntry::SwitchGame), UiFlags::ColorUiGold)); |
vecDialogItems.push_back(std::make_unique<UiListItem>(gbIsHellfire ? _("Switch to Diablo") : _("Switch to Hellfire"), static_cast<int>(SpecialMenuEntry::SwitchGame), UiFlags::ColorUiGold)); |
||||||
if (diabdat_mpq) |
if (diabdat_mpq) |
||||||
vecDialogItems.push_back(std::make_unique<UiListItem>(gbIsSpawn ? _("Switch to Fullgame") : _("Switch to Shareware"), static_cast<int>(SpecialMenuEntry::ToggleSpawn), UiFlags::ColorUiGold)); |
vecDialogItems.push_back(std::make_unique<UiListItem>(gbIsSpawn ? _("Switch to Fullgame") : _("Switch to Shareware"), static_cast<int>(SpecialMenuEntry::ToggleSpawn), UiFlags::ColorUiGold)); |
||||||
|
|
||||||
bool switchOptionExists = vecDialogItems.size() > 0; |
bool switchOptionExists = vecDialogItems.size() > 0; |
||||||
int catCount = switchOptionExists ? 1 : 0; |
int catCount = switchOptionExists ? 1 : 0; |
||||||
for (auto *pCategory : sgOptions.GetCategories()) { |
for (auto *pCategory : sgOptions.GetCategories()) { |
||||||
bool categoryCreated = false; |
bool categoryCreated = false; |
||||||
for (auto *pEntry : pCategory->GetEntries()) { |
for (auto *pEntry : pCategory->GetEntries()) { |
||||||
if (!IsValidEntry(pEntry)) |
if (!IsValidEntry(pEntry)) |
||||||
continue; |
continue; |
||||||
if (!categoryCreated) { |
if (!categoryCreated) { |
||||||
if (catCount > 0) |
if (catCount > 0) |
||||||
vecDialogItems.push_back(std::make_unique<UiListItem>("", -1, UiFlags::ElementDisabled)); |
vecDialogItems.push_back(std::make_unique<UiListItem>("", -1, UiFlags::ElementDisabled)); |
||||||
catCount += 1; |
catCount += 1; |
||||||
vecDialogItems.push_back(std::make_unique<UiListItem>(pCategory->GetName().data(), static_cast<int>(SpecialMenuEntry::None), UiFlags::ColorWhitegold | UiFlags::ElementDisabled)); |
vecDialogItems.push_back(std::make_unique<UiListItem>(pCategory->GetName().data(), static_cast<int>(SpecialMenuEntry::None), UiFlags::ColorWhitegold | UiFlags::ElementDisabled)); |
||||||
categoryCreated = true; |
categoryCreated = true; |
||||||
} |
} |
||||||
auto formatArgs = CreateDrawStringFormatArgForEntry(pEntry); |
auto formatArgs = CreateDrawStringFormatArgForEntry(pEntry); |
||||||
vecDialogItems.push_back(std::make_unique<UiListItem>("{}: {}", formatArgs, vecOptions.size(), UiFlags::ColorUiGold)); |
vecDialogItems.push_back(std::make_unique<UiListItem>("{}: {}", formatArgs, vecOptions.size(), UiFlags::ColorUiGold)); |
||||||
vecOptions.push_back(pEntry); |
vecOptions.push_back(pEntry); |
||||||
} |
} |
||||||
} |
} |
||||||
|
|
||||||
vecDialogItems.push_back(std::make_unique<UiListItem>("", -1, UiFlags::ElementDisabled)); |
vecDialogItems.push_back(std::make_unique<UiListItem>("", -1, UiFlags::ElementDisabled)); |
||||||
vecDialogItems.push_back(std::make_unique<UiListItem>(_("Previous Menu"), static_cast<int>(SpecialMenuEntry::PreviousMenu), UiFlags::ColorUiGold)); |
vecDialogItems.push_back(std::make_unique<UiListItem>(_("Previous Menu"), static_cast<int>(SpecialMenuEntry::PreviousMenu), UiFlags::ColorUiGold)); |
||||||
|
|
||||||
vecDialog.push_back(std::make_unique<UiList>(vecDialogItems, rectList.size.height / 26, rectList.position.x, rectList.position.y, rectList.size.width, 26, UiFlags::FontSize24 | UiFlags::AlignCenter)); |
vecDialog.push_back(std::make_unique<UiList>(vecDialogItems, rectList.size.height / 26, rectList.position.x, rectList.position.y, rectList.size.width, 26, UiFlags::FontSize24 | UiFlags::AlignCenter)); |
||||||
|
|
||||||
UiInitList(ItemFocused, ItemSelected, EscPressed, vecDialog, true, nullptr, switchOptionExists ? 0 : 1); |
UiInitList(ItemFocused, ItemSelected, EscPressed, vecDialog, true, nullptr, switchOptionExists ? 0 : 1); |
||||||
|
|
||||||
while (!endMenu) { |
while (!endMenu) { |
||||||
UiClearScreen(); |
UiClearScreen(); |
||||||
UiRenderItems(vecDialog); |
UiRenderItems(vecDialog); |
||||||
UiPollAndRender(); |
UiPollAndRender(); |
||||||
} |
} |
||||||
|
|
||||||
vecDialogItems.clear(); |
vecDialogItems.clear(); |
||||||
vecDialog.clear(); |
vecDialog.clear(); |
||||||
vecOptions.clear(); |
vecOptions.clear(); |
||||||
|
|
||||||
ArtBackground.Unload(); |
ArtBackground.Unload(); |
||||||
ArtBackgroundWidescreen.Unload(); |
ArtBackgroundWidescreen.Unload(); |
||||||
UnloadScrollBar(); |
UnloadScrollBar(); |
||||||
|
|
||||||
if (recreateUI) { |
if (recreateUI) { |
||||||
UiInitialize(); |
UiInitialize(); |
||||||
FreeItemGFX(); |
FreeItemGFX(); |
||||||
InitItemGFX(); |
InitItemGFX(); |
||||||
if (IsHardwareCursor()) |
if (IsHardwareCursor()) |
||||||
SetHardwareCursor(CursorInfo::UnknownCursor()); |
SetHardwareCursor(CursorInfo::UnknownCursor()); |
||||||
recreateUI = false; |
recreateUI = false; |
||||||
endMenu = false; |
endMenu = false; |
||||||
} |
} |
||||||
} while (!endMenu); |
} while (!endMenu); |
||||||
} |
} |
||||||
|
|
||||||
} // namespace devilution
|
} // namespace devilution
|
||||||
|
|||||||
Loading…
Reference in new issue