You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
476 lines
11 KiB
476 lines
11 KiB
#include "../../types.h" |
|
|
|
int selhero_SaveCount = 0; |
|
_uiheroinfo heros[MAX_CHARACTERS]; |
|
_uiheroinfo heroInfo; |
|
|
|
static std::vector<_uiheroinfo> hero_infos; |
|
|
|
static BOOL __stdcall ui_add_hero_info(_uiheroinfo *info) |
|
{ |
|
hero_infos.emplace_back(*info); |
|
return TRUE; |
|
} |
|
|
|
void RenderStats() |
|
{ |
|
char lvl[3] = "--"; |
|
char str[3] = "--"; |
|
char mag[3] = "--"; |
|
char dex[3] = "--"; |
|
char vit[3] = "--"; |
|
|
|
if (heroInfo.heroclass != UI_NUM_CLASSES) { |
|
sprintf(lvl, "%d", heroInfo.level); |
|
sprintf(str, "%d", heroInfo.strength); |
|
sprintf(mag, "%d", heroInfo.magic); |
|
sprintf(dex, "%d", heroInfo.dexterity); |
|
sprintf(vit, "%d", heroInfo.vitality); |
|
} |
|
|
|
PrintText16Silver(31, 323, "Level:", JustRight, 118); |
|
PrintText16Silver(149, 323, lvl, JustCentre, 61); |
|
PrintText16Silver(31, 358, "Strength:", JustRight, 118); |
|
PrintText16Silver(149, 358, str, JustCentre, 61); |
|
PrintText16Silver(31, 380, "Magic:", JustRight, 118); |
|
PrintText16Silver(149, 380, mag, JustCentre, 61); |
|
PrintText16Silver(31, 401, "Dexterity:", JustRight, 118); |
|
PrintText16Silver(149, 401, dex, JustCentre, 61); |
|
PrintText16Silver(31, 422, "Vitality:", JustRight, 118); |
|
PrintText16Silver(149, 422, vit, JustCentre, 61); |
|
} |
|
|
|
void selhero_Render() |
|
{ |
|
heroInfo.heroclass = UI_NUM_CLASSES; |
|
if (SelectedItem <= selhero_SaveCount) { |
|
memcpy(&heroInfo, &heros[SelectedItem - 1], sizeof(heroInfo)); |
|
} |
|
|
|
DrawArtImage(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, pPcxTitleImage); |
|
RenderDiabloLogoSm(); |
|
|
|
PrintText30Silver(-1, 161, "Single Player Characters", JustCentre); |
|
|
|
DrawArtImage(30, 211, gdwHeroWidth, gdwHeroHeight, heroInfo.heroclass, pPcxHeroImage); |
|
RenderStats(); |
|
|
|
int w = 369; |
|
int x = 241; |
|
|
|
PrintText30Silver(x - 1, 211, "Select Hero", JustCentre, w); |
|
|
|
int selectorTop = 256; |
|
int y = selectorTop; |
|
for (int i = 0; i < selhero_SaveCount; i++) { |
|
PrintText24Gold(x - 1, y, heros[i].name, JustCentre, w); |
|
y += 26; |
|
} |
|
PrintText24Gold(x - 1, y, "New Hero", JustCentre, w); |
|
|
|
DrawSelector16(x, selectorTop + 3, w, 32, 26); |
|
|
|
PrintText30Gold(279, 429, "OK"); |
|
PrintText30Gold(378, 429, "Delete"); |
|
PrintText30Gold(501, 429, "Cancel"); |
|
} |
|
|
|
void selhero_Render_DifficultySelection() |
|
{ |
|
DrawArtImage(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, pPcxTitleImage); |
|
RenderDiabloLogoSm(); |
|
|
|
DrawArtImage(30, 211, gdwHeroWidth, gdwHeroHeight, heroInfo.heroclass, pPcxHeroImage); |
|
RenderStats(); |
|
|
|
char *GameOptions[3] = { "Normal", "Nightmare", "Hell" }; |
|
|
|
// this should not be hard coded. |
|
int x = 280; |
|
int y = 256; |
|
|
|
for (int i = 0; i < 3; i++) { |
|
y += 40; |
|
PrintText16Silver(x, y, GameOptions[i]); |
|
} |
|
} |
|
|
|
void selhero_Render_GameType() |
|
{ |
|
DrawArtImage(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, pPcxTitleImage); |
|
RenderDiabloLogoSm(); |
|
|
|
DrawArtImage(30, 211, gdwHeroWidth, gdwHeroHeight, heroInfo.heroclass, pPcxHeroImage); |
|
RenderStats(); |
|
|
|
char *GameOptions[2] = { "New Game", "Load Game" }; |
|
|
|
// this should not be hard coded. |
|
int x = 280; |
|
int y = 256; |
|
|
|
for (int i = 0; i < 2; i++) { |
|
y += 40; |
|
PrintText16Silver(x, y, GameOptions[i]); |
|
} |
|
} |
|
|
|
void selhero_Render_Name() |
|
{ |
|
DrawArtImage(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, pPcxTitleImage); |
|
RenderDiabloLogoSm(); |
|
|
|
DrawArtImage(30, 211, gdwHeroWidth, gdwHeroHeight, heroInfo.heroclass, pPcxHeroImage); |
|
RenderStats(); |
|
|
|
PrintText30Silver(-1, 161, "New Single Player Hero", JustCentre); |
|
|
|
int w = 369; |
|
int x = 241; |
|
int y = 318; |
|
|
|
PrintText30Silver(x - 1, 211, "Enter Name", JustCentre, w); |
|
|
|
DrawSelector(x, y - 2, w, 39, 26); |
|
|
|
char lable[16]; |
|
strcpy(lable, heroInfo.name); |
|
if (GetAnimationFrame(2, 500)) { |
|
lable[strlen(lable)] = '|'; |
|
} |
|
|
|
PrintText24Gold(x + 67, y, lable); // todo add blinking "|" |
|
|
|
PrintText30Gold(329, 429, "OK"); |
|
PrintText30Gold(451, 429, "Cancel"); |
|
} |
|
|
|
// Have this load the function above and then render it in the main menu. |
|
// Cnacel box is also needed. |
|
void selhero_Render_ClassSelector() |
|
{ |
|
DrawArtImage(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, pPcxTitleImage); |
|
RenderDiabloLogoSm(); |
|
|
|
DrawArtImage(30, 211, gdwHeroWidth, gdwHeroHeight, heroInfo.heroclass, pPcxHeroImage); |
|
RenderStats(); |
|
|
|
PrintText30Silver(-1, 161, "New Single Player Hero", JustCentre); |
|
|
|
int w = 369; |
|
int x = 241; |
|
int y = 285; |
|
|
|
PrintText30Silver(x - 1, 211, "Choose Class", JustCentre, w); |
|
|
|
char *heroclasses[3] = { "Warrior", "Rogue", "Sorcerer" }; |
|
|
|
int selectorTop = y; |
|
|
|
for (int i = 0; i < 3; i++) { |
|
if (i > 1) { |
|
y += 1; // "Rouge" and "Sorcerer" has a smaller gap then other items |
|
} |
|
PrintText24Gold(x - 1, y, heroclasses[i], JustCentre, w); |
|
y += 33; |
|
} |
|
|
|
if (SelectedItem > 1) { |
|
selectorTop += 1; // "Rouge" and "Sorcerer" has a smaller gap then other items |
|
} |
|
|
|
DrawSelector(x, selectorTop - 2, w, 39, 33); |
|
|
|
PrintText30Gold(329, 429, "OK"); |
|
PrintText30Gold(451, 429, "Cancel"); |
|
} |
|
|
|
BOOL __stdcall SelHero_GetHeroInfo(_uiheroinfo *pInfo) |
|
{ |
|
heros[selhero_SaveCount] = *pInfo; |
|
selhero_SaveCount++; |
|
|
|
return TRUE; |
|
} |
|
|
|
void selhero_Loade(BOOL(__stdcall *fninfo)(BOOL(__stdcall *fninfofunc)(_uiheroinfo *))) |
|
{ |
|
LoadTitelArt("ui_art\\selhero.pcx"); |
|
|
|
hero_infos.clear(); |
|
fninfo(ui_add_hero_info); |
|
|
|
selhero_SaveCount = 0; |
|
fninfo(SelHero_GetHeroInfo); |
|
|
|
//memset(heroInfo, 0, sizeof(_uiheroinfo)); |
|
heroInfo.heroclass = UI_NUM_CLASSES; |
|
} |
|
|
|
void selhero_Free() |
|
{ |
|
mem_free_dbg(pPcxTitleImage); |
|
pPcxTitleImage = NULL; |
|
} |
|
|
|
void selhero_setDefaultStats(BOOL(__stdcall *fnstats)(unsigned int, _uidefaultstats *)) |
|
{ |
|
_uidefaultstats defaults; |
|
fnstats(SelectedItem - 1, &defaults); |
|
|
|
heroInfo.heroclass = SelectedItem - 1; |
|
heroInfo.strength = defaults.strength; |
|
heroInfo.magic = defaults.magic; |
|
heroInfo.dexterity = defaults.dexterity; |
|
heroInfo.vitality = defaults.vitality; |
|
} |
|
|
|
BOOL __stdcall UiSelHeroSingDialog( |
|
BOOL(__stdcall *fninfo)(BOOL(__stdcall *fninfofunc)(_uiheroinfo *)), |
|
BOOL(__stdcall *fncreate)(_uiheroinfo *), |
|
BOOL(__stdcall *fnremove)(_uiheroinfo *), |
|
BOOL(__stdcall *fnstats)(unsigned int, _uidefaultstats *), |
|
int *dlgresult, |
|
char *name, |
|
int *difficulty) |
|
{ |
|
selhero_Loade(fninfo); |
|
MenuItem[SINGLEPLAYER_LOAD] = 1 + selhero_SaveCount; |
|
|
|
submenu = SINGLEPLAYER_LOAD; |
|
if (!selhero_SaveCount) { |
|
PreviousItem[SINGLEPLAYER_CLASSES] = 0; |
|
submenu = SINGLEPLAYER_CLASSES; |
|
} |
|
|
|
SelectedItem = 1; |
|
SelectedItemMax = MenuItem[submenu]; |
|
|
|
int nameLen; |
|
SDL_Event event; |
|
int x, y; |
|
|
|
*difficulty = gnDifficulty; // BUGFIX this replicates a bug that allowed setting deficulity in SP |
|
|
|
bool endMenu = false; |
|
while (!endMenu) { |
|
CapFPS(); |
|
|
|
switch (submenu) { |
|
case SINGLEPLAYER_LOAD: |
|
selhero_Render(); |
|
break; |
|
case SINGLEPLAYER_CLASSES: |
|
selhero_setDefaultStats(fnstats); |
|
selhero_Render_ClassSelector(); |
|
break; |
|
case SINGLEPLAYER_NAME: |
|
selhero_Render_Name(); |
|
break; |
|
} |
|
|
|
DrawMouse(); |
|
UiFadeIn(); |
|
|
|
while (SDL_PollEvent(&event)) { |
|
switch (event.type) { |
|
case SDL_KEYDOWN: |
|
switch (event.key.keysym.sym) { |
|
case SDLK_ESCAPE: |
|
if (PreviousItem[submenu]) { |
|
SetMenu(PreviousItem[submenu]); |
|
break; |
|
} |
|
|
|
*dlgresult = EXIT_MENU; |
|
endMenu = true; |
|
break; |
|
case SDLK_BACKSPACE: |
|
nameLen = strlen(heroInfo.name); |
|
if (nameLen > 0) { |
|
heroInfo.name[nameLen-1] = '\0'; |
|
} |
|
break; |
|
case SDLK_UP: |
|
SelectedItem--; |
|
if (SelectedItem < 1) { |
|
SelectedItem = SelectedItemMax ? SelectedItemMax : 1; |
|
} |
|
effects_play_sound("sfx\\items\\titlemov.wav"); |
|
break; |
|
case SDLK_DOWN: |
|
SelectedItem++; |
|
if (SelectedItem > SelectedItemMax) { |
|
SelectedItem = 1; |
|
} |
|
effects_play_sound("sfx\\items\\titlemov.wav"); |
|
break; |
|
case SDLK_RETURN: |
|
case SDLK_KP_ENTER: |
|
case SDLK_SPACE: |
|
switch (submenu) { |
|
case SINGLEPLAYER_LOAD: |
|
if (SelectedItem == SelectedItemMax) { |
|
memset(&heroInfo.name, 0, sizeof(heroInfo.name)); |
|
SetMenu(SINGLEPLAYER_CLASSES); |
|
break; |
|
} |
|
|
|
strcpy(name, heroInfo.name); |
|
*dlgresult = LOAD_GAME; |
|
endMenu = true; |
|
break; |
|
case SINGLEPLAYER_CLASSES: |
|
SetMenu(SINGLEPLAYER_NAME); |
|
break; |
|
case SINGLEPLAYER_NAME: |
|
if (!heroInfo.hassaved) { |
|
fncreate(&heroInfo); |
|
} |
|
strcpy(name, heroInfo.name); |
|
endMenu = true; |
|
break; |
|
} |
|
break; |
|
default: |
|
if (submenu != SINGLEPLAYER_NAME) { |
|
break; |
|
} |
|
|
|
char letter = event.key.keysym.sym; |
|
if (int(letter) > 96 && int(letter) < 123 || int(letter) == 32) |
|
nameLen = strlen(heroInfo.name); |
|
if (nameLen < 15) { |
|
heroInfo.name[nameLen] = letter; |
|
} |
|
break; |
|
} |
|
break; |
|
case SDL_QUIT: |
|
exit(0); |
|
} |
|
} |
|
} |
|
|
|
BlackPalette(); |
|
selhero_Free(); |
|
|
|
return TRUE; |
|
} |
|
|
|
BOOL __stdcall UiSelHeroMultDialog( |
|
BOOL(__stdcall *fninfo)(BOOL(__stdcall *fninfofunc)(_uiheroinfo *)), |
|
BOOL(__stdcall *fncreate)(_uiheroinfo *), |
|
BOOL(__stdcall *fnremove)(_uiheroinfo *), |
|
BOOL(__stdcall *fnstats)(unsigned int, _uidefaultstats *), |
|
int *dlgresult, |
|
int *hero_is_created, |
|
char *name) |
|
{ |
|
selhero_Loade(fninfo); |
|
|
|
DUMMY(); |
|
submenu = MULTIPLAYER_LOBBY; |
|
|
|
SelectedItem = 1; |
|
SelectedItemMax = MenuItem[submenu]; |
|
SDL_Event event; |
|
|
|
int endMenu = false; |
|
while (endMenu == false) { |
|
CapFPS(); |
|
|
|
switch (submenu) { |
|
case MULTIPLAYER_LOBBY: |
|
selhero_Render_GameType(); |
|
break; |
|
case MULTIPLAYER_DIFFICULTY: |
|
selhero_Render_DifficultySelection(); |
|
break; |
|
} |
|
|
|
DrawMouse(); |
|
UiFadeIn(); |
|
|
|
while (SDL_PollEvent(&event)) { |
|
switch (event.type) { |
|
case SDL_KEYDOWN: |
|
switch (event.key.keysym.sym) { |
|
case SDLK_ESCAPE: |
|
if (PreviousItem[submenu]) { |
|
SetMenu(PreviousItem[submenu]); |
|
break; |
|
} |
|
|
|
*dlgresult = EXIT_MENU; |
|
return TRUE; |
|
case SDLK_UP: |
|
SelectedItem--; |
|
if (SelectedItem < 1) { |
|
SelectedItem = SelectedItemMax ? SelectedItemMax : 1; |
|
} |
|
effects_play_sound("sfx\\items\\titlemov.wav"); |
|
break; |
|
case SDLK_DOWN: |
|
SelectedItem++; |
|
if (SelectedItem > SelectedItemMax) { |
|
SelectedItem = 1; |
|
} |
|
effects_play_sound("sfx\\items\\titlemov.wav"); |
|
break; |
|
case SDLK_RETURN: |
|
case SDLK_KP_ENTER: |
|
case SDLK_SPACE: |
|
switch (submenu) { |
|
case MULTIPLAYER_LOBBY: |
|
SetMenu(MULTIPLAYER_DIFFICULTY); |
|
break; |
|
case MULTIPLAYER_DIFFICULTY: |
|
strcpy(heroInfo.name, "testname"); |
|
strcpy(name, heroInfo.name); |
|
if (!heroInfo.hassaved) { |
|
fncreate(&heroInfo); |
|
} |
|
*dlgresult = NEW_GAME; |
|
endMenu = true; |
|
break; |
|
} |
|
break; |
|
} |
|
break; |
|
case SDL_MOUSEBUTTONDOWN: |
|
if (event.button.button == SDL_BUTTON_LEFT) { |
|
SDL_Rect CreateHeroCancelBox; |
|
CreateHeroCancelBox.y = 550; |
|
CreateHeroCancelBox.x = 675; |
|
CreateHeroCancelBox.w = 100; |
|
CreateHeroCancelBox.h = 30; |
|
|
|
switch (submenu) { |
|
case MULTIPLAYER_DIFFICULTY: |
|
SDL_Rect NormalSelectBox; |
|
NormalSelectBox.x = 280; |
|
NormalSelectBox.y = 350; |
|
NormalSelectBox.w = 300; |
|
NormalSelectBox.h = 30; |
|
|
|
if (IsInsideRect(&event, &NormalSelectBox)) { |
|
strcpy(name, heroInfo.name); |
|
gnDifficulty = DIFF_NORMAL; |
|
*dlgresult = LOAD_GAME; |
|
} |
|
break; |
|
} |
|
} |
|
break; |
|
case SDL_QUIT: |
|
exit(0); |
|
} |
|
} |
|
} |
|
|
|
BlackPalette(); |
|
selhero_Free(); |
|
|
|
return TRUE; |
|
}
|
|
|