Browse Source

Full "Delete Hero" implementation

pull/197/head
danellos 7 years ago committed by Anders Jenbo
parent
commit
0f9fc228ce
  1. 1
      CMakeLists.txt
  2. 10
      SourceX/DiabloUI/diabloui.cpp
  3. 3
      SourceX/DiabloUI/diabloui.h
  4. 142
      SourceX/DiabloUI/selhero.cpp
  5. 1
      SourceX/DiabloUI/selhero.h
  6. 74
      SourceX/DiabloUI/selyesno.cpp
  7. 12
      SourceX/DiabloUI/selyesno.h
  8. 10
      SourceX/miniwin/misc.cpp

1
CMakeLists.txt

@ -206,6 +206,7 @@ add_executable(devilutionx
SourceX/DiabloUI/selconn.cpp SourceX/DiabloUI/selconn.cpp
SourceX/DiabloUI/selgame.cpp SourceX/DiabloUI/selgame.cpp
SourceX/DiabloUI/selhero.cpp SourceX/DiabloUI/selhero.cpp
SourceX/DiabloUI/selyesno.cpp
SourceX/DiabloUI/title.cpp SourceX/DiabloUI/title.cpp
SourceX/main.cpp) SourceX/main.cpp)

10
SourceX/DiabloUI/diabloui.cpp

@ -23,6 +23,7 @@ void (*gfnSoundFunction)(char *file);
void (*gfnListFocus)(int value); void (*gfnListFocus)(int value);
void (*gfnListSelect)(int value); void (*gfnListSelect)(int value);
void (*gfnListEsc)(); void (*gfnListEsc)();
void (*gfnListConfirm)(int value);
UI_Item *gUiItems; UI_Item *gUiItems;
int gUiItemCnt; int gUiItemCnt;
bool UiItemsWraps; bool UiItemsWraps;
@ -138,7 +139,7 @@ void UiDestroy()
font = NULL; font = NULL;
} }
void UiInitList(int min, int max, void (*fnFocus)(int value), void (*fnSelect)(int value), void (*fnEsc)(), UI_Item *items, int itemCnt, bool itemsWraps) void UiInitList(int min, int max, void (*fnFocus)(int value), void (*fnSelect)(int value), void (*fnEsc)(), UI_Item *items, int itemCnt, bool itemsWraps, void (*fnConfirm)(int value))
{ {
SelectedItem = min; SelectedItem = min;
SelectedItemMin = min; SelectedItemMin = min;
@ -146,6 +147,7 @@ void UiInitList(int min, int max, void (*fnFocus)(int value), void (*fnSelect)(i
gfnListFocus = fnFocus; gfnListFocus = fnFocus;
gfnListSelect = fnSelect; gfnListSelect = fnSelect;
gfnListEsc = fnEsc; gfnListEsc = fnEsc;
gfnListConfirm = fnConfirm;
gUiItems = items; gUiItems = items;
gUiItemCnt = itemCnt; gUiItemCnt = itemCnt;
UiItemsWraps = itemsWraps; UiItemsWraps = itemsWraps;
@ -307,6 +309,12 @@ void UiFocusNavigationEsc()
gfnListEsc(); gfnListEsc();
} }
void UiFocusNavigationConfirm()
{
if (gfnListConfirm)
gfnListConfirm(SelectedItem);
}
bool IsInsideRect(const SDL_Event *event, const SDL_Rect *rect) bool IsInsideRect(const SDL_Event *event, const SDL_Rect *rect)
{ {
const SDL_Point point = { event->button.x, event->button.y }; const SDL_Point point = { event->button.x, event->button.y };

3
SourceX/DiabloUI/diabloui.h

@ -110,7 +110,8 @@ void LoadMaskedArtFont(char *pszFile, Art *art, int frames, int mask = 250);
void SetMenu(int MenuId); void SetMenu(int MenuId);
void UiFocusNavigationSelect(); void UiFocusNavigationSelect();
void UiFocusNavigationEsc(); void UiFocusNavigationEsc();
void UiInitList(int min, int max, void(*fnFocus)(int value), void(*fnSelect)(int value), void(*fnEsc)(), UI_Item *items, int size, bool wraps = false); void UiFocusNavigationConfirm();
void UiInitList(int min, int max, void (*fnFocus)(int value), void (*fnSelect)(int value), void (*fnEsc)(), UI_Item *items, int size, bool wraps = false, void (*fcConfirm)(int value) = NULL);
void UiRender(); void UiRender();
void UiRenderItems(UI_Item *items, int size); void UiRenderItems(UI_Item *items, int size);
void WordWrap(UI_Item *item); void WordWrap(UI_Item *item);

142
SourceX/DiabloUI/selhero.cpp

@ -1,13 +1,14 @@
#include "selhero.h" #include "selhero.h"
#include "selyesno.h"
#include "devilution.h"
#include "DiabloUI/diabloui.h" #include "DiabloUI/diabloui.h"
#include "devilution.h"
namespace dvl { namespace dvl {
int selhero_SaveCount = 0; int selhero_SaveCount = 0;
_uiheroinfo heros[MAX_CHARACTERS]; _uiheroinfo selhero_heros[MAX_CHARACTERS];
_uiheroinfo heroInfo; _uiheroinfo selhero_heroInfo;
char listItems[6][16]; char listItems[6][16];
char textStats[5][4]; char textStats[5][4];
char title[32]; char title[32];
@ -16,11 +17,14 @@ char selhero_Description[256];
int selhero_result; int selhero_result;
bool selhero_endMenu; bool selhero_endMenu;
bool isMultiPlayer; bool isMultiPlayer;
bool navigateConfirm;
BOOL(*gfnHeroStats) BOOL(*gfnHeroStats)
(unsigned int, _uidefaultstats *); (unsigned int, _uidefaultstats *);
BOOL(*gfnHeroCreate) BOOL(*gfnHeroCreate)
(_uiheroinfo *); (_uiheroinfo *);
BOOL(*gfnHeroDelete)
(_uiheroinfo *);
UI_Item SELHERO_DIALOG[] = { UI_Item SELHERO_DIALOG[] = {
{ { 0, 0, 640, 480 }, UI_IMAGE, 0, 0, NULL, &ArtBackground }, { { 0, 0, 640, 480 }, UI_IMAGE, 0, 0, NULL, &ArtBackground },
@ -47,7 +51,7 @@ UI_Item SELLIST_DIALOG[] = {
{ { 265, 360, 320, 26 }, UI_LIST, UIS_CENTER | UIS_MED | UIS_GOLD, 4, listItems[4] }, { { 265, 360, 320, 26 }, UI_LIST, UIS_CENTER | UIS_MED | UIS_GOLD, 4, listItems[4] },
{ { 265, 386, 320, 26 }, UI_LIST, UIS_CENTER | UIS_MED | UIS_GOLD, 5, listItems[5] }, { { 265, 386, 320, 26 }, UI_LIST, UIS_CENTER | UIS_MED | UIS_GOLD, 5, listItems[5] },
{ { 239, 429, 120, 35 }, UI_BUTTON, UIS_CENTER | UIS_BIG | UIS_GOLD, 0, "OK", (void *)UiFocusNavigationSelect }, { { 239, 429, 120, 35 }, UI_BUTTON, UIS_CENTER | UIS_BIG | UIS_GOLD, 0, "OK", (void *)UiFocusNavigationSelect },
{ { 364, 429, 120, 35 }, UI_BUTTON, UIS_CENTER | UIS_BIG | UIS_DISABLED, 0, "Delete" }, { { 364, 429, 120, 35 }, UI_BUTTON, UIS_CENTER | UIS_BIG | UIS_DISABLED, 0, "Delete", (void *)UiFocusNavigationConfirm },
{ { 489, 429, 120, 35 }, UI_BUTTON, UIS_CENTER | UIS_BIG | UIS_GOLD, 0, "Cancel", (void *)UiFocusNavigationEsc }, { { 489, 429, 120, 35 }, UI_BUTTON, UIS_CENTER | UIS_BIG | UIS_GOLD, 0, "Cancel", (void *)UiFocusNavigationEsc },
}; };
@ -62,7 +66,7 @@ UI_Item SELCLASS_DIALOG[] = {
UI_Item ENTERNAME_DIALOG[] = { UI_Item ENTERNAME_DIALOG[] = {
{ { 264, 211, 320, 33 }, UI_TEXT, UIS_CENTER | UIS_BIG, 0, "Enter Name" }, { { 264, 211, 320, 33 }, UI_TEXT, UIS_CENTER | UIS_BIG, 0, "Enter Name" },
{ { 265, 317, 320, 33 }, UI_EDIT, UIS_LIST | UIS_MED | UIS_GOLD, 15, heroInfo.name }, { { 265, 317, 320, 33 }, UI_EDIT, UIS_LIST | UIS_MED | UIS_GOLD, 15, selhero_heroInfo.name },
{ { 279, 429, 140, 35 }, UI_BUTTON, UIS_CENTER | UIS_BIG | UIS_GOLD, 0, "OK", (void *)UiFocusNavigationSelect }, { { 279, 429, 140, 35 }, UI_BUTTON, UIS_CENTER | UIS_BIG | UIS_GOLD, 0, "OK", (void *)UiFocusNavigationSelect },
{ { 429, 429, 140, 35 }, UI_BUTTON, UIS_CENTER | UIS_BIG | UIS_GOLD, 0, "Cancel", (void *)UiFocusNavigationEsc }, { { 429, 429, 140, 35 }, UI_BUTTON, UIS_CENTER | UIS_BIG | UIS_GOLD, 0, "Cancel", (void *)UiFocusNavigationEsc },
}; };
@ -84,20 +88,20 @@ void selhero_Free()
void selhero_SetStats() void selhero_SetStats()
{ {
SELHERO_DIALOG[2].value = heroInfo.heroclass; SELHERO_DIALOG[2].value = selhero_heroInfo.heroclass;
sprintf(textStats[0], "%d", heroInfo.level); sprintf(textStats[0], "%d", selhero_heroInfo.level);
sprintf(textStats[1], "%d", heroInfo.strength); sprintf(textStats[1], "%d", selhero_heroInfo.strength);
sprintf(textStats[2], "%d", heroInfo.magic); sprintf(textStats[2], "%d", selhero_heroInfo.magic);
sprintf(textStats[3], "%d", heroInfo.dexterity); sprintf(textStats[3], "%d", selhero_heroInfo.dexterity);
sprintf(textStats[4], "%d", heroInfo.vitality); sprintf(textStats[4], "%d", selhero_heroInfo.vitality);
} }
void selhero_List_Init() void selhero_List_Init()
{ {
UiInitList(0, selhero_SaveCount, selhero_List_Focus, selhero_List_Select, selhero_List_Esc, SELLIST_DIALOG, size(SELLIST_DIALOG)); UiInitList(0, selhero_SaveCount, selhero_List_Focus, selhero_List_Select, selhero_List_Esc, SELLIST_DIALOG, size(SELLIST_DIALOG), false, selhero_List_DeleteConfirm);
int i; int i;
for (i = 0; i < selhero_SaveCount && i < 6; i++) { for (i = 0; i < selhero_SaveCount && i < 6; i++) {
sprintf(listItems[i], heros[i].name); sprintf(listItems[i], selhero_heros[i].name);
} }
if (i < 6) if (i < 6)
sprintf(listItems[i], "New Hero"); sprintf(listItems[i], "New Hero");
@ -110,9 +114,11 @@ void selhero_List_Init()
void selhero_List_Focus(int value) void selhero_List_Focus(int value)
{ {
int baseFlags = UIS_CENTER | UIS_BIG;
if (selhero_SaveCount && value < selhero_SaveCount) { if (selhero_SaveCount && value < selhero_SaveCount) {
memcpy(&heroInfo, &heros[value], sizeof(heroInfo)); memcpy(&selhero_heroInfo, &selhero_heros[value], sizeof(selhero_heroInfo));
selhero_SetStats(); selhero_SetStats();
SELLIST_DIALOG[8].flags = baseFlags | UIS_GOLD;
return; return;
} }
@ -122,19 +128,25 @@ void selhero_List_Focus(int value)
sprintf(textStats[2], "--"); sprintf(textStats[2], "--");
sprintf(textStats[3], "--"); sprintf(textStats[3], "--");
sprintf(textStats[4], "--"); sprintf(textStats[4], "--");
SELLIST_DIALOG[8].flags = baseFlags | UIS_DISABLED;
}
void selhero_List_DeleteConfirm(int value)
{
navigateConfirm = true;
} }
void selhero_List_Select(int value) void selhero_List_Select(int value)
{ {
if (value == selhero_SaveCount) { if (value == selhero_SaveCount) {
UiInitList(0, 2, selhero_ClassSelector_Focus, selhero_ClassSelector_Select, selhero_ClassSelector_Esc, SELCLASS_DIALOG, size(SELCLASS_DIALOG)); UiInitList(0, 2, selhero_ClassSelector_Focus, selhero_ClassSelector_Select, selhero_ClassSelector_Esc, SELCLASS_DIALOG, size(SELCLASS_DIALOG));
memset(&heroInfo.name, 0, sizeof(heroInfo.name)); memset(&selhero_heroInfo.name, 0, sizeof(selhero_heroInfo.name));
sprintf(title, "New Single Player Hero"); sprintf(title, "New Single Player Hero");
if (isMultiPlayer) { if (isMultiPlayer) {
sprintf(title, "New Multi Player Hero"); sprintf(title, "New Multi Player Hero");
} }
return; return;
} else if (heroInfo.hassaved) { } else if (selhero_heroInfo.hassaved) {
UiInitList(0, 1, selhero_Load_Focus, selhero_Load_Select, selhero_List_Init, SELLOAD_DIALOG, size(SELLOAD_DIALOG), true); UiInitList(0, 1, selhero_Load_Focus, selhero_Load_Select, selhero_List_Init, SELLOAD_DIALOG, size(SELLOAD_DIALOG), true);
sprintf(title, "Single Player Characters"); sprintf(title, "Single Player Characters");
return; return;
@ -156,12 +168,12 @@ void selhero_ClassSelector_Focus(int value)
_uidefaultstats defaults; _uidefaultstats defaults;
gfnHeroStats(value, &defaults); gfnHeroStats(value, &defaults);
heroInfo.level = 1; selhero_heroInfo.level = 1;
heroInfo.heroclass = value; selhero_heroInfo.heroclass = value;
heroInfo.strength = defaults.strength; selhero_heroInfo.strength = defaults.strength;
heroInfo.magic = defaults.magic; selhero_heroInfo.magic = defaults.magic;
heroInfo.dexterity = defaults.dexterity; selhero_heroInfo.dexterity = defaults.dexterity;
heroInfo.vitality = defaults.vitality; selhero_heroInfo.vitality = defaults.vitality;
selhero_SetStats(); selhero_SetStats();
} }
@ -172,7 +184,7 @@ void selhero_ClassSelector_Select(int value)
if (isMultiPlayer) { if (isMultiPlayer) {
sprintf(title, "New Multi Player Hero"); sprintf(title, "New Multi Player Hero");
} }
memset(heroInfo.name, '\0', sizeof(heroInfo.name)); memset(selhero_heroInfo.name, '\0', sizeof(selhero_heroInfo.name));
UiInitList(0, 0, NULL, selhero_Name_Select, selhero_Name_Esc, ENTERNAME_DIALOG, size(ENTERNAME_DIALOG)); UiInitList(0, 0, NULL, selhero_Name_Select, selhero_Name_Esc, ENTERNAME_DIALOG, size(ENTERNAME_DIALOG));
} }
@ -189,7 +201,7 @@ void selhero_ClassSelector_Esc()
void selhero_Name_Select(int value) void selhero_Name_Select(int value)
{ {
UiInitList(0, 0, NULL, NULL, NULL, NULL, 0); UiInitList(0, 0, NULL, NULL, NULL, NULL, 0);
gfnHeroCreate(&heroInfo); gfnHeroCreate(&selhero_heroInfo);
selhero_endMenu = true; selhero_endMenu = true;
} }
@ -216,71 +228,81 @@ void selhero_Load_Select(int value)
BOOL SelHero_GetHeroInfo(_uiheroinfo *pInfo) BOOL SelHero_GetHeroInfo(_uiheroinfo *pInfo)
{ {
heros[selhero_SaveCount] = *pInfo; selhero_heros[selhero_SaveCount] = *pInfo;
selhero_SaveCount++; selhero_SaveCount++;
return true; return true;
} }
BOOL UiSelHeroDialog( BOOL UiSelHeroDialog(
BOOL(*fninfo)(BOOL(*fninfofunc)(_uiheroinfo *)), BOOL (*fninfo)(BOOL (*fninfofunc)(_uiheroinfo *)),
BOOL(*fncreate)(_uiheroinfo *), BOOL (*fncreate)(_uiheroinfo *),
BOOL(*fnstats)(unsigned int, _uidefaultstats *), BOOL (*fnstats)(unsigned int, _uidefaultstats *),
BOOL (*fnremove)(_uiheroinfo *),
int *dlgresult, int *dlgresult,
char *name) char *name)
{ {
selhero_result = *dlgresult; do {
gfnHeroStats = fnstats; selhero_result = *dlgresult;
gfnHeroCreate = fncreate; gfnHeroStats = fnstats;
LoadBackgroundArt("ui_art\\selhero.pcx"); gfnHeroCreate = fncreate;
gfnHeroDelete = fnremove;
selhero_SaveCount = 0; LoadBackgroundArt("ui_art\\selhero.pcx");
fninfo(SelHero_GetHeroInfo);
navigateConfirm = false;
if (selhero_SaveCount) {
selhero_List_Init(); selhero_SaveCount = 0;
} else { fninfo(SelHero_GetHeroInfo);
selhero_List_Select(selhero_SaveCount);
} if (selhero_SaveCount) {
selhero_List_Init();
} else {
selhero_List_Select(selhero_SaveCount);
}
selhero_endMenu = false; selhero_endMenu = false;
while (!selhero_endMenu) { while (!selhero_endMenu && !navigateConfirm) {
UiRenderItems(SELHERO_DIALOG, size(SELHERO_DIALOG)); UiRenderItems(SELHERO_DIALOG, size(SELHERO_DIALOG));
UiRender(); UiRender();
} }
BlackPalette(); BlackPalette();
selhero_Free(); selhero_Free();
strcpy(name, heroInfo.name); if (navigateConfirm) {
if (!UiSelHeroDelYesNoDialog(gfnHeroDelete, &selhero_heroInfo, isMultiPlayer))
app_fatal("Unable to load Yes/No dialog");
}
} while (navigateConfirm);
*dlgresult = selhero_result; *dlgresult = selhero_result;
strcpy(name, selhero_heroInfo.name);
return true; return true;
} }
BOOL UiSelHeroSingDialog( BOOL UiSelHeroSingDialog(
BOOL(*fninfo)(BOOL(*fninfofunc)(_uiheroinfo *)), BOOL (*fninfo)(BOOL (*fninfofunc)(_uiheroinfo *)),
BOOL(*fncreate)(_uiheroinfo *), BOOL (*fncreate)(_uiheroinfo *),
BOOL(*fnremove)(_uiheroinfo *), BOOL (*fnremove)(_uiheroinfo *),
BOOL(*fnstats)(unsigned int, _uidefaultstats *), BOOL (*fnstats)(unsigned int, _uidefaultstats *),
int *dlgresult, int *dlgresult,
char *name, char *name,
int *difficulty) int *difficulty)
{ {
isMultiPlayer = false; isMultiPlayer = false;
return UiSelHeroDialog(fninfo, fncreate, fnstats, dlgresult, name); return UiSelHeroDialog(fninfo, fncreate, fnstats, fnremove, dlgresult, name);
} }
BOOL UiSelHeroMultDialog( BOOL UiSelHeroMultDialog(
BOOL(*fninfo)(BOOL(*fninfofunc)(_uiheroinfo *)), BOOL (*fninfo)(BOOL (*fninfofunc)(_uiheroinfo *)),
BOOL(*fncreate)(_uiheroinfo *), BOOL (*fncreate)(_uiheroinfo *),
BOOL(*fnremove)(_uiheroinfo *), BOOL (*fnremove)(_uiheroinfo *),
BOOL(*fnstats)(unsigned int, _uidefaultstats *), BOOL (*fnstats)(unsigned int, _uidefaultstats *),
int *dlgresult, int *dlgresult,
BOOL *hero_is_created, BOOL *hero_is_created,
char *name) char *name)
{ {
isMultiPlayer = true; isMultiPlayer = true;
return UiSelHeroDialog(fninfo, fncreate, fnstats, dlgresult, name); return UiSelHeroDialog(fninfo, fncreate, fnstats, fnremove, dlgresult, name);
} }
} }

1
SourceX/DiabloUI/selhero.h

@ -5,6 +5,7 @@ namespace dvl {
void selhero_List_Init(); void selhero_List_Init();
void selhero_List_Focus(int value); void selhero_List_Focus(int value);
void selhero_List_Select(int value); void selhero_List_Select(int value);
void selhero_List_DeleteConfirm(int value);
void selhero_List_Esc(); void selhero_List_Esc();
void selhero_ClassSelector_Focus(int value); void selhero_ClassSelector_Focus(int value);
void selhero_ClassSelector_Select(int value); void selhero_ClassSelector_Select(int value);

74
SourceX/DiabloUI/selyesno.cpp

@ -0,0 +1,74 @@
#include "selyesno.h"
#include "diablo.h"
#include "diabloui.h"
namespace dvl {
_uiheroinfo selyesno_heroInfo;
int selyesno_endMenu;
BOOL(*selyesno_gfnRemove)
(_uiheroinfo *);
char confirmationMessage[256];
char selyesno_title[32];
UI_Item DEL_SELYESNO_DIALOG[] = {
{ { 0, 0, 640, 480 }, UI_IMAGE, 0, 0, NULL, &ArtBackground },
{ { 24, 161, 590, 35 }, UI_TEXT, UIS_CENTER | UIS_BIG, 0, selyesno_title },
{ { 100, 230, 280, 270 }, UI_TEXT, UIS_BIG, 0, confirmationMessage },
{ { 230, 390, 180, 35 }, UI_LIST, UIS_CENTER | UIS_BIG | UIS_GOLD, 1, "Yes" },
{ { 230, 426, 180, 35 }, UI_LIST, UIS_CENTER | UIS_BIG | UIS_GOLD, 0, "No" },
};
void selyesno_Free()
{
mem_free_dbg(ArtBackground.data);
ArtBackground.data = NULL;
}
void selyesno_Select(int value)
{
if (value == 1)
selyesno_gfnRemove(&selyesno_heroInfo);
selyesno_endMenu = true;
}
void selyesno_Esc()
{
selyesno_endMenu = true;
}
BOOL UiSelHeroDelYesNoDialog(
BOOL (*fnremove)(_uiheroinfo *),
_uiheroinfo *selectHero,
bool isMultiplayer)
{
selyesno_heroInfo = *selectHero;
selyesno_gfnRemove = fnremove;
LoadBackgroundArt("ui_art\\black.pcx");
if (isMultiplayer) {
sprintf(selyesno_title, "Delete Multiplayer Hero");
} else {
sprintf(selyesno_title, "Delete Single Player Hero");
}
sprintf(confirmationMessage, "Are you sure you want to delete the character \"%s\"?", selyesno_heroInfo.name);
WordWrap(&DEL_SELYESNO_DIALOG[2]);
UiInitList(0, 1, NULL, selyesno_Select, selyesno_Esc, DEL_SELYESNO_DIALOG, size(DEL_SELYESNO_DIALOG), false, NULL);
selyesno_endMenu = false;
while (!selyesno_endMenu) {
UiRenderItems(DEL_SELYESNO_DIALOG, size(DEL_SELYESNO_DIALOG));
UiRender();
}
BlackPalette();
selyesno_Free();
return true;
}
}

12
SourceX/DiabloUI/selyesno.h

@ -0,0 +1,12 @@
#pragma once
#include "diablo.h"
#include "diabloui.h"
namespace dvl {
BOOL UiSelHeroDelYesNoDialog(BOOL (*fnremove)(_uiheroinfo *), _uiheroinfo *selectHero, bool isMultiplayer);
void selyesno_Free();
void selyesno_Select(int value);
void selyesno_Esc();
}

10
SourceX/miniwin/misc.cpp

@ -227,7 +227,14 @@ UINT GetDriveTypeA(LPCSTR lpRootPathName)
WINBOOL DeleteFileA(LPCSTR lpFileName) WINBOOL DeleteFileA(LPCSTR lpFileName)
{ {
UNIMPLEMENTED(); FILE *f = fopen(lpFileName, "r+");
if (f) {
fclose(f);
remove(lpFileName);
f = NULL;
}
return true; return true;
} }
@ -798,5 +805,4 @@ void __debugbreak()
{ {
DUMMY(); DUMMY();
} }
} }

Loading…
Cancel
Save