From 15838861cd0d55d5a7ea042f38ed6b2034b0d143 Mon Sep 17 00:00:00 2001 From: Matt Date: Fri, 1 Mar 2019 00:23:15 +0100 Subject: [PATCH] Add load and save test. --- test/tests/CMakeLists.txt | 9 ++ test/tests/NetworkLoadSave.cpp | 214 +++++++++++++++++++++++++++++++++ test/tests/tests.vcxproj | 1 + 3 files changed, 224 insertions(+) create mode 100644 test/tests/NetworkLoadSave.cpp diff --git a/test/tests/CMakeLists.txt b/test/tests/CMakeLists.txt index 3e46d7fd1a..842b6e7e54 100644 --- a/test/tests/CMakeLists.txt +++ b/test/tests/CMakeLists.txt @@ -226,3 +226,12 @@ SET_CHECK_CXX_FLAGS(test_pathfinding) target_link_libraries(test_pathfinding ${GTEST_LIBRARIES} libopenrct2 ${LDL} z) target_link_platform_libraries(test_pathfinding) add_test(NAME pathfinding COMMAND test_pathfinding) + +# LoadSave test +set(NETWORKLOADSAVE_TEST_SOURCES "${CMAKE_CURRENT_LIST_DIR}/NetworkLoadSave.cpp" + "${CMAKE_CURRENT_LIST_DIR}/TestData.cpp") +add_executable(test_networkloadsave ${NETWORKLOADSAVE_TEST_SOURCES}) +SET_CHECK_CXX_FLAGS(test_networkloadsave) +target_link_libraries(test_networkloadsave ${GTEST_LIBRARIES} libopenrct2 ${LDL} z) +target_link_platform_libraries(test_networkloadsave) +add_test(NAME networkloadsave COMMAND test_networkloadsave) diff --git a/test/tests/NetworkLoadSave.cpp b/test/tests/NetworkLoadSave.cpp new file mode 100644 index 0000000000..0e65ee504e --- /dev/null +++ b/test/tests/NetworkLoadSave.cpp @@ -0,0 +1,214 @@ +/***************************************************************************** + * Copyright (c) 2014-2019 OpenRCT2 developers + * + * For a complete list of all authors, please refer to contributors.md + * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2 + * + * OpenRCT2 is licensed under the GNU General Public License version 3. + *****************************************************************************/ + +#include "TestData.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace OpenRCT2; + +// Copied from Network.cpp +static bool LoadMap(IStream* stream) +{ + bool result = false; + try + { + auto context = GetContext(); + auto& objManager = context->GetObjectManager(); + auto importer = ParkImporter::CreateS6(context->GetObjectRepository()); + auto loadResult = importer->LoadFromStream(stream, false); + objManager.LoadObjects(loadResult.RequiredObjects.data(), loadResult.RequiredObjects.size()); + importer->Import(); + + sprite_position_tween_reset(); + + // Read checksum + [[maybe_unused]] uint32_t checksum = stream->ReadValue(); + + // Read other data not in normal save files + stream->Read(gSpriteSpatialIndex, 0x10001 * sizeof(uint16_t)); + gGamePaused = stream->ReadValue(); + _guestGenerationProbability = stream->ReadValue(); + _suggestedGuestMaximum = stream->ReadValue(); + gCheatsSandboxMode = stream->ReadValue() != 0; + gCheatsDisableClearanceChecks = stream->ReadValue() != 0; + gCheatsDisableSupportLimits = stream->ReadValue() != 0; + gCheatsDisableTrainLengthLimit = stream->ReadValue() != 0; + gCheatsEnableChainLiftOnAllTrack = stream->ReadValue() != 0; + gCheatsShowAllOperatingModes = stream->ReadValue() != 0; + gCheatsShowVehiclesFromOtherTrackTypes = stream->ReadValue() != 0; + gCheatsFastLiftHill = stream->ReadValue() != 0; + gCheatsDisableBrakesFailure = stream->ReadValue() != 0; + gCheatsDisableAllBreakdowns = stream->ReadValue() != 0; + gCheatsBuildInPauseMode = stream->ReadValue() != 0; + gCheatsIgnoreRideIntensity = stream->ReadValue() != 0; + gCheatsDisableVandalism = stream->ReadValue() != 0; + gCheatsDisableLittering = stream->ReadValue() != 0; + gCheatsNeverendingMarketing = stream->ReadValue() != 0; + gCheatsFreezeWeather = stream->ReadValue() != 0; + gCheatsDisablePlantAging = stream->ReadValue() != 0; + gCheatsAllowArbitraryRideTypeChanges = stream->ReadValue() != 0; + gCheatsDisableRideValueAging = stream->ReadValue() != 0; + gConfigGeneral.show_real_names_of_guests = stream->ReadValue() != 0; + gCheatsIgnoreResearchStatus = stream->ReadValue() != 0; + + result = true; + } + catch (const std::exception&) + { + } + return result; +} + +// Copied from Network.cpp +static bool SaveMap(IStream* stream, const std::vector& objects) +{ + bool result = false; + viewport_set_saved_view(); + try + { + auto s6exporter = std::make_unique(); + s6exporter->ExportObjectsList = objects; + s6exporter->Export(); + s6exporter->SaveGame(stream); + + // Write other data not in normal save files + stream->Write(gSpriteSpatialIndex, 0x10001 * sizeof(uint16_t)); + stream->WriteValue(gGamePaused); + stream->WriteValue(_guestGenerationProbability); + stream->WriteValue(_suggestedGuestMaximum); + stream->WriteValue(gCheatsSandboxMode); + stream->WriteValue(gCheatsDisableClearanceChecks); + stream->WriteValue(gCheatsDisableSupportLimits); + stream->WriteValue(gCheatsDisableTrainLengthLimit); + stream->WriteValue(gCheatsEnableChainLiftOnAllTrack); + stream->WriteValue(gCheatsShowAllOperatingModes); + stream->WriteValue(gCheatsShowVehiclesFromOtherTrackTypes); + stream->WriteValue(gCheatsFastLiftHill); + stream->WriteValue(gCheatsDisableBrakesFailure); + stream->WriteValue(gCheatsDisableAllBreakdowns); + stream->WriteValue(gCheatsBuildInPauseMode); + stream->WriteValue(gCheatsIgnoreRideIntensity); + stream->WriteValue(gCheatsDisableVandalism); + stream->WriteValue(gCheatsDisableLittering); + stream->WriteValue(gCheatsNeverendingMarketing); + stream->WriteValue(gCheatsFreezeWeather); + stream->WriteValue(gCheatsDisablePlantAging); + stream->WriteValue(gCheatsAllowArbitraryRideTypeChanges); + stream->WriteValue(gCheatsDisableRideValueAging); + stream->WriteValue(gConfigGeneral.show_real_names_of_guests); + stream->WriteValue(gCheatsIgnoreResearchStatus); + + result = true; + } + catch (const std::exception&) + { + } + return result; +} + +// Special version of game_load_init which does not call reset_sprite_spatial_index +// This is conditionally done in game_load_init for when we are not a client. +static void network_game_load_init() +{ + gScreenFlags = SCREEN_FLAGS_PLAYING; + + reset_all_sprite_quadrant_placements(); + scenery_set_default_placement_configuration(); + + gWindowUpdateTicks = 0; + + load_palette(); + + gGameSpeed = 1; +} + +TEST(NetworkLoadSave, all) +{ + std::string path = TestData::GetParkPath("bpb.sv6"); + + gOpenRCT2Headless = true; + gOpenRCT2NoGraphics = true; + + core_init(); + + auto mainContext = CreateContext(); + bool initialised = mainContext->Initialise(); + ASSERT_TRUE(initialised); + + auto& objManager = mainContext->GetObjectManager(); + + // Load initial park data. + { + auto importer = ParkImporter::CreateS6(mainContext->GetObjectRepository()); + auto loadResult = importer->Load(path.c_str()); + objManager.LoadObjects(loadResult.RequiredObjects.data(), loadResult.RequiredObjects.size()); + importer->Import(); + + game_load_init(); + } + + // Advance the park for 100 ticks to have changes in the park. + { + for (int i = 0; i < 100; i++) + { + mainContext->GetGameState()->UpdateLogic(); + } + } + + MemoryStream savedPark; + rct_sprite_checksum checksumSave; + rct_sprite_checksum checksumLoad; + + // Save park. + { + std::vector objects = objManager.GetPackableObjects(); + + bool saveResult = SaveMap(&savedPark, objects); + ASSERT_TRUE(saveResult); + + checksumSave = sprite_checksum(); + } + + // Import the exported version. + { + savedPark.SetPosition(0); + + bool loadResult = LoadMap(&savedPark); + ASSERT_TRUE(loadResult); + + network_game_load_init(); + + checksumLoad = sprite_checksum(); + } + + ASSERT_EQ(checksumSave.ToString(), checksumLoad.ToString()); + + SUCCEED(); +} diff --git a/test/tests/tests.vcxproj b/test/tests/tests.vcxproj index d7fd9aaff5..f4d448af46 100644 --- a/test/tests/tests.vcxproj +++ b/test/tests/tests.vcxproj @@ -64,6 +64,7 @@ +