diff --git a/src/game.c b/src/game.c index b502ab38cf..8f9666fef4 100644 --- a/src/game.c +++ b/src/game.c @@ -25,13 +25,16 @@ #include "rct2.h" #include "game.h" #include "news_item.h" +#include "object.h" #include "osinterface.h" #include "peep.h" +#include "sawyercoding.h" #include "scenario.h" #include "screenshot.h" #include "strings.h" #include "title.h" #include "tutorial.h" +#include "viewport.h" #include "widget.h" #include "window.h" #include "window_error.h" @@ -1201,6 +1204,104 @@ static void load_landscape() } } +/** + * + * rct2: 0x00675E1B + */ +int game_load_save() +{ + rct_window *mainWindow; + HANDLE hFile; + char *path; + int i, j; + + path = (char*)0x0141EF68; + hFile = CreateFile( + path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS | FILE_ATTRIBUTE_NORMAL, NULL + ); + if (hFile == NULL) { + RCT2_GLOBAL(0x009AC31B, uint8) = 255; + RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_STRING_ID, uint16) = STR_FILE_CONTAINS_INVALID_DATA; + return 0; + } + + RCT2_GLOBAL(0x009E382C, HANDLE) = hFile; + // RCT2_CALLPROC_EBPSAFE(0x00676FD2); // check file checksum + + rct_s6_header *s6Header = 0x009E34E4; + rct_s6_info *s6Info = 0x0141F570; + + // Read first chunk + sawyercoding_read_chunk(hFile, 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(); + if (j > 0) + object_load_list(); + } + } + + object_read_and_load_entries(hFile); + + // Read flags (16 bytes) + sawyercoding_read_chunk(hFile, RCT2_ADDRESS_CURRENT_MONTH_YEAR); + + // Read map elements + memset(RCT2_ADDRESS_MAP_ELEMENTS, 0, MAX_MAP_ELEMENTS * sizeof(rct_map_element)); + sawyercoding_read_chunk(hFile, RCT2_ADDRESS_MAP_ELEMENTS); + + // Read game data, including sprites + sawyercoding_read_chunk(hFile, 0x010E63B8); + + CloseHandle(hFile); + + // Check expansion pack + // RCT2_CALLPROC_EBPSAFE(0x006757E6); + + // The rest is the same as in scenario load and play + RCT2_CALLPROC_EBPSAFE(0x006A9FC0); + map_update_tile_pointers(); + RCT2_CALLPROC_EBPSAFE(0x0069EBE4); + RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) = SCREEN_FLAGS_PLAYING; + viewport_init_all(); + game_create_windows(); + mainWindow = window_get_main(); + + mainWindow->var_4B0 = -1; + mainWindow->saved_view_x = RCT2_GLOBAL(RCT2_ADDRESS_SAVED_VIEW_X, sint16); + mainWindow->saved_view_y = RCT2_GLOBAL(RCT2_ADDRESS_SAVED_VIEW_Y, sint16); + uint8 _cl = (RCT2_GLOBAL(0x0138869E, sint16) & 0xFF) - mainWindow->viewport->zoom; + mainWindow->viewport->zoom = RCT2_GLOBAL(0x0138869E, sint16) & 0xFF; + *((char*)(&RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, sint32))) = RCT2_GLOBAL(0x0138869E, sint16) >> 8; + if (_cl != 0) { + if (_cl < 0) { + _cl = -_cl; + mainWindow->viewport->view_width >>= _cl; + mainWindow->viewport->view_height >>= _cl; + } else { + mainWindow->viewport->view_width <<= _cl; + mainWindow->viewport->view_height <<= _cl; + } + } + mainWindow->saved_view_x -= mainWindow->viewport->view_width >> 1; + mainWindow->saved_view_y -= mainWindow->viewport->view_height >> 1; + window_invalidate(mainWindow); + + RCT2_CALLPROC_EBPSAFE(0x0069E9A7); + RCT2_CALLPROC_EBPSAFE(0x006DFEE4); + RCT2_CALLPROC_EBPSAFE(0x006ACA58); + RCT2_GLOBAL(0x009DEB7C, uint16) = 0; + if (RCT2_GLOBAL(0x0013587C4, uint32) == 0) // this check is not in scenario play + RCT2_CALLPROC_EBPSAFE(0x0069E869); + + RCT2_CALLPROC_EBPSAFE(0x006837E3); // (palette related) + gfx_invalidate_screen(); + return 1; +} + /** * * rct2: 0x0066DBB7 @@ -1223,8 +1324,7 @@ static void load_game() } strcpy(0x009ABB37, 0x0141EF68); - RCT2_CALLPROC_EBPSAFE(0x00675E1B); // game_load - if (1) { + if (game_load_save()) { gfx_invalidate_screen(); rct2_endupdate(); } else { diff --git a/src/game.h b/src/game.h index 23aaff9a33..8619d04526 100644 --- a/src/game.h +++ b/src/game.h @@ -28,5 +28,6 @@ void game_logic_update(); int game_do_command(int eax, int ebx, int ecx, int edx, int esi, int edi, int ebp); void game_load_or_quit_no_save_prompt(); +int game_load_save(); #endif diff --git a/src/rct2.c b/src/rct2.c index fa49f9d794..569a82a7a1 100644 --- a/src/rct2.c +++ b/src/rct2.c @@ -235,7 +235,7 @@ void check_cmdline_arg() if(!stricmp(processed_arg + last_period, "sv6")) { strcpy(0x00141EF68, processed_arg); - RCT2_CALLPROC_EBPSAFE(0x00675E1B); //load_saved_game + game_load_save(); } else if(!stricmp(processed_arg + last_period, "sc6")) { diff --git a/src/scenario.c b/src/scenario.c index 05871c5780..1364cddb6e 100644 --- a/src/scenario.c +++ b/src/scenario.c @@ -329,6 +329,7 @@ void scenario_load(char *path) ); if (hFile != INVALID_HANDLE_VALUE) { RCT2_GLOBAL(0x009E382C, HANDLE*) = hFile; + // RCT2_CALLPROC_EBPSAFE(0x00676FD2); // check file checksum // Read first chunk sawyercoding_read_chunk(hFile, s6Header); @@ -393,7 +394,7 @@ void scenario_load(char *path) } RCT2_GLOBAL(0x009AC31B, uint8) = 255; - RCT2_GLOBAL(0x009AC31C, uint16) = 3011; + RCT2_GLOBAL(0x009AC31C, uint16) = STR_FILE_CONTAINS_INVALID_DATA; } /** diff --git a/src/strings.h b/src/strings.h index f664887074..3afedf5f26 100644 --- a/src/strings.h +++ b/src/strings.h @@ -438,6 +438,7 @@ enum { STR_LICENCE_AGREEMENT_NOTICE_2 = 2970, STR_UNABLE_TO_LOAD_FILE = 3010, + STR_FILE_CONTAINS_INVALID_DATA = 3011, STR_BEGINNER_PARKS = 3064, STR_CHALLENGING_PARKS = STR_BEGINNER_PARKS + 1,