mirror of https://github.com/OpenRCT2/OpenRCT2.git
use new S6Importer for loading saved games
This commit is contained in:
parent
30467a1467
commit
3bb1d47813
69
src/game.c
69
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() {
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue