void title_sequence_rename_save(int preset, int index, const char *newName) { if (preset >= TITLE_SEQUENCE_DEFAULT_PRESETS && preset < gConfigTitleSequences.num_presets && index >= 0 && index < gConfigTitleSequences.presets[preset].num_saves && filename_valid_characters(newName) && !title_sequence_save_exists(preset, newName)) { // Rename the save file char separator = platform_get_path_separator(); utf8 src[MAX_PATH], dest[MAX_PATH]; platform_get_user_directory(src, "title sequences"); platform_get_user_directory(dest, "title sequences"); strcat(src, gConfigTitleSequences.presets[preset].name); strcat(dest, gConfigTitleSequences.presets[preset].name); strncat(src, &separator, 1); strncat(dest, &separator, 1); strcat(src, gConfigTitleSequences.presets[preset].saves[index]); strcat(dest, newName); // Add the appropriate extension if needed char *extension = (char*)path_get_extension(newName); if (_stricmp(extension, ".sv6") != 0 && _stricmp(extension, ".sc6") != 0) strcat(dest, ".sv6"); platform_file_move(src, dest); safe_strncpy(gConfigTitleSequences.presets[preset].saves[index], newName, TITLE_SEQUENCE_MAX_SAVE_LENGTH); // Add the appropriate extension if needed if (_stricmp(extension, ".sv6") != 0 && _stricmp(extension, ".sc6") != 0) strcat(gConfigTitleSequences.presets[preset].saves[index], ".sv6"); title_sequence_save_preset_script(preset); } }
/** * Copy saved games and landscapes to user directory */ static void openrct2_copy_original_user_files_over() { utf8 path[MAX_PATH]; platform_get_user_directory(path, "save"); openrct2_copy_files_over((utf8*)RCT2_ADDRESS_SAVED_GAMES_PATH, path, ".sv6"); platform_get_user_directory(path, "landscape"); openrct2_copy_files_over((utf8*)RCT2_ADDRESS_LANDSCAPES_PATH, path, ".sc6"); }
IPlatformEnvironment * SetupEnvironment() { utf8 userPath[MAX_PATH]; platform_resolve_openrct_data_path(); platform_resolve_user_data_path(); platform_get_user_directory(userPath, NULL, sizeof(userPath)); if (!platform_ensure_directory_exists(userPath)) { Console::Error::WriteLine("Could not create user directory (do you have write access to your documents folder?)"); return nullptr; } openrct2_set_exe_path(); config_set_defaults(); if (!config_open_default()) { if (!config_find_or_browse_install_directory()) { gConfigGeneral.last_run_version = String::Duplicate(OPENRCT2_VERSION); config_save_default(); utf8 path[MAX_PATH]; config_get_default_path(path, sizeof(path)); Console::Error::WriteLine("An RCT2 install directory must be specified! Please edit \"game_path\" in %s.", path); return nullptr; } config_save_default(); } if (!rct2_init_directories()) { return nullptr; } if (!rct2_startup_checks()) { return nullptr; } utf8 path[260]; std::string basePaths[4]; basePaths[(size_t)DIRBASE::RCT1] = String::ToStd(gConfigGeneral.rct1_path); basePaths[(size_t)DIRBASE::RCT2] = String::ToStd(gConfigGeneral.rct2_path); platform_get_openrct_data_path(path, sizeof(path)); basePaths[(size_t)DIRBASE::OPENRCT2] = std::string(path); platform_get_user_directory(path, nullptr, sizeof(path)); basePaths[(size_t)DIRBASE::USER] = std::string(path); IPlatformEnvironment * env = CreatePlatformEnvironment(basePaths); return env; }
void title_sequence_create_preset(const char *name) { if (filename_valid_characters(name) && !title_sequence_name_exists(name)) { int preset = gConfigTitleSequences.num_presets; gConfigTitleSequences.num_presets++; gConfigTitleSequences.presets = realloc(gConfigTitleSequences.presets, sizeof(title_sequence) * (size_t)gConfigTitleSequences.num_presets); safe_strncpy(gConfigTitleSequences.presets[preset].name, name, TITLE_SEQUENCE_NAME_SIZE); gConfigTitleSequences.presets[preset].path[0] = 0; gConfigTitleSequences.presets[preset].saves = malloc(0); gConfigTitleSequences.presets[preset].commands = malloc(0); gConfigTitleSequences.presets[preset].num_saves = 0; gConfigTitleSequences.presets[preset].num_commands = 0; // Create the folder utf8 path[MAX_PATH]; platform_get_user_directory(path, "title sequences"); strcat(path, gConfigTitleSequences.presets[preset].name); platform_file_delete(path); platform_ensure_directory_exists(path); title_sequence_save_preset_script(preset); gCurrentTitleSequence = preset; } }
void title_sequence_remove_save(int preset, int index) { if (preset >= TITLE_SEQUENCE_DEFAULT_PRESETS && preset < gConfigTitleSequences.num_presets && index >= 0 && index < gConfigTitleSequences.presets[preset].num_saves) { // Delete the save file char separator = platform_get_path_separator(); utf8 path[MAX_PATH]; platform_get_user_directory(path, "title sequences"); strcat(path, gConfigTitleSequences.presets[preset].name); strncat(path, &separator, 1); strcat(path, gConfigTitleSequences.presets[preset].saves[index]); platform_file_delete(path); // Remove all references to this save in the commands and decrement save indecies for (int i = 0; i < gConfigTitleSequences.presets[preset].num_commands; i++) { if (gConfigTitleSequences.presets[preset].commands[i].command == TITLE_SCRIPT_LOAD) { if (gConfigTitleSequences.presets[preset].commands[i].saveIndex == index) gConfigTitleSequences.presets[preset].commands[i].saveIndex = 0xFF; else if (gConfigTitleSequences.presets[preset].commands[i].saveIndex > index && gConfigTitleSequences.presets[preset].commands[i].saveIndex != 0xFF) gConfigTitleSequences.presets[preset].commands[i].saveIndex--; } } for (int i = index; i < gConfigTitleSequences.presets[preset].num_saves - 1; i++) { safe_strncpy(gConfigTitleSequences.presets[preset].saves[i], gConfigTitleSequences.presets[preset].saves[i + 1], TITLE_SEQUENCE_MAX_SAVE_LENGTH); } gConfigTitleSequences.presets[preset].num_saves--; gConfigTitleSequences.presets[preset].saves = realloc(gConfigTitleSequences.presets[preset].saves, sizeof(char[TITLE_SEQUENCE_MAX_SAVE_LENGTH]) * (size_t)gConfigTitleSequences.presets[preset].num_saves); title_sequence_save_preset_script(preset); } }
void title_sequence_add_save(int preset, const char *path, const char *newName) { utf8 newPath[MAX_PATH]; char *extension = (char*)path_get_extension(newName); safe_strncpy(newPath, newName, MAX_PATH); if (_stricmp(extension, ".sv6") != 0 && _stricmp(extension, ".sc6") != 0) strcat(newPath, ".sv6"); if (preset >= TITLE_SEQUENCE_DEFAULT_PRESETS && preset < gConfigTitleSequences.num_presets && filename_valid_characters(newPath) && !title_sequence_save_exists(preset, newPath) && platform_file_exists(path)) { // Copy the save file char separator = platform_get_path_separator(); platform_get_user_directory(newPath, "title sequences"); strcat(newPath, gConfigTitleSequences.presets[preset].name); strncat(newPath, &separator, 1); strcat(newPath, newName); // Add the appropriate extension if needed if (_stricmp(extension, ".sv6") != 0 && _stricmp(extension, ".sc6") != 0) strcat(newPath, ".sv6"); platform_file_copy(path, newPath, false); gConfigTitleSequences.presets[preset].num_saves++; gConfigTitleSequences.presets[preset].saves = realloc(gConfigTitleSequences.presets[preset].saves, sizeof(char[TITLE_SEQUENCE_MAX_SAVE_LENGTH]) * (size_t)gConfigTitleSequences.presets[preset].num_saves); safe_strncpy(gConfigTitleSequences.presets[preset].saves[gConfigTitleSequences.presets[preset].num_saves - 1], newName, TITLE_SEQUENCE_MAX_SAVE_LENGTH); // Add the appropriate extension if needed if (_stricmp(extension, ".sv6") != 0 && _stricmp(extension, ".sc6") != 0) strcat(gConfigTitleSequences.presets[preset].saves[gConfigTitleSequences.presets[preset].num_saves - 1], ".sv6"); } }
void title_sequence_delete_preset(int preset) { if (preset >= TITLE_SEQUENCE_DEFAULT_PRESETS && preset < gConfigTitleSequences.num_presets) { // Delete the folder utf8 path[MAX_PATH]; char separator = platform_get_path_separator(); platform_get_user_directory(path, "title sequences"); strcat(path, gConfigTitleSequences.presets[preset].name); if (!platform_directory_delete(path)) { log_error("Failed to delete directory: \"%s\"", path); } free(gConfigTitleSequences.presets[preset].saves); free(gConfigTitleSequences.presets[preset].commands); for (int i = preset; i < gConfigTitleSequences.num_presets - 1; i++) { gConfigTitleSequences.presets[i] = gConfigTitleSequences.presets[i + 1]; } gConfigTitleSequences.num_presets--; gConfigTitleSequences.presets = realloc(gConfigTitleSequences.presets, sizeof(title_sequence) * (size_t)gConfigTitleSequences.num_presets); gCurrentTitleSequence--; if (gCurrentPreviewTitleSequence > preset) title_sequence_change_preset(gCurrentPreviewTitleSequence - 1); else if (gCurrentPreviewTitleSequence == preset) title_sequence_change_preset(0); } }
static void window_install_track_design(rct_window* w) { utf8 destPath[MAX_PATH]; platform_get_user_directory(destPath, "track", sizeof(destPath)); if (!platform_ensure_directory_exists(destPath)) { log_error("Unable to create directory '%s'", destPath); context_show_error(STR_CANT_SAVE_TRACK_DESIGN, STR_NONE); return; } safe_strcat_path(destPath, _trackName.c_str(), sizeof(destPath)); path_append_extension(destPath, ".td6", sizeof(destPath)); if (platform_file_exists(destPath)) { log_info("%s already exists, prompting user for a different track design name", destPath); context_show_error(STR_UNABLE_TO_INSTALL_THIS_TRACK_DESIGN, STR_NONE); window_text_input_raw_open( w, WIDX_INSTALL, STR_SELECT_NEW_NAME_FOR_TRACK_DESIGN, STR_AN_EXISTING_TRACK_DESIGN_ALREADY_HAS_THIS_NAME, _trackName.c_str(), 255); } else { if (track_repository_install(_trackPath.c_str())) { window_close(w); } else { context_show_error(STR_CANT_SAVE_TRACK_DESIGN, STR_NONE); } } }
void title_sequence_rename_preset(int preset, const char *newName) { if (preset >= TITLE_SEQUENCE_DEFAULT_PRESETS && preset < gConfigTitleSequences.num_presets && filename_valid_characters(newName) && !title_sequence_name_exists(newName)) { // Rename the folder utf8 src[MAX_PATH], dest[MAX_PATH]; platform_get_user_directory(src, "title sequences"); platform_get_user_directory(dest, "title sequences"); strcat(src, gConfigTitleSequences.presets[preset].name); strcat(dest, newName); platform_file_move(src, dest); safe_strncpy(gConfigTitleSequences.presets[preset].name, newName, TITLE_SEQUENCE_NAME_SIZE); // Rename the config preset name if needed if (preset == gCurrentPreviewTitleSequence) { gConfigInterface.current_title_sequence_preset = gConfigTitleSequences.presets[preset].name; } } }
void theme_rename_preset(int preset, const char *newName) { if (preset >= 2) { utf8 src[MAX_PATH], dest[MAX_PATH]; platform_get_user_directory(src, "themes"); platform_get_user_directory(dest, "themes"); strcat(src, gConfigThemes.presets[preset].name); strcat(dest, newName); strcat(src, ".ini"); strcat(dest, ".ini"); platform_file_move(src, dest); strcpy(gConfigThemes.presets[gCurrentTheme].name, newName); if (preset == gCurrentTheme) { gConfigInterface.current_theme_preset = gConfigThemes.presets[gCurrentTheme].name; } } }
static std::wstring GetDumpDirectory() { char userDirectory[MAX_PATH]; platform_get_user_directory(userDirectory, NULL, sizeof(userDirectory)); wchar_t * userDirectoryW = utf8_to_widechar(userDirectory); auto result = std::wstring(userDirectoryW); free(userDirectoryW); return result; }
void theme_delete_preset(int preset) { if (preset >= 2) { utf8 path[MAX_PATH]; platform_get_user_directory(path, "themes"); strcat(path, gConfigThemes.presets[preset].name); strcat(path, ".ini"); platform_file_delete(path); free(gConfigThemes.presets[preset].windows); for (int i = preset; i < gConfigThemes.num_presets - 1; i++) { gConfigThemes.presets[i] = gConfigThemes.presets[i + 1]; } gConfigThemes.num_presets--; theme_change_preset(0); } }
/** * Searches and grabs the metadata for all the scenarios. */ void scenario_load_list() { utf8 directory[MAX_PATH]; // Clear scenario list gScenarioListCount = 0; // Get scenario directory from RCT2 safe_strcpy(directory, gConfigGeneral.game_path, sizeof(directory)); safe_strcat_path(directory, "Scenarios", sizeof(directory)); scenario_list_include(directory); // Get scenario directory from user directory platform_get_user_directory(directory, "scenario"); scenario_list_include(directory); scenario_list_sort(); scenario_scores_load(); utf8 scoresPath[MAX_PATH]; scenario_scores_legacy_get_path(scoresPath); scenario_scores_legacy_load(scoresPath); scenario_scores_legacy_load(get_file_path(PATH_ID_SCORES)); }
void title_sequence_duplicate_preset(int duplicate, const char *name) { if (duplicate >= 0 && duplicate < gConfigTitleSequences.num_presets && filename_valid_characters(name) && !title_sequence_name_exists(name)) { int preset = gConfigTitleSequences.num_presets; gConfigTitleSequences.num_presets++; gConfigTitleSequences.presets = realloc(gConfigTitleSequences.presets, sizeof(title_sequence) * (size_t)gConfigTitleSequences.num_presets); safe_strncpy(gConfigTitleSequences.presets[preset].name, name, TITLE_SEQUENCE_NAME_SIZE); gConfigTitleSequences.presets[preset].path[0] = 0; size_t savesSize = sizeof(char[TITLE_SEQUENCE_MAX_SAVE_LENGTH]) * gConfigTitleSequences.presets[duplicate].num_saves; size_t commandsSize = sizeof(title_command) * gConfigTitleSequences.presets[duplicate].num_commands; gConfigTitleSequences.presets[preset].saves = malloc(savesSize); gConfigTitleSequences.presets[preset].commands = malloc(commandsSize); memcpy(gConfigTitleSequences.presets[preset].saves, gConfigTitleSequences.presets[duplicate].saves, savesSize); memcpy(gConfigTitleSequences.presets[preset].commands, gConfigTitleSequences.presets[duplicate].commands, commandsSize); gConfigTitleSequences.presets[preset].num_saves = gConfigTitleSequences.presets[duplicate].num_saves; gConfigTitleSequences.presets[preset].num_commands = gConfigTitleSequences.presets[duplicate].num_commands; bool loadmm = false; for (int i = 0; i < gConfigTitleSequences.presets[preset].num_commands; i++) { if (gConfigTitleSequences.presets[preset].commands[i].command == TITLE_SCRIPT_LOADMM) { loadmm = true; gConfigTitleSequences.presets[preset].commands[i].command = TITLE_SCRIPT_LOAD; gConfigTitleSequences.presets[preset].commands[i].saveIndex = gConfigTitleSequences.presets[duplicate].num_saves; } } // Create the folder utf8 path[MAX_PATH], srcPath[MAX_PATH]; platform_get_user_directory(path, "title sequences"); strcat(path, gConfigTitleSequences.presets[preset].name); platform_file_delete(path); platform_ensure_directory_exists(path); // Copy the saves char separator = platform_get_path_separator(); for (int i = 0; i < gConfigTitleSequences.presets[preset].num_saves; i++) { if (gConfigTitleSequences.presets[duplicate].path[0]) { safe_strncpy(srcPath, gConfigTitleSequences.presets[duplicate].path, MAX_PATH); strcat(srcPath, gConfigTitleSequences.presets[duplicate].saves[i]); } else { platform_get_user_directory(srcPath, "title sequences"); strcat(srcPath, gConfigTitleSequences.presets[duplicate].name); strncat(srcPath, &separator, 1); strcat(srcPath, gConfigTitleSequences.presets[duplicate].saves[i]); } platform_get_user_directory(path, "title sequences"); strcat(path, gConfigTitleSequences.presets[preset].name); strncat(path, &separator, 1); strcat(path, gConfigTitleSequences.presets[preset].saves[i]); platform_file_copy(srcPath, path, false); } if (loadmm) { title_sequence_add_save(preset, get_file_path(PATH_ID_SIXFLAGS_MAGICMOUNTAIN), "Six Flags Magic Mountain.SC6"); } title_sequence_save_preset_script(preset); gCurrentTitleSequence = preset; } }
bool openrct2_initialise() { utf8 userPath[MAX_PATH]; platform_resolve_user_data_path(); platform_get_user_directory(userPath, NULL); if (!platform_ensure_directory_exists(userPath)) { log_fatal("Could not create user directory (do you have write access to your documents folder?)"); return false; } if (!openrct2_setup_rct2_segment()) { log_fatal("Unable to load RCT2 data sector"); return false; } openrct2_set_exe_path(); config_set_defaults(); if (!config_open_default()) { if (!config_find_or_browse_install_directory()) { log_fatal("An RCT2 install directory must be specified!"); return false; } } gOpenRCT2ShowChangelog = true; if (gConfigGeneral.last_run_version != NULL && (strcmp(gConfigGeneral.last_run_version, OPENRCT2_VERSION) == 0)) gOpenRCT2ShowChangelog = false; gConfigGeneral.last_run_version = OPENRCT2_VERSION; config_save_default(); // TODO add configuration option to allow multiple instances // if (!gOpenRCT2Headless && !platform_lock_single_instance()) { // log_fatal("OpenRCT2 is already running."); // return false; // } get_system_info(); if (!gOpenRCT2Headless) { audio_init(); audio_get_devices(); } if (!language_open(gConfigGeneral.language)) { log_fatal("Failed to open language, exiting."); return false; } http_init(); themes_set_default(); themes_load_presets(); title_sequences_set_default(); title_sequences_load_presets(); openrct2_setup_rct2_hooks(); if (!rct2_init()) return false; chat_init(); openrct2_copy_original_user_files_over(); // TODO move to audio initialise function if (str_is_null_or_empty(gConfigSound.device)) { Mixer_Init(NULL); RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_SOUND_DEVICE, uint32) = 0; } else { Mixer_Init(gConfigSound.device); for (int i = 0; i < gAudioDeviceCount; i++) { if (strcmp(gAudioDevices[i].name, gConfigSound.device) == 0) { RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_SOUND_DEVICE, uint32) = i; } } } return true; }
static exitcode_t HandleCommandSetRCT2(CommandLineArgEnumerator * enumerator) { exitcode_t result = CommandLine::HandleCommandDefault(); if (result != EXITCODE_CONTINUE) { return result; } // Get the path that was passed const utf8 * rawPath; if (!enumerator->TryPopString(&rawPath)) { Console::Error::WriteLine("Expected a path."); return EXITCODE_FAIL; } utf8 path[MAX_PATH]; Path::GetAbsolute(path, sizeof(path), rawPath); // Check if path exists Console::WriteLine("Checking path..."); if (!platform_directory_exists(path)) { Console::Error::WriteLine("The path '%s' does not exist", path); return EXITCODE_FAIL; } // Check if g1.dat exists (naive but good check) Console::WriteLine("Checking g1.dat..."); utf8 pathG1Check[MAX_PATH]; String::Set(pathG1Check, sizeof(pathG1Check), path); Path::Append(pathG1Check, sizeof(pathG1Check), "Data"); Path::Append(pathG1Check, sizeof(pathG1Check), "g1.dat"); if (!platform_file_exists(pathG1Check)) { Console::Error::WriteLine("RCT2 path not valid."); Console::Error::WriteLine("Unable to find %s.", pathG1Check); return EXITCODE_FAIL; } // Check user path that will contain the config utf8 userPath[MAX_PATH]; platform_resolve_user_data_path(); platform_get_user_directory(userPath, NULL, sizeof(userPath)); if (!platform_ensure_directory_exists(userPath)) { Console::Error::WriteLine("Unable to access or create directory '%s'.", userPath); return EXITCODE_FAIL; } // Update RCT2 path in config config_set_defaults(); config_open_default(); String::DiscardDuplicate(&gConfigGeneral.rct2_path, path); if (config_save_default()) { Console::WriteFormat("Updating RCT2 path to '%s'.", path); Console::WriteLine(); Console::WriteLine("Updated config.ini"); return EXITCODE_OK; } else { Console::Error::WriteLine("Unable to update config.ini"); return EXITCODE_FAIL; } }
void GetThemePath(utf8 * buffer, size_t bufferSize) { platform_get_user_directory(buffer, "themes"); }
rct_window *window_loadsave_open(int type, char *defaultName) { gLoadSaveCallback = NULL; gLoadSaveTitleSequenceSave = false; char path[MAX_PATH], *ch; int includeNewItem; rct_window* w; _type = type; _defaultName[0] = '\0'; if (!str_is_null_or_empty(defaultName)) { safe_strcpy(_defaultName, defaultName, sizeof(_defaultName)); } w = window_bring_to_front_by_class(WC_LOADSAVE); if (w == NULL) { w = window_create_centred(WW, WH, &window_loadsave_events, WC_LOADSAVE, WF_STICK_TO_FRONT); w->widgets = window_loadsave_widgets; w->enabled_widgets = (1 << WIDX_CLOSE) | (1 << WIDX_UP) | (1 << WIDX_NEW) | (1 << WIDX_SORT_NAME) | (1 << WIDX_SORT_DATE) | (1 << WIDX_BROWSE); w->colours[0] = 7; w->colours[1] = 7; w->colours[2] = 7; } _loadsaveType = type; switch (type & 0x0F) { case (LOADSAVETYPE_LOAD | LOADSAVETYPE_GAME): w->widgets[WIDX_TITLE].image = STR_FILE_DIALOG_TITLE_LOAD_GAME; break; case (LOADSAVETYPE_SAVE | LOADSAVETYPE_GAME) : w->widgets[WIDX_TITLE].image = STR_FILE_DIALOG_TITLE_SAVE_GAME; break; case (LOADSAVETYPE_LOAD | LOADSAVETYPE_LANDSCAPE) : w->widgets[WIDX_TITLE].image = STR_FILE_DIALOG_TITLE_LOAD_LANDSCAPE; break; case (LOADSAVETYPE_SAVE | LOADSAVETYPE_LANDSCAPE) : w->widgets[WIDX_TITLE].image = STR_FILE_DIALOG_TITLE_SAVE_LANDSCAPE; break; case (LOADSAVETYPE_SAVE | LOADSAVETYPE_SCENARIO) : w->widgets[WIDX_TITLE].image = STR_FILE_DIALOG_TITLE_SAVE_SCENARIO; break; case (LOADSAVETYPE_LOAD | LOADSAVETYPE_TRACK) : w->widgets[WIDX_TITLE].image = STR_FILE_DIALOG_TITLE_INSTALL_NEW_TRACK_DESIGN; break; default: log_error("Unsupported load / save type: %d", type & 0x0F); return NULL; } w->no_list_items = 0; w->selected_list_item = -1; includeNewItem = (type & 0x01) == LOADSAVETYPE_SAVE; switch (type & 0x0E) { case LOADSAVETYPE_GAME: platform_get_user_directory(path, "save"); if (!platform_ensure_directory_exists(path)) { log_error("Unable to create save directory."); window_close(w); return NULL; } window_loadsave_populate_list(w, includeNewItem, path, ".sv6"); break; case LOADSAVETYPE_LANDSCAPE: platform_get_user_directory(path, "landscape"); if (!platform_ensure_directory_exists(path)) { log_error("Unable to create landscapes directory."); window_close(w); return NULL; } window_loadsave_populate_list(w, includeNewItem, path, ".sc6"); break; case LOADSAVETYPE_SCENARIO: platform_get_user_directory(path, "scenario"); if (!platform_ensure_directory_exists(path)) { log_error("Unable to create scenarios directory."); window_close(w); return NULL; } window_loadsave_populate_list(w, includeNewItem, path, ".sc6"); break; case LOADSAVETYPE_TRACK: /* Uncomment when user tracks are separated platform_get_user_directory(path, "tracks"); if (!platform_ensure_directory_exists(path)) { log_error("Unable to create tracks directory."); window_close(w); return NULL; } */ safe_strcpy(path, RCT2_ADDRESS(RCT2_ADDRESS_TRACKS_PATH, char), MAX_PATH); ch = strchr(path, '*'); if (ch != NULL) *ch = 0; window_loadsave_populate_list(w, includeNewItem, path, ".td?"); break; } w->no_list_items = _listItemsCount; window_init_scroll_widgets(w); return w; }