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:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -30,6 +30,7 @@ class S6Exporter
|
||||
{
|
||||
public:
|
||||
bool ExportObjects;
|
||||
bool RemoveTracklessRides;
|
||||
|
||||
S6Exporter();
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
111
src/scenario.c
111
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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user