From a86bc57a9605b5a6b67f18d876c39e81f85e9fac Mon Sep 17 00:00:00 2001 From: Ted John Date: Sun, 8 May 2016 16:02:00 +0100 Subject: [PATCH] use S6Exporter for scenario_save --- src/interface/viewport.c | 23 ++++++++ src/interface/viewport.h | 2 + src/rct2/S6Exporter.cpp | 102 ++++++++++++++++++++++++++--------- src/rct2/S6Exporter.h | 1 + src/rct2/S6Importer.cpp | 3 ++ src/scenario.c | 111 +-------------------------------------- src/scenario.h | 1 + 7 files changed, 109 insertions(+), 134 deletions(-) diff --git a/src/interface/viewport.c b/src/interface/viewport.c index 26b5fec266..19fbb254ad 100644 --- a/src/interface/viewport.c +++ b/src/interface/viewport.c @@ -1668,3 +1668,26 @@ sint16 get_height_marker_offset() // Height labels in metres return 2 * 256; } + +void viewport_set_saved_view() +{ + sint16 viewX = 0; + sint16 viewY = 0; + uint8 viewZoom = 0; + uint8 viewRotation = 0; + + rct_window * w = window_get_main(); + if (w != NULL) { + rct_viewport *viewport = w->viewport; + + viewX = viewport->view_width / 2 + viewport->view_x; + viewY = viewport->view_height / 2 + viewport->view_y; + viewZoom = viewport->zoom; + viewRotation = get_current_rotation(); + } + + gSavedViewX = viewX; + gSavedViewY = viewY; + gSavedViewZoom = viewZoom; + gSavedViewRotation = viewRotation; +} diff --git a/src/interface/viewport.h b/src/interface/viewport.h index 6a9dc679de..d890ec9175 100644 --- a/src/interface/viewport.h +++ b/src/interface/viewport.h @@ -148,4 +148,6 @@ void screen_get_map_xy_side_with_z(sint16 screenX, sint16 screenY, sint16 z, sin uint8 get_current_rotation(); sint16 get_height_marker_offset(); +void viewport_set_saved_view(); + #endif diff --git a/src/rct2/S6Exporter.cpp b/src/rct2/S6Exporter.cpp index 56166030e5..baecf6ed39 100644 --- a/src/rct2/S6Exporter.cpp +++ b/src/rct2/S6Exporter.cpp @@ -45,6 +45,8 @@ extern "C" S6Exporter::S6Exporter() { + ExportObjects = false; + RemoveTracklessRides = false; memset(&_s6, 0, sizeof(_s6)); } @@ -86,11 +88,13 @@ void S6Exporter::SaveScenario(SDL_RWops *rw) void S6Exporter::Save(SDL_RWops * rw, bool isScenario) { - _s6.header.type = isScenario ? S6_TYPE_SAVEDGAME : S6_TYPE_SCENARIO; + _s6.header.type = isScenario ? S6_TYPE_SCENARIO : S6_TYPE_SAVEDGAME; _s6.header.num_packed_objects = scenario_get_num_packed_objects_to_write(); _s6.header.version = S6_RCT2_VERSION; _s6.header.magic_number = S6_MAGIC_NUMBER; + _s6.game_version_number = 201028; + uint8 * buffer = (uint8 *)malloc(0x600000); if (buffer == NULL) { @@ -250,41 +254,91 @@ void S6Exporter::Export() String::Set(_s6.scenario_filename, sizeof(_s6.scenario_filename), _scenarioFileName); + if (RemoveTracklessRides) + { + scenario_remove_trackless_rides(&_s6); + } + scenario_fix_ghosts(&_s6); game_convert_strings_to_rct2(&_s6); } extern "C" { - // Save game state without modifying any of the state for multiplayer - int scenario_save_network(SDL_RWops * rw) - { - // Set saved view - sint16 viewX, viewY; - uint8 viewZoom, viewRotation; - rct_window * w = window_get_main(); - if (w != nullptr) - { - rct_viewport *viewport = w->viewport; + enum { + S6_SAVE_FLAG_EXPORT = 1 << 0, + S6_SAVE_FLAG_SCENARIO = 1 << 1, + S6_SAVE_FLAG_AUTOMATIC = 1 << 31, + }; - viewX = viewport->view_width / 2 + viewport->view_x; - viewY = viewport->view_height / 2 + viewport->view_y; - viewZoom = viewport->zoom; - viewRotation = get_current_rotation(); + /** + * + * rct2: 0x006754F5 + * @param flags bit 0: pack objects, 1: save as scenario + */ + int scenario_save(SDL_RWops* rw, int flags) + { + if (flags & S6_SAVE_FLAG_SCENARIO) + { + log_verbose("saving scenario"); } else { - viewX = 0; - viewY = 0; - viewZoom = 0; - viewRotation = 0; + log_verbose("saving game"); } - gSavedViewX = viewX; - gSavedViewY = viewY; - gSavedViewZoom = viewZoom; - gSavedViewRotation = viewRotation; - + if (!(flags & S6_SAVE_FLAG_AUTOMATIC)) + { + window_close_construction_windows(); + } + + map_reorganise_elements(); + reset_0x69EBE4(); + sprite_clear_all_unused(); + + viewport_set_saved_view(); + + bool result = false; + auto s6exporter = new S6Exporter(); + try + { + s6exporter->ExportObjects = (flags & S6_SAVE_FLAG_EXPORT); + s6exporter->RemoveTracklessRides = true; + s6exporter->Export(); + if (flags & S6_SAVE_FLAG_SCENARIO) + { + s6exporter->SaveScenario(rw); + } + else + { + s6exporter->SaveGame(rw); + } + result = true; + } + catch (Exception) + { + } + delete s6exporter; + + if (flags & S6_SAVE_FLAG_EXPORT) + { + reset_loaded_objects(); + } + + gfx_invalidate_screen(); + + if (result && !(flags & S6_SAVE_FLAG_AUTOMATIC)) + { + gScreenAge = 0; + } + return result; + } + + // Save game state without modifying any of the state for multiplayer + int scenario_save_network(SDL_RWops * rw) + { + viewport_set_saved_view(); + bool result = false; auto s6exporter = new S6Exporter(); try diff --git a/src/rct2/S6Exporter.h b/src/rct2/S6Exporter.h index 7eddc93b13..b715c71b22 100644 --- a/src/rct2/S6Exporter.h +++ b/src/rct2/S6Exporter.h @@ -30,6 +30,7 @@ class S6Exporter { public: bool ExportObjects; + bool RemoveTracklessRides; S6Exporter(); diff --git a/src/rct2/S6Importer.cpp b/src/rct2/S6Importer.cpp index e7f3f84b71..01fd34e955 100644 --- a/src/rct2/S6Importer.cpp +++ b/src/rct2/S6Importer.cpp @@ -422,6 +422,9 @@ extern "C" { set_load_objects_fail_reason(); } + catch (Exception) + { + } delete s6Importer; // #2407: Resetting screen time to not open a save prompt shortly after loading a park. diff --git a/src/scenario.c b/src/scenario.c index 8a8e70f7fc..33eacfe3a4 100644 --- a/src/scenario.c +++ b/src/scenario.c @@ -767,27 +767,6 @@ int scenario_write_available_objects(FILE *file) return 1; } -static void sub_677552() -{ - RCT2_GLOBAL(RCT2_ADDRESS_GAME_VERSION_NUMBER, uint32) = 201028; - RCT2_GLOBAL(0x001358778, uint32) = RCT2_GLOBAL(0x009E2D28, uint32); -} - -static void sub_674BCF() -{ - char *savedExpansionPackNames = (char*)0x0135946C; - - for (int i = 0; i < 16; i++) { - char *dst = &savedExpansionPackNames[i * 128]; - if (RCT2_GLOBAL(RCT2_ADDRESS_EXPANSION_FLAGS, uint16) & (1 << i)) { - char *src = &(RCT2_ADDRESS(RCT2_ADDRESS_EXPANSION_NAMES, char)[i * 128]); - safe_strcpy(dst, src, 128); - } else { - *dst = 0; - } - } -} - /** * Modifies the given S6 data so that ghost elements, rides with no track elements or unused banners / user strings are saved. */ @@ -822,7 +801,7 @@ void scenario_fix_ghosts(rct_s6_data *s6) } } -static void scenario_remove_trackless_rides(rct_s6_data *s6) +void scenario_remove_trackless_rides(rct_s6_data *s6) { bool rideHasTrack[MAX_RIDES]; ride_all_has_any_track_elements(rideHasTrack); @@ -840,94 +819,6 @@ static void scenario_remove_trackless_rides(rct_s6_data *s6) } } -/** - * - * rct2: 0x006754F5 - * @param flags bit 0: pack objects, 1: save as scenario - */ -int scenario_save(SDL_RWops* rw, int flags) -{ - rct_window *w; - rct_viewport *viewport; - int viewX, viewY, viewZoom, viewRotation; - - if (flags & 2) - log_verbose("saving scenario"); - else - log_verbose("saving game"); - - - if (!(flags & 0x80000000)) - window_close_construction_windows(); - - map_reorganise_elements(); - reset_0x69EBE4(); - sprite_clear_all_unused(); - sub_677552(); - sub_674BCF(); - - // Set saved view - w = window_get_main(); - if (w != NULL) { - viewport = w->viewport; - - viewX = viewport->view_width / 2 + viewport->view_x; - viewY = viewport->view_height / 2 + viewport->view_y; - viewZoom = viewport->zoom; - viewRotation = get_current_rotation(); - } else { - viewX = gSavedViewX; - viewY = gSavedViewY; - viewZoom = gSavedViewZoom; - viewRotation = gSavedViewRotation; - } - - gSavedViewX = viewX; - gSavedViewY = viewY; - gSavedViewZoom = viewZoom; - gSavedViewRotation = viewRotation; - - // Prepare S6 - rct_s6_data *s6 = malloc(sizeof(rct_s6_data)); - s6->header.type = flags & 2 ? S6_TYPE_SCENARIO : S6_TYPE_SAVEDGAME; - s6->header.num_packed_objects = flags & 1 ? scenario_get_num_packed_objects_to_write() : 0; - s6->header.version = S6_RCT2_VERSION; - s6->header.magic_number = S6_MAGIC_NUMBER; - - memcpy(&s6->info, (rct_s6_info*)0x0141F570, sizeof(rct_s6_info)); - - for (int i = 0; i < OBJECT_ENTRY_COUNT; i++) { - rct_object_entry_extended *entry = &(RCT2_ADDRESS(0x00F3F03C, rct_object_entry_extended)[i]); - - if (gObjectList[i] == (void *)0xFFFFFFFF) { - memset(&s6->objects[i], 0xFF, sizeof(rct_object_entry)); - } else { - s6->objects[i] = *((rct_object_entry*)entry); - } - } - - memcpy(&s6->elapsed_months, (void*)0x00F663A8, 16); - memcpy(s6->map_elements, (void*)0x00F663B8, 0x180000); - memcpy(&s6->dword_010E63B8, (void*)0x010E63B8, 0x2E8570); - - safe_strcpy(s6->scenario_filename, _scenarioFileName, sizeof(s6->scenario_filename)); - - scenario_fix_ghosts(s6); - scenario_remove_trackless_rides(s6); - game_convert_strings_to_rct2(s6); - scenario_save_s6(rw, s6); - - free(s6); - - if (flags & 1) - reset_loaded_objects(); - - gfx_invalidate_screen(); - if (!(flags & 0x80000000)) - gScreenAge = 0; - return 1; -} - bool scenario_save_s6(SDL_RWops* rw, rct_s6_data *s6) { uint8 *buffer; diff --git a/src/scenario.h b/src/scenario.h index 35f3235606..6054eeea0c 100644 --- a/src/scenario.h +++ b/src/scenario.h @@ -477,6 +477,7 @@ int scenario_save_network(SDL_RWops* rw); bool scenario_save_s6(SDL_RWops* rw, rct_s6_data *s6); int scenario_get_num_packed_objects_to_write(); int scenario_write_packed_objects(SDL_RWops* rw); +void scenario_remove_trackless_rides(rct_s6_data *s6); void scenario_fix_ghosts(rct_s6_data *s6); void scenario_set_filename(const char *value); void scenario_failure();