mirror of https://github.com/OpenRCT2/OpenRCT2.git
implement save scenario and fix various load / save dialog issues, fixes #433
This commit is contained in:
parent
8e3ee3f7e9
commit
d9e0f8ff6a
11
src/editor.c
11
src/editor.c
|
@ -121,7 +121,7 @@ static int show_convert_saved_game_to_scenario_dialog(char *resultPath)
|
|||
void editor_convert_save_to_scenario()
|
||||
{
|
||||
rct_s6_info *s6Info = (rct_s6_info*)0x0141F570;
|
||||
char *ch, savedGamePath[MAX_PATH];
|
||||
char savedGamePath[MAX_PATH];
|
||||
rct_window *w;
|
||||
rct_viewport *viewport;
|
||||
|
||||
|
@ -129,14 +129,7 @@ void editor_convert_save_to_scenario()
|
|||
if (!show_convert_saved_game_to_scenario_dialog(savedGamePath))
|
||||
return;
|
||||
|
||||
// Ensure it ends with .SV6
|
||||
ch = savedGamePath;
|
||||
while (*++ch != '.') {
|
||||
if (*ch == 0) {
|
||||
strcpy(ch, ".SV6");
|
||||
break;
|
||||
}
|
||||
}
|
||||
path_set_extension(savedGamePath, ".SV6");
|
||||
|
||||
// Load the saved game
|
||||
if (!game_load_save(savedGamePath))
|
||||
|
|
59
src/game.c
59
src/game.c
|
@ -43,6 +43,7 @@
|
|||
#include "title.h"
|
||||
#include "tutorial.h"
|
||||
#include "util/sawyercoding.h"
|
||||
#include "util/util.h"
|
||||
#include "windows/error.h"
|
||||
#include "windows/tooltip.h"
|
||||
#include "world/climate.h"
|
||||
|
@ -763,33 +764,51 @@ static void load_game()
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006750E9
|
||||
*/
|
||||
static int show_save_game_dialog(char *resultPath)
|
||||
{
|
||||
rct_s6_info *s6Info = (rct_s6_info*)0x0141F570;
|
||||
|
||||
int result;
|
||||
char title[256];
|
||||
char filename[MAX_PATH];
|
||||
char filterName[256];
|
||||
|
||||
format_string(title, STR_SAVE_GAME_1040, NULL);
|
||||
strcpy(filename, RCT2_ADDRESS(RCT2_ADDRESS_SAVED_GAMES_PATH_2, char));
|
||||
format_string(filterName, STR_RCT2_SAVED_GAME, NULL);
|
||||
|
||||
pause_sounds();
|
||||
result = osinterface_open_common_file_dialog(0, title, filename, "*.SV6", filterName);
|
||||
unpause_sounds();
|
||||
|
||||
if (result)
|
||||
strcpy(resultPath, filename);
|
||||
return result;
|
||||
}
|
||||
|
||||
char save_game()
|
||||
{
|
||||
int eax, ebx, ecx, edx, esi, edi, ebp;
|
||||
RCT2_CALLFUNC_X(0x006750E9, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
|
||||
if (eax == 0) {
|
||||
// user pressed "cancel"
|
||||
char path[256];
|
||||
|
||||
if (!show_save_game_dialog(path)) {
|
||||
gfx_invalidate_screen();
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *src = (char*)0x0141EF67;
|
||||
do {
|
||||
src++;
|
||||
} while (*src != '.' && *src != '\0');
|
||||
strcpy(src, ".SV6");
|
||||
strcpy((char*) RCT2_ADDRESS_SAVED_GAMES_PATH_2, (char*) 0x0141EF68);
|
||||
|
||||
eax = 0;
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_FLAGS, uint8) & 8)
|
||||
eax |= 1;
|
||||
RCT2_CALLPROC_X(0x006754F5, eax, 0, 0, 0, 0, 0, 0);
|
||||
// check success?
|
||||
|
||||
game_do_command(0, 1047, 0, -1, GAME_COMMAND_0, 0, 0);
|
||||
gfx_invalidate_screen();
|
||||
// Ensure path has .SV6 extension
|
||||
path_set_extension(path, ".SV6");
|
||||
|
||||
return 1;
|
||||
if (scenario_save(path, gGeneral_config.save_plugin_data ? 1 : 0)) {
|
||||
game_do_command(0, 1047, 0, -1, GAME_COMMAND_0, 0, 0);
|
||||
gfx_invalidate_screen();
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -185,8 +185,13 @@ enum {
|
|||
STR_LOAD_LANDSCAPE_DIALOG_TITLE = 1037,
|
||||
STR_CONVERT_SAVED_GAME_TO_SCENARIO_1038 = 1038,
|
||||
|
||||
STR_SAVE_GAME_1040 = 1040,
|
||||
STR_SAVE_SCENARIO = 1041,
|
||||
|
||||
STR_RCT2_SAVED_GAME = 1043,
|
||||
STR_RCT2_SCENARIO_FILE = 1044,
|
||||
STR_RCT2_LANDSCAPE_FILE = 1045,
|
||||
STR_SCENARIO_SAVE_FAILED = 1048,
|
||||
|
||||
STR_INVISIBLE_SUPPORTS = 1051,
|
||||
STR_INVISIBLE_PEOPLE = 1052,
|
||||
|
@ -1203,6 +1208,8 @@ enum {
|
|||
|
||||
STR_NO_DETAILS_YET = 3317,
|
||||
|
||||
STR_UNABLE_TO_SAVE_SCENARIO_FILE = 3320,
|
||||
|
||||
STR_OBJECTIVE = 3322,
|
||||
|
||||
STR_CANT_ADVANCE_TO_NEXT_EDITOR_STAGE = 3328,
|
||||
|
|
|
@ -795,15 +795,16 @@ int osinterface_open_common_file_dialog(int type, char *title, char *filename, c
|
|||
|
||||
// Get directory path from given filename
|
||||
strcpy(initialDirectory, filename);
|
||||
dotAddress = strrchr(filename, '.');
|
||||
dotAddress = strrchr(initialDirectory, '.');
|
||||
if (dotAddress != NULL) {
|
||||
slashAddress = strrchr(filename, '\\');
|
||||
slashAddress = strrchr(initialDirectory, '\\');
|
||||
if (slashAddress < dotAddress)
|
||||
*(slashAddress + 1) = 0;
|
||||
}
|
||||
|
||||
// Clear filename
|
||||
*filename = 0;
|
||||
if (type != 0)
|
||||
*filename = 0;
|
||||
|
||||
// Set open file name options
|
||||
memset(&openFileName, 0, sizeof(OPENFILENAME));
|
||||
|
|
|
@ -45,6 +45,8 @@ int scenario_load_basic(const char *path, rct_s6_header *header, rct_s6_info *in
|
|||
{
|
||||
FILE *file;
|
||||
|
||||
log_verbose("loading scenario details, %s", path);
|
||||
|
||||
file = fopen(path, "rb");
|
||||
if (file != NULL) {
|
||||
// Read first chunk
|
||||
|
@ -70,8 +72,9 @@ int scenario_load_basic(const char *path, rct_s6_header *header, rct_s6_info *in
|
|||
fclose(file);
|
||||
}
|
||||
|
||||
RCT2_GLOBAL(0x009AC31B, sint8) = -1;
|
||||
RCT2_GLOBAL(0x009AC31C, sint16) = 3011;
|
||||
log_error("invalid scenario, %s", path);
|
||||
// RCT2_GLOBAL(0x009AC31B, sint8) = -1;
|
||||
// RCT2_GLOBAL(0x009AC31C, sint16) = 3011;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -205,6 +208,8 @@ int scenario_load_and_play_from_path(const char *path)
|
|||
if (!scenario_load(path))
|
||||
return 0;
|
||||
|
||||
log_verbose("starting scenario, %s", path);
|
||||
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) = SCREEN_FLAGS_PLAYING;
|
||||
viewport_init_all();
|
||||
game_create_windows();
|
||||
|
@ -660,3 +665,62 @@ unsigned int scenario_rand()
|
|||
RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_SRAND_0, uint32) += ror32(RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_SRAND_1, uint32) ^ 0x1234567F, 7);
|
||||
return RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_SRAND_1, uint32) = ror32(eax, 3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare rides, for the finish five rollercoasters objective.
|
||||
* rct2: 0x006788F7
|
||||
*/
|
||||
void scenario_prepare_rides_for_save()
|
||||
{
|
||||
RCT2_CALLPROC_EBPSAFE(0x006788F7);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006726C7
|
||||
*/
|
||||
int scenario_prepare_for_save()
|
||||
{
|
||||
rct_s6_info *s6Info = (rct_s6_info*)0x0141F570;
|
||||
char buffer[256];
|
||||
|
||||
s6Info->entry.flags = 255;
|
||||
|
||||
char *stex = RCT2_GLOBAL(0x009ADAE4, char*);
|
||||
if (stex != (char*)0xFFFFFFFF) {
|
||||
format_string(buffer, RCT2_GLOBAL(stex, uint16), NULL);
|
||||
strncpy(s6Info->name, buffer, sizeof(s6Info->name));
|
||||
s6Info->entry = *((rct_object_entry*)0x00F4287C);
|
||||
}
|
||||
|
||||
if (s6Info->name[0] == 0)
|
||||
format_string(s6Info->name, RCT2_GLOBAL(0x013573D4, rct_string_id), (void*)0x013573D8);
|
||||
|
||||
s6Info->objective_type = RCT2_GLOBAL(RCT2_ADDRESS_OBJECTIVE_TYPE, uint8);
|
||||
s6Info->objective_arg_1 = RCT2_GLOBAL(RCT2_ADDRESS_OBJECTIVE_YEAR, uint8);
|
||||
s6Info->objective_arg_2 = RCT2_GLOBAL(RCT2_ADDRESS_OBJECTIVE_CURRENCY, uint8);
|
||||
s6Info->objective_arg_3 = RCT2_GLOBAL(RCT2_ADDRESS_OBJECTIVE_NUM_GUESTS, uint8);
|
||||
|
||||
scenario_prepare_rides_for_save();
|
||||
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_OBJECTIVE_TYPE, uint8) == OBJECTIVE_GUESTS_AND_RATING)
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) |= PARK_FLAGS_PARK_OPEN;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006754F5
|
||||
* @param flags bit 0: pack objects, 1: save as scenario
|
||||
*/
|
||||
int scenario_save(char *path, int flags)
|
||||
{
|
||||
if (flags & 2)
|
||||
log_verbose("saving scenario, %s", path);
|
||||
else
|
||||
log_verbose("saving game, %s", path);
|
||||
|
||||
strcpy((char*)0x0141EF68, path);
|
||||
return !(RCT2_CALLPROC_X(0x006754F5, flags, 0, 0, 0, 0, 0, 0) & 0x100);
|
||||
}
|
|
@ -408,5 +408,7 @@ int scenario_load_and_play(const rct_scenario_basic *scenario);
|
|||
int scenario_load_and_play_from_path(const char *path);
|
||||
void scenario_update();
|
||||
unsigned int scenario_rand();
|
||||
int scenario_prepare_for_save();
|
||||
int scenario_save(char *path, int flags);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -41,6 +41,19 @@ int mph_to_kmph(int mph)
|
|||
return (mph * 1648) / 1024;
|
||||
}
|
||||
|
||||
void path_set_extension(char *path, const char *extension)
|
||||
{
|
||||
char *ch = path;
|
||||
while (*ch != '.' && *ch != 0) {
|
||||
ch++;
|
||||
}
|
||||
|
||||
if (extension[0] != '.')
|
||||
*ch++ = '.';
|
||||
|
||||
strcpy(ch, extension);
|
||||
}
|
||||
|
||||
long fsize(FILE *fp)
|
||||
{
|
||||
long originalPosition, size;
|
||||
|
|
|
@ -27,6 +27,7 @@ int squaredmetres_to_squaredfeet(int squaredMetres);
|
|||
int metres_to_feet(int metres);
|
||||
int mph_to_kmph(int mph);
|
||||
|
||||
void path_set_extension(char *path, const char *extension);
|
||||
long fsize(FILE *fp);
|
||||
|
||||
int bitscanforward(int source);
|
||||
|
|
|
@ -20,12 +20,18 @@
|
|||
|
||||
#include <stdbool.h>
|
||||
#include "../addresses.h"
|
||||
#include "../audio/audio.h"
|
||||
#include "../config.h"
|
||||
#include "../editor.h"
|
||||
#include "../scenario.h"
|
||||
#include "../sprites.h"
|
||||
#include "../localisation/string_ids.h"
|
||||
#include "../localisation/localisation.h"
|
||||
#include "../interface/viewport.h"
|
||||
#include "../interface/widget.h"
|
||||
#include "../interface/window.h"
|
||||
#include "../platform/osinterface.h"
|
||||
#include "../title.h"
|
||||
#include "../util/util.h"
|
||||
#include "error.h"
|
||||
|
||||
enum WINDOW_EDITOR_TOP_TOOLBAR_WIDGET_IDX {
|
||||
|
@ -250,11 +256,74 @@ void window_editor_bottom_toolbar_jump_forward_to_objective_selection() {
|
|||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x0066f7c0
|
||||
*/
|
||||
void window_editor_bottom_toolbar_jump_forward_to_save_scenario() {
|
||||
RCT2_CALLPROC_EBPSAFE(0x0066f7c0);
|
||||
*
|
||||
* rct2: 0x00675181
|
||||
*/
|
||||
static int show_save_scenario_dialog(char *resultPath)
|
||||
{
|
||||
rct_s6_info *s6Info = (rct_s6_info*)0x0141F570;
|
||||
|
||||
int result;
|
||||
char title[256];
|
||||
char filename[MAX_PATH];
|
||||
char filterName[256];
|
||||
|
||||
|
||||
format_string(title, STR_SAVE_SCENARIO, NULL);
|
||||
subsitute_path(filename, RCT2_ADDRESS(RCT2_ADDRESS_SCENARIOS_PATH, char), s6Info->name);
|
||||
strcat(filename, ".SC6");
|
||||
format_string(filterName, STR_RCT2_SCENARIO_FILE, NULL);
|
||||
|
||||
pause_sounds();
|
||||
result = osinterface_open_common_file_dialog(0, title, filename, "*.SC6", filterName);
|
||||
unpause_sounds();
|
||||
|
||||
if (result)
|
||||
strcpy(resultPath, filename);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x0066F7C0
|
||||
*/
|
||||
void window_editor_bottom_toolbar_jump_forward_to_save_scenario()
|
||||
{
|
||||
rct_s6_info *s6Info = (rct_s6_info*)0x0141F570;
|
||||
int parkFlagsBackup, success;
|
||||
char path[256];
|
||||
|
||||
if (!scenario_prepare_for_save()) {
|
||||
window_error_open(STR_UNABLE_TO_SAVE_SCENARIO_FILE, RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, rct_string_id));
|
||||
gfx_invalidate_screen();
|
||||
return;
|
||||
}
|
||||
|
||||
window_close_all();
|
||||
if (!show_save_scenario_dialog(path)) {
|
||||
gfx_invalidate_screen();
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
s6Info->var_000 = 255;
|
||||
|
||||
// Ensure path has .SC6 extension
|
||||
path_set_extension(path, ".SC6");
|
||||
|
||||
// Save the scenario
|
||||
parkFlagsBackup = RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32);
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) &= ~PARK_FLAGS_18;
|
||||
success = scenario_save(path, gGeneral_config.save_plugin_data ? 3 : 2);
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) = parkFlagsBackup;
|
||||
|
||||
if (success) {
|
||||
// RCT2_CALLPROC_EBPSAFE(0x0066DC83);
|
||||
title_load();
|
||||
} else {
|
||||
window_error_open(STR_SCENARIO_SAVE_FAILED, -1);
|
||||
s6Info->var_000 = 4;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -103,8 +103,7 @@ void window_error_open(rct_string_id title, rct_string_id message)
|
|||
dst += get_string_length(dst);
|
||||
}
|
||||
|
||||
printf(_window_error_text+1);
|
||||
printf("\r\n");
|
||||
log_verbose("show error, %s", _window_error_text + 1);
|
||||
|
||||
// Check if there is any text to display
|
||||
if (dst == _window_error_text + 1)
|
||||
|
|
Loading…
Reference in New Issue