From 6af0cb2b88d2657e4a5f8e8adcd3b5f049953e1f Mon Sep 17 00:00:00 2001 From: Ted John Date: Mon, 21 May 2018 19:06:21 +0100 Subject: [PATCH] Fix import of S4 and S6 --- src/openrct2/Context.cpp | 2 +- src/openrct2/ParkImporter.h | 4 +- src/openrct2/object/ObjectManager.cpp | 6 +-- src/openrct2/rct1/S4Importer.cpp | 8 ++-- src/openrct2/rct2/S6Importer.cpp | 66 ++++++++------------------- src/openrct2/scenario/Scenario.h | 2 +- test/tests/MultiLaunch.cpp | 6 +-- test/tests/TileElements.cpp | 4 +- 8 files changed, 33 insertions(+), 65 deletions(-) diff --git a/src/openrct2/Context.cpp b/src/openrct2/Context.cpp index dacc5bc7ae..8f7c1cf470 100644 --- a/src/openrct2/Context.cpp +++ b/src/openrct2/Context.cpp @@ -559,7 +559,7 @@ namespace OpenRCT2 try { auto result = parkImporter->LoadFromStream(stream, info.Type == FILE_TYPE::SCENARIO, false, path.c_str()); - // _objectManager->LoadObjects(result.RequiredObjects.data(), result.RequiredObjects.size()); + _objectManager->LoadObjects(result.RequiredObjects.data(), result.RequiredObjects.size()); parkImporter->Import(); String::Set(gScenarioSavePath, Util::CountOf(gScenarioSavePath), path.c_str()); String::Set(gCurrentLoadedPath, Util::CountOf(gCurrentLoadedPath), path.c_str()); diff --git a/src/openrct2/ParkImporter.h b/src/openrct2/ParkImporter.h index 724bb1e4a2..96c4cd59a7 100644 --- a/src/openrct2/ParkImporter.h +++ b/src/openrct2/ParkImporter.h @@ -80,7 +80,7 @@ namespace ParkImporter bool ExtensionIsScenario(const std::string &extension); } -class ObjectLoadException : std::exception +class ObjectLoadException : public std::exception { public: std::vector const MissingObjects; @@ -91,7 +91,7 @@ public: } }; -class UnsupportedRCTCFlagException : std::exception +class UnsupportedRCTCFlagException : public std::exception { public: uint8 const Flag; diff --git a/src/openrct2/object/ObjectManager.cpp b/src/openrct2/object/ObjectManager.cpp index 40448fef5f..212dd7128f 100644 --- a/src/openrct2/object/ObjectManager.cpp +++ b/src/openrct2/object/ObjectManager.cpp @@ -135,7 +135,7 @@ public: { // Find all the required objects bool missingObjects; - auto requiredObjects = GetRequiredObjects(entries, &missingObjects); + auto requiredObjects = GetRequiredObjects(entries, count, &missingObjects); if (missingObjects) { return false; @@ -482,11 +482,11 @@ private: return invalidEntries; } - std::vector GetRequiredObjects(const rct_object_entry * entries, bool * missingObjects) + std::vector GetRequiredObjects(const rct_object_entry * entries, size_t count, bool * missingObjects) { std::vector requiredObjects; *missingObjects = false; - for (sint32 i = 0; i < OBJECT_ENTRY_COUNT; i++) + for (sint32 i = 0; i < count; i++) { const rct_object_entry * entry = &entries[i]; const ObjectRepositoryItem * ori = nullptr; diff --git a/src/openrct2/rct1/S4Importer.cpp b/src/openrct2/rct1/S4Importer.cpp index 32558a9308..03a4c32897 100644 --- a/src/openrct2/rct1/S4Importer.cpp +++ b/src/openrct2/rct1/S4Importer.cpp @@ -177,7 +177,7 @@ public: bool skipObjectCheck, const utf8 * path) override { - _s4 = ReadAndDecodeS4(stream, isScenario); + _s4 = *ReadAndDecodeS4(stream, isScenario); _s4Path = path; // Only determine what objects we required to import this saved game @@ -298,9 +298,9 @@ public: } private: - rct1_s4 ReadAndDecodeS4(IStream * stream, bool isScenario) + std::unique_ptr ReadAndDecodeS4(IStream * stream, bool isScenario) { - rct1_s4 s4; + auto s4 = std::make_unique(); size_t dataSize = stream->GetLength() - stream->GetPosition(); auto deleter_lambda = [dataSize](uint8 * ptr) { Memory::FreeArray(ptr, dataSize); }; auto data = std::unique_ptr(stream->ReadArray(dataSize), deleter_lambda); @@ -319,7 +319,7 @@ private: if (decodedSize == sizeof(rct1_s4)) { - std::memcpy(&s4, decodedData.get(), sizeof(rct1_s4)); + std::memcpy(s4.get(), decodedData.get(), sizeof(rct1_s4)); return s4; } else diff --git a/src/openrct2/rct2/S6Importer.cpp b/src/openrct2/rct2/S6Importer.cpp index a71fc1ca90..a91361fdfc 100644 --- a/src/openrct2/rct2/S6Importer.cpp +++ b/src/openrct2/rct2/S6Importer.cpp @@ -55,13 +55,6 @@ #include "../world/Sprite.h" #include "../world/Surface.h" -class ObjectLoadException : public std::runtime_error -{ -public: - ObjectLoadException() : std::runtime_error("Unable to load objects.") { } - explicit ObjectLoadException(const std::string &message) : std::runtime_error(message) { } -}; - /** * Class to import RollerCoaster Tycoon 2 scenarios (*.SC6) and saved games (*.SV6). */ @@ -147,7 +140,7 @@ public: if (_s6.header.classic_flag == 0xf) { - return ParkLoadResult::CreateUnsupportedRCTCflag(_s6.header.classic_flag); + throw UnsupportedRCTCFlagException(_s6.header.classic_flag); } // Read packed objects @@ -179,15 +172,9 @@ public: chunkReader.ReadChunk(&_s6.next_free_tile_element_pointer_index, 3048816); } - auto missingObjects = _objectManager->GetInvalidObjects(_s6.objects); - - if (!missingObjects.empty()) - { - return ParkLoadResult::CreateMissingObjects(missingObjects); - } - _s6Path = path; - return ParkLoadResult::CreateOK(); + + return ParkLoadResult(std::vector(std::begin(_s6.objects), std::end(_s6.objects))); } bool GetDetails(scenario_index_entry * dst) override @@ -452,10 +439,11 @@ public: // pad_13CE778 // Fix and set dynamic variables - if (!_objectManager->LoadObjects(_s6.objects, OBJECT_ENTRY_COUNT)) - { - throw ObjectLoadException(); - } + // TODO objects should already be loaded + // if (!_objectManager->LoadObjects(_s6.objects, OBJECT_ENTRY_COUNT)) + // { + // throw ObjectLoadException(); + // } map_strip_ghost_flag_from_elements(); map_update_tile_pointers(); game_convert_strings_to_utf8(); @@ -893,47 +881,33 @@ void load_from_sv6(const char * path) * rct2: 0x00676053 * scenario (ebx) */ -ParkLoadResult * load_from_sc6(const char * path) +void load_from_sc6(const char * path) { - ParkLoadResult * result = nullptr; auto context = OpenRCT2::GetContext(); - auto s6Importer = new S6Importer(context->GetObjectRepository(), context->GetObjectManager()); + auto s6Importer = std::make_unique(context->GetObjectRepository(), context->GetObjectManager()); try { - result = new ParkLoadResult(s6Importer->LoadScenario(path)); - if (result->Error == PARK_LOAD_ERROR_OK) - { - s6Importer->Import(); - - game_fix_save_vars(); - sprite_position_tween_reset(); - } + auto result = s6Importer->LoadScenario(path); + s6Importer->Import(); + game_fix_save_vars(); + sprite_position_tween_reset(); + return; } - catch (const ObjectLoadException &) + catch (const ObjectLoadException&) { gErrorType = ERROR_TYPE_FILE_LOAD; gErrorStringId = STR_GAME_SAVE_FAILED; } - catch (const IOException &) + catch (const IOException&) { gErrorType = ERROR_TYPE_FILE_LOAD; gErrorStringId = STR_GAME_SAVE_FAILED; } - catch (const std::exception &) + catch (const std::exception&) { gErrorType = ERROR_TYPE_FILE_LOAD; gErrorStringId = STR_FILE_CONTAINS_INVALID_DATA; } - delete s6Importer; - - if (result == nullptr) - { - result = new ParkLoadResult(ParkLoadResult::CreateUnknown()); - } - if (result->Error != PARK_LOAD_ERROR_OK) - { - gScreenAge = 0; - gLastAutoSaveUpdate = AUTOSAVE_PAUSE; - } - return result; + gScreenAge = 0; + gLastAutoSaveUpdate = AUTOSAVE_PAUSE; } diff --git a/src/openrct2/scenario/Scenario.h b/src/openrct2/scenario/Scenario.h index 11fe037e4b..a2d25fe1f7 100644 --- a/src/openrct2/scenario/Scenario.h +++ b/src/openrct2/scenario/Scenario.h @@ -385,7 +385,7 @@ extern uint32 gLastAutoSaveUpdate; extern char gScenarioFileName[260]; -ParkLoadResult * load_from_sc6(const char *path); +void load_from_sc6(const char *path); void scenario_begin(); void scenario_update(); diff --git a/test/tests/MultiLaunch.cpp b/test/tests/MultiLaunch.cpp index dbd8b939cf..7830e23e9a 100644 --- a/test/tests/MultiLaunch.cpp +++ b/test/tests/MultiLaunch.cpp @@ -29,11 +29,7 @@ TEST(MultiLaunchTest, all) bool initialised = context->Initialise(); ASSERT_TRUE(initialised); - ParkLoadResult * plr = load_from_sv6(path.c_str()); - - ASSERT_EQ(ParkLoadResult_GetError(plr), PARK_LOAD_ERROR_OK); - ParkLoadResult_Delete(plr); - + load_from_sv6(path.c_str()); game_load_init(); // Check ride count to check load was successful diff --git a/test/tests/TileElements.cpp b/test/tests/TileElements.cpp index e305c980e8..0564478295 100644 --- a/test/tests/TileElements.cpp +++ b/test/tests/TileElements.cpp @@ -21,9 +21,7 @@ protected: bool initialised = _context->Initialise(); ASSERT_TRUE(initialised); - ParkLoadResult * plr = load_from_sv6(parkPath.c_str()); - ASSERT_EQ(ParkLoadResult_GetError(plr), PARK_LOAD_ERROR_OK); - ParkLoadResult_Delete(plr); + load_from_sv6(parkPath.c_str()); game_load_init(); SUCCEED(); }