From 95b7380ae9b7309a5e67f90c4603eb4e33ccbaba Mon Sep 17 00:00:00 2001 From: obligaron Date: Tue, 19 Oct 2021 22:50:06 +0200 Subject: [PATCH] Startup game (diablo or hellfire) can be selected. --- CMakeLists.txt | 1 + Source/DiabloUI/diabloui.cpp | 5 ++- Source/DiabloUI/diabloui.h | 2 +- Source/DiabloUI/selstart.cpp | 80 ++++++++++++++++++++++++++++++++++++ Source/DiabloUI/selstart.h | 7 ++++ Source/diablo.cpp | 13 +++++- Source/options.cpp | 2 + Source/options.h | 8 ++++ 8 files changed, 114 insertions(+), 4 deletions(-) create mode 100644 Source/DiabloUI/selstart.cpp create mode 100644 Source/DiabloUI/selstart.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 64906fab4..5ba046e85 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -465,6 +465,7 @@ set(libdevilutionx_SRCS Source/DiabloUI/selgame.cpp Source/DiabloUI/selhero.cpp Source/DiabloUI/selok.cpp + Source/DiabloUI/selstart.cpp Source/DiabloUI/selyesno.cpp Source/DiabloUI/support_lines.cpp Source/DiabloUI/title.cpp diff --git a/Source/DiabloUI/diabloui.cpp b/Source/DiabloUI/diabloui.cpp index 98f69ed1e..c770e1c61 100644 --- a/Source/DiabloUI/diabloui.cpp +++ b/Source/DiabloUI/diabloui.cpp @@ -537,6 +537,7 @@ void UnloadUiGFX() void UiInitialize() { + UnloadUiGFX(); LoadUiGFX(); if (ArtCursor.surface != nullptr) { @@ -597,7 +598,7 @@ Sint16 GetCenterOffset(Sint16 w, Sint16 bw) return (bw - w) / 2; } -void LoadBackgroundArt(const char *pszFile, int frames) +void LoadBackgroundArt(const char *pszFile, int frames, bool withFading) { SDL_Color pPal[256]; LoadArt(pszFile, &ArtBackground, frames, pPal); @@ -608,7 +609,7 @@ void LoadBackgroundArt(const char *pszFile, int frames) ApplyGamma(logical_palette, orig_palette, 256); fadeTc = 0; - fadeValue = 0; + fadeValue = withFading ? 0 : 256; if (IsHardwareCursorEnabled() && ArtCursor.surface != nullptr && GetCurrentCursorInfo().type() != CursorType::UserInterface) { #if SDL_VERSION_ATLEAST(2, 0, 0) diff --git a/Source/DiabloUI/diabloui.h b/Source/DiabloUI/diabloui.h index 02f7fe0f7..556b71fe0 100644 --- a/Source/DiabloUI/diabloui.h +++ b/Source/DiabloUI/diabloui.h @@ -113,7 +113,7 @@ bool UiItemMouseEvents(SDL_Event *event, const std::vector> *vecDialog); void UiAddLogo(std::vector> *vecDialog, int size = LOGO_MED, int y = 0); void UiFocusNavigationSelect(); diff --git a/Source/DiabloUI/selstart.cpp b/Source/DiabloUI/selstart.cpp new file mode 100644 index 000000000..a8883c442 --- /dev/null +++ b/Source/DiabloUI/selstart.cpp @@ -0,0 +1,80 @@ +#include "selstart.h" + +#include "control.h" +#include "DiabloUI/diabloui.h" +#include "options.h" +#include "utils/language.h" + +namespace devilution { +namespace { + +bool endMenu; + +std::vector> vecDialogItems; +std::vector> vecDialog; + +Art artLogo; + +void ItemSelected(int value) +{ + auto option = static_cast(vecDialogItems[value]->m_value); + sgOptions.Hellfire.startUpGameOption = option; + gbIsHellfire = option == StartUpGameOption::Hellfire; + endMenu = true; +} + +void EscPressed() +{ + endMenu = true; +} + +void FocusChanged(int value) +{ + auto option = static_cast(vecDialogItems[value]->m_value); + gbIsHellfire = option == StartUpGameOption::Hellfire; + ArtBackground.Unload(); + ArtBackgroundWidescreen.Unload(); + LoadBackgroundArt("ui_art\\mainmenu.pcx", 1, false); + SetFadeLevel(256); + artLogo.Unload(); + if (gbIsHellfire) { + LoadArt("ui_art\\mainmenuw.pcx", &ArtBackgroundWidescreen); + LoadMaskedArt("ui_art\\hf_logo2.pcx", &artLogo, 16); + } else { + LoadMaskedArt("ui_art\\smlogo.pcx", &artLogo, 15); + } + gbIsHellfire = true; +} + +} // namespace + +void UiSelStartUpGameOption() +{ + LoadArt("ui_art\\mainmenuw.pcx", &ArtBackgroundWidescreen); + LoadBackgroundArt("ui_art\\mainmenu.pcx"); + UiAddBackground(&vecDialog); + + SDL_Rect rect = { 0, (Sint16)(UI_OFFSET_Y), 0, 0 }; + vecDialog.push_back(std::make_unique(&artLogo, rect, UiFlags::AlignCenter, /*bAnimated=*/true)); + + vecDialogItems.push_back(std::make_unique(_("Enter Hellfire"), static_cast(StartUpGameOption::Hellfire))); + vecDialogItems.push_back(std::make_unique(_("Switch to Diablo"), static_cast(StartUpGameOption::Diablo))); + vecDialog.push_back(std::make_unique(vecDialogItems, PANEL_LEFT + 64, (UI_OFFSET_Y + 240), 510, 43, UiFlags::AlignCenter | UiFlags::FontSize42 | UiFlags::ColorUiGold, 5)); + + UiInitList(vecDialogItems.size(), FocusChanged, ItemSelected, EscPressed, vecDialog, true); + + endMenu = false; + while (!endMenu) { + UiClearScreen(); + UiRenderItems(vecDialog); + UiPollAndRender(); + } + + artLogo.Unload(); + ArtBackground.Unload(); + ArtBackgroundWidescreen.Unload(); + vecDialogItems.clear(); + vecDialog.clear(); +} + +} // namespace devilution diff --git a/Source/DiabloUI/selstart.h b/Source/DiabloUI/selstart.h new file mode 100644 index 000000000..b0ab70d43 --- /dev/null +++ b/Source/DiabloUI/selstart.h @@ -0,0 +1,7 @@ +#pragma once + +namespace devilution { + +void UiSelStartUpGameOption(); + +} // namespace devilution diff --git a/Source/diablo.cpp b/Source/diablo.cpp index 2d6801735..5320ed449 100644 --- a/Source/diablo.cpp +++ b/Source/diablo.cpp @@ -74,6 +74,7 @@ #ifdef GPERF_HEAP_FIRST_GAME_ITERATION #include #endif +#include namespace devilution { @@ -910,7 +911,7 @@ void DiabloInit() if (forceSpawn) gbIsSpawn = true; - if (forceDiablo) + if (forceDiablo || sgOptions.Hellfire.startUpGameOption == StartUpGameOption::Diablo) gbIsHellfire = false; gbIsHellfireSaveGame = gbIsHellfire; @@ -936,6 +937,14 @@ void DiabloInit() ReadOnlyTest(); + if (gbIsHellfire && sgOptions.Hellfire.startUpGameOption == StartUpGameOption::None) { + UiSelStartUpGameOption(); + if (!gbIsHellfire) { + // Reinitalize the UI Elements cause we changed the game + UiInitialize(); + } + } + DiabloInitScreen(); snd_init(); @@ -1568,7 +1577,9 @@ int DiabloMain(int argc, char **argv) DiabloParseFlags(argc, argv); InitKeymapActions(); LoadOptions(); + DiabloInit(); + DiabloSplash(); mainmenu_loop(); DiabloDeinit(); diff --git a/Source/options.cpp b/Source/options.cpp index dffaa51f8..d51459a4d 100644 --- a/Source/options.cpp +++ b/Source/options.cpp @@ -220,6 +220,7 @@ void LoadOptions() sgOptions.Hellfire.bIntro = GetIniBool("Hellfire", "Intro", true); sgOptions.Hellfire.lastSinglePlayerHero = GetIniInt("Hellfire", "LastSinglePlayerHero", 0); sgOptions.Hellfire.lastMultiplayerHero = GetIniInt("Hellfire", "LastMultiplayerHero", 0); + sgOptions.Hellfire.startUpGameOption = static_cast(GetIniInt("Hellfire", "StartUpGameOption", static_cast(StartUpGameOption::None))); GetIniValue("Hellfire", "SItem", sgOptions.Hellfire.szItem, sizeof(sgOptions.Hellfire.szItem), ""); sgOptions.Audio.nSoundVolume = GetIniInt("Audio", "Sound Volume", VOLUME_MAX); @@ -375,6 +376,7 @@ void SaveOptions() SetIniValue("Hellfire", "SItem", sgOptions.Hellfire.szItem); SetIniValue("Hellfire", "LastSinglePlayerHero", sgOptions.Hellfire.lastSinglePlayerHero); SetIniValue("Hellfire", "LastMultiplayerHero", sgOptions.Hellfire.lastMultiplayerHero); + SetIniValue("Hellfire", "StartUpGameOption", static_cast(sgOptions.Hellfire.startUpGameOption)); SetIniValue("Audio", "Sound Volume", sgOptions.Audio.nSoundVolume); SetIniValue("Audio", "Music Volume", sgOptions.Audio.nMusicVolume); diff --git a/Source/options.h b/Source/options.h index 2c768fdb1..a8d6581ce 100644 --- a/Source/options.h +++ b/Source/options.h @@ -8,6 +8,12 @@ namespace devilution { +enum class StartUpGameOption { + None, + Hellfire, + Diablo, +}; + struct DiabloOptions { /** @brief Play game intro video on startup. */ bool bIntro; @@ -26,6 +32,8 @@ struct HellfireOptions { std::uint32_t lastSinglePlayerHero; /** @brief Remembers what multiplayer hero/save was last used. */ std::uint32_t lastMultiplayerHero; + + StartUpGameOption startUpGameOption; }; struct AudioOptions {