1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2026-01-19 21:13:05 +01:00

use S6Exporter for scenario_save

This commit is contained in:
Ted John
2016-05-08 16:02:00 +01:00
parent 4eb7a7ee0e
commit a86bc57a96
7 changed files with 109 additions and 134 deletions

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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

View File

@@ -30,6 +30,7 @@ class S6Exporter
{
public:
bool ExportObjects;
bool RemoveTracklessRides;
S6Exporter();

View File

@@ -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.

View File

@@ -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;

View File

@@ -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();