diff --git a/Source/DiabloUI/selhero.cpp b/Source/DiabloUI/selhero.cpp index 144965f79..ab9895752 100644 --- a/Source/DiabloUI/selhero.cpp +++ b/Source/DiabloUI/selhero.cpp @@ -20,7 +20,14 @@ namespace devilution { -static const char *selhero_GenerateName(HeroClass hero_class); +bool selhero_endMenu; +bool selhero_isMultiPlayer; + +bool (*gfnHeroInfo)(bool (*fninfofunc)(_uiheroinfo *)); +bool (*gfnHeroCreate)(_uiheroinfo *); +void (*gfnHeroStats)(unsigned int, _uidefaultstats *); + +namespace { std::size_t selhero_SaveCount = 0; _uiheroinfo selhero_heros[MAX_CHARACTERS]; @@ -28,31 +35,30 @@ _uiheroinfo selhero_heroInfo; const size_t kMaxViewportItems = 6; char textStats[5][4]; char title[32]; -char selhero_Lable[32]; -char selhero_Description[256]; _selhero_selections selhero_result; -bool selhero_endMenu; -bool selhero_isMultiPlayer; bool selhero_navigateYesNo; bool selhero_deleteEnabled; -bool(*gfnHeroInfo) -(bool (*fninfofunc)(_uiheroinfo *)); -bool(*gfnHeroCreate) -(_uiheroinfo *); -void (*gfnHeroStats)(unsigned int, _uidefaultstats *); - -namespace { - std::vector vecSelHeroDialog; std::vector vecSelHeroDlgItems; std::vector vecSelDlgItems; UiImage *SELHERO_DIALOG_HERO_IMG; -} // namespace bool bUIElementsLoaded = false; +void selhero_List_Focus(int value); +void selhero_List_Select(int value); +void selhero_List_Esc(); +void selhero_Load_Focus(int value); +void selhero_Load_Select(int value); +void selhero_Name_Select(int value); +void selhero_Name_Esc(); +void selhero_ClassSelector_Focus(int value); +void selhero_ClassSelector_Select(int value); +void selhero_ClassSelector_Esc(); +const char *selhero_GenerateName(HeroClass hero_class); + void selhero_UiFocusNavigationYesNo() { if (selhero_deleteEnabled) @@ -104,8 +110,6 @@ void selhero_SetStats() snprintf(textStats[4], sizeof(textStats[4]), "%d", selhero_heroInfo.vitality); } -namespace { - std::size_t listOffset = 0; UiArtTextButton *SELLIST_DIALOG_DELETE_BUTTON; @@ -144,96 +148,6 @@ bool SelHero_GetHeroInfo(_uiheroinfo *pInfo) return true; } -} // namespace - -void selhero_Init() -{ - LoadBackgroundArt("ui_art\\selhero.pcx"); - UiAddBackground(&vecSelHeroDialog); - UiAddLogo(&vecSelHeroDialog); - LoadScrollBar(); - - selhero_SaveCount = 0; - gfnHeroInfo(SelHero_GetHeroInfo); - std::reverse(selhero_heros, selhero_heros + selhero_SaveCount); - - selhero_FreeDlgItems(); - SDL_Rect rect1 = { (Sint16)(PANEL_LEFT + 24), (Sint16)(UI_OFFSET_Y + 161), 590, 35 }; - vecSelHeroDialog.push_back(new UiArtText(title, rect1, UIS_CENTER | UIS_BIG)); - - SDL_Rect rect2 = { (Sint16)(PANEL_LEFT + 30), (Sint16)(UI_OFFSET_Y + 211), 180, 76 }; - SELHERO_DIALOG_HERO_IMG = new UiImage(&ArtHero, static_cast(enum_size::value), rect2); - vecSelHeroDialog.push_back(SELHERO_DIALOG_HERO_IMG); - - SDL_Rect rect3 = { (Sint16)(PANEL_LEFT + 39), (Sint16)(UI_OFFSET_Y + 323), 110, 21 }; - vecSelHeroDialog.push_back(new UiArtText("Level:", rect3, UIS_RIGHT)); - - SDL_Rect rect4 = { (Sint16)(PANEL_LEFT + 39), (Sint16)(UI_OFFSET_Y + 323), 110, 21 }; - vecSelHeroDialog.push_back(new UiArtText("Level:", rect4, UIS_RIGHT)); - SDL_Rect rect5 = { (Sint16)(PANEL_LEFT + 159), (Sint16)(UI_OFFSET_Y + 323), 40, 21 }; - vecSelHeroDialog.push_back(new UiArtText(textStats[0], rect5, UIS_CENTER)); - - SDL_Rect rect6 = { (Sint16)(PANEL_LEFT + 39), (Sint16)(UI_OFFSET_Y + 358), 110, 21 }; - vecSelHeroDialog.push_back(new UiArtText("Strength:", rect6, UIS_RIGHT)); - SDL_Rect rect7 = { (Sint16)(PANEL_LEFT + 159), (Sint16)(UI_OFFSET_Y + 358), 40, 21 }; - vecSelHeroDialog.push_back(new UiArtText(textStats[1], rect7, UIS_CENTER)); - - SDL_Rect rect8 = { (Sint16)(PANEL_LEFT + 39), (Sint16)(UI_OFFSET_Y + 380), 110, 21 }; - vecSelHeroDialog.push_back(new UiArtText("Magic:", rect8, UIS_RIGHT)); - SDL_Rect rect9 = { (Sint16)(PANEL_LEFT + 159), (Sint16)(UI_OFFSET_Y + 380), 40, 21 }; - vecSelHeroDialog.push_back(new UiArtText(textStats[2], rect9, UIS_CENTER)); - - SDL_Rect rect10 = { (Sint16)(PANEL_LEFT + 39), (Sint16)(UI_OFFSET_Y + 401), 110, 21 }; - vecSelHeroDialog.push_back(new UiArtText("Dexterity:", rect10, UIS_RIGHT)); - SDL_Rect rect11 = { (Sint16)(PANEL_LEFT + 159), (Sint16)(UI_OFFSET_Y + 401), 40, 21 }; - vecSelHeroDialog.push_back(new UiArtText(textStats[3], rect11, UIS_CENTER)); - - SDL_Rect rect12 = { (Sint16)(PANEL_LEFT + 39), (Sint16)(UI_OFFSET_Y + 422), 110, 21 }; - vecSelHeroDialog.push_back(new UiArtText("Vitality:", rect12, UIS_RIGHT)); - SDL_Rect rect13 = { (Sint16)(PANEL_LEFT + 159), (Sint16)(UI_OFFSET_Y + 422), 40, 21 }; - vecSelHeroDialog.push_back(new UiArtText(textStats[4], rect13, UIS_CENTER)); -} - -void selhero_List_Init() -{ - listOffset = 0; - selhero_FreeDlgItems(); - - SDL_Rect rect1 = { (Sint16)(PANEL_LEFT + 264), (Sint16)(UI_OFFSET_Y + 211), 320, 33 }; - vecSelDlgItems.push_back(new UiArtText("Select Hero", rect1, UIS_CENTER | UIS_BIG)); - - selhero_FreeListItems(); - const size_t num_viewport_heroes = std::min(selhero_SaveCount + 1, kMaxViewportItems); - for (std::size_t i = 0; i < num_viewport_heroes; i++) { - vecSelHeroDlgItems.push_back(new UiListItem("", -1)); - } - selhero_UpdateViewportItems(); - - vecSelDlgItems.push_back(new UiList(vecSelHeroDlgItems, PANEL_LEFT + 265, (UI_OFFSET_Y + 256), 320, 26, UIS_CENTER | UIS_MED | UIS_GOLD)); - - SDL_Rect rect2 = { (Sint16)(PANEL_LEFT + 585), (Sint16)(UI_OFFSET_Y + 244), 25, 178 }; - UiScrollBar *scrollBar = new UiScrollBar(&ArtScrollBarBackground, &ArtScrollBarThumb, &ArtScrollBarArrow, rect2); - vecSelDlgItems.push_back(scrollBar); - - SDL_Rect rect3 = { (Sint16)(PANEL_LEFT + 239), (Sint16)(UI_OFFSET_Y + 429), 120, 35 }; - vecSelDlgItems.push_back(new UiArtTextButton("OK", &UiFocusNavigationSelect, rect3, UIS_CENTER | UIS_BIG | UIS_GOLD)); - - SDL_Rect rect4 = { (Sint16)(PANEL_LEFT + 364), (Sint16)(UI_OFFSET_Y + 429), 120, 35 }; - SELLIST_DIALOG_DELETE_BUTTON = new UiArtTextButton("Delete", &selhero_UiFocusNavigationYesNo, rect4, UIS_CENTER | UIS_BIG | UIS_DISABLED); - vecSelDlgItems.push_back(SELLIST_DIALOG_DELETE_BUTTON); - - SDL_Rect rect5 = { (Sint16)(PANEL_LEFT + 489), (Sint16)(UI_OFFSET_Y + 429), 120, 35 }; - vecSelDlgItems.push_back(new UiArtTextButton("Cancel", &UiFocusNavigationEsc, rect5, UIS_CENTER | UIS_BIG | UIS_GOLD)); - - 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"); - } else { - strcpy(title, "Single Player Characters"); - } -} - void selhero_List_Focus(int value) { const std::size_t index = static_cast(value); @@ -356,7 +270,7 @@ void selhero_ClassSelector_Focus(int value) selhero_SetStats(); } -static bool shouldPrefillHeroName() +bool shouldPrefillHeroName() { #if defined __3DS__ return false; @@ -487,86 +401,7 @@ void selhero_Load_Select(int value) selhero_result = SELHERO_NEW_DUNGEON; } -static void UiSelHeroDialog( - bool (*fninfo)(bool (*fninfofunc)(_uiheroinfo *)), - bool (*fncreate)(_uiheroinfo *), - void (*fnstats)(unsigned int, _uidefaultstats *), - bool (*fnremove)(_uiheroinfo *), - _selhero_selections *dlgresult, - char (*name)[16]) -{ - bUIElementsLoaded = true; - - do { - gfnHeroInfo = fninfo; - gfnHeroCreate = fncreate; - gfnHeroStats = fnstats; - selhero_result = *dlgresult; - - selhero_navigateYesNo = false; - - selhero_Init(); - - if (selhero_SaveCount) { - selhero_List_Init(); - } else { - selhero_List_Select(selhero_SaveCount); - } - - selhero_endMenu = false; - while (!selhero_endMenu && !selhero_navigateYesNo) { - UiClearScreen(); - UiRenderItems(vecSelHeroDialog); - UiPollAndRender(); - } - selhero_Free(); - - if (selhero_navigateYesNo) { - char dialogTitle[32]; - char dialogText[256]; - if (selhero_isMultiPlayer) { - strncpy(dialogTitle, "Delete Multi Player Hero", sizeof(dialogTitle) - 1); - } else { - strncpy(dialogTitle, "Delete Single Player Hero", sizeof(dialogTitle) - 1); - } - snprintf(dialogText, sizeof(dialogText), "Are you sure you want to delete the character \"%s\"?", selhero_heroInfo.name); - - if (UiSelHeroYesNoDialog(dialogTitle, dialogText)) - fnremove(&selhero_heroInfo); - } - } while (selhero_navigateYesNo); - - *dlgresult = selhero_result; - strncpy(*name, selhero_heroInfo.name, sizeof(*name)); -} - -void UiSelHeroSingDialog( - bool (*fninfo)(bool (*fninfofunc)(_uiheroinfo *)), - bool (*fncreate)(_uiheroinfo *), - bool (*fnremove)(_uiheroinfo *), - void (*fnstats)(unsigned int, _uidefaultstats *), - _selhero_selections *dlgresult, - char (*name)[16], - _difficulty *difficulty) -{ - selhero_isMultiPlayer = false; - UiSelHeroDialog(fninfo, fncreate, fnstats, fnremove, dlgresult, name); - *difficulty = nDifficulty; -} - -void UiSelHeroMultDialog( - bool (*fninfo)(bool (*fninfofunc)(_uiheroinfo *)), - bool (*fncreate)(_uiheroinfo *), - bool (*fnremove)(_uiheroinfo *), - void (*fnstats)(unsigned int, _uidefaultstats *), - _selhero_selections *dlgresult, - char (*name)[16]) -{ - selhero_isMultiPlayer = true; - UiSelHeroDialog(fninfo, fncreate, fnstats, fnremove, dlgresult, name); -} - -static const char *selhero_GenerateName(HeroClass hero_class) +const char *selhero_GenerateName(HeroClass hero_class) { static const char *const kNames[6][10] = { { @@ -654,4 +489,173 @@ static const char *selhero_GenerateName(HeroClass hero_class) return kNames[static_cast(hero_class) % 6][iRand]; } +} // namespace + +void selhero_Init() +{ + LoadBackgroundArt("ui_art\\selhero.pcx"); + UiAddBackground(&vecSelHeroDialog); + UiAddLogo(&vecSelHeroDialog); + LoadScrollBar(); + + selhero_SaveCount = 0; + gfnHeroInfo(SelHero_GetHeroInfo); + std::reverse(selhero_heros, selhero_heros + selhero_SaveCount); + + selhero_FreeDlgItems(); + SDL_Rect rect1 = { (Sint16)(PANEL_LEFT + 24), (Sint16)(UI_OFFSET_Y + 161), 590, 35 }; + vecSelHeroDialog.push_back(new UiArtText(title, rect1, UIS_CENTER | UIS_BIG)); + + SDL_Rect rect2 = { (Sint16)(PANEL_LEFT + 30), (Sint16)(UI_OFFSET_Y + 211), 180, 76 }; + SELHERO_DIALOG_HERO_IMG = new UiImage(&ArtHero, static_cast(enum_size::value), rect2); + vecSelHeroDialog.push_back(SELHERO_DIALOG_HERO_IMG); + + SDL_Rect rect3 = { (Sint16)(PANEL_LEFT + 39), (Sint16)(UI_OFFSET_Y + 323), 110, 21 }; + vecSelHeroDialog.push_back(new UiArtText("Level:", rect3, UIS_RIGHT)); + + SDL_Rect rect4 = { (Sint16)(PANEL_LEFT + 39), (Sint16)(UI_OFFSET_Y + 323), 110, 21 }; + vecSelHeroDialog.push_back(new UiArtText("Level:", rect4, UIS_RIGHT)); + SDL_Rect rect5 = { (Sint16)(PANEL_LEFT + 159), (Sint16)(UI_OFFSET_Y + 323), 40, 21 }; + vecSelHeroDialog.push_back(new UiArtText(textStats[0], rect5, UIS_CENTER)); + + SDL_Rect rect6 = { (Sint16)(PANEL_LEFT + 39), (Sint16)(UI_OFFSET_Y + 358), 110, 21 }; + vecSelHeroDialog.push_back(new UiArtText("Strength:", rect6, UIS_RIGHT)); + SDL_Rect rect7 = { (Sint16)(PANEL_LEFT + 159), (Sint16)(UI_OFFSET_Y + 358), 40, 21 }; + vecSelHeroDialog.push_back(new UiArtText(textStats[1], rect7, UIS_CENTER)); + + SDL_Rect rect8 = { (Sint16)(PANEL_LEFT + 39), (Sint16)(UI_OFFSET_Y + 380), 110, 21 }; + vecSelHeroDialog.push_back(new UiArtText("Magic:", rect8, UIS_RIGHT)); + SDL_Rect rect9 = { (Sint16)(PANEL_LEFT + 159), (Sint16)(UI_OFFSET_Y + 380), 40, 21 }; + vecSelHeroDialog.push_back(new UiArtText(textStats[2], rect9, UIS_CENTER)); + + SDL_Rect rect10 = { (Sint16)(PANEL_LEFT + 39), (Sint16)(UI_OFFSET_Y + 401), 110, 21 }; + vecSelHeroDialog.push_back(new UiArtText("Dexterity:", rect10, UIS_RIGHT)); + SDL_Rect rect11 = { (Sint16)(PANEL_LEFT + 159), (Sint16)(UI_OFFSET_Y + 401), 40, 21 }; + vecSelHeroDialog.push_back(new UiArtText(textStats[3], rect11, UIS_CENTER)); + + SDL_Rect rect12 = { (Sint16)(PANEL_LEFT + 39), (Sint16)(UI_OFFSET_Y + 422), 110, 21 }; + vecSelHeroDialog.push_back(new UiArtText("Vitality:", rect12, UIS_RIGHT)); + SDL_Rect rect13 = { (Sint16)(PANEL_LEFT + 159), (Sint16)(UI_OFFSET_Y + 422), 40, 21 }; + vecSelHeroDialog.push_back(new UiArtText(textStats[4], rect13, UIS_CENTER)); +} + +void selhero_List_Init() +{ + listOffset = 0; + selhero_FreeDlgItems(); + + SDL_Rect rect1 = { (Sint16)(PANEL_LEFT + 264), (Sint16)(UI_OFFSET_Y + 211), 320, 33 }; + vecSelDlgItems.push_back(new UiArtText("Select Hero", rect1, UIS_CENTER | UIS_BIG)); + + selhero_FreeListItems(); + const size_t num_viewport_heroes = std::min(selhero_SaveCount + 1, kMaxViewportItems); + for (std::size_t i = 0; i < num_viewport_heroes; i++) { + vecSelHeroDlgItems.push_back(new UiListItem("", -1)); + } + selhero_UpdateViewportItems(); + + vecSelDlgItems.push_back(new UiList(vecSelHeroDlgItems, PANEL_LEFT + 265, (UI_OFFSET_Y + 256), 320, 26, UIS_CENTER | UIS_MED | UIS_GOLD)); + + SDL_Rect rect2 = { (Sint16)(PANEL_LEFT + 585), (Sint16)(UI_OFFSET_Y + 244), 25, 178 }; + UiScrollBar *scrollBar = new UiScrollBar(&ArtScrollBarBackground, &ArtScrollBarThumb, &ArtScrollBarArrow, rect2); + vecSelDlgItems.push_back(scrollBar); + + SDL_Rect rect3 = { (Sint16)(PANEL_LEFT + 239), (Sint16)(UI_OFFSET_Y + 429), 120, 35 }; + vecSelDlgItems.push_back(new UiArtTextButton("OK", &UiFocusNavigationSelect, rect3, UIS_CENTER | UIS_BIG | UIS_GOLD)); + + SDL_Rect rect4 = { (Sint16)(PANEL_LEFT + 364), (Sint16)(UI_OFFSET_Y + 429), 120, 35 }; + SELLIST_DIALOG_DELETE_BUTTON = new UiArtTextButton("Delete", &selhero_UiFocusNavigationYesNo, rect4, UIS_CENTER | UIS_BIG | UIS_DISABLED); + vecSelDlgItems.push_back(SELLIST_DIALOG_DELETE_BUTTON); + + SDL_Rect rect5 = { (Sint16)(PANEL_LEFT + 489), (Sint16)(UI_OFFSET_Y + 429), 120, 35 }; + vecSelDlgItems.push_back(new UiArtTextButton("Cancel", &UiFocusNavigationEsc, rect5, UIS_CENTER | UIS_BIG | UIS_GOLD)); + + 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"); + } else { + strcpy(title, "Single Player Characters"); + } +} + +static void UiSelHeroDialog( + bool (*fninfo)(bool (*fninfofunc)(_uiheroinfo *)), + bool (*fncreate)(_uiheroinfo *), + void (*fnstats)(unsigned int, _uidefaultstats *), + bool (*fnremove)(_uiheroinfo *), + _selhero_selections *dlgresult, + char (*name)[16]) +{ + bUIElementsLoaded = true; + + do { + gfnHeroInfo = fninfo; + gfnHeroCreate = fncreate; + gfnHeroStats = fnstats; + selhero_result = *dlgresult; + + selhero_navigateYesNo = false; + + selhero_Init(); + + if (selhero_SaveCount) { + selhero_List_Init(); + } else { + selhero_List_Select(selhero_SaveCount); + } + + selhero_endMenu = false; + while (!selhero_endMenu && !selhero_navigateYesNo) { + UiClearScreen(); + UiRenderItems(vecSelHeroDialog); + UiPollAndRender(); + } + selhero_Free(); + + if (selhero_navigateYesNo) { + char dialogTitle[32]; + char dialogText[256]; + if (selhero_isMultiPlayer) { + strncpy(dialogTitle, "Delete Multi Player Hero", sizeof(dialogTitle) - 1); + } else { + strncpy(dialogTitle, "Delete Single Player Hero", sizeof(dialogTitle) - 1); + } + snprintf(dialogText, sizeof(dialogText), "Are you sure you want to delete the character \"%s\"?", selhero_heroInfo.name); + + if (UiSelHeroYesNoDialog(dialogTitle, dialogText)) + fnremove(&selhero_heroInfo); + } + } while (selhero_navigateYesNo); + + *dlgresult = selhero_result; + strncpy(*name, selhero_heroInfo.name, sizeof(*name)); +} + +void UiSelHeroSingDialog( + bool (*fninfo)(bool (*fninfofunc)(_uiheroinfo *)), + bool (*fncreate)(_uiheroinfo *), + bool (*fnremove)(_uiheroinfo *), + void (*fnstats)(unsigned int, _uidefaultstats *), + _selhero_selections *dlgresult, + char (*name)[16], + _difficulty *difficulty) +{ + selhero_isMultiPlayer = false; + UiSelHeroDialog(fninfo, fncreate, fnstats, fnremove, dlgresult, name); + *difficulty = nDifficulty; +} + +void UiSelHeroMultDialog( + bool (*fninfo)(bool (*fninfofunc)(_uiheroinfo *)), + bool (*fncreate)(_uiheroinfo *), + bool (*fnremove)(_uiheroinfo *), + void (*fnstats)(unsigned int, _uidefaultstats *), + _selhero_selections *dlgresult, + char (*name)[16]) +{ + selhero_isMultiPlayer = true; + UiSelHeroDialog(fninfo, fncreate, fnstats, fnremove, dlgresult, name); +} + } // namespace devilution diff --git a/Source/DiabloUI/selhero.h b/Source/DiabloUI/selhero.h index 089ab3621..6c2c93ee4 100644 --- a/Source/DiabloUI/selhero.h +++ b/Source/DiabloUI/selhero.h @@ -9,17 +9,5 @@ extern bool selhero_endMenu; void selhero_Init(); void selhero_List_Init(); -void selhero_List_Focus(int value); -void selhero_List_Select(int value); -bool selhero_List_DeleteYesNo(); -void selhero_List_Esc(); -void selhero_ClassSelector_Focus(int value); -void selhero_ClassSelector_Select(int value); -void selhero_ClassSelector_Esc(); -void selhero_UiFocusNavigationYesNo(); -void selhero_Name_Select(int value); -void selhero_Name_Esc(); -void selhero_Load_Focus(int value); -void selhero_Load_Select(int value); } // namespace devilution