diff --git a/Source/diablo.cpp b/Source/diablo.cpp index ef3d78258..0e37ea997 100644 --- a/Source/diablo.cpp +++ b/Source/diablo.cpp @@ -1462,6 +1462,7 @@ bool CanPlayerTakeAction() { return !IsPlayerDead() && IsGameRunning(); } +} // namespace void InitKeymapActions() { @@ -1709,7 +1710,6 @@ void InitKeymapActions() }); #endif } -} // namespace void FreeGameMem() { diff --git a/Source/diablo.h b/Source/diablo.h index 9188e6b4d..76c030a16 100644 --- a/Source/diablo.h +++ b/Source/diablo.h @@ -60,11 +60,11 @@ enum class MouseActionType : int { extern uint32_t glSeedTbl[NUMLEVELS]; extern Point MousePosition; -extern bool gbRunGame; +extern DVL_API_FOR_TEST bool gbRunGame; extern bool gbRunGameResult; extern bool ReturnToMainMenu; extern bool gbProcessPlayers; -extern bool gbLoadGame; +extern DVL_API_FOR_TEST bool gbLoadGame; extern bool cineflag; extern int force_redraw; /* These are defined in fonts.h */ @@ -82,6 +82,7 @@ extern char gszProductName[64]; extern MouseActionType LastMouseButtonAction; +void InitKeymapActions(); void FreeGameMem(); bool StartGame(bool bNewGame, bool bSinglePlayer); [[noreturn]] void diablo_quit(int exitStatus); diff --git a/Source/engine/sound.h b/Source/engine/sound.h index 17c0cdda8..6ca096314 100644 --- a/Source/engine/sound.h +++ b/Source/engine/sound.h @@ -10,6 +10,7 @@ #include #include "levels/gendung.h" +#include "utils/attributes.h" #ifndef NOSOUND #include "utils/soundsample.h" @@ -68,7 +69,7 @@ void music_unmute(); /* data */ -extern bool gbMusicOn; -extern bool gbSoundOn; +extern DVL_API_FOR_TEST bool gbMusicOn; +extern DVL_API_FOR_TEST bool gbSoundOn; } // namespace devilution diff --git a/Source/init.h b/Source/init.h index 3730e7bba..57d15fde0 100644 --- a/Source/init.h +++ b/Source/init.h @@ -14,8 +14,8 @@ namespace devilution { extern bool gbActive; extern std::optional hellfire_mpq; extern EventHandler CurrentEventHandler; -extern std::optional spawn_mpq; -extern std::optional diabdat_mpq; +extern DVL_API_FOR_TEST std::optional spawn_mpq; +extern DVL_API_FOR_TEST std::optional diabdat_mpq; extern DVL_API_FOR_TEST bool gbIsSpawn; extern DVL_API_FOR_TEST bool gbIsHellfire; extern DVL_API_FOR_TEST bool gbVanilla; diff --git a/Source/utils/display.cpp b/Source/utils/display.cpp index cb9ab1445..c9f1a959b 100644 --- a/Source/utils/display.cpp +++ b/Source/utils/display.cpp @@ -152,14 +152,6 @@ void CalculateUIRectangle() }; } -void AdjustToScreenGeometry(Size windowSize) -{ - gnScreenWidth = windowSize.width; - gnScreenHeight = windowSize.height; - CalculateUIRectangle(); - CalculatePanelAreas(); -} - Size GetPreferredWindowSize() { Size windowSize = *sgOptions.Graphics.resolution; @@ -175,6 +167,14 @@ Size GetPreferredWindowSize() } // namespace +void AdjustToScreenGeometry(Size windowSize) +{ + gnScreenWidth = windowSize.width; + gnScreenHeight = windowSize.height; + CalculateUIRectangle(); + CalculatePanelAreas(); +} + float GetDpiScalingFactor() { #ifdef USE_SDL1 diff --git a/Source/utils/ui_fwd.h b/Source/utils/ui_fwd.h index 6e6d1243e..15412cbe6 100644 --- a/Source/utils/ui_fwd.h +++ b/Source/utils/ui_fwd.h @@ -18,6 +18,7 @@ Uint16 GetViewportHeight(); /** @brief Returns the UI (Menus, Messages, Help) can use. Currently this is 640x480 like vanilla. */ const Rectangle &GetUIRectangle(); +void AdjustToScreenGeometry(Size windowSize); float GetDpiScalingFactor(); /** * @brief Set the screen to fullscreen or windowe if fullsc diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index ca1120dd4..f8b35ce61 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -35,6 +35,7 @@ set(tests player_test quests_test random_test + timedemo_test scrollrt_test stores_test utf8_test diff --git a/test/Fixtures.cmake b/test/Fixtures.cmake index 6ef13bf9a..568bcf99f 100644 --- a/test/Fixtures.cmake +++ b/test/Fixtures.cmake @@ -64,6 +64,9 @@ set(devilutionx_fixtures Levels/L4Data/Vile1.DUN Levels/L4Data/Warlord.DUN Levels/L4Data/Warlord2.DUN + timedemo/WarriorLevel1to2/demo_0.dmo + timedemo/WarriorLevel1to2/demo_0_reference_spawn_0.sv + timedemo/WarriorLevel1to2/spawn_0.sv ) foreach(fixture ${devilutionx_fixtures}) diff --git a/test/fixtures/timedemo/WarriorLevel1to2/demo_0.dmo b/test/fixtures/timedemo/WarriorLevel1to2/demo_0.dmo new file mode 100644 index 000000000..f71815bac Binary files /dev/null and b/test/fixtures/timedemo/WarriorLevel1to2/demo_0.dmo differ diff --git a/test/fixtures/timedemo/WarriorLevel1to2/demo_0_reference_spawn_0.sv b/test/fixtures/timedemo/WarriorLevel1to2/demo_0_reference_spawn_0.sv new file mode 100644 index 000000000..ce781a9be Binary files /dev/null and b/test/fixtures/timedemo/WarriorLevel1to2/demo_0_reference_spawn_0.sv differ diff --git a/test/fixtures/timedemo/WarriorLevel1to2/spawn_0.sv b/test/fixtures/timedemo/WarriorLevel1to2/spawn_0.sv new file mode 100644 index 000000000..d9c9c78c2 Binary files /dev/null and b/test/fixtures/timedemo/WarriorLevel1to2/spawn_0.sv differ diff --git a/test/timedemo_test.cpp b/test/timedemo_test.cpp new file mode 100644 index 000000000..8570e3ba9 --- /dev/null +++ b/test/timedemo_test.cpp @@ -0,0 +1,66 @@ +#include +#include +#include + +#include "diablo.h" +#include "engine/demomode.h" +#include "options.h" +#include "pfile.h" +#include "utils/display.h" +#include "utils/paths.h" + +using namespace devilution; + +namespace { + +bool Dummy_GetHeroInfo(_uiheroinfo *pInfo) +{ + return true; +} + +void RunTimedemo(std::string timedemoFolderName) +{ + std::string unitTestFolderCompletePath = paths::BasePath() + "/test/fixtures/timedemo/" + timedemoFolderName; + paths::SetPrefPath(unitTestFolderCompletePath); + paths::SetConfigPath(unitTestFolderCompletePath); + LoadCoreArchives(); + LoadGameArchives(); + + // The tests need spawn.mpq or diabdat.mpq + // Please provide them so that the tests can run successfully + ASSERT_TRUE(spawn_mpq || diabdat_mpq); + + InitKeymapActions(); + LoadOptions(); + + const int demoNumber = 0; + + // Currently only spawn.mpq is present when building on github actions + gbIsSpawn = true; + gbIsHellfire = false; + gbMusicOn = false; + gbSoundOn = false; + gbQuietMode = true; + demo::InitPlayBack(demoNumber, true); + + pfile_ui_set_hero_infos(Dummy_GetHeroInfo); + gbLoadGame = true; + + demo::OverrideOptions(); + + AdjustToScreenGeometry(*sgOptions.Graphics.resolution); + + StartGame(false, true); + + ASSERT_EQ(pfile_compare_hero_demo(demoNumber), HeroCompareResult::Same); + ASSERT_FALSE(gbRunGame); + gbRunGame = false; + init_cleanup(); +} + +} // namespace + +TEST(Timedemo, WarriorLevel1to2) +{ + RunTimedemo("WarriorLevel1to2"); +}