From 3bb1d478132921cfdaa80c2704738c5b5e7c0c6d Mon Sep 17 00:00:00 2001 From: Ted John Date: Sat, 7 May 2016 17:37:50 +0100 Subject: [PATCH] use new S6Importer for loading saved games --- src/game.c | 69 ----------------------------------------- src/object.h | 3 +- src/object_list.c | 35 +++++++++++---------- src/rct2/S6Importer.cpp | 53 +++++++++++++++++++++++++++++++ 4 files changed, 74 insertions(+), 86 deletions(-) diff --git a/src/game.c b/src/game.c index 26b06f3e15..ed0ae704bd 100644 --- a/src/game.c +++ b/src/game.c @@ -733,75 +733,6 @@ void game_convert_strings_to_rct2(rct_s6_data *s6) } } -/** - * - * rct2: 0x00675E1B - */ -int game_load_sv6(SDL_RWops* rw) -{ - int i, j; - - if (!sawyercoding_validate_checksum(rw)) { - log_error("invalid checksum"); - - gErrorType = ERROR_TYPE_FILE_LOAD; - gGameCommandErrorTitle = STR_FILE_CONTAINS_INVALID_DATA; - return 0; - } - - rct_s6_header *s6Header = (rct_s6_header*)0x009E34E4; - rct_s6_info *s6Info = (rct_s6_info*)0x0141F570; - - // Read first chunk - sawyercoding_read_chunk(rw, (uint8*)s6Header); - if (s6Header->type == S6_TYPE_SAVEDGAME) { - // Read packed objects - if (s6Header->num_packed_objects > 0) { - j = 0; - for (i = 0; i < s6Header->num_packed_objects; i++) - j += object_load_packed(rw); - if (j > 0) - object_list_load(); - } - } - - uint8 load_success = object_read_and_load_entries(rw); - - // Read flags (16 bytes) - sawyercoding_read_chunk(rw, (uint8*)RCT2_ADDRESS_CURRENT_MONTH_YEAR); - - // Read map elements - memset((void*)RCT2_ADDRESS_MAP_ELEMENTS, 0, MAX_MAP_ELEMENTS * sizeof(rct_map_element)); - sawyercoding_read_chunk(rw, (uint8*)RCT2_ADDRESS_MAP_ELEMENTS); - - // Read game data, including sprites - sawyercoding_read_chunk(rw, (uint8*)0x010E63B8); - - if (!load_success){ - set_load_objects_fail_reason(); - if (gInputFlags & INPUT_FLAG_5){ - //call 0x0040705E Sets cursor position and something else. Calls maybe wind func 8 probably pointless - gInputFlags &= ~INPUT_FLAG_5; - } - - return 0;//This never gets called - } - - // The rest is the same as in scenario_load - reset_loaded_objects(); - map_update_tile_pointers(); - reset_0x69EBE4(); - openrct2_reset_object_tween_locations(); - game_convert_strings_to_utf8(); - game_fix_save_vars(); // OpenRCT2 fix broken save games - - // #2407: Resetting screen time to not open a save prompt shortly after loading a park. - gScreenAge = 0; - - gLastAutoSaveTick = SDL_GetTicks(); - return 1; -} - // OpenRCT2 workaround to recalculate some values which are saved redundantly in the save to fix corrupted files. // For example recalculate guest count by looking at all the guests instead of trusting the value in the file. void game_fix_save_vars() { diff --git a/src/object.h b/src/object.h index 39c49a6ffb..d01c7df67f 100644 --- a/src/object.h +++ b/src/object.h @@ -104,7 +104,8 @@ extern void *gLastLoadedObjectChunkData; int object_load_entry(const utf8 *path, rct_object_entry *outEntry); void object_list_load(); void set_load_objects_fail_reason(); -int object_read_and_load_entries(SDL_RWops* rw); +bool object_read_and_load_entries(SDL_RWops* rw); +bool object_load_entries(rct_object_entry* entries); int object_load_packed(SDL_RWops* rw); void object_unload_all(); diff --git a/src/object_list.c b/src/object_list.c index e441841654..3281dbc6f8 100644 --- a/src/object_list.c +++ b/src/object_list.c @@ -530,28 +530,32 @@ void set_load_objects_fail_reason() * * rct2: 0x006AA0C6 */ -int object_read_and_load_entries(SDL_RWops* rw) +bool object_read_and_load_entries(SDL_RWops* rw) { object_unload_all(); - int i, j; - rct_object_entry *entries; + // Read all the object entries + rct_object_entry *entries = malloc(OBJECT_ENTRY_COUNT * sizeof(rct_object_entry)); + sawyercoding_read_chunk(rw, (uint8*)entries); + bool result = object_load_entries(entries); + free(entries); + return result; +} +bool object_load_entries(rct_object_entry* entries) +{ log_verbose("loading required objects"); - // Read all the object entries - entries = malloc(OBJECT_ENTRY_COUNT * sizeof(rct_object_entry)); - sawyercoding_read_chunk(rw, (uint8*)entries); - - uint8 load_fail = 0; + bool loadFailed = false; // Load each object - for (i = 0; i < OBJECT_ENTRY_COUNT; i++) { - if (!check_object_entry(&entries[i])) + for (int i = 0; i < OBJECT_ENTRY_COUNT; i++) { + if (!check_object_entry(&entries[i])) { continue; + } // Get entry group index int entryGroupIndex = i; - for (j = 0; j < countof(object_entry_group_counts); j++) { + for (int j = 0; j < countof(object_entry_group_counts); j++) { if (entryGroupIndex < object_entry_group_counts[j]) break; entryGroupIndex -= object_entry_group_counts[j]; @@ -561,18 +565,17 @@ int object_read_and_load_entries(SDL_RWops* rw) if (!object_load_chunk(entryGroupIndex, &entries[i], NULL)) { log_error("failed to load entry: %.8s", entries[i].name); memcpy((char*)RCT2_ADDRESS_COMMON_FORMAT_ARGS, &entries[i], sizeof(rct_object_entry)); - load_fail = 1; + loadFailed = true; } } - free(entries); - if (load_fail){ + if (loadFailed) { object_unload_all(); - return 0; + return false; } log_verbose("finished loading required objects"); - return 1; + return true; } diff --git a/src/rct2/S6Importer.cpp b/src/rct2/S6Importer.cpp index e71f772d5d..7d439f5f31 100644 --- a/src/rct2/S6Importer.cpp +++ b/src/rct2/S6Importer.cpp @@ -20,12 +20,14 @@ extern "C" { + #include "../game.h" #include "../localisation/date.h" #include "../localisation/localisation.h" #include "../management/finance.h" #include "../management/marketing.h" #include "../management/news_item.h" #include "../management/research.h" + #include "../openrct2.h" #include "../peep/staff.h" #include "../ride/ride.h" #include "../ride/ride_ratings.h" @@ -139,6 +141,8 @@ void S6Importer::LoadScenario(SDL_RWops *rw) void S6Importer::Import() { + RCT2_GLOBAL(0x009E34E4, rct_s6_header) = _s6.header; + gDateMonthsElapsed = _s6.elapsed_months; gDateMonthTicks = _s6.current_day; RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_TICKS, uint32) = _s6.scenario_ticks; @@ -346,4 +350,53 @@ void S6Importer::Import() gWidePathTileLoopX = _s6.wide_path_tile_loop_x; gWidePathTileLoopY = _s6.wide_path_tile_loop_y; // pad_13CE778 + + // Fix and set dynamic variables + if (!object_load_entries(_s6.objects)) { + throw Exception("Unable to load objects."); + } + reset_loaded_objects(); + map_update_tile_pointers(); + reset_0x69EBE4(); + game_convert_strings_to_utf8(); + game_fix_save_vars(); // OpenRCT2 fix broken save games +} + +extern "C" +{ + /** + * + * rct2: 0x00675E1B + */ + int game_load_sv6(SDL_RWops* rw) + { + if (!sawyercoding_validate_checksum(rw)) { + log_error("invalid checksum"); + + gErrorType = ERROR_TYPE_FILE_LOAD; + gGameCommandErrorTitle = STR_FILE_CONTAINS_INVALID_DATA; + return 0; + } + + bool result = false; + auto s6Importer = new S6Importer(); + try + { + s6Importer->LoadSavedGame(rw); + s6Importer->Import(); + + openrct2_reset_object_tween_locations(); + result = true; + } + catch (Exception ex) + { + set_load_objects_fail_reason(); + } + delete s6Importer; + + // #2407: Resetting screen time to not open a save prompt shortly after loading a park. + gScreenAge = 0; + gLastAutoSaveTick = SDL_GetTicks(); + return result; + } }