From 4e8843ee7ca23bb30cb4920378c32bfa5f269c21 Mon Sep 17 00:00:00 2001 From: Anders Jenbo Date: Mon, 12 Oct 2020 14:36:54 +0200 Subject: [PATCH] Implement most of the Hellfire menu Still missing is the support screen (functionally identical to the credit screen) This also fixes a long standing issue with the menu code where it would some times return the index and some times the value of the selected menu item. It now always returns the index and reciver must look up the value. --- SourceX/DiabloUI/diabloui.cpp | 32 ++++++++++++++++---------- SourceX/DiabloUI/diabloui.h | 4 ++-- SourceX/DiabloUI/mainmenu.cpp | 16 +++++++++---- SourceX/DiabloUI/selconn.cpp | 9 ++------ SourceX/DiabloUI/selgame.cpp | 36 ++++++++++++++--------------- SourceX/DiabloUI/selhero.cpp | 43 +++++++++++++++++++++++++++-------- SourceX/DiabloUI/selok.cpp | 2 +- SourceX/DiabloUI/selyesno.cpp | 4 ++-- SourceX/DiabloUI/title.cpp | 9 ++++++++ SourceX/DiabloUI/ui_item.h | 4 ++-- enums.h | 4 ---- 11 files changed, 100 insertions(+), 63 deletions(-) diff --git a/SourceX/DiabloUI/diabloui.cpp b/SourceX/DiabloUI/diabloui.cpp index 01b6a173c..48aeeba7d 100644 --- a/SourceX/DiabloUI/diabloui.cpp +++ b/SourceX/DiabloUI/diabloui.cpp @@ -75,11 +75,11 @@ void UiDestroy() UnloadArtFonts(); } -void UiInitList(int min, int max, void (*fnFocus)(int value), void (*fnSelect)(int value), void (*fnEsc)(), std::vector items, bool itemsWraps, bool (*fnYesNo)()) +void UiInitList(int count, void (*fnFocus)(int value), void (*fnSelect)(int value), void (*fnEsc)(), std::vector items, bool itemsWraps, bool (*fnYesNo)()) { - SelectedItem = min; - SelectedItemMin = min; - SelectedItemMax = max; + SelectedItem = 0; + SelectedItemMin = 0; + SelectedItemMax = std::max(count - 1, 0); ListViewportSize = SelectedItemMax - SelectedItemMin + 1; gfnListFocus = fnFocus; gfnListSelect = fnSelect; @@ -88,7 +88,7 @@ void UiInitList(int min, int max, void (*fnFocus)(int value), void (*fnSelect)(i gUiItems = items; UiItemsWraps = itemsWraps; if (fnFocus) - fnFocus(min); + fnFocus(0); #ifndef __SWITCH__ SDL_StopTextInput(); // input is enabled by default @@ -421,12 +421,20 @@ bool IsInsideRect(const SDL_Event &event, const SDL_Rect &rect) void LoadUiGFX() { +#ifdef HELLFIRE + LoadMaskedArt("ui_art\\hf_logo2.pcx", &ArtLogos[LOGO_MED], 16); +#else LoadMaskedArt("ui_art\\smlogo.pcx", &ArtLogos[LOGO_MED], 15); +#endif LoadMaskedArt("ui_art\\focus16.pcx", &ArtFocus[FOCUS_SMALL], 8); LoadMaskedArt("ui_art\\focus.pcx", &ArtFocus[FOCUS_MED], 8); LoadMaskedArt("ui_art\\focus42.pcx", &ArtFocus[FOCUS_BIG], 8); LoadMaskedArt("ui_art\\cursor.pcx", &ArtCursor, 1, 0); +#ifdef HELLFIRE + LoadArt("ui_art\\heros.pcx", &ArtHero, 6); +#else LoadArt("ui_art\\heros.pcx", &ArtHero, 4); +#endif } void UiInitialize() @@ -589,10 +597,10 @@ int GetCenterOffset(int w, int bw) return (bw - w) / 2; } -void LoadBackgroundArt(const char *pszFile) +void LoadBackgroundArt(const char *pszFile, int frames) { SDL_Color pPal[256]; - LoadArt(pszFile, &ArtBackground, 1, pPal); + LoadArt(pszFile, &ArtBackground, frames, pPal); if (ArtBackground.surface == NULL) return; @@ -709,7 +717,7 @@ void Render(const UiList *ui_list) for (std::size_t i = 0; i < ui_list->m_vecItems.size(); ++i) { SDL_Rect rect = ui_list->itemRect(i); const UiListItem *item = ui_list->GetItem(i); - if (item->m_value == SelectedItem) + if (i == SelectedItem) DrawSelector(rect); DrawArtStr(item->m_text, rect, ui_list->m_iFlags); } @@ -807,17 +815,17 @@ bool HandleMouseEventList(const SDL_Event &event, UiList *ui_list) if (event.type != SDL_MOUSEBUTTONDOWN || event.button.button != SDL_BUTTON_LEFT) return false; - const UiListItem *list_item = ui_list->itemAt(event.button.y); + const int index = ui_list->indexAt(event.button.y); - if (gfnListFocus != NULL && SelectedItem != list_item->m_value) { - UiFocus(list_item->m_value); + if (gfnListFocus != NULL && SelectedItem != index) { + UiFocus(index); #ifdef USE_SDL1 dbClickTimer = SDL_GetTicks(); } else if (gfnListFocus == NULL || dbClickTimer + 500 >= SDL_GetTicks()) { #else } else if (gfnListFocus == NULL || event.button.clicks >= 2) { #endif - SelectedItem = list_item->m_value; + SelectedItem = index; UiFocusNavigationSelect(); #ifdef USE_SDL1 } else { diff --git a/SourceX/DiabloUI/diabloui.h b/SourceX/DiabloUI/diabloui.h index 9595fe06e..d470f26d5 100644 --- a/SourceX/DiabloUI/diabloui.h +++ b/SourceX/DiabloUI/diabloui.h @@ -39,13 +39,13 @@ bool UiItemMouseEvents(SDL_Event *event, std::vector items); int GetCenterOffset(int w, int bw = 0); void LoadPalInMem(const SDL_Color *pPal); void DrawMouse(); -void LoadBackgroundArt(const char *pszFile); +void LoadBackgroundArt(const char *pszFile, int frames = 1); void UiAddBackground(std::vector *vecDialog); void UiAddLogo(std::vector *vecDialog, int size = LOGO_MED, int y = 0); void UiFocusNavigationSelect(); void UiFocusNavigationEsc(); void UiFocusNavigationYesNo(); -void UiInitList(int min, int max, void (*fnFocus)(int value), void (*fnSelect)(int value), void (*fnEsc)(), std::vector items, bool wraps = false, bool (*fnYesNo)() = NULL); +void UiInitList(int count, void (*fnFocus)(int value), void (*fnSelect)(int value), void (*fnEsc)(), std::vector items, bool wraps = false, bool (*fnYesNo)() = NULL); void UiInitScrollBar(UiScrollBar *ui_sb, std::size_t viewport_size, const std::size_t *current_offset); void UiClearScreen(); void UiPollAndRender(); diff --git a/SourceX/DiabloUI/mainmenu.cpp b/SourceX/DiabloUI/mainmenu.cpp index 95484245b..34f3521db 100644 --- a/SourceX/DiabloUI/mainmenu.cpp +++ b/SourceX/DiabloUI/mainmenu.cpp @@ -14,15 +14,15 @@ int MainMenuResult; void UiMainMenuSelect(int value) { - MainMenuResult = value; + MainMenuResult = vecMenuItems[value]->m_value; } void mainmenu_Esc() { - if (SelectedItem == MAINMENU_EXIT_DIABLO) { - UiMainMenuSelect(MAINMENU_EXIT_DIABLO); + if (SelectedItem == 4) { + UiMainMenuSelect(4); } else { - SelectedItem = MAINMENU_EXIT_DIABLO; + SelectedItem = 4; } } @@ -38,8 +38,14 @@ void mainmenu_Load(char *name, void (*fnSound)(char *file)) vecMenuItems.push_back(new UiListItem("Single Player", MAINMENU_SINGLE_PLAYER)); vecMenuItems.push_back(new UiListItem("Multi Player", MAINMENU_MULTIPLAYER)); vecMenuItems.push_back(new UiListItem("Replay Intro", MAINMENU_REPLAY_INTRO)); +#ifdef HELLFIRE + vecMenuItems.push_back(new UiListItem("Support", MAINMENU_SHOW_CREDITS)); + vecMenuItems.push_back(new UiListItem("Credits", MAINMENU_SHOW_CREDITS)); + vecMenuItems.push_back(new UiListItem("Exit Hellfire", MAINMENU_EXIT_DIABLO)); +#else vecMenuItems.push_back(new UiListItem("Show Credits", MAINMENU_SHOW_CREDITS)); vecMenuItems.push_back(new UiListItem("Exit Diablo", MAINMENU_EXIT_DIABLO)); +#endif UiAddBackground(&vecMainMenuDialog); UiAddLogo(&vecMainMenuDialog); @@ -55,7 +61,7 @@ void mainmenu_Load(char *name, void (*fnSound)(char *file)) LoadBackgroundArt("ui_art\\swmmenu.pcx"); } - UiInitList(MAINMENU_SINGLE_PLAYER, MAINMENU_EXIT_DIABLO, NULL, UiMainMenuSelect, mainmenu_Esc, vecMainMenuDialog, true); + UiInitList(vecMenuItems.size(), NULL, UiMainMenuSelect, mainmenu_Esc, vecMainMenuDialog, true); } void mainmenu_Free() diff --git a/SourceX/DiabloUI/selconn.cpp b/SourceX/DiabloUI/selconn.cpp index c43a43665..8bd3a3749 100644 --- a/SourceX/DiabloUI/selconn.cpp +++ b/SourceX/DiabloUI/selconn.cpp @@ -27,7 +27,6 @@ void selconn_Load() { LoadBackgroundArt("ui_art\\selconn.pcx"); - // vecConnItems Should be in the same order as conn_type (See enums.h) #ifndef NONET vecConnItems.push_back(new UiListItem("Client-Server (TCP)", SELCONN_TCP)); #ifdef BUGGY @@ -71,7 +70,7 @@ void selconn_Load() SDL_Rect rect10 = { PANEL_LEFT + 454, (UI_OFFSET_Y + 427), 140, 35 }; vecSelConnDlg.push_back(new UiArtTextButton("Cancel", &UiFocusNavigationEsc, rect10, UIS_CENTER | UIS_VCENTER | UIS_BIG | UIS_GOLD)); - UiInitList(0, vecConnItems.size() - 1, selconn_Focus, selconn_Select, selconn_Esc, vecSelConnDlg); + UiInitList(vecConnItems.size(), selconn_Focus, selconn_Select, selconn_Esc, vecSelConnDlg); } void selconn_Free() @@ -102,18 +101,14 @@ void selconn_Focus(int value) { int players = MAX_PLRS; switch (value) { -#ifndef NONET case SELCONN_TCP: strncpy(selconn_Description, "All computers must be connected to a TCP-compatible network.", sizeof(selconn_Description) - 1); players = MAX_PLRS; break; -#ifdef BUGGY case SELCONN_UDP: strncpy(selconn_Description, "All computers must be connected to a UDP-compatible network.", sizeof(selconn_Description) - 1); players = MAX_PLRS; break; -#endif -#endif case SELCONN_LOOPBACK: strncpy(selconn_Description, "Play by yourself with no network exposure.", sizeof(selconn_Description) - 1); players = 1; @@ -126,7 +121,7 @@ void selconn_Focus(int value) void selconn_Select(int value) { - provider = value; + provider = vecConnItems[value]->m_value; selconn_Free(); selconn_EndMenu = SNetInitializeProvider(provider, selconn_ClientInfo, selconn_UserInfo, selconn_UiInfo, selconn_FileInfo); diff --git a/SourceX/DiabloUI/selgame.cpp b/SourceX/DiabloUI/selgame.cpp index e786503da..4cda137a6 100644 --- a/SourceX/DiabloUI/selgame.cpp +++ b/SourceX/DiabloUI/selgame.cpp @@ -99,12 +99,12 @@ void selgame_GameSelection_Init() SDL_Rect rect6 = { PANEL_LEFT + 449, (UI_OFFSET_Y + 427), 140, 35 }; vecSelGameDialog.push_back(new UiArtTextButton("CANCEL", &UiFocusNavigationEsc, rect6, UIS_CENTER | UIS_VCENTER | UIS_BIG | UIS_GOLD)); - UiInitList(0, 1, selgame_GameSelection_Focus, selgame_GameSelection_Select, selgame_GameSelection_Esc, vecSelGameDialog); + UiInitList(vecSelGameDlgItems.size(), selgame_GameSelection_Focus, selgame_GameSelection_Select, selgame_GameSelection_Esc, vecSelGameDialog); } void selgame_GameSelection_Focus(int value) { - switch (value) { + switch (vecSelGameDlgItems[value]->m_value) { case 0: strncpy(selgame_Description, "Create a new game with a difficulty setting of your choice.", sizeof(selgame_Description) - 1); break; @@ -168,7 +168,7 @@ void selgame_GameSelection_Select(int value) SDL_Rect rect6 = { PANEL_LEFT + 449, (UI_OFFSET_Y + 427), 140, 35 }; vecSelGameDialog.push_back(new UiArtTextButton("CANCEL", &UiFocusNavigationEsc, rect6, UIS_CENTER | UIS_VCENTER | UIS_BIG | UIS_GOLD)); - UiInitList(0, NUM_DIFFICULTIES - 1, selgame_Diff_Focus, selgame_Diff_Select, selgame_Diff_Esc, vecSelGameDialog, true); + UiInitList(vecSelGameDlgItems.size(), selgame_Diff_Focus, selgame_Diff_Select, selgame_Diff_Esc, vecSelGameDialog, true); break; } case 1: { @@ -186,7 +186,7 @@ void selgame_GameSelection_Select(int value) SDL_Rect rect7 = { PANEL_LEFT + 449, (UI_OFFSET_Y + 427), 140, 35 }; vecSelGameDialog.push_back(new UiArtTextButton("CANCEL", &UiFocusNavigationEsc, rect7, UIS_CENTER | UIS_VCENTER | UIS_BIG | UIS_GOLD)); - UiInitList(0, 0, NULL, selgame_Password_Init, selgame_GameSelection_Init, vecSelGameDialog); + UiInitList(0, NULL, selgame_Password_Init, selgame_GameSelection_Init, vecSelGameDialog); break; } } @@ -201,7 +201,7 @@ void selgame_GameSelection_Esc() void selgame_Diff_Focus(int value) { - switch (value) { + switch (vecSelGameDlgItems[value]->m_value) { case DIFF_NORMAL: strncpy(selgame_Label, "Normal", sizeof(selgame_Label) - 1); strncpy(selgame_Description, "Normal Difficulty\nThis is where a starting character should begin the quest to defeat Diablo.", sizeof(selgame_Description) - 1); @@ -238,7 +238,7 @@ bool IsDifficultyAllowed(int value) void selgame_Diff_Select(int value) { - if (selhero_isMultiPlayer && !IsDifficultyAllowed(value)) { + if (selhero_isMultiPlayer && !IsDifficultyAllowed(vecSelGameDlgItems[value]->m_value)) { selgame_GameSelection_Select(0); return; } @@ -292,10 +292,10 @@ void selgame_GameSpeedSelection() SDL_Rect rect4 = { PANEL_LEFT + 299, (UI_OFFSET_Y + 211), 295, 35 }; vecSelGameDialog.push_back(new UiArtText("Select Game Speed", rect4, UIS_CENTER | UIS_BIG)); - vecSelGameDlgItems.push_back(new UiListItem("Normal", 0)); - vecSelGameDlgItems.push_back(new UiListItem("Fast", 1)); - vecSelGameDlgItems.push_back(new UiListItem("Faster", 2)); - vecSelGameDlgItems.push_back(new UiListItem("Fastest", 3)); + vecSelGameDlgItems.push_back(new UiListItem("Normal", 20)); + vecSelGameDlgItems.push_back(new UiListItem("Fast", 30)); + vecSelGameDlgItems.push_back(new UiListItem("Faster", 40)); + vecSelGameDlgItems.push_back(new UiListItem("Fastest", 50)); vecSelGameDialog.push_back(new UiList(vecSelGameDlgItems, PANEL_LEFT + 300, (UI_OFFSET_Y + 279), 295, 26, UIS_CENTER | UIS_MED | UIS_GOLD)); @@ -305,25 +305,25 @@ void selgame_GameSpeedSelection() SDL_Rect rect6 = { PANEL_LEFT + 449, (UI_OFFSET_Y + 427), 140, 35 }; vecSelGameDialog.push_back(new UiArtTextButton("CANCEL", &UiFocusNavigationEsc, rect6, UIS_CENTER | UIS_VCENTER | UIS_BIG | UIS_GOLD)); - UiInitList(0, 3, selgame_Speed_Focus, selgame_Speed_Select, selgame_Speed_Esc, vecSelGameDialog, true); + UiInitList(vecSelGameDlgItems.size(), selgame_Speed_Focus, selgame_Speed_Select, selgame_Speed_Esc, vecSelGameDialog, true); } void selgame_Speed_Focus(int value) { - switch (value) { - case 0: + switch (vecSelGameDlgItems[value]->m_value) { + case 20: strncpy(selgame_Label, "Normal", sizeof(selgame_Label) - 1); strncpy(selgame_Description, "Normal Speed\nThis is where a starting character should begin the quest to defeat Diablo.", sizeof(selgame_Description) - 1); break; - case 1: + case 30: strncpy(selgame_Label, "Fast", sizeof(selgame_Label) - 1); strncpy(selgame_Description, "Fast Speed\nThe denizens of the Labyrinth have been hastened and will prove to be a greater challenge. This is recommended for experienced characters only.", sizeof(selgame_Description) - 1); break; - case 2: + case 40: strncpy(selgame_Label, "Faster", sizeof(selgame_Label) - 1); strncpy(selgame_Description, "Faster Speed\nMost monsters of the dungeon will seek you out quicker than ever before. Only an experienced champion should try their luck at this speed.", sizeof(selgame_Description) - 1); break; - case 3: + case 50: strncpy(selgame_Label, "Fastest", sizeof(selgame_Label) - 1); strncpy(selgame_Description, "Fastest Speed\nThe minions of the underworld will rush to attack without hesitation. Only a true speed demon should enter at this pace.", sizeof(selgame_Description) - 1); break; @@ -338,7 +338,7 @@ void selgame_Speed_Esc() void selgame_Speed_Select(int value) { - gbTickRate = 20 + 10 * value; + gbTickRate = vecSelGameDlgItems[value]->m_value; if (provider == SELCONN_LOOPBACK) { selgame_Password_Select(0); @@ -378,7 +378,7 @@ void selgame_Password_Init(int value) SDL_Rect rect7 = { PANEL_LEFT + 449, (UI_OFFSET_Y + 427), 140, 35 }; vecSelGameDialog.push_back(new UiArtTextButton("CANCEL", &UiFocusNavigationEsc, rect7, UIS_CENTER | UIS_VCENTER | UIS_BIG | UIS_GOLD)); - UiInitList(0, 0, NULL, selgame_Password_Select, selgame_Password_Esc, vecSelGameDialog); + UiInitList(0, NULL, selgame_Password_Select, selgame_Password_Esc, vecSelGameDialog); } void selgame_Password_Select(int value) diff --git a/SourceX/DiabloUI/selhero.cpp b/SourceX/DiabloUI/selhero.cpp index 76cd22f1c..7e6386502 100644 --- a/SourceX/DiabloUI/selhero.cpp +++ b/SourceX/DiabloUI/selhero.cpp @@ -91,7 +91,12 @@ void selhero_Free() void selhero_SetStats() { - SELHERO_DIALOG_HERO_IMG->m_frame = selhero_heroInfo.heroclass; + int heroclass = selhero_heroInfo.heroclass; +#ifdef HELLFIRE + if (heroclass == UI_BARBARIAN) + heroclass = UI_WARRIOR; +#endif + SELHERO_DIALOG_HERO_IMG->m_frame = heroclass; snprintf(textStats[0], sizeof(textStats[0]), "%d", selhero_heroInfo.level); snprintf(textStats[1], sizeof(textStats[1]), "%d", selhero_heroInfo.strength); snprintf(textStats[2], sizeof(textStats[2]), "%d", selhero_heroInfo.magic); @@ -208,7 +213,7 @@ void selhero_List_Init() SDL_Rect rect5 = { PANEL_LEFT + 489, (UI_OFFSET_Y + 429), 120, 35 }; vecSelDlgItems.push_back(new UiArtTextButton("Cancel", &UiFocusNavigationEsc, rect5, UIS_CENTER | UIS_BIG | UIS_GOLD)); - UiInitList(0, selhero_SaveCount, selhero_List_Focus, selhero_List_Select, selhero_List_Esc, vecSelDlgItems, false, selhero_List_DeleteYesNo); + UiInitList(selhero_SaveCount + 1, selhero_List_Focus, selhero_List_Select, selhero_List_Esc, vecSelDlgItems, false, selhero_List_DeleteYesNo); UiInitScrollBar(scrollBar, kMaxViewportItems, &listOffset); if (selhero_isMultiPlayer) { strcpy(title, "Multi Player Characters"); @@ -230,7 +235,11 @@ void selhero_List_Focus(int value) return; } +#ifdef HELLFIRE + SELHERO_DIALOG_HERO_IMG->m_frame = 5; +#else SELHERO_DIALOG_HERO_IMG->m_frame = UI_NUM_CLASSES; +#endif strncpy(textStats[0], "--", sizeof(textStats[0]) - 1); strncpy(textStats[1], "--", sizeof(textStats[1]) - 1); strncpy(textStats[2], "--", sizeof(textStats[2]) - 1); @@ -256,10 +265,23 @@ void selhero_List_Select(int value) vecSelDlgItems.push_back(new UiArtText("Choose Class", rect1, UIS_CENTER | UIS_BIG)); selhero_FreeListItems(); + int itemH = 33; vecSelHeroDlgItems.push_back(new UiListItem("Warrior", UI_WARRIOR)); vecSelHeroDlgItems.push_back(new UiListItem("Rogue", UI_ROGUE)); vecSelHeroDlgItems.push_back(new UiListItem("Sorcerer", UI_SORCERER)); - vecSelDlgItems.push_back(new UiList(vecSelHeroDlgItems, PANEL_LEFT + 264, (UI_OFFSET_Y + 285), 320, 33, UIS_CENTER | UIS_MED | UIS_GOLD)); +#ifdef HELLFIRE + vecSelHeroDlgItems.push_back(new UiListItem("Monk", UI_MONK)); + if (UseBardTest) { + vecSelHeroDlgItems.push_back(new UiListItem("Bard", UI_BARD)); + } + if (UseBarbarianTest) { + vecSelHeroDlgItems.push_back(new UiListItem("Barbarian", UI_BARBARIAN)); + } + if (vecSelHeroDlgItems.size() > 4) + itemH = 26; +#endif + int itemY = 246 + (176 - vecSelHeroDlgItems.size() * itemH) / 2; + vecSelDlgItems.push_back(new UiList(vecSelHeroDlgItems, PANEL_LEFT + 264, (UI_OFFSET_Y + itemY), 320, itemH, UIS_CENTER | UIS_MED | UIS_GOLD)); SDL_Rect rect2 = { PANEL_LEFT + 279, (UI_OFFSET_Y + 429), 140, 35 }; vecSelDlgItems.push_back(new UiArtTextButton("OK", &UiFocusNavigationSelect, rect2, UIS_CENTER | UIS_BIG | UIS_GOLD)); @@ -267,7 +289,7 @@ void selhero_List_Select(int value) SDL_Rect rect3 = { PANEL_LEFT + 429, (UI_OFFSET_Y + 429), 140, 35 }; vecSelDlgItems.push_back(new UiArtTextButton("Cancel", &UiFocusNavigationEsc, rect3, UIS_CENTER | UIS_BIG | UIS_GOLD)); - UiInitList(0, 2, selhero_ClassSelector_Focus, selhero_ClassSelector_Select, selhero_ClassSelector_Esc, vecSelDlgItems); + UiInitList(vecSelHeroDlgItems.size(), selhero_ClassSelector_Focus, selhero_ClassSelector_Select, selhero_ClassSelector_Esc, vecSelDlgItems); memset(&selhero_heroInfo.name, 0, sizeof(selhero_heroInfo.name)); strncpy(title, "New Single Player Hero", sizeof(title) - 1); if (selhero_isMultiPlayer) { @@ -293,7 +315,7 @@ void selhero_List_Select(int value) SDL_Rect rect3 = { PANEL_LEFT + 429, (UI_OFFSET_Y + 427), 140, 35 }; vecSelDlgItems.push_back(new UiArtTextButton("Cancel", &UiFocusNavigationEsc, rect3, UIS_CENTER | UIS_VCENTER | UIS_BIG | UIS_GOLD)); - UiInitList(0, 1, selhero_Load_Focus, selhero_Load_Select, selhero_List_Init, vecSelDlgItems, true); + UiInitList(vecSelHeroDlgItems.size(), selhero_Load_Focus, selhero_Load_Select, selhero_List_Init, vecSelDlgItems, true); strncpy(title, "Single Player Characters", sizeof(title) - 1); return; } @@ -315,7 +337,7 @@ void selhero_ClassSelector_Focus(int value) gfnHeroStats(value, &defaults); selhero_heroInfo.level = 1; - selhero_heroInfo.heroclass = value; + selhero_heroInfo.heroclass = vecSelHeroDlgItems[value]->m_value; selhero_heroInfo.strength = defaults.strength; selhero_heroInfo.magic = defaults.magic; selhero_heroInfo.dexterity = defaults.dexterity; @@ -326,7 +348,8 @@ void selhero_ClassSelector_Focus(int value) void selhero_ClassSelector_Select(int value) { - if (gbSpawned && (value == 1 || value == 2)) { + int hClass = vecSelHeroDlgItems[value]->m_value; + if (gbSpawned && (hClass == UI_ROGUE || hClass == UI_SORCERER)) { ArtBackground.Unload(); UiSelOkDialog(NULL, "The Rogue and Sorcerer are only available in the full retail version of Diablo. Visit https://www.gog.com/game/diablo to purchase.", false); LoadBackgroundArt("ui_art\\selhero.pcx"); @@ -355,7 +378,7 @@ void selhero_ClassSelector_Select(int value) SDL_Rect rect4 = { PANEL_LEFT + 429, (UI_OFFSET_Y + 429), 140, 35 }; vecSelDlgItems.push_back(new UiArtTextButton("Cancel", &UiFocusNavigationEsc, rect4, UIS_CENTER | UIS_BIG | UIS_GOLD)); - UiInitList(0, 0, NULL, selhero_Name_Select, selhero_Name_Esc, vecSelDlgItems); + UiInitList(0, NULL, selhero_Name_Select, selhero_Name_Esc, vecSelDlgItems); } void selhero_ClassSelector_Esc() @@ -405,7 +428,7 @@ void selhero_Name_Select(int value) #ifdef PREFILL_PLAYER_NAME strncpy(selhero_heroInfo.name, selhero_GenerateName(selhero_heroInfo.heroclass), sizeof(selhero_heroInfo.name) - 1); #endif - selhero_ClassSelector_Select(selhero_heroInfo.heroclass); + selhero_ClassSelector_Select(0); } void selhero_Name_Esc() @@ -421,7 +444,7 @@ void selhero_Load_Select(int value) { UiInitList_clear(); selhero_endMenu = true; - if (value == 0) { + if (vecSelHeroDlgItems[value]->m_value == 0) { selhero_result = SELHERO_CONTINUE; return; } else if (!selhero_isMultiPlayer) { diff --git a/SourceX/DiabloUI/selok.cpp b/SourceX/DiabloUI/selok.cpp index 57ff6f222..a3a78210f 100644 --- a/SourceX/DiabloUI/selok.cpp +++ b/SourceX/DiabloUI/selok.cpp @@ -81,7 +81,7 @@ void UiSelOkDialog(const char *title, const char *body, bool background) strncpy(dialogText, body, sizeof(dialogText) - 1); WordWrapArtStr(dialogText, MESSAGE_WIDTH); - UiInitList(0, 0, NULL, selok_Select, selok_Esc, vecSelOkDialog, false, NULL); + UiInitList(0, NULL, selok_Select, selok_Esc, vecSelOkDialog, false, NULL); selok_endMenu = false; while (!selok_endMenu) { diff --git a/SourceX/DiabloUI/selyesno.cpp b/SourceX/DiabloUI/selyesno.cpp index 73ac7316a..5b1c68d46 100644 --- a/SourceX/DiabloUI/selyesno.cpp +++ b/SourceX/DiabloUI/selyesno.cpp @@ -35,7 +35,7 @@ void selyesno_Free() void selyesno_Select(int value) { - selyesno_value = value == 0; + selyesno_value = vecSelYesNoDialogItems[value]->m_value == 0; selyesno_endMenu = true; } @@ -64,7 +64,7 @@ bool UiSelHeroYesNoDialog(const char *title, const char *body) strncpy(selyesno_confirmationMessage, body, sizeof(selyesno_confirmationMessage) - 1); WordWrapArtStr(selyesno_confirmationMessage, MESSAGE_WIDTH); - UiInitList(0, 1, NULL, selyesno_Select, selyesno_Esc, vecSelYesNoDialog, true, NULL); + UiInitList(vecSelYesNoDialogItems.size(), NULL, selyesno_Select, selyesno_Esc, vecSelYesNoDialog, true, NULL); selyesno_value = true; selyesno_endMenu = false; diff --git a/SourceX/DiabloUI/title.cpp b/SourceX/DiabloUI/title.cpp index 386cc58ce..e18255a22 100644 --- a/SourceX/DiabloUI/title.cpp +++ b/SourceX/DiabloUI/title.cpp @@ -8,8 +8,12 @@ std::vector vecTitleScreen; void title_Load() { +#ifdef HELLFIRE + LoadBackgroundArt("ui_art\\hf_logo1.pcx", 16); +#else LoadBackgroundArt("ui_art\\title.pcx"); LoadMaskedArt("ui_art\\logo.pcx", &ArtLogos[LOGO_BIG], 15); +#endif } void title_Free() @@ -26,11 +30,16 @@ void title_Free() void UiTitleDialog() { +#ifdef HELLFIRE + SDL_Rect rect = { 0, UI_OFFSET_Y, 0, 0 }; + vecTitleScreen.push_back(new UiImage(&ArtBackground, /*animated=*/true, /*frame=*/0, rect, UIS_CENTER)); +#else UiAddBackground(&vecTitleScreen); UiAddLogo(&vecTitleScreen, LOGO_BIG, 182); SDL_Rect rect = { PANEL_LEFT + 49, (UI_OFFSET_Y + 410), 550, 26 }; vecTitleScreen.push_back(new UiArtText("Copyright \xA9 1996-2001 Blizzard Entertainment", rect, UIS_MED | UIS_CENTER)); +#endif title_Load(); diff --git a/SourceX/DiabloUI/ui_item.h b/SourceX/DiabloUI/ui_item.h index ad445b309..c3c4a026e 100644 --- a/SourceX/DiabloUI/ui_item.h +++ b/SourceX/DiabloUI/ui_item.h @@ -330,12 +330,12 @@ public: return tmp; } - UiListItem *itemAt(Sint16 y) const + int indexAt(Sint16 y) const { ASSERT(y >= m_rect.y); const std::size_t index = (y - m_rect.y) / m_height; ASSERT(index < m_vecItems.size()); - return m_vecItems[index]; + return index; } UiListItem *GetItem(int i) const diff --git a/enums.h b/enums.h index 1c6b7f560..f06d26989 100644 --- a/enums.h +++ b/enums.h @@ -3487,12 +3487,8 @@ typedef enum dlrg_flag { } dlrg_flag; typedef enum conn_type { -#ifndef NONET SELCONN_TCP, -#ifdef BUGGY SELCONN_UDP, -#endif -#endif SELCONN_LOOPBACK, } conn_type;