From 72affc3d517eb151d83afe112eb04d5ad4bb6181 Mon Sep 17 00:00:00 2001 From: Gleb Mazovetskiy Date: Thu, 9 Jan 2025 13:18:42 +0000 Subject: [PATCH] More dependency untangling 1. Moves more assets-related stuff from `init` to `engine/assets`. 2. Removes `SDL_audiolib` dependency from `soundsample.h`. 3. Cleans up some unused/missing includes. --- Source/DiabloUI/diabloui.cpp | 1 + Source/DiabloUI/dialogs.cpp | 2 + Source/DiabloUI/hero/selhero.cpp | 7 +- Source/DiabloUI/mainmenu.cpp | 1 + Source/DiabloUI/settingsmenu.cpp | 2 + Source/appfat.cpp | 6 +- Source/appfat.h | 7 + Source/capture.cpp | 2 +- Source/control.cpp | 1 - Source/diablo.cpp | 3 +- Source/diablo.h | 8 +- Source/discord/discord.cpp | 2 +- Source/dvlnet/packet.h | 1 + Source/effects.cpp | 2 +- Source/engine/assets.cpp | 209 +++++++++++++++++++++++++++ Source/engine/assets.hpp | 22 +++ Source/engine/dx.cpp | 1 + Source/engine/palette.h | 2 + Source/engine/path.cpp | 5 +- Source/engine/path.h | 4 +- Source/engine/render/clx_render.cpp | 2 + Source/engine/sound.cpp | 2 +- Source/gamemenu.cpp | 2 +- Source/help.cpp | 2 +- Source/init.cpp | 216 ---------------------------- Source/init.h | 39 ----- Source/interfac.cpp | 3 +- Source/items.cpp | 2 +- Source/levels/gendung.cpp | 7 +- Source/levels/gendung.h | 1 + Source/levels/town.cpp | 4 +- Source/levels/trigs.cpp | 2 +- Source/lighting.h | 4 - Source/loadsave.cpp | 2 +- Source/missiles.cpp | 2 +- Source/monster.cpp | 3 +- Source/monster.h | 1 - Source/mpq/mpq_writer.cpp | 2 +- Source/objects.cpp | 2 - Source/options.cpp | 9 +- Source/pack.cpp | 1 - Source/panels/spell_book.cpp | 2 +- Source/panels/spell_icons.cpp | 1 - Source/pfile.cpp | 1 - Source/player.cpp | 5 +- Source/qol/chatlog.cpp | 1 - Source/quests.cpp | 1 - Source/stores.cpp | 4 +- Source/utils/log.hpp | 1 + Source/utils/soundsample.cpp | 22 +++ Source/utils/soundsample.h | 31 ++-- test/app_fatal_for_testing.cpp | 22 +++ test/dun_render_benchmark.cpp | 2 +- test/inv_test.cpp | 1 + test/language_for_testing.cpp | 2 + test/pack_test.cpp | 1 + test/timedemo_test.cpp | 3 +- 57 files changed, 365 insertions(+), 331 deletions(-) diff --git a/Source/DiabloUI/diabloui.cpp b/Source/DiabloUI/diabloui.cpp index b9d754f2614..f5d0873bc6d 100644 --- a/Source/DiabloUI/diabloui.cpp +++ b/Source/DiabloUI/diabloui.cpp @@ -23,6 +23,7 @@ #include "engine/render/clx_render.hpp" #include "engine/ticks.hpp" #include "hwcursor.hpp" +#include "init.h" #include "utils/algorithm/container.hpp" #include "utils/display.h" #include "utils/is_of.hpp" diff --git a/Source/DiabloUI/dialogs.cpp b/Source/DiabloUI/dialogs.cpp index 4b60e8a27af..1f3a6162c73 100644 --- a/Source/DiabloUI/dialogs.cpp +++ b/Source/DiabloUI/dialogs.cpp @@ -14,7 +14,9 @@ #include "engine/load_clx.hpp" #include "engine/load_pcx.hpp" #include "engine/palette.h" +#include "headless_mode.hpp" #include "hwcursor.hpp" +#include "init.h" #include "utils/display.h" #include "utils/is_of.hpp" #include "utils/language.h" diff --git a/Source/DiabloUI/hero/selhero.cpp b/Source/DiabloUI/hero/selhero.cpp index 109e7d631b6..3506265462b 100644 --- a/Source/DiabloUI/hero/selhero.cpp +++ b/Source/DiabloUI/hero/selhero.cpp @@ -15,6 +15,7 @@ #include "DiabloUI/selyesno.h" #include "control.h" #include "controls/plrctrls.h" +#include "engine/assets.hpp" #include "game_mode.hpp" #include "menu.h" #include "options.h" @@ -161,10 +162,10 @@ void SelheroListSelect(size_t value) vecSelHeroDlgItems.push_back(std::make_unique(_("Sorcerer"), static_cast(HeroClass::Sorcerer))); if (gbIsHellfire) { vecSelHeroDlgItems.push_back(std::make_unique(_("Monk"), static_cast(HeroClass::Monk))); - if (gbBard || *sgOptions.Gameplay.testBard) { + if (HaveBardAssets() || *sgOptions.Gameplay.testBard) { vecSelHeroDlgItems.push_back(std::make_unique(_("Bard"), static_cast(HeroClass::Bard))); } - if (gbBarbarian || *sgOptions.Gameplay.testBarbarian) { + if (HaveBarbarianAssets() || *sgOptions.Gameplay.testBarbarian) { vecSelHeroDlgItems.push_back(std::make_unique(_("Barbarian"), static_cast(HeroClass::Barbarian))); } } @@ -263,7 +264,7 @@ void AddSelHeroBackground() void SelheroClassSelectorSelect(size_t value) { auto hClass = static_cast(vecSelHeroDlgItems[value]->m_value); - if (gbIsSpawn && (hClass == HeroClass::Rogue || hClass == HeroClass::Sorcerer || (hClass == HeroClass::Bard && !gbBard))) { + if (gbIsSpawn && (hClass == HeroClass::Rogue || hClass == HeroClass::Sorcerer || (hClass == HeroClass::Bard && !HaveBardAssets()))) { RemoveSelHeroBackground(); UiSelOkDialog(nullptr, _("The Rogue and Sorcerer are only available in the full retail version of Diablo. Visit https://www.gog.com/game/diablo to purchase.").data(), false); AddSelHeroBackground(); diff --git a/Source/DiabloUI/mainmenu.cpp b/Source/DiabloUI/mainmenu.cpp index d36ff3b2e08..0e8e6a13a68 100644 --- a/Source/DiabloUI/mainmenu.cpp +++ b/Source/DiabloUI/mainmenu.cpp @@ -3,6 +3,7 @@ #include "DiabloUI/diabloui.h" #include "DiabloUI/selok.h" #include "control.h" +#include "engine/assets.hpp" #include "engine/load_clx.hpp" #include "game_mode.hpp" #include "utils/language.h" diff --git a/Source/DiabloUI/settingsmenu.cpp b/Source/DiabloUI/settingsmenu.cpp index 37ae4142656..81f008749bb 100644 --- a/Source/DiabloUI/settingsmenu.cpp +++ b/Source/DiabloUI/settingsmenu.cpp @@ -2,6 +2,7 @@ #include #include +#include #include @@ -11,6 +12,7 @@ #include "controls/controller_motion.h" #include "controls/plrctrls.h" #include "controls/remap_keyboard.h" +#include "engine/assets.hpp" #include "engine/render/text_render.hpp" #include "hwcursor.hpp" #include "options.h" diff --git a/Source/appfat.cpp b/Source/appfat.cpp index 938f359027c..637d341c0bd 100644 --- a/Source/appfat.cpp +++ b/Source/appfat.cpp @@ -49,15 +49,15 @@ void FreeDlg() SNetDestroy(); } -[[noreturn]] void DisplayFatalErrorAndExit(std::string_view title, std::string_view body) +} // namespace + +void DisplayFatalErrorAndExit(std::string_view title, std::string_view body) { FreeDlg(); UiErrorOkDialog(title, body); diablo_quit(1); } -} // namespace - void app_fatal(std::string_view str) { DisplayFatalErrorAndExit(_("Error"), str); diff --git a/Source/appfat.h b/Source/appfat.h index 285c368edeb..2eb29c8e26f 100644 --- a/Source/appfat.h +++ b/Source/appfat.h @@ -21,6 +21,13 @@ namespace devilution { #define assert(exp) (void)((exp) || (assert_fail(__LINE__, __FILE__, #exp), 0)) #endif +/** + * @brief Terminates the game and displays an error message box. + * @param str Message box title. + * @param str Error message. + */ +[[noreturn]] void DisplayFatalErrorAndExit(std::string_view title, std::string_view body); + /** * @brief Terminates the game and displays an error message box. * @param str Error message. diff --git a/Source/capture.cpp b/Source/capture.cpp index 856263d768c..2cc286a6e79 100644 --- a/Source/capture.cpp +++ b/Source/capture.cpp @@ -46,7 +46,7 @@ SDL_RWops *CaptureFile(std::string *dstPath) const std::tm *tm = std::localtime(&tt); const std::string filename = tm != nullptr ? fmt::format("Screenshot from {:04}-{:02}-{:02} {:02}-{:02}-{:02}", - tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec) + tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec) : "Screenshot"; *dstPath = StrCat(paths::PrefPath(), filename, ext); int i = 0; diff --git a/Source/control.cpp b/Source/control.cpp index 3d1f126bc86..261ce0387e5 100644 --- a/Source/control.cpp +++ b/Source/control.cpp @@ -29,7 +29,6 @@ #include "engine/trn.hpp" #include "gamemenu.h" #include "headless_mode.hpp" -#include "init.h" #include "inv.h" #include "inv_iterators.hpp" #include "levels/setmaps.h" diff --git a/Source/diablo.cpp b/Source/diablo.cpp index 968bef574cd..94c34600eb3 100644 --- a/Source/diablo.cpp +++ b/Source/diablo.cpp @@ -12,6 +12,7 @@ #include #include "DiabloUI/selstart.h" +#include "appfat.h" #include "automap.h" #include "capture.h" #include "control.h" @@ -124,8 +125,6 @@ bool gbProcessPlayers; bool gbLoadGame; bool cineflag; int PauseMode; -bool gbBard; -bool gbBarbarian; clicktype sgbMouseDown; uint16_t gnTickDelay = 50; char gszProductName[64] = "DevilutionX vUnknown"; diff --git a/Source/diablo.h b/Source/diablo.h index e742e2561cd..3ea16a521e8 100644 --- a/Source/diablo.h +++ b/Source/diablo.h @@ -7,6 +7,12 @@ #include +#include + +#ifdef USE_SDL1 +#include "utils/sdl2_to_1_2_backports.h" +#endif + #ifdef _DEBUG #include "monstdat.h" #endif @@ -69,8 +75,6 @@ extern bool cineflag; /* These are defined in fonts.h */ extern void FontsCleanup(); extern DVL_API_FOR_TEST int PauseMode; -extern bool gbBard; -extern bool gbBarbarian; extern clicktype sgbMouseDown; extern uint16_t gnTickDelay; extern char gszProductName[64]; diff --git a/Source/discord/discord.cpp b/Source/discord/discord.cpp index 6353facb69f..160d735d114 100644 --- a/Source/discord/discord.cpp +++ b/Source/discord/discord.cpp @@ -17,7 +17,7 @@ #include #include "config.h" -#include "init.h" +#include "game_mode.hpp" #include "levels/gendung.h" #include "levels/setmaps.h" #include "multi.h" diff --git a/Source/dvlnet/packet.h b/Source/dvlnet/packet.h index e407d62d95b..a8e675d27bc 100644 --- a/Source/dvlnet/packet.h +++ b/Source/dvlnet/packet.h @@ -16,6 +16,7 @@ #include "appfat.h" #include "dvlnet/abstract_net.h" #include "utils/attributes.h" +#include "utils/endian_read.hpp" #include "utils/endian_write.hpp" #include "utils/str_cat.hpp" #include "utils/stubs.h" diff --git a/Source/effects.cpp b/Source/effects.cpp index 24cadcd75e1..838eb74c570 100644 --- a/Source/effects.cpp +++ b/Source/effects.cpp @@ -17,7 +17,7 @@ #include "engine/sound.h" #include "engine/sound_defs.hpp" #include "engine/sound_position.hpp" -#include "init.h" +#include "game_mode.hpp" #include "player.h" #include "utils/is_of.hpp" diff --git a/Source/engine/assets.cpp b/Source/engine/assets.cpp index f5caa393e61..560d15ef0c0 100644 --- a/Source/engine/assets.cpp +++ b/Source/engine/assets.cpp @@ -5,11 +5,17 @@ #include #include +#include "appfat.h" #include "game_mode.hpp" #include "utils/file_util.h" #include "utils/log.hpp" #include "utils/paths.h" #include "utils/str_cat.hpp" +#include "utils/str_split.hpp" + +#if defined(_WIN32) && !defined(__UWP__) && !defined(DEVILUTIONX_WINDOWS_NO_WCHAR) +#include +#endif #ifndef UNPACKED_MPQS #include "mpq/mpq_sdl_rwops.hpp" @@ -258,4 +264,207 @@ std::string FailedToOpenFileErrorMessage(std::string_view path, std::string_view return fmt::format(fmt::runtime(_("Failed to open file:\n{:s}\n\n{:s}\n\nThe MPQ file(s) might be damaged. Please check the file integrity.")), path, error); } +namespace { +#ifdef UNPACKED_MPQS +std::optional FindUnpackedMpqData(const std::vector &paths, std::string_view mpqName) +{ + std::string targetPath; + for (const std::string &path : paths) { + targetPath.clear(); + targetPath.reserve(path.size() + mpqName.size() + 1); + targetPath.append(path).append(mpqName) += DirectorySeparator; + if (FileExists(targetPath)) { + LogVerbose(" Found unpacked MPQ directory: {}", targetPath); + return targetPath; + } + } + return std::nullopt; +} +#else +std::optional LoadMPQ(const std::vector &paths, std::string_view mpqName) +{ + std::optional archive; + std::string mpqAbsPath; + std::int32_t error = 0; + for (const auto &path : paths) { + mpqAbsPath = path + mpqName.data(); + if ((archive = MpqArchive::Open(mpqAbsPath.c_str(), error))) { + LogVerbose(" Found: {} in {}", mpqName, path); + return archive; + } + if (error != 0) { + LogError("Error {}: {}", MpqArchive::ErrorMessage(error), mpqAbsPath); + } + } + if (error == 0) { + LogVerbose("Missing: {}", mpqName); + } + + return std::nullopt; +} +#endif + +std::vector GetMPQSearchPaths() +{ + std::vector paths; + paths.push_back(paths::BasePath()); + paths.push_back(paths::PrefPath()); + if (paths[0] == paths[1]) + paths.pop_back(); + paths.push_back(paths::ConfigPath()); + if (paths[0] == paths[1] || (paths.size() == 3 && (paths[0] == paths[2] || paths[1] == paths[2]))) + paths.pop_back(); + +#if (defined(__unix__) || defined(__APPLE__)) && !defined(__ANDROID__) + // `XDG_DATA_HOME` is usually the root path of `paths::PrefPath()`, so we only + // add `XDG_DATA_DIRS`. + const char *xdgDataDirs = std::getenv("XDG_DATA_DIRS"); + if (xdgDataDirs != nullptr) { + for (const std::string_view path : SplitByChar(xdgDataDirs, ':')) { + std::string fullPath(path); + if (!path.empty() && path.back() != '/') + fullPath += '/'; + fullPath.append("diasurgical/devilutionx/"); + paths.push_back(std::move(fullPath)); + } + } else { + paths.emplace_back("/usr/local/share/diasurgical/devilutionx/"); + paths.emplace_back("/usr/share/diasurgical/devilutionx/"); + } +#elif defined(NXDK) + paths.emplace_back("D:\\"); +#elif defined(_WIN32) && !defined(__UWP__) && !defined(DEVILUTIONX_WINDOWS_NO_WCHAR) + char gogpath[_FSG_PATH_MAX]; + fsg_get_gog_game_path(gogpath, "1412601690"); + if (strlen(gogpath) > 0) { + paths.emplace_back(std::string(gogpath) + "/"); + paths.emplace_back(std::string(gogpath) + "/hellfire/"); + } +#endif + + if (paths.empty() || !paths.back().empty()) { + paths.emplace_back(); // PWD + } + + if (SDL_LOG_PRIORITY_VERBOSE >= SDL_LogGetPriority(SDL_LOG_CATEGORY_APPLICATION)) { + LogVerbose("Paths:\n base: {}\n pref: {}\n config: {}\n assets: {}", + paths::BasePath(), paths::PrefPath(), paths::ConfigPath(), paths::AssetsPath()); + + std::string message; + for (std::size_t i = 0; i < paths.size(); ++i) { + message.append(fmt::format("\n{:6d}. '{}'", i + 1, paths[i])); + } + LogVerbose("MPQ search paths:{}", message); + } + + return paths; +} + +} // namespace + +void LoadCoreArchives() +{ + auto paths = GetMPQSearchPaths(); + +#ifdef UNPACKED_MPQS + font_data_path = FindUnpackedMpqData(paths, "fonts"); +#else // !UNPACKED_MPQS +#if !defined(__ANDROID__) && !defined(__APPLE__) && !defined(__3DS__) && !defined(__SWITCH__) + // Load devilutionx.mpq first to get the font file for error messages + devilutionx_mpq = LoadMPQ(paths, "devilutionx.mpq"); +#endif + font_mpq = LoadMPQ(paths, "fonts.mpq"); // Extra fonts +#endif +} + +void LoadLanguageArchive() +{ +#ifdef UNPACKED_MPQS + lang_data_path = std::nullopt; +#else + lang_mpq = std::nullopt; +#endif + + std::string_view code = GetLanguageCode(); + if (code != "en") { + std::string langMpqName { code }; +#ifdef UNPACKED_MPQS + lang_data_path = FindUnpackedMpqData(GetMPQSearchPaths(), langMpqName); +#else + langMpqName.append(".mpq"); + lang_mpq = LoadMPQ(GetMPQSearchPaths(), langMpqName); +#endif + } +} + +void LoadGameArchives() +{ + auto paths = GetMPQSearchPaths(); +#ifdef UNPACKED_MPQS + diabdat_data_path = FindUnpackedMpqData(paths, "diabdat"); + if (!diabdat_data_path) { + spawn_data_path = FindUnpackedMpqData(paths, "spawn"); + if (spawn_data_path) + gbIsSpawn = true; + } + if (!HeadlessMode) { + AssetRef ref = FindAsset("ui_art\\title.clx"); + if (!ref.ok()) { + LogError("{}", SDL_GetError()); + InsertCDDlg(_("diabdat.mpq or spawn.mpq")); + } + } + hellfire_data_path = FindUnpackedMpqData(paths, "hellfire"); + if (hellfire_data_path) + gbIsHellfire = true; + if (forceHellfire && !hellfire_data_path) + InsertCDDlg("hellfire"); + + const bool hasMonk = FileExists(*hellfire_data_path + "plrgfx/monk/mha/mhaas.clx"); + const bool hasMusic = FileExists(*hellfire_data_path + "music/dlvlf.wav") + || FileExists(*hellfire_data_path + "music/dlvlf.mp3"); + const bool hasVoice = FileExists(*hellfire_data_path + "sfx/hellfire/cowsut1.wav") + || FileExists(*hellfire_data_path + "sfx/hellfire/cowsut1.mp3"); + + if (gbIsHellfire && (!hasMonk || !hasMusic || !hasVoice)) { + DisplayFatalErrorAndExit(_("Some Hellfire MPQs are missing"), _("Not all Hellfire MPQs were found.\nPlease copy all the hf*.mpq files.")); + } +#else // !UNPACKED_MPQS + diabdat_mpq = LoadMPQ(paths, "DIABDAT.MPQ"); + if (!diabdat_mpq) { + // DIABDAT.MPQ is uppercase on the original CD and the GOG version. + diabdat_mpq = LoadMPQ(paths, "diabdat.mpq"); + } + + if (!diabdat_mpq) { + spawn_mpq = LoadMPQ(paths, "spawn.mpq"); + if (spawn_mpq) + gbIsSpawn = true; + } + if (!HeadlessMode) { + AssetRef ref = FindAsset("ui_art\\title.pcx"); + if (!ref.ok()) { + LogError("{}", SDL_GetError()); + InsertCDDlg(_("diabdat.mpq or spawn.mpq")); + } + } + + hellfire_mpq = LoadMPQ(paths, "hellfire.mpq"); + if (hellfire_mpq) + gbIsHellfire = true; + if (forceHellfire && !hellfire_mpq) + InsertCDDlg("hellfire.mpq"); + + hfmonk_mpq = LoadMPQ(paths, "hfmonk.mpq"); + hfbard_mpq = LoadMPQ(paths, "hfbard.mpq"); + hfbarb_mpq = LoadMPQ(paths, "hfbarb.mpq"); + hfmusic_mpq = LoadMPQ(paths, "hfmusic.mpq"); + hfvoice_mpq = LoadMPQ(paths, "hfvoice.mpq"); + + if (gbIsHellfire && (!hfmonk_mpq || !hfmusic_mpq || !hfvoice_mpq)) { + DisplayFatalErrorAndExit(_("Some Hellfire MPQs are missing"), _("Not all Hellfire MPQs were found.\nPlease copy all the hf*.mpq files.")); + } +#endif +} + } // namespace devilution diff --git a/Source/engine/assets.hpp b/Source/engine/assets.hpp index 0d964cf598c..aae897eaddb 100644 --- a/Source/engine/assets.hpp +++ b/Source/engine/assets.hpp @@ -300,4 +300,26 @@ extern std::optional lang_mpq; extern std::optional devilutionx_mpq; #endif +void LoadCoreArchives(); +void LoadLanguageArchive(); +void LoadGameArchives(); + +#ifdef UNPACKED_MPQS +[[nodiscard]] inline bool HaveSpawn() { return spawn_data_path.has_value(); } +[[nodiscard]] inline bool HaveDiabdat() { return diabdat_data_path.has_value(); } +[[nodiscard]] inline bool HaveHellfire() { return hellfire_data_path.has_value(); } +[[nodiscard]] inline bool HaveExtraFonts() { return font_data_path.has_value(); } + +// Bard and barbarian are not currently supported in unpacked mode. +[[nodiscard]] inline bool HaveBardAssets() { return false; } +[[nodiscard]] inline bool HaveBarbarianAssets() { return false; } +#else +[[nodiscard]] inline bool HaveSpawn() { return spawn_mpq.has_value(); } +[[nodiscard]] inline bool HaveDiabdat() { return diabdat_mpq.has_value(); } +[[nodiscard]] inline bool HaveHellfire() { return hellfire_mpq.has_value(); } +[[nodiscard]] inline bool HaveExtraFonts() { return font_mpq.has_value(); } +[[nodiscard]] inline bool HaveBardAssets() { return hfbard_mpq.has_value(); } +[[nodiscard]] inline bool HaveBarbarianAssets() { return hfbarb_mpq.has_value(); } +#endif + } // namespace devilution diff --git a/Source/engine/dx.cpp b/Source/engine/dx.cpp index c2a3b05c222..ff5dc0c5065 100644 --- a/Source/engine/dx.cpp +++ b/Source/engine/dx.cpp @@ -11,6 +11,7 @@ #include "controls/plrctrls.h" #include "engine/render/primitive_render.hpp" #include "headless_mode.hpp" +#include "init.h" #include "options.h" #include "utils/display.h" #include "utils/log.hpp" diff --git a/Source/engine/palette.h b/Source/engine/palette.h index a9cc0959ac0..d84aab9e54b 100644 --- a/Source/engine/palette.h +++ b/Source/engine/palette.h @@ -8,6 +8,8 @@ #include #include +#include + #include "levels/gendung.h" namespace devilution { diff --git a/Source/engine/path.cpp b/Source/engine/path.cpp index 9891c6d2366..8930ba67bd8 100644 --- a/Source/engine/path.cpp +++ b/Source/engine/path.cpp @@ -5,14 +5,15 @@ */ #include "engine/path.h" -#include #include +#include #include +#include "appfat.h" #include "crawl.hpp" +#include "engine/direction.hpp" #include "levels/gendung.h" -#include "lighting.h" #include "objects.h" namespace devilution { diff --git a/Source/engine/path.h b/Source/engine/path.h index 931c545c473..58fb73dfa6d 100644 --- a/Source/engine/path.h +++ b/Source/engine/path.h @@ -6,14 +6,12 @@ #pragma once #include -#include #include -#include #include -#include "engine/direction.hpp" #include "engine/point.hpp" +#include "utils/attributes.h" namespace devilution { diff --git a/Source/engine/render/clx_render.cpp b/Source/engine/render/clx_render.cpp index 05ca136cd22..475a5c556ce 100644 --- a/Source/engine/render/clx_render.cpp +++ b/Source/engine/render/clx_render.cpp @@ -6,9 +6,11 @@ #include "clx_render.hpp" #include +#include #include "engine/point.hpp" #include "engine/render/blit_impl.hpp" +#include "engine/surface.hpp" #include "utils/attributes.h" #include "utils/clx_decode.hpp" #include "utils/static_vector.hpp" diff --git a/Source/engine/sound.cpp b/Source/engine/sound.cpp index 235f1d61c4a..65f4946e657 100644 --- a/Source/engine/sound.cpp +++ b/Source/engine/sound.cpp @@ -13,11 +13,11 @@ #include #include +#include #include #include #include "engine/assets.hpp" -#include "init.h" #include "options.h" #include "utils/log.hpp" #include "utils/math.h" diff --git a/Source/gamemenu.cpp b/Source/gamemenu.cpp index 9fc19a3fec6..f7fcba3183a 100644 --- a/Source/gamemenu.cpp +++ b/Source/gamemenu.cpp @@ -13,8 +13,8 @@ #include "engine/sound_defs.hpp" #include "gmenu.h" #include "headless_mode.hpp" -#include "init.h" #include "loadsave.h" +#include "multi.h" #include "options.h" #include "pfile.h" #include "qol/floatingnumbers.h" diff --git a/Source/help.cpp b/Source/help.cpp index b9ecaf318fe..b6c83e49fb0 100644 --- a/Source/help.cpp +++ b/Source/help.cpp @@ -10,7 +10,7 @@ #include "DiabloUI/ui_flags.hpp" #include "engine/render/clx_render.hpp" #include "engine/render/text_render.hpp" -#include "init.h" +#include "game_mode.hpp" #include "minitext.h" #include "qol/chatlog.h" #include "stores.h" diff --git a/Source/init.cpp b/Source/init.cpp index 745c0fedb52..515ae29686b 100644 --- a/Source/init.cpp +++ b/Source/init.cpp @@ -12,10 +12,6 @@ #include #include -#if defined(_WIN32) && !defined(__UWP__) && !defined(DEVILUTIONX_WINDOWS_NO_WCHAR) -#include -#endif - #include "DiabloUI/diabloui.h" #include "engine/assets.hpp" #include "engine/backbuffer_state.hpp" @@ -46,7 +42,6 @@ int _newlib_heap_size_user = 100 * 1024 * 1024; namespace devilution { -/** True if the game is the current active window */ bool gbActive; namespace { @@ -54,101 +49,6 @@ namespace { constexpr char DevilutionXMpqVersion[] = "1\n"; constexpr char ExtraFontsVersion[] = "1\n"; -#ifdef UNPACKED_MPQS -std::optional FindUnpackedMpqData(const std::vector &paths, std::string_view mpqName) -{ - std::string targetPath; - for (const std::string &path : paths) { - targetPath.clear(); - targetPath.reserve(path.size() + mpqName.size() + 1); - targetPath.append(path).append(mpqName) += DirectorySeparator; - if (FileExists(targetPath)) { - LogVerbose(" Found unpacked MPQ directory: {}", targetPath); - return targetPath; - } - } - return std::nullopt; -} -#else -std::optional LoadMPQ(const std::vector &paths, std::string_view mpqName) -{ - std::optional archive; - std::string mpqAbsPath; - std::int32_t error = 0; - for (const auto &path : paths) { - mpqAbsPath = path + mpqName.data(); - if ((archive = MpqArchive::Open(mpqAbsPath.c_str(), error))) { - LogVerbose(" Found: {} in {}", mpqName, path); - return archive; - } - if (error != 0) { - LogError("Error {}: {}", MpqArchive::ErrorMessage(error), mpqAbsPath); - } - } - if (error == 0) { - LogVerbose("Missing: {}", mpqName); - } - - return std::nullopt; -} -#endif - -std::vector GetMPQSearchPaths() -{ - std::vector paths; - paths.push_back(paths::BasePath()); - paths.push_back(paths::PrefPath()); - if (paths[0] == paths[1]) - paths.pop_back(); - paths.push_back(paths::ConfigPath()); - if (paths[0] == paths[1] || (paths.size() == 3 && (paths[0] == paths[2] || paths[1] == paths[2]))) - paths.pop_back(); - -#if (defined(__unix__) || defined(__APPLE__)) && !defined(__ANDROID__) - // `XDG_DATA_HOME` is usually the root path of `paths::PrefPath()`, so we only - // add `XDG_DATA_DIRS`. - const char *xdgDataDirs = std::getenv("XDG_DATA_DIRS"); - if (xdgDataDirs != nullptr) { - for (const std::string_view path : SplitByChar(xdgDataDirs, ':')) { - std::string fullPath(path); - if (!path.empty() && path.back() != '/') - fullPath += '/'; - fullPath.append("diasurgical/devilutionx/"); - paths.push_back(std::move(fullPath)); - } - } else { - paths.emplace_back("/usr/local/share/diasurgical/devilutionx/"); - paths.emplace_back("/usr/share/diasurgical/devilutionx/"); - } -#elif defined(NXDK) - paths.emplace_back("D:\\"); -#elif defined(_WIN32) && !defined(__UWP__) && !defined(DEVILUTIONX_WINDOWS_NO_WCHAR) - char gogpath[_FSG_PATH_MAX]; - fsg_get_gog_game_path(gogpath, "1412601690"); - if (strlen(gogpath) > 0) { - paths.emplace_back(std::string(gogpath) + "/"); - paths.emplace_back(std::string(gogpath) + "/hellfire/"); - } -#endif - - if (paths.empty() || !paths.back().empty()) { - paths.emplace_back(); // PWD - } - - if (SDL_LOG_PRIORITY_VERBOSE >= SDL_LogGetPriority(SDL_LOG_CATEGORY_APPLICATION)) { - LogVerbose("Paths:\n base: {}\n pref: {}\n config: {}\n assets: {}", - paths::BasePath(), paths::PrefPath(), paths::ConfigPath(), paths::AssetsPath()); - - std::string message; - for (std::size_t i = 0; i < paths.size(); ++i) { - message.append(fmt::format("\n{:6d}. '{}'", i + 1, paths[i])); - } - LogVerbose("MPQ search paths:{}", message); - } - - return paths; -} - bool AssetContentsEq(AssetRef &&ref, std::string_view expected) { const size_t size = ref.size(); @@ -243,122 +143,6 @@ void init_cleanup() NetClose(); } -void LoadCoreArchives() -{ - auto paths = GetMPQSearchPaths(); - -#ifdef UNPACKED_MPQS - font_data_path = FindUnpackedMpqData(paths, "fonts"); -#else // !UNPACKED_MPQS -#if !defined(__ANDROID__) && !defined(__APPLE__) && !defined(__3DS__) && !defined(__SWITCH__) - // Load devilutionx.mpq first to get the font file for error messages - devilutionx_mpq = LoadMPQ(paths, "devilutionx.mpq"); -#endif - font_mpq = LoadMPQ(paths, "fonts.mpq"); // Extra fonts -#endif -} - -void LoadLanguageArchive() -{ -#ifdef UNPACKED_MPQS - lang_data_path = std::nullopt; -#else - lang_mpq = std::nullopt; -#endif - - std::string_view code = GetLanguageCode(); - if (code != "en") { - std::string langMpqName { code }; -#ifdef UNPACKED_MPQS - lang_data_path = FindUnpackedMpqData(GetMPQSearchPaths(), langMpqName); -#else - langMpqName.append(".mpq"); - lang_mpq = LoadMPQ(GetMPQSearchPaths(), langMpqName); -#endif - } -} - -void LoadGameArchives() -{ - auto paths = GetMPQSearchPaths(); -#ifdef UNPACKED_MPQS - diabdat_data_path = FindUnpackedMpqData(paths, "diabdat"); - if (!diabdat_data_path) { - spawn_data_path = FindUnpackedMpqData(paths, "spawn"); - if (spawn_data_path) - gbIsSpawn = true; - } - if (!HeadlessMode) { - AssetRef ref = FindAsset("ui_art\\title.clx"); - if (!ref.ok()) { - LogError("{}", SDL_GetError()); - InsertCDDlg(_("diabdat.mpq or spawn.mpq")); - } - } - hellfire_data_path = FindUnpackedMpqData(paths, "hellfire"); - if (hellfire_data_path) - gbIsHellfire = true; - if (forceHellfire && !hellfire_data_path) - InsertCDDlg("hellfire"); - - const bool hasMonk = FileExists(*hellfire_data_path + "plrgfx/monk/mha/mhaas.clx"); - const bool hasMusic = FileExists(*hellfire_data_path + "music/dlvlf.wav") - || FileExists(*hellfire_data_path + "music/dlvlf.mp3"); - const bool hasVoice = FileExists(*hellfire_data_path + "sfx/hellfire/cowsut1.wav") - || FileExists(*hellfire_data_path + "sfx/hellfire/cowsut1.mp3"); - - // Bard and barbarian are not currently supported in unpacked mode - // because they use the same paths as rogue and warrior. - gbBard = false; - gbBarbarian = false; - - if (gbIsHellfire && (!hasMonk || !hasMusic || !hasVoice)) { - UiErrorOkDialog(_("Some Hellfire MPQs are missing"), _("Not all Hellfire MPQs were found.\nPlease copy all the hf*.mpq files.")); - diablo_quit(1); - } -#else // !UNPACKED_MPQS - diabdat_mpq = LoadMPQ(paths, "DIABDAT.MPQ"); - if (!diabdat_mpq) { - // DIABDAT.MPQ is uppercase on the original CD and the GOG version. - diabdat_mpq = LoadMPQ(paths, "diabdat.mpq"); - } - - if (!diabdat_mpq) { - spawn_mpq = LoadMPQ(paths, "spawn.mpq"); - if (spawn_mpq) - gbIsSpawn = true; - } - if (!HeadlessMode) { - AssetRef ref = FindAsset("ui_art\\title.pcx"); - if (!ref.ok()) { - LogError("{}", SDL_GetError()); - InsertCDDlg(_("diabdat.mpq or spawn.mpq")); - } - } - - hellfire_mpq = LoadMPQ(paths, "hellfire.mpq"); - if (hellfire_mpq) - gbIsHellfire = true; - if (forceHellfire && !hellfire_mpq) - InsertCDDlg("hellfire.mpq"); - - hfmonk_mpq = LoadMPQ(paths, "hfmonk.mpq"); - hfbard_mpq = LoadMPQ(paths, "hfbard.mpq"); - if (hfbard_mpq) - gbBard = true; - hfbarb_mpq = LoadMPQ(paths, "hfbarb.mpq"); - if (hfbarb_mpq) - gbBarbarian = true; - hfmusic_mpq = LoadMPQ(paths, "hfmusic.mpq"); - hfvoice_mpq = LoadMPQ(paths, "hfvoice.mpq"); - - if (gbIsHellfire && (!hfmonk_mpq || !hfmusic_mpq || !hfvoice_mpq)) { - UiErrorOkDialog(_("Some Hellfire MPQs are missing"), _("Not all Hellfire MPQs were found.\nPlease copy all the hf*.mpq files.")); - diablo_quit(1); - } -#endif -} - void init_create_window() { if (!SpawnWindow(PROJECT_NAME)) diff --git a/Source/init.h b/Source/init.h index 8429fd5a172..eab3ae3d680 100644 --- a/Source/init.h +++ b/Source/init.h @@ -21,42 +21,6 @@ namespace devilution { /** True if the game is the current active window */ extern bool gbActive; -inline bool HaveSpawn() -{ -#ifdef UNPACKED_MPQS - return bool(spawn_data_path); -#else - return bool(spawn_mpq); -#endif -} - -inline bool HaveDiabdat() -{ -#ifdef UNPACKED_MPQS - return bool(diabdat_data_path); -#else - return bool(diabdat_mpq); -#endif -} - -inline bool HaveHellfire() -{ -#ifdef UNPACKED_MPQS - return bool(hellfire_data_path); -#else - return bool(hellfire_mpq); -#endif -} - -inline bool HaveExtraFonts() -{ -#ifdef UNPACKED_MPQS - return bool(font_data_path); -#else - return bool(font_mpq); -#endif -} - #ifdef UNPACKED_MPQS bool AreExtraFontsOutOfDate(const std::string &path); #else @@ -86,9 +50,6 @@ inline bool IsDevilutionXMpqOutOfDate() } void init_cleanup(); -void LoadCoreArchives(); -void LoadLanguageArchive(); -void LoadGameArchives(); void init_create_window(); void MainWndProc(const SDL_Event &event); diff --git a/Source/interfac.cpp b/Source/interfac.cpp index 78c3c24f5af..009475858fb 100644 --- a/Source/interfac.cpp +++ b/Source/interfac.cpp @@ -20,10 +20,11 @@ #include "engine/palette.h" #include "engine/render/clx_render.hpp" #include "engine/render/primitive_render.hpp" +#include "game_mode.hpp" #include "headless_mode.hpp" #include "hwcursor.hpp" -#include "init.h" #include "loadsave.h" +#include "multi.h" #include "pfile.h" #include "plrmsg.h" #include "utils/log.hpp" diff --git a/Source/items.cpp b/Source/items.cpp index 7577df4ab92..5bd770b1ec7 100644 --- a/Source/items.cpp +++ b/Source/items.cpp @@ -27,8 +27,8 @@ #include "engine/render/clx_render.hpp" #include "engine/render/primitive_render.hpp" #include "engine/render/text_render.hpp" +#include "game_mode.hpp" #include "headless_mode.hpp" -#include "init.h" #include "inv_iterators.hpp" #include "levels/town.h" #include "lighting.h" diff --git a/Source/levels/gendung.cpp b/Source/levels/gendung.cpp index 03d8e331082..f53bed99a75 100644 --- a/Source/levels/gendung.cpp +++ b/Source/levels/gendung.cpp @@ -15,7 +15,8 @@ #include "engine/load_file.hpp" #include "engine/random.hpp" #include "engine/world_tile.hpp" -#include "init.h" +#include "game_mode.hpp" +#include "items.h" #include "levels/drlg_l1.h" #include "levels/drlg_l2.h" #include "levels/drlg_l3.h" @@ -23,7 +24,9 @@ #include "levels/reencode_dun_cels.hpp" #include "levels/town.h" #include "lighting.h" -#include "options.h" +#include "monster.h" +#include "objects.h" +#include "utils/algorithm/container.hpp" #include "utils/bitset2d.hpp" #include "utils/is_of.hpp" #include "utils/log.hpp" diff --git a/Source/levels/gendung.h b/Source/levels/gendung.h index f6f8ede9c51..7c318d7c85f 100644 --- a/Source/levels/gendung.h +++ b/Source/levels/gendung.h @@ -11,6 +11,7 @@ #include #include +#include #include #include "engine/clx_sprite.hpp" diff --git a/Source/levels/town.cpp b/Source/levels/town.cpp index 66681fd6c0c..d1f927a1ef8 100644 --- a/Source/levels/town.cpp +++ b/Source/levels/town.cpp @@ -4,9 +4,11 @@ #include "engine/load_file.hpp" #include "engine/random.hpp" -#include "init.h" +#include "engine/world_tile.hpp" +#include "game_mode.hpp" #include "levels/drlg_l1.h" #include "levels/trigs.h" +#include "multi.h" #include "player.h" #include "quests.h" diff --git a/Source/levels/trigs.cpp b/Source/levels/trigs.cpp index c5254946304..c51edec19a8 100644 --- a/Source/levels/trigs.cpp +++ b/Source/levels/trigs.cpp @@ -15,7 +15,7 @@ #include "cursor.h" #include "diablo_msg.hpp" #include "game_mode.hpp" -#include "init.h" +#include "multi.h" #include "utils/algorithm/container.hpp" #include "utils/is_of.hpp" #include "utils/language.h" diff --git a/Source/lighting.h b/Source/lighting.h index aae59976386..2a0de57ad7c 100644 --- a/Source/lighting.h +++ b/Source/lighting.h @@ -7,12 +7,8 @@ #include #include -#include -#include -#include #include -#include #include "automap.h" #include "engine/displacement.hpp" diff --git a/Source/loadsave.cpp b/Source/loadsave.cpp index 55303eae8ce..b485e2468ff 100644 --- a/Source/loadsave.cpp +++ b/Source/loadsave.cpp @@ -24,7 +24,7 @@ #include "doom.h" #include "engine/point.hpp" #include "engine/random.hpp" -#include "init.h" +#include "game_mode.hpp" #include "inv.h" #include "levels/dun_tile.hpp" #include "lighting.h" diff --git a/Source/missiles.cpp b/Source/missiles.cpp index 3f183861597..d693e7363c4 100644 --- a/Source/missiles.cpp +++ b/Source/missiles.cpp @@ -22,8 +22,8 @@ #include "engine/points_in_rectangle_range.hpp" #include "engine/random.hpp" #include "engine/render/primitive_render.hpp" +#include "game_mode.hpp" #include "headless_mode.hpp" -#include "init.h" #include "inv.h" #include "levels/dun_tile.hpp" #include "levels/trigs.h" diff --git a/Source/monster.cpp b/Source/monster.cpp index 572d0fa4630..91e1620db1a 100644 --- a/Source/monster.cpp +++ b/Source/monster.cpp @@ -15,6 +15,7 @@ #include #include +#include #include #include #include @@ -32,7 +33,6 @@ #include "engine/world_tile.hpp" #include "game_mode.hpp" #include "headless_mode.hpp" -#include "init.h" #include "levels/crypt.h" #include "levels/drlg_l4.h" #include "levels/themes.h" @@ -55,7 +55,6 @@ #include "utils/static_vector.hpp" #include "utils/status_macros.hpp" #include "utils/str_cat.hpp" -#include "utils/utf8.hpp" #ifdef _DEBUG #include "debug.h" diff --git a/Source/monster.h b/Source/monster.h index 006e8736b0b..93221b1a68c 100644 --- a/Source/monster.h +++ b/Source/monster.h @@ -22,7 +22,6 @@ #include "engine/sound.h" #include "engine/world_tile.hpp" #include "game_mode.hpp" -#include "init.h" #include "levels/dun_tile.hpp" #include "misdat.h" #include "monstdat.h" diff --git a/Source/mpq/mpq_writer.cpp b/Source/mpq/mpq_writer.cpp index c4e4de1d5c0..9d5a3b2b1bb 100644 --- a/Source/mpq/mpq_writer.cpp +++ b/Source/mpq/mpq_writer.cpp @@ -6,11 +6,11 @@ #include #include +#include #include #include "appfat.h" #include "encrypt.h" -#include "utils/endian_read.hpp" #include "utils/file_util.h" #include "utils/language.h" #include "utils/log.hpp" diff --git a/Source/objects.cpp b/Source/objects.cpp index 60431d21888..185b9d0f356 100644 --- a/Source/objects.cpp +++ b/Source/objects.cpp @@ -27,7 +27,6 @@ #include "engine/points_in_rectangle_range.hpp" #include "engine/random.hpp" #include "headless_mode.hpp" -#include "init.h" #include "inv.h" #include "inv_iterators.hpp" #include "levels/crypt.h" @@ -49,7 +48,6 @@ #include "utils/language.h" #include "utils/log.hpp" #include "utils/str_cat.hpp" -#include "utils/utf8.hpp" namespace devilution { diff --git a/Source/options.cpp b/Source/options.cpp index 8311457fd47..7192df1eb09 100644 --- a/Source/options.cpp +++ b/Source/options.cpp @@ -19,6 +19,7 @@ #include "controls/game_controls.h" #include "controls/plrctrls.h" #include "discord/discord.h" +#include "engine/assets.hpp" #include "engine/demomode.h" #include "engine/sound_defs.hpp" #include "game_mode.hpp" @@ -717,10 +718,10 @@ void OptionEntryResolution::SetActiveListIndex(size_t index) OptionEntryResampler::OptionEntryResampler() : OptionEntryListBase("Resampler", OptionEntryFlags::CantChangeInGame - // When there are exactly 2 options there is no submenu, so we need to recreate the UI - // to reflect the change in the "Resampling quality" setting visibility. - | (NumResamplers == 2 ? OptionEntryFlags::RecreateUI : OptionEntryFlags::None), - N_("Resampler"), N_("Audio resampler")) + // When there are exactly 2 options there is no submenu, so we need to recreate the UI + // to reflect the change in the "Resampling quality" setting visibility. + | (NumResamplers == 2 ? OptionEntryFlags::RecreateUI : OptionEntryFlags::None), + N_("Resampler"), N_("Audio resampler")) { } void OptionEntryResampler::LoadFromIni(std::string_view category) diff --git a/Source/pack.cpp b/Source/pack.cpp index c8b029bc13e..0f917c056f6 100644 --- a/Source/pack.cpp +++ b/Source/pack.cpp @@ -9,7 +9,6 @@ #include "engine/random.hpp" #include "game_mode.hpp" -#include "init.h" #include "items/validation.h" #include "loadsave.h" #include "playerdat.hpp" diff --git a/Source/panels/spell_book.cpp b/Source/panels/spell_book.cpp index 23ead32efe4..a640bd65191 100644 --- a/Source/panels/spell_book.cpp +++ b/Source/panels/spell_book.cpp @@ -15,7 +15,7 @@ #include "engine/rectangle.hpp" #include "engine/render/clx_render.hpp" #include "engine/render/text_render.hpp" -#include "init.h" +#include "game_mode.hpp" #include "missiles.h" #include "panels/spell_icons.hpp" #include "panels/ui_panels.hpp" diff --git a/Source/panels/spell_icons.cpp b/Source/panels/spell_icons.cpp index 9d0230abb1d..ad07ecaa44d 100644 --- a/Source/panels/spell_icons.cpp +++ b/Source/panels/spell_icons.cpp @@ -9,7 +9,6 @@ #include "engine/render/clx_render.hpp" #include "engine/render/primitive_render.hpp" #include "game_mode.hpp" -#include "init.h" namespace devilution { diff --git a/Source/pfile.cpp b/Source/pfile.cpp index 3e660b95663..4f98a2af7ac 100644 --- a/Source/pfile.cpp +++ b/Source/pfile.cpp @@ -17,7 +17,6 @@ #include "engine/load_file.hpp" #include "engine/render/primitive_render.hpp" #include "game_mode.hpp" -#include "init.h" #include "loadsave.h" #include "menu.h" #include "mpq/mpq_common.hpp" diff --git a/Source/player.cpp b/Source/player.cpp index cba3a5ea37d..18b6816b0b3 100644 --- a/Source/player.cpp +++ b/Source/player.cpp @@ -28,7 +28,6 @@ #include "gamemenu.h" #include "headless_mode.hpp" #include "help.h" -#include "init.h" #include "inv_iterators.hpp" #include "levels/trigs.h" #include "lighting.h" @@ -1463,9 +1462,9 @@ void ValidatePlayer() HeroClass GetPlayerSpriteClass(HeroClass cls) { - if (cls == HeroClass::Bard && !gbBard) + if (cls == HeroClass::Bard && !HaveBardAssets()) return HeroClass::Rogue; - if (cls == HeroClass::Barbarian && !gbBarbarian) + if (cls == HeroClass::Barbarian && !HaveBarbarianAssets()) return HeroClass::Warrior; return cls; } diff --git a/Source/qol/chatlog.cpp b/Source/qol/chatlog.cpp index 4fde2956aac..5704cdd5da7 100644 --- a/Source/qol/chatlog.cpp +++ b/Source/qol/chatlog.cpp @@ -20,7 +20,6 @@ #include "engine/render/text_render.hpp" #include "gamemenu.h" #include "help.h" -#include "init.h" #include "inv.h" #include "minitext.h" #include "stores.h" diff --git a/Source/quests.cpp b/Source/quests.cpp index f7e69a3b44f..c96a922a63d 100644 --- a/Source/quests.cpp +++ b/Source/quests.cpp @@ -18,7 +18,6 @@ #include "engine/render/text_render.hpp" #include "engine/world_tile.hpp" #include "game_mode.hpp" -#include "init.h" #include "levels/gendung.h" #include "levels/town.h" #include "levels/trigs.h" diff --git a/Source/stores.cpp b/Source/stores.cpp index e5afd51751e..bd22465e6d6 100644 --- a/Source/stores.cpp +++ b/Source/stores.cpp @@ -14,14 +14,14 @@ #include "controls/plrctrls.h" #include "cursor.h" #include "engine/backbuffer_state.hpp" -#include "engine/load_cel.hpp" #include "engine/random.hpp" #include "engine/render/clx_render.hpp" #include "engine/render/primitive_render.hpp" #include "engine/render/text_render.hpp" #include "engine/trn.hpp" -#include "init.h" +#include "game_mode.hpp" #include "minitext.h" +#include "multi.h" #include "options.h" #include "panels/info_box.hpp" #include "qol/stash.h" diff --git a/Source/utils/log.hpp b/Source/utils/log.hpp index 26c42952778..3876581552d 100644 --- a/Source/utils/log.hpp +++ b/Source/utils/log.hpp @@ -4,6 +4,7 @@ #include #include +#include #include #include "utils/str_cat.hpp" diff --git a/Source/utils/soundsample.cpp b/Source/utils/soundsample.cpp index ac34d536969..40ce0ba47a9 100644 --- a/Source/utils/soundsample.cpp +++ b/Source/utils/soundsample.cpp @@ -7,6 +7,8 @@ #include #include +#include + #include #ifdef USE_SDL1 #include "utils/sdl2_to_1_2_backports.h" @@ -91,6 +93,26 @@ float VolumeLogToLinear(int logVolume, int logMin, int logMax) ///// SoundSample ///// +void SoundSample::SetFinishCallback(Aulib::Stream::Callback &&callback) +{ + stream_->setFinishCallback(std::forward(callback)); +} + +void SoundSample::Stop() +{ + stream_->stop(); +} + +void SoundSample::Mute() +{ + stream_->mute(); +} + +void SoundSample::Unmute() +{ + stream_->unmute(); +} + void SoundSample::Release() { stream_ = nullptr; diff --git a/Source/utils/soundsample.h b/Source/utils/soundsample.h index 5673d6479cd..6f2223a2335 100644 --- a/Source/utils/soundsample.h +++ b/Source/utils/soundsample.h @@ -2,13 +2,19 @@ #include #include +#include #include - -#include +#include #include "engine/sound_defs.hpp" #include "utils/stdcompat/shared_ptr_array.hpp" +// Forward-declares Aulib::Stream to avoid adding dependencies +// on SDL_audiolib to every user of this header. +namespace Aulib { +class Stream; +} // namespace Aulib + namespace devilution { class SoundSample final { @@ -28,10 +34,7 @@ class SoundSample final { // Returns 0 on success. int SetChunkStream(std::string filePath, bool isMp3, bool logErrors = true); - void SetFinishCallback(Aulib::Stream::Callback &&callback) - { - stream_->setFinishCallback(std::forward(callback)); - } + void SetFinishCallback(std::function &&callback); /** * @brief Sets the sample's WAV, FLAC, or Ogg/Vorbis data. @@ -72,23 +75,13 @@ class SoundSample final { /** * @brief Stop playing the sound */ - void Stop() - { - stream_->stop(); - } + void Stop(); void SetVolume(int logVolume, int logMin, int logMax); void SetStereoPosition(int logPan); - void Mute() - { - stream_->mute(); - } - - void Unmute() - { - stream_->unmute(); - } + void Mute(); + void Unmute(); /** * @return Audio duration in ms diff --git a/test/app_fatal_for_testing.cpp b/test/app_fatal_for_testing.cpp index fd888865a5c..348a73e2ef5 100644 --- a/test/app_fatal_for_testing.cpp +++ b/test/app_fatal_for_testing.cpp @@ -3,10 +3,32 @@ namespace devilution { +[[noreturn]] void DisplayFatalErrorAndExit(std::string_view title, std::string_view body) +{ + std::cerr << "fatal error: " << title << "\n" + << body << std::endl; + std::abort(); +} + [[noreturn]] void app_fatal(std::string_view str) { std::cerr << "app_fatal: " << str << std::endl; std::abort(); } +[[noreturn]] void ErrDlg(const char *title, std::string_view error, std::string_view logFilePath, int logLineNr) +{ + std::cerr << "ErrDlg: " << title << "\n" + << error << "\n" + << logFilePath << ":" << logLineNr << std::endl; + std::abort(); +} + +[[noreturn]] void assert_fail(int nLineNo, const char *pszFile, const char *pszFail) +{ + std::cerr << "assert_fail: " << pszFile << ":" << nLineNo << "\n" + << pszFail << std::endl; + std::abort(); +} + } // namespace devilution diff --git a/test/dun_render_benchmark.cpp b/test/dun_render_benchmark.cpp index d5b4a0b993c..ece59309344 100644 --- a/test/dun_render_benchmark.cpp +++ b/test/dun_render_benchmark.cpp @@ -5,12 +5,12 @@ #include #include "diablo.h" +#include "engine/assets.hpp" #include "engine/clx_sprite.hpp" #include "engine/displacement.hpp" #include "engine/load_file.hpp" #include "engine/render/dun_render.hpp" #include "engine/surface.hpp" -#include "init.h" #include "levels/dun_tile.hpp" #include "levels/gendung.h" #include "lighting.h" diff --git a/test/inv_test.cpp b/test/inv_test.cpp index 29d25e8f289..999b12f8c02 100644 --- a/test/inv_test.cpp +++ b/test/inv_test.cpp @@ -1,6 +1,7 @@ #include #include "cursor.h" +#include "engine/assets.hpp" #include "inv.h" #include "player.h" #include "storm/storm_net.hpp" diff --git a/test/language_for_testing.cpp b/test/language_for_testing.cpp index 08667758e80..292d04ce60b 100644 --- a/test/language_for_testing.cpp +++ b/test/language_for_testing.cpp @@ -1,5 +1,6 @@ #include #include +#include std::string_view GetLanguageCode() { return "en"; } bool HasTranslation(const std::string &locale) { return true; } @@ -7,3 +8,4 @@ void LanguageInitialize() { } std::string_view LanguageTranslate(const char *key) { return key; } std::string_view LanguagePluralTranslate(const char *singular, std::string_view plural, int count) { return count == 1 ? singular : plural; } std::string_view LanguageParticularTranslate(std::string_view context, std::string_view message) { return message; } +std::vector GetLocales() { return {}; } diff --git a/test/pack_test.cpp b/test/pack_test.cpp index 862427c5e28..36df4e024aa 100644 --- a/test/pack_test.cpp +++ b/test/pack_test.cpp @@ -3,6 +3,7 @@ #include #include "cursor.h" +#include "engine/assets.hpp" #include "game_mode.hpp" #include "monstdat.h" #include "pack.h" diff --git a/test/timedemo_test.cpp b/test/timedemo_test.cpp index b67498bbbf9..d8c19de5183 100644 --- a/test/timedemo_test.cpp +++ b/test/timedemo_test.cpp @@ -2,10 +2,11 @@ #include #include -#include "diablo.h" +#include "engine/assets.hpp" #include "engine/demomode.h" #include "game_mode.hpp" #include "headless_mode.hpp" +#include "init.h" #include "lua/lua.hpp" #include "monstdat.h" #include "options.h"