use new S6Importer for loading saved games

This commit is contained in:
Ted John 2016-05-07 17:37:50 +01:00
parent 30467a1467
commit 3bb1d47813
4 changed files with 74 additions and 86 deletions

View File

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

View File

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

View File

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

View File

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