From b68a3cb43d12072639a3956a5b125cd952583c3e Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Sat, 22 Nov 2014 23:30:03 +0000 Subject: [PATCH] improve RCT2 install directory problems, fixes #587 --- src/config.c | 29 ++++++++-- src/config.h | 1 + src/openrct2.c | 4 +- src/platform/osinterface.c | 24 ++++---- src/rct2.c | 115 ++++++++++++++++++++++++------------- src/rct2.h | 8 +-- 6 files changed, 119 insertions(+), 62 deletions(-) diff --git a/src/config.c b/src/config.c index de97f9544e..3f3710a8a1 100644 --- a/src/config.c +++ b/src/config.c @@ -347,6 +347,8 @@ static int config_find_rct2_path(char *resultPath) { int i; + log_verbose("searching common installation locations."); + const char *searchLocations[] = { "C:\\Program Files\\Infogrames\\RollerCoaster Tycoon 2", "C:\\Program Files (x86)\\Infogrames\\RollerCoaster Tycoon 2", @@ -367,6 +369,23 @@ static int config_find_rct2_path(char *resultPath) return 0; } +int config_find_or_browse_install_directory() +{ + char *installPath; + + if (!config_find_rct2_path(gGeneral_config.game_path)) { + osinterface_show_messagebox("Unable to find RCT2 installation directory. Please select the directory where you installed RCT2!"); + installPath = osinterface_open_directory_browser("Please select your RCT2 directory"); + if (installPath == NULL) + return 0; + + strcpy(gGeneral_config.game_path, installPath); + } + + config_save(); + return 1; +} + /** * Create a new default settings file. * This should be created from some other resource when openRCT2 grows @@ -375,13 +394,11 @@ static int config_find_rct2_path(char *resultPath) static void config_create_default(char *path) { gGeneral_config = gGeneral_config_default; - - if (!config_find_rct2_path(gGeneral_config.game_path)) { - osinterface_show_messagebox("Unable to find RCT2 installation directory. Please select the directory where you installed RCT2!"); - char *res = osinterface_open_directory_browser("Please select your RCT2 directory"); - strcpy(gGeneral_config.game_path, res); + if (!config_find_or_browse_install_directory()) { + log_fatal("An RCT2 install directory must be specified!"); + exit(-1); } - + config_save_ini(path); } diff --git a/src/config.h b/src/config.h index 0fff44272e..28f6ea9e13 100644 --- a/src/config.h +++ b/src/config.h @@ -100,6 +100,7 @@ extern uint16 gShortcutKeys[SHORTCUT_COUNT]; void config_reset_shortcut_keys(); void config_load(); void config_save(); +int config_find_or_browse_install_directory(); // New config format diff --git a/src/openrct2.c b/src/openrct2.c index 8b8c7c6ee9..36dd388bdc 100644 --- a/src/openrct2.c +++ b/src/openrct2.c @@ -56,7 +56,9 @@ void openrct2_launch() audio_get_devices(); get_dsound_devices(); language_open(gGeneral_config.language); - rct2_init(); + if (!rct2_init()) + return; + Mixer_Init(NULL); switch (gOpenRCT2StartupAction) { diff --git a/src/platform/osinterface.c b/src/platform/osinterface.c index 35a7e83a41..e4440d44a5 100644 --- a/src/platform/osinterface.c +++ b/src/platform/osinterface.c @@ -849,27 +849,31 @@ int osinterface_open_common_file_dialog(int type, char *title, char *filename, c return result; } -void osinterface_show_messagebox(char* message){ +void osinterface_show_messagebox(char* message) +{ MessageBox(NULL, message, "OpenRCT2", MB_OK); } -char* osinterface_open_directory_browser(char *title) { - BROWSEINFO bi; - char pszBuffer[MAX_PATH]; - LPITEMIDLIST pidl; - LPMALLOC lpMalloc; +char* osinterface_open_directory_browser(char *title) +{ + BROWSEINFO bi; + char pszBuffer[MAX_PATH]; + LPITEMIDLIST pidl; + LPMALLOC lpMalloc; // Initialize COM if (FAILED(CoInitializeEx(0, COINIT_APARTMENTTHREADED))) { - MessageBox(NULL, _T("Error opening browse window"), _T("ERROR"), MB_OK); CoUninitialize(); + + log_error("Error opening directory browse window"); return 0; } // Get a pointer to the shell memory allocator if (FAILED(SHGetMalloc(&lpMalloc))) { - MessageBox(NULL, _T("Error opening browse window"), _T("ERROR"), MB_OK); CoUninitialize(); + + log_error("Error opening directory browse window"); return 0; } @@ -881,7 +885,7 @@ char* osinterface_open_directory_browser(char *title) { bi.lpfn = NULL; bi.lParam = 0; - char *outPath = "C:\\"; + char *outPath = NULL; if (pidl = SHBrowseForFolder(&bi)) { // Copy the path directory to the buffer @@ -900,7 +904,7 @@ char* osinterface_get_orct2_homefolder() char *path=NULL; path = malloc(sizeof(char) * MAX_PATH); if (path == NULL){ - osinterface_show_messagebox("Error allocating memory!"); + log_fatal("Error allocating memory!"); exit(EXIT_FAILURE); } diff --git a/src/rct2.c b/src/rct2.c index de77bbe566..b907217d4a 100644 --- a/src/rct2.c +++ b/src/rct2.c @@ -56,8 +56,8 @@ typedef struct tm tm_t; void print_launch_information(); -void rct2_init_directories(); -void rct2_startup_checks(); +int rct2_init_directories(); +int rct2_startup_checks(); static void rct2_update_2(); @@ -71,7 +71,7 @@ void rct2_quit() { openrct2_finish(); } -void rct2_init() +int rct2_init() { log_verbose("initialising game"); @@ -80,8 +80,12 @@ void rct2_init() get_system_time(); RCT2_GLOBAL(0x009DEA69, short) = RCT2_GLOBAL(RCT2_ADDRESS_OS_TIME_DAY, short); RCT2_GLOBAL(0x009DEA6B, short) = RCT2_GLOBAL(RCT2_ADDRESS_OS_TIME_DAY, short); - rct2_init_directories(); - rct2_startup_checks(); + if (!rct2_init_directories()) + return 0; + + if (!rct2_startup_checks()) + return 0; + config_reset_shortcut_keys(); RCT2_GLOBAL(RCT2_ADDRESS_PLACE_OBJECT_MODIFIER, uint8) = 0; // config_load(); @@ -119,15 +123,23 @@ void rct2_init() gfx_clear(RCT2_ADDRESS(RCT2_ADDRESS_SCREEN_DPI, rct_drawpixelinfo), 10); RCT2_GLOBAL(RCT2_ADDRESS_RUN_INTRO_TICK_PART, uint8) = gGeneral_config.play_intro ? 8 : 255; + + return 1; } -// rct2: 0x00683499 -void rct2_init_directories() +/** + * + * rct2: 0x00683499 + */ +int rct2_init_directories() { // check install directory - if (!platform_directory_exists(gGeneral_config.game_path) ) { - osinterface_show_messagebox("Invalid RCT2 installation path. Please correct in config.ini."); - exit(-1); + if (!platform_directory_exists(gGeneral_config.game_path)) { + log_verbose("install directory does not exist, %s", gGeneral_config.game_path); + if (!config_find_or_browse_install_directory()) { + log_fatal("Invalid RCT2 installation path. Please correct in config.ini."); + return 0; + } } strcpy(RCT2_ADDRESS(RCT2_ADDRESS_APP_PATH, char), gGeneral_config.game_path); @@ -151,6 +163,7 @@ void rct2_init_directories() strcat(RCT2_ADDRESS(RCT2_ADDRESS_TRACKS_PATH, char), "\\Tracks\\*.TD?"); strcpy(RCT2_ADDRESS(RCT2_ADDRESS_SAVED_GAMES_PATH_2, char), RCT2_ADDRESS(RCT2_ADDRESS_SAVED_GAMES_PATH, char)); + return 1; } void subsitute_path(char *dest, const char *path, const char *filename) @@ -161,12 +174,19 @@ void subsitute_path(char *dest, const char *path, const char *filename) strcpy(dest, filename); } -// rct2: 0x00674B42 -void rct2_startup_checks() +/** + * + * rct2: 0x00674B42 + */ +int rct2_startup_checks() { - // Check data files - check_file_paths(); - check_files_integrity(); + if (!check_file_paths()) + return 0; + + if (!check_files_integrity()) + return 0; + + return 1; } void rct2_update() @@ -212,23 +232,29 @@ int rct2_open_file(const char *path) return 0; } -// rct2: 0x00674C95 -void check_file_paths() +/** + * + * rct2: 0x00674C95 + */ +int check_file_paths() { - for (int pathId = 0; pathId < PATH_ID_END; pathId += 1) - { - check_file_path(pathId); - } + for (int pathId = 0; pathId < PATH_ID_END; pathId++) + if (!check_file_path(pathId)) + return 0; + + return 1; } -// rct2: 0x00674CA5 -void check_file_path(int pathId) +/** + * + * rct2: 0x00674CA5 + */ +int check_file_path(int pathId) { const char * path = get_file_path(pathId); HANDLE file = CreateFile(path, FILE_GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, NULL); - switch (pathId) - { + switch (pathId) { case PATH_ID_GAMECFG: case PATH_ID_SCORES: case PATH_ID_TRACKSIDX: @@ -254,38 +280,45 @@ void check_file_path(int pathId) // the original implementation always assumes they are stored on CD-ROM. // This has been removed for now for the sake of simplicity and could be added // later in a more convenient way using the INI file. - RCT2_ERROR("Could not find file %s", path); - RCT2_CALLPROC_X(0x006E3838, 0x343, 0x337, 0, 0, 0, 0, 0); // exit_with_error + log_fatal("Could not find file %s", path); + return 0; } break; } if (file != INVALID_HANDLE_VALUE) CloseHandle(file); + + return 1; } -// rct2: 0x00674C0B -void check_files_integrity() +/** + * + * rct2: 0x00674C0B + */ +int check_files_integrity() { - int i = 0; - while (files_to_check[i].pathId != PATH_ID_END) - { - WIN32_FIND_DATA find_data; - const char * path = get_file_path(files_to_check[i].pathId); - HANDLE file = FindFirstFile(path, &find_data); + int i; + const char *path; + HANDLE file; + WIN32_FIND_DATA find_data; - if (file == INVALID_HANDLE_VALUE || find_data.nFileSizeLow != files_to_check[i].fileSize) - { + for (i = 0; files_to_check[i].pathId != PATH_ID_END; i++) { + path = get_file_path(files_to_check[i].pathId); + file = FindFirstFile(path, &find_data); + + if (file == INVALID_HANDLE_VALUE || find_data.nFileSizeLow != files_to_check[i].fileSize) { if (file != INVALID_HANDLE_VALUE) FindClose(file); - RCT2_ERROR("Integrity check failed for %s", path); - RCT2_CALLPROC_X(0x006E3838, 0x343, 0x337, 0, 0, 0, 0, 0); // exit_with_error + + log_fatal("Integrity check failed for %s", path); + return 0; } FindClose(file); - - i += 1; } + + return 1; } void rct2_update_2() diff --git a/src/rct2.h b/src/rct2.h index 95a70dd904..4ec4787f73 100644 --- a/src/rct2.h +++ b/src/rct2.h @@ -269,14 +269,14 @@ static const struct file_to_check { PATH_ID_END, 0 } }; -void rct2_init(); +int rct2_init(); void rct2_update(); void rct2_endupdate(); void subsitute_path(char *dest, const char *path, const char *filename); int check_mutex(); -void check_file_paths(); -void check_file_path(int pathId); -void check_files_integrity(); +int check_file_paths(); +int check_file_path(int pathId); +int check_files_integrity(); const char *get_file_path(int pathId); void get_system_info(); void get_system_time();