mirror of https://github.com/OpenRCT2/OpenRCT2.git
Merge pull request #3009 from OpenRCT2/improve-native-file-dialog
Improve native file dialog
This commit is contained in:
commit
966aaf1adc
60
src/game.c
60
src/game.c
|
@ -611,40 +611,6 @@ static void game_load_or_quit(int *eax, int *ebx, int *ecx, int *edx, int *esi,
|
||||||
*ebx = 0;
|
*ebx = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* rct2: 0x00674F40
|
|
||||||
*/
|
|
||||||
static int open_landscape_file_dialog()
|
|
||||||
{
|
|
||||||
int result;
|
|
||||||
format_string((char*)RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, STR_LOAD_LANDSCAPE_DIALOG_TITLE, 0);
|
|
||||||
safe_strcpy((char*)0x0141EF68, (char*)RCT2_ADDRESS_LANDSCAPES_PATH, MAX_PATH);
|
|
||||||
format_string((char*)0x0141EE68, STR_RCT2_LANDSCAPE_FILE, 0);
|
|
||||||
audio_pause_sounds();
|
|
||||||
result = platform_open_common_file_dialog(FD_OPEN, (char*)RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, (char*)0x0141EF68, "*.SV6;*.SV4;*.SC6", (char*)0x0141EE68);
|
|
||||||
audio_unpause_sounds();
|
|
||||||
// window_proc
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* rct2: 0x00674EB6
|
|
||||||
*/
|
|
||||||
static int open_load_game_dialog()
|
|
||||||
{
|
|
||||||
int result;
|
|
||||||
format_string((char*)RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, STR_LOAD_GAME_DIALOG_TITLE, 0);
|
|
||||||
safe_strcpy((char*)0x0141EF68, (char*)RCT2_ADDRESS_SAVED_GAMES_PATH, MAX_PATH);
|
|
||||||
format_string((char*)0x0141EE68, STR_RCT2_SAVED_GAME, 0);
|
|
||||||
audio_pause_sounds();
|
|
||||||
result = platform_open_common_file_dialog(FD_OPEN, (char*)RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, (char*)0x0141EF68, "*.SV6", (char*)0x0141EE68);
|
|
||||||
audio_unpause_sounds();
|
|
||||||
// window_proc
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* rct2: 0x0066DC0F
|
* rct2: 0x0066DC0F
|
||||||
|
@ -1025,32 +991,6 @@ void reset_all_sprite_quadrant_placements()
|
||||||
sprite_move(spr->unknown.x, spr->unknown.y, spr->unknown.z, spr);
|
sprite_move(spr->unknown.x, spr->unknown.y, spr->unknown.z, spr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* 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);
|
|
||||||
safe_strcpy(filename, RCT2_ADDRESS(RCT2_ADDRESS_SAVED_GAMES_PATH_2, char), MAX_PATH);
|
|
||||||
format_string(filterName, STR_RCT2_SAVED_GAME, NULL);
|
|
||||||
|
|
||||||
audio_pause_sounds();
|
|
||||||
result = platform_open_common_file_dialog(FD_SAVE, title, filename, "*.SV6", filterName);
|
|
||||||
audio_unpause_sounds();
|
|
||||||
|
|
||||||
if (result)
|
|
||||||
safe_strcpy(resultPath, filename, MAX_PATH);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void save_game()
|
void save_game()
|
||||||
{
|
{
|
||||||
if (!gFirstTimeSave) {
|
if (!gFirstTimeSave) {
|
||||||
|
|
|
@ -487,8 +487,6 @@ enum {
|
||||||
LOADSAVETYPE_LANDSCAPE = 1 << 1,
|
LOADSAVETYPE_LANDSCAPE = 1 << 1,
|
||||||
LOADSAVETYPE_SCENARIO = 2 << 1,
|
LOADSAVETYPE_SCENARIO = 2 << 1,
|
||||||
LOADSAVETYPE_TRACK = 3 << 1,
|
LOADSAVETYPE_TRACK = 3 << 1,
|
||||||
|
|
||||||
LOADSAVETYPE_NETWORK = 1 << 4,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
|
|
@ -280,18 +280,22 @@ enum {
|
||||||
STR_CAN_ONLY_BUILD_THIS_ABOVE_GROUND = 1033,
|
STR_CAN_ONLY_BUILD_THIS_ABOVE_GROUND = 1033,
|
||||||
STR_CAN_ONLY_BUILD_THIS_ON_LAND = 1034,
|
STR_CAN_ONLY_BUILD_THIS_ON_LAND = 1034,
|
||||||
STR_LOCAL_AUTHORITY_WONT_ALLOW_CONSTRUCTION_ABOVE_TREE_HEIGHT = 1035,
|
STR_LOCAL_AUTHORITY_WONT_ALLOW_CONSTRUCTION_ABOVE_TREE_HEIGHT = 1035,
|
||||||
STR_LOAD_GAME_DIALOG_TITLE = 1036,
|
|
||||||
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_FILE_DIALOG_TITLE_LOAD_GAME = 1036,
|
||||||
|
STR_FILE_DIALOG_TITLE_LOAD_LANDSCAPE = 1037,
|
||||||
|
STR_FILE_DIALOG_TITLE_CONVERT_SAVED_GAME_TO_SCENARIO = 1038,
|
||||||
|
STR_FILE_DIALOG_TITLE_INSTALL_NEW_TRACK_DESIGN = 1039,
|
||||||
|
STR_FILE_DIALOG_TITLE_SAVE_GAME = 1040,
|
||||||
|
STR_FILE_DIALOG_TITLE_SAVE_SCENARIO = 1041,
|
||||||
|
STR_FILE_DIALOG_TITLE_SAVE_LANDSCAPE = 1042,
|
||||||
|
STR_OPENRCT2_SAVED_GAME = 1043,
|
||||||
|
STR_OPENRCT2_SCENARIO_FILE = 1044,
|
||||||
|
STR_OPENRCT2_LANDSCAPE_FILE = 1045,
|
||||||
|
STR_OPENRCT2_TRACK_DESIGN_FILE = 1046,
|
||||||
|
STR_GAME_SAVE_FAILED = 1047,
|
||||||
STR_SCENARIO_SAVE_FAILED = 1048,
|
STR_SCENARIO_SAVE_FAILED = 1048,
|
||||||
|
STR_LANDSCAPE_SAVE_FAILED = 1049,
|
||||||
|
STR_FAILED_TO_LOAD_FILE_CONTAINS_INVALID_DATA = 1050,
|
||||||
|
|
||||||
STR_INVISIBLE_SUPPORTS = 1051,
|
STR_INVISIBLE_SUPPORTS = 1051,
|
||||||
STR_INVISIBLE_PEOPLE = 1052,
|
STR_INVISIBLE_PEOPLE = 1052,
|
||||||
|
|
|
@ -163,13 +163,18 @@ void execute_cmd(char *command, int *exit_value, char *buf, size_t *buf_size) {
|
||||||
if (buf && buf_size) {
|
if (buf && buf_size) {
|
||||||
n_chars = fread(buf, 1, *buf_size, f);
|
n_chars = fread(buf, 1, *buf_size, f);
|
||||||
|
|
||||||
|
// some commands may return a new-line terminated result, trim that…
|
||||||
|
if (n_chars > 0 && buf[n_chars - 1] == '\n') {
|
||||||
|
buf[n_chars - 1] = '\0';
|
||||||
|
}
|
||||||
// make sure string is null-terminated
|
// make sure string is null-terminated
|
||||||
if (n_chars == *buf_size) {
|
if (n_chars == *buf_size) {
|
||||||
n_chars--;
|
n_chars--;
|
||||||
}
|
}
|
||||||
buf[n_chars] = '\0';
|
buf[n_chars] = '\0';
|
||||||
|
|
||||||
*buf_size = n_chars;
|
// account for null terminator
|
||||||
|
*buf_size = n_chars + 1;
|
||||||
} else {
|
} else {
|
||||||
fflush(f);
|
fflush(f);
|
||||||
}
|
}
|
||||||
|
@ -212,7 +217,7 @@ dialog_type get_dialog_app(char *cmd, size_t *cmd_size) {
|
||||||
return dtype;
|
return dtype;
|
||||||
}
|
}
|
||||||
|
|
||||||
int platform_open_common_file_dialog(filedialog_type type, utf8 *title, utf8 *filename, utf8 *filterPattern, utf8 *filterName) {
|
bool platform_open_common_file_dialog(utf8 *outFilename, file_dialog_desc *desc) {
|
||||||
int exit_value;
|
int exit_value;
|
||||||
char executable[MAX_PATH];
|
char executable[MAX_PATH];
|
||||||
char cmd[MAX_PATH];
|
char cmd[MAX_PATH];
|
||||||
|
@ -221,16 +226,17 @@ int platform_open_common_file_dialog(filedialog_type type, utf8 *title, utf8 *fi
|
||||||
dialog_type dtype;
|
dialog_type dtype;
|
||||||
char *action;
|
char *action;
|
||||||
char *flags;
|
char *flags;
|
||||||
char *filter = NULL;
|
char filter[MAX_PATH] = { 0 };
|
||||||
char filterPatternRegex[64];
|
char filterPatternRegex[64];
|
||||||
char *allFilesPatternDescription;
|
char *allFilesPatternDescription;
|
||||||
|
int allFilesPatternLength = 0;
|
||||||
|
|
||||||
size = MAX_PATH;
|
size = MAX_PATH;
|
||||||
dtype = get_dialog_app(executable, &size);
|
dtype = get_dialog_app(executable, &size);
|
||||||
|
|
||||||
switch (dtype) {
|
switch (dtype) {
|
||||||
case DT_KDIALOG:
|
case DT_KDIALOG:
|
||||||
switch (type) {
|
switch (desc->type) {
|
||||||
case FD_OPEN:
|
case FD_OPEN:
|
||||||
action = "--getopenfilename";
|
action = "--getopenfilename";
|
||||||
break;
|
break;
|
||||||
|
@ -239,16 +245,44 @@ int platform_open_common_file_dialog(filedialog_type type, utf8 *title, utf8 *fi
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (filterPattern && filterName) {
|
{
|
||||||
filter = (char*) malloc(1 + strlen(filterPattern) + 3 + strlen(filterName) + 1);
|
bool first = true;
|
||||||
sprintf(filter, "\"%s | %s\"", filterPattern, filterName);
|
for (int j = 0; j < countof(desc->filters); j++) {
|
||||||
|
if (desc->filters[j].pattern && desc->filters[j].name) {
|
||||||
|
char filterTemp[100] = { 0 };
|
||||||
|
if (first) {
|
||||||
|
snprintf(filterTemp, countof(filterTemp), "%s | %s", desc->filters[j].pattern, desc->filters[j].name);
|
||||||
|
first = false;
|
||||||
|
} else {
|
||||||
|
snprintf(filterTemp, countof(filterTemp), "\\n%s | %s", desc->filters[j].pattern, desc->filters[j].name);
|
||||||
|
}
|
||||||
|
safe_strcat(filter, filterTemp, countof(filter));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
char filterTemp[100] = { 0 };
|
||||||
|
if (first) {
|
||||||
|
snprintf(filterTemp, countof(filterTemp), "*|%s", (char *)language_get_string(STR_ALL_FILES));
|
||||||
|
} else {
|
||||||
|
snprintf(filterTemp, countof(filterTemp), "\\n*|%s", (char *)language_get_string(STR_ALL_FILES));
|
||||||
|
}
|
||||||
|
safe_strcat(filter, filterTemp, countof(filter));
|
||||||
|
|
||||||
|
// kdialog wants filters space-delimited and we don't expect ';' anywhere else,
|
||||||
|
// this is much easier and quicker to do than being overly careful about replacing
|
||||||
|
// it only where truly needed.
|
||||||
|
int filterSize = strlen(filter);
|
||||||
|
for (int i = 0; i < filterSize + 3; i++) {
|
||||||
|
if (filter[i] == ';') {
|
||||||
|
filter[i] = ' ';
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
snprintf(cmd, MAX_PATH, "%s --title \"%s\" %s ~ %s", executable, title, action, filter?filter:"");
|
snprintf(cmd, MAX_PATH, "%s --title \"%s\" %s ~ \"%s\"", executable, desc->title, action, filter);
|
||||||
break;
|
break;
|
||||||
case DT_ZENITY:
|
case DT_ZENITY:
|
||||||
action = "--file-selection";
|
action = "--file-selection";
|
||||||
switch (type) {
|
switch (desc->type) {
|
||||||
case FD_SAVE:
|
case FD_SAVE:
|
||||||
flags = "--confirm-overwrite --save";
|
flags = "--confirm-overwrite --save";
|
||||||
break;
|
break;
|
||||||
|
@ -258,29 +292,37 @@ int platform_open_common_file_dialog(filedialog_type type, utf8 *title, utf8 *fi
|
||||||
}
|
}
|
||||||
|
|
||||||
// Zenity seems to be case sensitive, while Kdialog isn't.
|
// Zenity seems to be case sensitive, while Kdialog isn't.
|
||||||
if (filterPattern && filterName) {
|
for (int j = 0; j < countof(desc->filters); j++) {
|
||||||
int regexIterator = 0;
|
if (desc->filters[j].pattern && desc->filters[j].name) {
|
||||||
for(int i = 0; i <= sizeof(filterPattern); i++) {
|
int regexIterator = 0;
|
||||||
if (isalpha(filterPattern[i])) {
|
for(int i = 0; i <= strlen(desc->filters[j].pattern); i++) {
|
||||||
filterPatternRegex[regexIterator+0] = '[';
|
if (isalpha(desc->filters[j].pattern[i])) {
|
||||||
filterPatternRegex[regexIterator+1] = (char)toupper(filterPattern[i]);
|
filterPatternRegex[regexIterator+0] = '[';
|
||||||
filterPatternRegex[regexIterator+2] = (char)tolower(filterPattern[i]);
|
filterPatternRegex[regexIterator+1] = (char)toupper(desc->filters[j].pattern[i]);
|
||||||
filterPatternRegex[regexIterator+3] = ']';
|
filterPatternRegex[regexIterator+2] = (char)tolower(desc->filters[j].pattern[i]);
|
||||||
regexIterator += 3;
|
filterPatternRegex[regexIterator+3] = ']';
|
||||||
|
regexIterator += 3;
|
||||||
|
}
|
||||||
|
else if(desc->filters[j].pattern[i] == ';') {
|
||||||
|
filterPatternRegex[regexIterator] = ' ';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
filterPatternRegex[regexIterator] = (char)desc->filters[j].pattern[i];
|
||||||
|
}
|
||||||
|
regexIterator++;
|
||||||
}
|
}
|
||||||
else {
|
filterPatternRegex[regexIterator+1] = 0;
|
||||||
filterPatternRegex[regexIterator] = (char)filterPattern[i];
|
|
||||||
}
|
char filterTemp[100] = { 0 };
|
||||||
regexIterator++;
|
snprintf(filterTemp, countof(filterTemp), " --file-filter=\"%s | %s\"", desc->filters[j].name, filterPatternRegex);
|
||||||
|
safe_strcat(filter, filterTemp, countof(filter));
|
||||||
}
|
}
|
||||||
filterPatternRegex[regexIterator+1] = 0;
|
|
||||||
|
|
||||||
allFilesPatternDescription = (char *)language_get_string(STR_ALL_FILES);
|
|
||||||
filter = (char*) malloc(strlen("--file-filter=\"") + strlen(filterPatternRegex) + 3 + strlen(filterName) + 2 + strlen(" --file-filter=\"") + strlen(allFilesPatternDescription) + strlen(" | *\""));
|
|
||||||
sprintf(filter, "--file-filter=\"%s | %s\" --file-filter=\"%s | *\"", filterName, filterPatternRegex, allFilesPatternDescription);
|
|
||||||
}
|
}
|
||||||
|
char filterTemp[100] = { 0 };
|
||||||
|
snprintf(filterTemp, countof(filterTemp), " --file-filter=\"%s | *\"", (char *)language_get_string(STR_ALL_FILES));
|
||||||
|
safe_strcat(filter, filterTemp, countof(filter));
|
||||||
|
|
||||||
snprintf(cmd, MAX_PATH, "%s %s %s --title=\"%s\" / %s", executable, action, flags, title, filter?filter:"");
|
snprintf(cmd, MAX_PATH, "%s %s %s --title=\"%s\" / %s", executable, action, flags, desc->title, filter);
|
||||||
break;
|
break;
|
||||||
default: return 0;
|
default: return 0;
|
||||||
}
|
}
|
||||||
|
@ -289,40 +331,32 @@ int platform_open_common_file_dialog(filedialog_type type, utf8 *title, utf8 *fi
|
||||||
execute_cmd(cmd, &exit_value, result, &size);
|
execute_cmd(cmd, &exit_value, result, &size);
|
||||||
|
|
||||||
if (exit_value != 0) {
|
if (exit_value != 0) {
|
||||||
free(filter);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
result[size-1] = '\0';
|
result[size-1] = '\0';
|
||||||
log_verbose("filename = %s", result);
|
log_verbose("filename = %s", result);
|
||||||
|
|
||||||
if (type == FD_OPEN && access(result, F_OK) == -1) {
|
if (desc->type == FD_OPEN && access(result, F_OK) == -1) {
|
||||||
char msg[MAX_PATH];
|
char msg[MAX_PATH];
|
||||||
|
|
||||||
snprintf(msg, MAX_PATH, "\"%s\" not found: %s, please choose another file\n", result, strerror(errno));
|
snprintf(msg, MAX_PATH, "\"%s\" not found: %s, please choose another file\n", result, strerror(errno));
|
||||||
platform_show_messagebox(msg);
|
platform_show_messagebox(msg);
|
||||||
|
|
||||||
if (filter != NULL)
|
return platform_open_common_file_dialog(outFilename, desc);
|
||||||
free(filter);
|
|
||||||
return platform_open_common_file_dialog(type, title, filename, filterPattern, filterName);
|
|
||||||
} else
|
} else
|
||||||
if (type == FD_SAVE && access(result, F_OK) != -1 && dtype == DT_KDIALOG) {
|
if (desc->type == FD_SAVE && access(result, F_OK) != -1 && dtype == DT_KDIALOG) {
|
||||||
snprintf(cmd, MAX_PATH, "%s --yesno \"Overwrite %s?\"", executable, result);
|
snprintf(cmd, MAX_PATH, "%s --yesno \"Overwrite %s?\"", executable, result);
|
||||||
|
|
||||||
size = MAX_PATH;
|
size = MAX_PATH;
|
||||||
execute_cmd(cmd, &exit_value, 0, 0);
|
execute_cmd(cmd, &exit_value, 0, 0);
|
||||||
|
|
||||||
if (exit_value != 0) {
|
if (exit_value != 0) {
|
||||||
if (filter != NULL)
|
|
||||||
free(filter);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
strncpy(filename, result, MAX_PATH);
|
strncpy(outFilename, result, MAX_PATH);
|
||||||
|
|
||||||
if (filter != NULL)
|
|
||||||
free(filter);
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -131,25 +131,29 @@ utf8 *platform_open_directory_browser(utf8 *title)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int platform_open_common_file_dialog(filedialog_type type, utf8 *title, utf8 *filename, utf8 *filterPattern, utf8 *filterName)
|
bool platform_open_common_file_dialog(utf8 *outFilename, file_dialog_desc *desc) {
|
||||||
{
|
|
||||||
@autoreleasepool
|
@autoreleasepool
|
||||||
{
|
{
|
||||||
NSString *fillPatternNS = [NSString stringWithUTF8String:filterPattern];
|
NSMutableArray *extensions = [NSMutableArray new];
|
||||||
fillPatternNS = [fillPatternNS stringByReplacingOccurrencesOfString:@"*." withString:@""];
|
for (int i=0; i < countof(desc->filters); ++i) {
|
||||||
NSArray *extensions = [fillPatternNS componentsSeparatedByString:@";"];
|
if (desc->filters[i].pattern != NULL) {
|
||||||
|
NSString *fp = [NSString stringWithUTF8String:desc->filters[i].pattern];
|
||||||
|
fp = [fp stringByReplacingOccurrencesOfString:@"*." withString:@""];
|
||||||
|
[extensions addObjectsFromArray:[fp componentsSeparatedByString:@";"]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
NSString *filePath = [NSString stringWithUTF8String:filename];
|
NSString *filePath = [NSString stringWithUTF8String:desc->default_filename];
|
||||||
NSString *directory = filePath.stringByDeletingLastPathComponent;
|
NSString *directory = filePath.stringByDeletingLastPathComponent;
|
||||||
NSString *basename = filePath.lastPathComponent;
|
NSString *basename = filePath.lastPathComponent;
|
||||||
|
|
||||||
NSSavePanel *panel;
|
NSSavePanel *panel;
|
||||||
if (type == FD_SAVE)
|
if (desc->type == FD_SAVE)
|
||||||
{
|
{
|
||||||
panel = [NSSavePanel savePanel];
|
panel = [NSSavePanel savePanel];
|
||||||
panel.nameFieldStringValue = [NSString stringWithFormat:@"%@.%@", basename, extensions.firstObject];
|
panel.nameFieldStringValue = [NSString stringWithFormat:@"%@.%@", basename, extensions.firstObject];
|
||||||
}
|
}
|
||||||
else if (type == FD_OPEN)
|
else if (desc->type == FD_OPEN)
|
||||||
{
|
{
|
||||||
NSOpenPanel *open = [NSOpenPanel openPanel];
|
NSOpenPanel *open = [NSOpenPanel openPanel];
|
||||||
open.canChooseDirectories = false;
|
open.canChooseDirectories = false;
|
||||||
|
@ -157,19 +161,19 @@ int platform_open_common_file_dialog(filedialog_type type, utf8 *title, utf8 *fi
|
||||||
open.allowsMultipleSelection = false;
|
open.allowsMultipleSelection = false;
|
||||||
panel = open;
|
panel = open;
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
panel.title = [NSString stringWithUTF8String:title];
|
panel.title = [NSString stringWithUTF8String:desc->title];
|
||||||
panel.allowedFileTypes = extensions;
|
panel.allowedFileTypes = extensions;
|
||||||
panel.directoryURL = [NSURL fileURLWithPath:directory];
|
panel.directoryURL = [NSURL fileURLWithPath:directory];
|
||||||
if ([panel runModal] == NSFileHandlingPanelCancelButton){
|
if ([panel runModal] == NSFileHandlingPanelCancelButton){
|
||||||
SDL_RaiseWindow(gWindow);
|
SDL_RaiseWindow(gWindow);
|
||||||
return 0;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
strcpy(filename, panel.URL.path.UTF8String);
|
strcpy(outFilename, panel.URL.path.UTF8String);
|
||||||
SDL_RaiseWindow(gWindow);
|
SDL_RaiseWindow(gWindow);
|
||||||
return 1;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,6 +88,16 @@ enum {
|
||||||
|
|
||||||
typedef enum {FD_OPEN, FD_SAVE} filedialog_type;
|
typedef enum {FD_OPEN, FD_SAVE} filedialog_type;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8 type;
|
||||||
|
const utf8 *title;
|
||||||
|
const utf8 *initial_directory;
|
||||||
|
const utf8 *default_filename;
|
||||||
|
struct {
|
||||||
|
const utf8 *name; // E.g. "Image Files"
|
||||||
|
const utf8 *pattern; // E.g. "*.png;*.jpg;*.gif"
|
||||||
|
} filters[8];
|
||||||
|
} file_dialog_desc;
|
||||||
|
|
||||||
extern openrct2_cursor gCursorState;
|
extern openrct2_cursor gCursorState;
|
||||||
extern const unsigned char *gKeysState;
|
extern const unsigned char *gKeysState;
|
||||||
|
@ -164,7 +174,7 @@ void platform_get_openrct_data_path(utf8 *outPath);
|
||||||
void platform_get_user_directory(utf8 *outPath, const utf8 *subDirectory);
|
void platform_get_user_directory(utf8 *outPath, const utf8 *subDirectory);
|
||||||
utf8* platform_get_username();
|
utf8* platform_get_username();
|
||||||
void platform_show_messagebox(utf8 *message);
|
void platform_show_messagebox(utf8 *message);
|
||||||
int platform_open_common_file_dialog(filedialog_type type, utf8 *title, utf8 *filename, utf8 *filterPattern, utf8 *filterName);
|
bool platform_open_common_file_dialog(utf8 *outFilename, file_dialog_desc *desc);
|
||||||
utf8 *platform_open_directory_browser(utf8 *title);
|
utf8 *platform_open_directory_browser(utf8 *title);
|
||||||
uint8 platform_get_locale_currency();
|
uint8 platform_get_locale_currency();
|
||||||
uint8 platform_get_currency_value(const char *currencyCode);
|
uint8 platform_get_currency_value(const char *currencyCode);
|
||||||
|
|
|
@ -580,76 +580,95 @@ void platform_show_messagebox(char *message)
|
||||||
*
|
*
|
||||||
* rct2: 0x004080EA
|
* rct2: 0x004080EA
|
||||||
*/
|
*/
|
||||||
int platform_open_common_file_dialog(filedialog_type type, utf8 *title, utf8 *filename, utf8 *filterPattern, utf8 *filterName)
|
bool platform_open_common_file_dialog(utf8 *outFilename, file_dialog_desc *desc)
|
||||||
{
|
{
|
||||||
wchar_t wctitle[256], wcfilename[MAX_PATH], wcfilterPattern[256], wcfilterName[256];
|
|
||||||
wchar_t initialDirectory[MAX_PATH], *dotAddress, *slashAddress;
|
|
||||||
OPENFILENAMEW openFileName;
|
OPENFILENAMEW openFileName;
|
||||||
BOOL result;
|
wchar_t wcFilename[MAX_PATH];
|
||||||
int tmp;
|
|
||||||
DWORD commonFlags;
|
|
||||||
|
|
||||||
MultiByteToWideChar(CP_UTF8, 0, title, -1, wctitle, countof(wctitle));
|
// Copy default filename to result filename buffer
|
||||||
MultiByteToWideChar(CP_UTF8, 0, filename, -1, wcfilename, countof(wcfilename));
|
if (desc->default_filename == NULL) {
|
||||||
MultiByteToWideChar(CP_UTF8, 0, filterPattern, -1, wcfilterPattern, countof(wcfilterPattern));
|
wcFilename[0] = 0;
|
||||||
MultiByteToWideChar(CP_UTF8, 0, filterName, -1, wcfilterName, countof(wcfilterName));
|
} else {
|
||||||
|
wchar_t *wcDefaultFilename = utf8_to_widechar(desc->default_filename);
|
||||||
// Get directory path from given filename
|
lstrcpyW(wcFilename, wcDefaultFilename);
|
||||||
lstrcpyW(initialDirectory, wcfilename);
|
free(wcDefaultFilename);
|
||||||
dotAddress = wcsrchr(initialDirectory, '.');
|
|
||||||
if (dotAddress != NULL) {
|
|
||||||
slashAddress = wcsrchr(initialDirectory, '\\');
|
|
||||||
if (slashAddress < dotAddress)
|
|
||||||
*(slashAddress + 1) = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear filename
|
|
||||||
if (type != FD_SAVE)
|
|
||||||
wcfilename[0] = 0;
|
|
||||||
|
|
||||||
// Set open file name options
|
// Set open file name options
|
||||||
memset(&openFileName, 0, sizeof(OPENFILENAMEW));
|
memset(&openFileName, 0, sizeof(OPENFILENAMEW));
|
||||||
openFileName.lStructSize = sizeof(OPENFILENAMEW);
|
openFileName.lStructSize = sizeof(OPENFILENAMEW);
|
||||||
openFileName.hwndOwner = windows_get_window_handle();
|
openFileName.hwndOwner = windows_get_window_handle();
|
||||||
openFileName.lpstrFile = wcfilename;
|
|
||||||
openFileName.nMaxFile = MAX_PATH;
|
openFileName.nMaxFile = MAX_PATH;
|
||||||
openFileName.lpstrInitialDir = initialDirectory;
|
openFileName.lpstrTitle = utf8_to_widechar(desc->title);
|
||||||
openFileName.lpstrTitle = wctitle;
|
openFileName.lpstrInitialDir = utf8_to_widechar(desc->initial_directory);
|
||||||
|
openFileName.lpstrFile = wcFilename;
|
||||||
|
|
||||||
// Copy filter name
|
utf8 filters[256];
|
||||||
lstrcpyW((wchar_t*)0x01423800, wcfilterName);
|
utf8 *ch = filters;
|
||||||
|
for (int i = 0; i < countof(desc->filters); i++) {
|
||||||
// Copy filter pattern
|
if (desc->filters[i].name != NULL) {
|
||||||
int wcfilterNameLength = lstrlenW(wcfilterName);
|
strcpy(ch, desc->filters[i].name);
|
||||||
int wcfilterPatternLength = lstrlenW(wcfilterPattern);
|
ch = strchr(ch, 0) + 1;
|
||||||
|
strcpy(ch, desc->filters[i].pattern);
|
||||||
lstrcpyW((wchar_t*)0x01423800 + wcfilterNameLength + 1, wcfilterPattern);
|
ch = strchr(ch, 0) + 1;
|
||||||
*((wchar_t*)((wchar_t*)0x01423800 + wcfilterNameLength + 1 + wcfilterPatternLength + 1)) = 0;
|
}
|
||||||
openFileName.lpstrFilter = (wchar_t*)0x01423800;
|
}
|
||||||
|
assert(ch != filters);
|
||||||
//
|
*ch = 0;
|
||||||
tmp = RCT2_GLOBAL(0x009E2C74, uint32);
|
|
||||||
if (RCT2_GLOBAL(0x009E2BB8, uint32) == 2 && RCT2_GLOBAL(0x009E1AF8, uint32) == 1)
|
// HACK: Replace all null terminators with 0x01 so that we convert the entire string
|
||||||
RCT2_GLOBAL(0x009E2C74, uint32) = 1;
|
size_t fullLength = (size_t)(ch - filters);
|
||||||
|
for (size_t i = 0; i < fullLength; i++) {
|
||||||
// Open dialog
|
if (filters[i] == '\0') {
|
||||||
commonFlags = OFN_EXPLORER | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY | OFN_NOCHANGEDIR;
|
filters[i] = 1;
|
||||||
if (type == FD_SAVE) {
|
}
|
||||||
wchar_t *defaultExtension = wcsrchr(wcfilterPattern, '.');
|
}
|
||||||
if (defaultExtension != NULL) {
|
wchar_t *wcFilter = utf8_to_widechar(filters);
|
||||||
openFileName.lpstrDefExt = defaultExtension + 1;
|
fullLength = lstrlenW(wcFilter);
|
||||||
|
for (size_t i = 0; i < fullLength; i++) {
|
||||||
|
if (wcFilter[i] == 1) {
|
||||||
|
wcFilter[i] = '\0';
|
||||||
}
|
}
|
||||||
openFileName.Flags = commonFlags | OFN_CREATEPROMPT | OFN_OVERWRITEPROMPT;
|
|
||||||
result = GetSaveFileNameW(&openFileName);
|
|
||||||
} else if (type == FD_OPEN) {
|
|
||||||
openFileName.Flags = commonFlags | OFN_NONETWORKBUTTON | OFN_FILEMUSTEXIST;
|
|
||||||
result = GetOpenFileNameW(&openFileName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
openFileName.lpstrFilter = wcFilter;
|
||||||
RCT2_GLOBAL(0x009E2C74, uint32) = tmp;
|
|
||||||
|
|
||||||
WideCharToMultiByte(CP_UTF8, 0, wcfilename, countof(wcfilename), filename, MAX_PATH, NULL, NULL);
|
// Open dialog
|
||||||
|
BOOL result;
|
||||||
|
DWORD commonFlags = OFN_EXPLORER | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY | OFN_NOCHANGEDIR;
|
||||||
|
if (desc->type == FD_OPEN) {
|
||||||
|
openFileName.Flags = commonFlags | OFN_NONETWORKBUTTON | OFN_FILEMUSTEXIST;
|
||||||
|
result = GetOpenFileNameW(&openFileName);
|
||||||
|
} else if (desc->type == FD_SAVE) {
|
||||||
|
openFileName.Flags = commonFlags | OFN_CREATEPROMPT | OFN_OVERWRITEPROMPT;
|
||||||
|
result = GetSaveFileNameW(&openFileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clean up
|
||||||
|
free((void*)openFileName.lpstrTitle);
|
||||||
|
free((void*)openFileName.lpstrInitialDir);
|
||||||
|
free((void*)openFileName.lpstrFilter);
|
||||||
|
|
||||||
|
if (result) {
|
||||||
|
utf8 *resultFilename = widechar_to_utf8(openFileName.lpstrFile);
|
||||||
|
strcpy(outFilename, resultFilename);
|
||||||
|
free(resultFilename);
|
||||||
|
|
||||||
|
// If there is no extension, append the pattern
|
||||||
|
const utf8 *outFilenameExtension = path_get_extension(outFilename);
|
||||||
|
if (str_is_null_or_empty(outFilenameExtension)) {
|
||||||
|
int filterIndex = openFileName.nFilterIndex - 1;
|
||||||
|
|
||||||
|
assert(filterIndex >= 0);
|
||||||
|
assert(filterIndex < countof(desc->filters));
|
||||||
|
|
||||||
|
const utf8 *pattern = desc->filters[filterIndex].pattern;
|
||||||
|
const utf8 *patternExtension = path_get_extension(pattern);
|
||||||
|
if (!str_is_null_or_empty(patternExtension)) {
|
||||||
|
strcat(outFilename, patternExtension);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3073,25 +3073,37 @@ int save_track_design(uint8 rideIndex){
|
||||||
// Track design files
|
// Track design files
|
||||||
format_string(RCT2_ADDRESS(0x141EE68, char), 2305, NULL);
|
format_string(RCT2_ADDRESS(0x141EE68, char), 2305, NULL);
|
||||||
|
|
||||||
|
// Show save dialog
|
||||||
|
utf8 initialDirectory[MAX_PATH];
|
||||||
|
{
|
||||||
|
strcpy(initialDirectory, path);
|
||||||
|
utf8 *a = strrchr(initialDirectory, '/');
|
||||||
|
utf8 *b = strrchr(initialDirectory, '\\');
|
||||||
|
utf8 *c = max(a, b);
|
||||||
|
if (c != NULL) {
|
||||||
|
*c = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
file_dialog_desc desc;
|
||||||
|
memset(&desc, 0, sizeof(desc));
|
||||||
|
desc.type = FD_SAVE;
|
||||||
|
desc.title = RCT2_ADDRESS(RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, utf8);
|
||||||
|
desc.initial_directory = initialDirectory;
|
||||||
|
desc.default_filename = path;
|
||||||
|
desc.filters[0].name = language_get_string(STR_OPENRCT2_TRACK_DESIGN_FILE);
|
||||||
|
desc.filters[0].pattern = "*.td6";
|
||||||
|
|
||||||
audio_pause_sounds();
|
audio_pause_sounds();
|
||||||
|
bool result = platform_open_common_file_dialog(path, &desc);
|
||||||
int result = platform_open_common_file_dialog(
|
|
||||||
FD_SAVE,
|
|
||||||
RCT2_ADDRESS(RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, char),
|
|
||||||
path,
|
|
||||||
"*.TD?",
|
|
||||||
RCT2_ADDRESS(0x141EE68, char));
|
|
||||||
|
|
||||||
audio_unpause_sounds();
|
audio_unpause_sounds();
|
||||||
|
|
||||||
if (result == 0){
|
if (!result) {
|
||||||
ride_list_item item = { .type = 0xFD, .entry_index = 0 };
|
ride_list_item item = { .type = 0xFD, .entry_index = 0 };
|
||||||
track_load_list(item);
|
track_load_list(item);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
path_append_extension(path, "TD6");
|
|
||||||
|
|
||||||
save_track_to_file(RCT2_ADDRESS(0x009D8178, rct_track_td6), path);
|
save_track_to_file(RCT2_ADDRESS(0x009D8178, rct_track_td6), path);
|
||||||
|
|
||||||
ride_list_item item = { .type = 0xFC, .entry_index = 0 };
|
ride_list_item item = { .type = 0xFC, .entry_index = 0 };
|
||||||
|
|
|
@ -318,34 +318,6 @@ void window_editor_bottom_toolbar_jump_forward_to_objective_selection() {
|
||||||
gfx_invalidate_screen();
|
gfx_invalidate_screen();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* 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);
|
|
||||||
substitute_path(filename, RCT2_ADDRESS(RCT2_ADDRESS_SCENARIOS_PATH, char), s6Info->name);
|
|
||||||
strcat(filename, ".SC6");
|
|
||||||
format_string(filterName, STR_RCT2_SCENARIO_FILE, NULL);
|
|
||||||
|
|
||||||
audio_pause_sounds();
|
|
||||||
result = platform_open_common_file_dialog(FD_SAVE, title, filename, "*.SC6", filterName);
|
|
||||||
audio_unpause_sounds();
|
|
||||||
|
|
||||||
if (result)
|
|
||||||
safe_strcpy(resultPath, filename, MAX_PATH);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* rct2: 0x0066F7C0
|
* rct2: 0x0066F7C0
|
||||||
|
@ -353,8 +325,6 @@ static int show_save_scenario_dialog(char *resultPath)
|
||||||
void window_editor_bottom_toolbar_jump_forward_to_save_scenario()
|
void window_editor_bottom_toolbar_jump_forward_to_save_scenario()
|
||||||
{
|
{
|
||||||
rct_s6_info *s6Info = (rct_s6_info*)0x0141F570;
|
rct_s6_info *s6Info = (rct_s6_info*)0x0141F570;
|
||||||
int parkFlagsBackup, success;
|
|
||||||
char path[256];
|
|
||||||
|
|
||||||
if (!scenario_prepare_for_save()) {
|
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));
|
window_error_open(STR_UNABLE_TO_SAVE_SCENARIO_FILE, RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, rct_string_id));
|
||||||
|
@ -363,37 +333,7 @@ void window_editor_bottom_toolbar_jump_forward_to_save_scenario()
|
||||||
}
|
}
|
||||||
|
|
||||||
window_close_all();
|
window_close_all();
|
||||||
|
|
||||||
window_loadsave_open(LOADSAVETYPE_SAVE | LOADSAVETYPE_SCENARIO, s6Info->name);
|
window_loadsave_open(LOADSAVETYPE_SAVE | LOADSAVETYPE_SCENARIO, s6Info->name);
|
||||||
return;
|
|
||||||
|
|
||||||
if (!show_save_scenario_dialog(path)) {
|
|
||||||
gfx_invalidate_screen();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
s6Info->editor_step = 255;
|
|
||||||
|
|
||||||
// Ensure path has .SC6 extension
|
|
||||||
path_append_extension(path, ".SC6");
|
|
||||||
|
|
||||||
// Save the scenario
|
|
||||||
parkFlagsBackup = RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32);
|
|
||||||
RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) &= ~PARK_FLAGS_18;
|
|
||||||
SDL_RWops* rw = SDL_RWFromFile(path, "wb+");
|
|
||||||
if (rw != NULL) {
|
|
||||||
success = scenario_save(rw, gConfigGeneral.save_plugin_data ? 3 : 2);
|
|
||||||
SDL_RWclose(rw);
|
|
||||||
}
|
|
||||||
RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) = parkFlagsBackup;
|
|
||||||
|
|
||||||
if (success) {
|
|
||||||
title_load();
|
|
||||||
} else {
|
|
||||||
window_error_open(STR_SCENARIO_SAVE_FAILED, -1);
|
|
||||||
s6Info->editor_step = EDITOR_STEP_OBJECTIVE_SELECTION;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -71,7 +71,6 @@ static rct_widget window_loadsave_widgets[] = {
|
||||||
|
|
||||||
static void window_loadsave_close(rct_window *w);
|
static void window_loadsave_close(rct_window *w);
|
||||||
static void window_loadsave_mouseup(rct_window *w, int widgetIndex);
|
static void window_loadsave_mouseup(rct_window *w, int widgetIndex);
|
||||||
static void window_loadsave_update(rct_window *w);
|
|
||||||
static void window_loadsave_scrollgetsize(rct_window *w, int scrollIndex, int *width, int *height);
|
static void window_loadsave_scrollgetsize(rct_window *w, int scrollIndex, int *width, int *height);
|
||||||
static void window_loadsave_scrollmousedown(rct_window *w, int scrollIndex, int x, int y);
|
static void window_loadsave_scrollmousedown(rct_window *w, int scrollIndex, int x, int y);
|
||||||
static void window_loadsave_scrollmouseover(rct_window *w, int scrollIndex, int x, int y);
|
static void window_loadsave_scrollmouseover(rct_window *w, int scrollIndex, int x, int y);
|
||||||
|
@ -173,23 +172,26 @@ rct_window *window_loadsave_open(int type, char *defaultName)
|
||||||
_loadsaveType = type;
|
_loadsaveType = type;
|
||||||
switch (type & 0x0F) {
|
switch (type & 0x0F) {
|
||||||
case (LOADSAVETYPE_LOAD | LOADSAVETYPE_GAME):
|
case (LOADSAVETYPE_LOAD | LOADSAVETYPE_GAME):
|
||||||
w->widgets[WIDX_TITLE].image = STR_LOAD_GAME;
|
w->widgets[WIDX_TITLE].image = STR_FILE_DIALOG_TITLE_LOAD_GAME;
|
||||||
break;
|
break;
|
||||||
case (LOADSAVETYPE_SAVE | LOADSAVETYPE_GAME) :
|
case (LOADSAVETYPE_SAVE | LOADSAVETYPE_GAME) :
|
||||||
w->widgets[WIDX_TITLE].image = STR_SAVE_GAME;
|
w->widgets[WIDX_TITLE].image = STR_FILE_DIALOG_TITLE_SAVE_GAME;
|
||||||
break;
|
break;
|
||||||
case (LOADSAVETYPE_LOAD | LOADSAVETYPE_LANDSCAPE) :
|
case (LOADSAVETYPE_LOAD | LOADSAVETYPE_LANDSCAPE) :
|
||||||
w->widgets[WIDX_TITLE].image = STR_LOAD_LANDSCAPE;
|
w->widgets[WIDX_TITLE].image = STR_FILE_DIALOG_TITLE_LOAD_LANDSCAPE;
|
||||||
break;
|
break;
|
||||||
case (LOADSAVETYPE_SAVE | LOADSAVETYPE_LANDSCAPE) :
|
case (LOADSAVETYPE_SAVE | LOADSAVETYPE_LANDSCAPE) :
|
||||||
w->widgets[WIDX_TITLE].image = STR_SAVE_LANDSCAPE;
|
w->widgets[WIDX_TITLE].image = STR_FILE_DIALOG_TITLE_SAVE_LANDSCAPE;
|
||||||
break;
|
break;
|
||||||
case (LOADSAVETYPE_SAVE | LOADSAVETYPE_SCENARIO) :
|
case (LOADSAVETYPE_SAVE | LOADSAVETYPE_SCENARIO) :
|
||||||
w->widgets[WIDX_TITLE].image = STR_SAVE_SCENARIO;
|
w->widgets[WIDX_TITLE].image = STR_FILE_DIALOG_TITLE_SAVE_SCENARIO;
|
||||||
break;
|
break;
|
||||||
case (LOADSAVETYPE_LOAD | LOADSAVETYPE_TRACK) :
|
case (LOADSAVETYPE_LOAD | LOADSAVETYPE_TRACK) :
|
||||||
w->widgets[WIDX_TITLE].image = 1039;
|
w->widgets[WIDX_TITLE].image = STR_FILE_DIALOG_TITLE_INSTALL_NEW_TRACK_DESIGN;
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
log_error("Unsupported load / save type: %d", type & 0x0F);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
w->no_list_items = 0;
|
w->no_list_items = 0;
|
||||||
|
@ -302,27 +304,53 @@ static void window_loadsave_mouseup(rct_window *w, int widgetIndex)
|
||||||
safe_strcpy(filter, "*", MAX_PATH);
|
safe_strcpy(filter, "*", MAX_PATH);
|
||||||
strncat(filter, _extension, MAX_PATH - strnlen(filter, MAX_PATH) - 1);
|
strncat(filter, _extension, MAX_PATH - strnlen(filter, MAX_PATH) - 1);
|
||||||
|
|
||||||
|
file_dialog_desc desc;
|
||||||
|
memset(&desc, 0, sizeof(desc));
|
||||||
|
desc.initial_directory = _directory;
|
||||||
|
if (_type & LOADSAVETYPE_SAVE) {
|
||||||
|
desc.default_filename = path;
|
||||||
|
}
|
||||||
|
|
||||||
switch (_type) {
|
switch (_type) {
|
||||||
case (LOADSAVETYPE_LOAD | LOADSAVETYPE_GAME) :
|
case (LOADSAVETYPE_LOAD | LOADSAVETYPE_GAME) :
|
||||||
result = platform_open_common_file_dialog(FD_OPEN, (char*)language_get_string(STR_LOAD_GAME), path, filter, _extension);
|
desc.type = FD_OPEN;
|
||||||
|
desc.title = language_get_string(STR_FILE_DIALOG_TITLE_LOAD_GAME);
|
||||||
|
desc.filters[0].name = language_get_string(STR_OPENRCT2_SAVED_GAME);
|
||||||
|
desc.filters[0].pattern = "*.sv4;*.sv6";
|
||||||
break;
|
break;
|
||||||
case (LOADSAVETYPE_SAVE | LOADSAVETYPE_GAME) :
|
case (LOADSAVETYPE_SAVE | LOADSAVETYPE_GAME) :
|
||||||
result = platform_open_common_file_dialog(FD_SAVE, (char*)language_get_string(STR_SAVE_GAME), path, filter, _extension);
|
desc.type = FD_SAVE;
|
||||||
|
desc.title = language_get_string(STR_FILE_DIALOG_TITLE_SAVE_GAME);
|
||||||
|
desc.filters[0].name = language_get_string(STR_OPENRCT2_SAVED_GAME);
|
||||||
|
desc.filters[0].pattern = "*.sv6";
|
||||||
break;
|
break;
|
||||||
case (LOADSAVETYPE_LOAD | LOADSAVETYPE_LANDSCAPE) :
|
case (LOADSAVETYPE_LOAD | LOADSAVETYPE_LANDSCAPE) :
|
||||||
result = platform_open_common_file_dialog(FD_OPEN, (char*)language_get_string(STR_LOAD_LANDSCAPE), path, filter, _extension);
|
desc.type = FD_OPEN;
|
||||||
|
desc.title = language_get_string(STR_FILE_DIALOG_TITLE_LOAD_LANDSCAPE);
|
||||||
|
desc.filters[0].name = language_get_string(STR_OPENRCT2_LANDSCAPE_FILE);
|
||||||
|
desc.filters[0].pattern = "*.sc4;*.sv4;*.sc6;*.sv6";
|
||||||
break;
|
break;
|
||||||
case (LOADSAVETYPE_SAVE | LOADSAVETYPE_LANDSCAPE) :
|
case (LOADSAVETYPE_SAVE | LOADSAVETYPE_LANDSCAPE) :
|
||||||
result = platform_open_common_file_dialog(FD_SAVE, (char*)language_get_string(STR_SAVE_LANDSCAPE), path, filter, _extension);
|
desc.type = FD_SAVE;
|
||||||
|
desc.title = language_get_string(STR_FILE_DIALOG_TITLE_SAVE_LANDSCAPE);
|
||||||
|
desc.filters[0].name = language_get_string(STR_OPENRCT2_LANDSCAPE_FILE);
|
||||||
|
desc.filters[0].pattern = "*.sc6";
|
||||||
break;
|
break;
|
||||||
case (LOADSAVETYPE_SAVE | LOADSAVETYPE_SCENARIO) :
|
case (LOADSAVETYPE_SAVE | LOADSAVETYPE_SCENARIO) :
|
||||||
result = platform_open_common_file_dialog(FD_SAVE, (char*)language_get_string(STR_SAVE_SCENARIO), path, filter, _extension);
|
desc.type = FD_SAVE;
|
||||||
|
desc.title = language_get_string(STR_FILE_DIALOG_TITLE_SAVE_SCENARIO);
|
||||||
|
desc.filters[0].name = language_get_string(STR_OPENRCT2_SCENARIO_FILE);
|
||||||
|
desc.filters[0].pattern = "*.sc6";
|
||||||
break;
|
break;
|
||||||
case (LOADSAVETYPE_LOAD | LOADSAVETYPE_TRACK) :
|
case (LOADSAVETYPE_LOAD | LOADSAVETYPE_TRACK) :
|
||||||
result = platform_open_common_file_dialog(FD_OPEN, (char*)language_get_string(1039), path, filter, _extension);
|
desc.type = FD_OPEN;
|
||||||
|
desc.title = language_get_string(STR_FILE_DIALOG_TITLE_INSTALL_NEW_TRACK_DESIGN);
|
||||||
|
desc.filters[0].name = language_get_string(STR_OPENRCT2_TRACK_DESIGN_FILE);
|
||||||
|
desc.filters[0].pattern = "*.td4;*.td6";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
result = platform_open_common_file_dialog(path, &desc);
|
||||||
if (result) {
|
if (result) {
|
||||||
window_loadsave_select(w, path);
|
window_loadsave_select(w, path);
|
||||||
}
|
}
|
||||||
|
@ -702,10 +730,6 @@ static void window_loadsave_select(rct_window *w, const char *path)
|
||||||
}
|
}
|
||||||
window_loadsave_invoke_callback(MODAL_RESULT_OK);
|
window_loadsave_invoke_callback(MODAL_RESULT_OK);
|
||||||
} else if (game_load_save(path)) {
|
} else if (game_load_save(path)) {
|
||||||
if (_loadsaveType & LOADSAVETYPE_NETWORK) {
|
|
||||||
network_begin_server(gConfigNetwork.default_port);
|
|
||||||
}
|
|
||||||
|
|
||||||
safe_strcpy(gScenarioSavePath, path, MAX_PATH);
|
safe_strcpy(gScenarioSavePath, path, MAX_PATH);
|
||||||
gFirstTimeSave = 0;
|
gFirstTimeSave = 0;
|
||||||
|
|
||||||
|
@ -789,7 +813,7 @@ static void window_loadsave_select(rct_window *w, const char *path)
|
||||||
window_loadsave_invoke_callback(MODAL_RESULT_OK);
|
window_loadsave_invoke_callback(MODAL_RESULT_OK);
|
||||||
title_load();
|
title_load();
|
||||||
} else {
|
} else {
|
||||||
window_error_open(STR_SAVE_SCENARIO, STR_SCENARIO_SAVE_FAILED);
|
window_error_open(STR_FILE_DIALOG_TITLE_SAVE_SCENARIO, STR_SCENARIO_SAVE_FAILED);
|
||||||
s6Info->editor_step = EDITOR_STEP_OBJECTIVE_SELECTION;
|
s6Info->editor_step = EDITOR_STEP_OBJECTIVE_SELECTION;
|
||||||
window_loadsave_invoke_callback(MODAL_RESULT_FAIL);
|
window_loadsave_invoke_callback(MODAL_RESULT_FAIL);
|
||||||
}
|
}
|
||||||
|
|
|
@ -160,6 +160,13 @@ static void window_server_start_scenarioselect_callback(const utf8 *path)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void window_server_start_loadsave_callback(int result)
|
||||||
|
{
|
||||||
|
if (result == MODAL_RESULT_OK) {
|
||||||
|
network_begin_server(gConfigNetwork.default_port);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void window_server_start_mouseup(rct_window *w, int widgetIndex)
|
static void window_server_start_mouseup(rct_window *w, int widgetIndex)
|
||||||
{
|
{
|
||||||
switch (widgetIndex) {
|
switch (widgetIndex) {
|
||||||
|
@ -199,7 +206,8 @@ static void window_server_start_mouseup(rct_window *w, int widgetIndex)
|
||||||
break;
|
break;
|
||||||
case WIDX_LOAD_SERVER:
|
case WIDX_LOAD_SERVER:
|
||||||
network_set_password(_password);
|
network_set_password(_password);
|
||||||
window_loadsave_open(LOADSAVETYPE_LOAD | LOADSAVETYPE_GAME | LOADSAVETYPE_NETWORK, NULL);
|
window_loadsave_open(LOADSAVETYPE_LOAD | LOADSAVETYPE_GAME, NULL);
|
||||||
|
gLoadSaveCallback = window_server_start_loadsave_callback;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue