implement save scenario and fix various load / save dialog issues, fixes #433

This commit is contained in:
IntelOrca 2014-11-25 02:05:48 +00:00
parent 8e3ee3f7e9
commit d9e0f8ff6a
10 changed files with 210 additions and 42 deletions

View File

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

View File

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

View File

@ -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,

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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