Exemplo n.º 1
0
static void window_multiplayer_information_paint(rct_window *w, rct_drawpixelinfo *dpi)
{
	window_draw_widgets(w, dpi);
	window_multiplayer_draw_tab_images(w, dpi);

	rct_drawpixelinfo clippedDPI;
	if (clip_drawpixelinfo(&clippedDPI, dpi, w->x, w->y, w->width, w->height)) {
		dpi = &clippedDPI;

		sint32 x = 3;
		sint32 y = 50;
		sint32 width = w->width - 6;

		const utf8 * name = network_get_server_name();
		{
			gfx_draw_string_left_wrapped(dpi, (void*)&name, x, y, width, STR_STRING, w->colours[1]);
			y += 11;
		}
		y += 3;

		const utf8 * description = network_get_server_description();
		if (!str_is_null_or_empty(description)) {
			gfx_draw_string_left_wrapped(dpi, (void*)&description, x, y, width, STR_STRING, w->colours[1]);
			y += 11;
		}
		y += 8;

		const utf8 * providerName = network_get_server_provider_name();
		if (!str_is_null_or_empty(providerName)) {
			gfx_draw_string_left(dpi, STR_PROVIDER_NAME, (void*)&providerName, COLOUR_BLACK, x, y);
			y += 11;
		}

		const utf8 * providerEmail = network_get_server_provider_email();
		if (!str_is_null_or_empty(providerEmail)) {
			gfx_draw_string_left(dpi, STR_PROVIDER_EMAIL, (void*)&providerEmail, COLOUR_BLACK, x, y);
			y += 11;
		}

		const utf8 * providerWebsite = network_get_server_provider_website();
		if (!str_is_null_or_empty(providerWebsite)) {
			gfx_draw_string_left(dpi, STR_PROVIDER_WEBSITE, (void*)&providerWebsite, COLOUR_BLACK, x, y);
		}
	}
}
Exemplo n.º 2
0
/**
*
*  rct2: 0x006D40A7
*/
static void window_install_track_text_input(rct_window *w, rct_widgetindex widgetIndex, char *text)
{
    if (widgetIndex != WIDX_INSTALL || str_is_null_or_empty(text)) {
        return;
    }

    _trackName = text;

    window_event_mouse_up_call(w, WIDX_INSTALL);
}
Exemplo n.º 3
0
static void window_title_editor_textinput(rct_window * w, rct_widgetindex widgetIndex, char * text)
{
    if (str_is_null_or_empty(text))
        return;

    switch (widgetIndex)
    {
    case WIDX_TITLE_EDITOR_NEW_BUTTON:
    case WIDX_TITLE_EDITOR_DUPLICATE_BUTTON:
    case WIDX_TITLE_EDITOR_RENAME_BUTTON:
        if (filename_valid_characters(text))
        {
            if (title_sequence_manager_get_index_for_name(text) == SIZE_MAX)
            {
                if (!title_sequence_manager_is_name_reserved(text))
                {
                    if (widgetIndex == WIDX_TITLE_EDITOR_NEW_BUTTON)
                    {
                        size_t newIndex = title_sequence_manager_create(text);
                        window_title_editor_load_sequence(newIndex);
                    }
                    else if (widgetIndex == WIDX_TITLE_EDITOR_DUPLICATE_BUTTON)
                    {
                        size_t newIndex = title_sequence_manager_duplicate(_selectedTitleSequence, text);
                        window_title_editor_load_sequence(newIndex);
                    }
                    else
                    {
                        size_t newIndex = title_sequence_manager_rename(_selectedTitleSequence, text);
                        window_title_editor_load_sequence(newIndex);
                    }
                    config_save_default();
                    window_invalidate(w);
                }
                else
                {
                    context_show_error(STR_ERROR_RESERVED_NAME, STR_NONE);
                }
            }
            else
            {
                context_show_error(STR_ERROR_EXISTING_NAME, STR_NONE);
            }
        }
        else
        {
            context_show_error(STR_ERROR_INVALID_CHARACTERS, STR_NONE);
        }
        break;
    case WIDX_TITLE_EDITOR_RENAME_SAVE:
        window_title_editor_rename_park(w->selected_list_item, text);
        break;
    }
}
Exemplo n.º 4
0
void openrct2_write_full_version_info(utf8 *buffer, size_t bufferSize)
{
	utf8 *ch = buffer;

	// Name and version
	strcpy(ch, OPENRCT2_NAME);
	strcat(buffer, ", v");
	strcat(buffer, OPENRCT2_VERSION);

	// Build information
	if (!str_is_null_or_empty(OPENRCT2_BRANCH)) {
		sprintf(strchr(buffer, 0), "-%s", OPENRCT2_BRANCH);
	}
	if (!str_is_null_or_empty(OPENRCT2_BUILD_NUMBER)) {
		sprintf(strchr(buffer, 0), " build %s", OPENRCT2_BUILD_NUMBER);
	}
	if (!str_is_null_or_empty(OPENRCT2_COMMIT_SHA1_SHORT)) {
		sprintf(strchr(buffer, 0), " (%s)", OPENRCT2_COMMIT_SHA1_SHORT);
	}
	if (!str_is_null_or_empty(OPENRCT2_BUILD_SERVER)) {
		sprintf(strchr(buffer, 0), " provided by %s", OPENRCT2_BUILD_SERVER);
	}
}
Exemplo n.º 5
0
static void window_scenarioselect_scrollpaint(rct_window *w, rct_drawpixelinfo *dpi, int scrollIndex)
{
	int colour;

	uint8 paletteIndex = ColourMapA[w->colours[1]].mid_light;
	gfx_clear(dpi, paletteIndex);

	rct_string_id highlighted_format = (theme_get_flags() & UITHEME_FLAG_USE_ALTERNATIVE_SCENARIO_SELECT_FONT) ? STR_WHITE_STRING : STR_WINDOW_COLOUR_2_STRINGID;
	rct_string_id unhighlighted_format = (theme_get_flags() & UITHEME_FLAG_USE_ALTERNATIVE_SCENARIO_SELECT_FONT) ? STR_WHITE_STRING : STR_BLACK_STRING;

	bool wide = gConfigGeneral.scenario_select_mode == SCENARIO_SELECT_MODE_ORIGIN;

	rct_widget *listWidget = &w->widgets[WIDX_SCENARIOLIST];
	int listWidth = listWidget->right - listWidget->left - 12;

	int y = 0;
	for (sc_list_item *listItem = _listItems; listItem->type != LIST_ITEM_TYPE_END; listItem++) {
		if (y > dpi->y + dpi->height) {
			continue;
		}

		switch (listItem->type) {
		case LIST_ITEM_TYPE_HEADING:;
			const int horizontalRuleMargin = 4;
			draw_category_heading(w, dpi, horizontalRuleMargin, listWidth - horizontalRuleMargin, y + 2, listItem->heading.string_id);
			y += 18;
			break;
		case LIST_ITEM_TYPE_SCENARIO:;
			// Draw hover highlight
			const scenario_index_entry *scenario = listItem->scenario.scenario;
			bool isHighlighted = w->highlighted_scenario == scenario;
			if (isHighlighted) {
				gfx_filter_rect(dpi, 0, y, w->width, y + 23, PALETTE_DARKEN_1);
			}

			bool isCompleted = scenario->highscore != NULL;
			bool isDisabled = listItem->scenario.is_locked;

			// Draw scenario name
			char buffer[64];
			safe_strcpy(buffer, scenario->name, sizeof(buffer));
			rct_string_id format = isDisabled ? STR_STRINGID : (isHighlighted ? highlighted_format : unhighlighted_format);
			set_format_arg(0, rct_string_id, STR_STRING);
			set_format_arg(2, char *, buffer);
			colour = isDisabled ? w->colours[1] | COLOUR_FLAG_INSET : COLOUR_BLACK;
			if (isDisabled) {
				gCurrentFontSpriteBase = FONT_SPRITE_BASE_MEDIUM_DARK;
			}
			gfx_draw_string_centred(dpi, format, wide ? 270 : 210, y + 1, colour, gCommonFormatArgs);

			// Check if scenario is completed
			if (isCompleted) {
				// Draw completion tick
				gfx_draw_sprite(dpi, SPR_MENU_CHECKMARK, wide ? 500 : 395, y + 1, 0);

				// Draw completion score
				const utf8 *completedByName = "???";
				if (!str_is_null_or_empty(scenario->highscore->name)) {
					completedByName = scenario->highscore->name;
				}
				safe_strcpy(buffer, completedByName, 64);
				set_format_arg(0, rct_string_id, STR_COMPLETED_BY);
				set_format_arg(2, rct_string_id, STR_STRING);
				set_format_arg(4, char *, buffer);
				gfx_draw_string_centred(dpi, format, wide ? 270 : 210, y + 11, COLOUR_BLACK, gCommonFormatArgs);
			}

			y += 24;
			break;
		}
	}
}
Exemplo n.º 6
0
static void window_scenarioselect_paint(rct_window *w, rct_drawpixelinfo *dpi)
{
	int i, x, y, format;
	rct_widget *widget;
	const scenario_index_entry *scenario;

	window_draw_widgets(w, dpi);

	format = (theme_get_flags() & UITHEME_FLAG_USE_ALTERNATIVE_SCENARIO_SELECT_FONT) ? STR_SMALL_WINDOW_COLOUR_2_STRINGID : STR_WINDOW_COLOUR_2_STRINGID;

	// Text for each tab
	for (i = 0; i < 8; i++) {
		widget = &window_scenarioselect_widgets[WIDX_TAB1 + i];
		if (widget->type == WWT_EMPTY)
			continue;

		x = (widget->left + widget->right) / 2 + w->x;
		y = (widget->top + widget->bottom) / 2 + w->y - 3;

		if (gConfigGeneral.scenario_select_mode == SCENARIO_SELECT_MODE_ORIGIN) {
			set_format_arg(0, rct_string_id, ScenarioOriginStringIds[i]);
		} else { // old-style
			set_format_arg(0, rct_string_id, ScenarioCategoryStringIds[i]);
		}
		gfx_draw_string_centred_wrapped(dpi, gCommonFormatArgs, x, y, 87, format, COLOUR_AQUAMARINE);
	}

	// Return if no scenario highlighted
	scenario = w->highlighted_scenario;
	if (scenario == NULL) {
		if (_showLockedInformation) {
			// Show locked information
			x = w->x + window_scenarioselect_widgets[WIDX_SCENARIOLIST].right + 4;
			y = w->y + window_scenarioselect_widgets[WIDX_TABCONTENT].top + 5;
			gfx_draw_string_centred_clipped(dpi, STR_SCENARIO_LOCKED, NULL, COLOUR_BLACK, x + 85, y, 170);
			y += 15;
			y += gfx_draw_string_left_wrapped(dpi, NULL, x, y, 170, STR_SCENARIO_LOCKED_DESC, COLOUR_BLACK) + 5;
		}
		return;
	}

	// Scenario path
	if (gConfigGeneral.debugging_tools) {
		utf8 path[MAX_PATH];

		gCurrentFontSpriteBase = FONT_SPRITE_BASE_MEDIUM;
		shorten_path(path, sizeof(path), scenario->path, w->width - 6);

		const utf8 *pathPtr = path;
		gfx_draw_string_left(dpi, STR_STRING, (void*)&pathPtr, w->colours[1], w->x + 3, w->y + w->height - 3 - 11);
	}

	// Scenario name
	x = w->x + window_scenarioselect_widgets[WIDX_SCENARIOLIST].right + 4;
	y = w->y + window_scenarioselect_widgets[WIDX_TABCONTENT].top + 5;
	set_format_arg(0, rct_string_id, STR_STRING);
	set_format_arg(2, const char *, scenario->name);
	gfx_draw_string_centred_clipped(dpi, STR_WINDOW_COLOUR_2_STRINGID, gCommonFormatArgs, COLOUR_BLACK, x + 85, y, 170);
	y += 15;

	// Scenario details
	set_format_arg(0, rct_string_id, STR_STRING);
	set_format_arg(2, const char *, scenario->details);
	y += gfx_draw_string_left_wrapped(dpi, gCommonFormatArgs, x, y, 170, STR_BLACK_STRING, COLOUR_BLACK) + 5;

	// Scenario objective
	set_format_arg(0, rct_string_id, ObjectiveNames[scenario->objective_type]);
	set_format_arg(2, short, scenario->objective_arg_3);
	set_format_arg(4, short, date_get_total_months(MONTH_OCTOBER, scenario->objective_arg_1));
	set_format_arg(6, int, scenario->objective_arg_2);
	y += gfx_draw_string_left_wrapped(dpi, gCommonFormatArgs, x, y, 170, STR_OBJECTIVE, COLOUR_BLACK) + 5;

	// Scenario score
	if (scenario->highscore != NULL) {
		// TODO: Should probably be translateable
		const utf8 *completedByName = "???";
		if (!str_is_null_or_empty(scenario->highscore->name)) {
			completedByName = scenario->highscore->name;
		}
		set_format_arg(0, rct_string_id, STR_STRING);
		set_format_arg(2, const char *, completedByName);
		set_format_arg(2 + sizeof(const char *), money32, scenario->highscore->company_value);
		y += gfx_draw_string_left_wrapped(dpi, gCommonFormatArgs, x, y, 170, STR_COMPLETED_BY_WITH_COMPANY_VALUE, COLOUR_BLACK);
	}
}
Exemplo n.º 7
0
    bool gfx_load_csg()
    {
        log_verbose("gfx_load_csg()");

        if (str_is_null_or_empty(gConfigGeneral.rct1_path))
        {
            log_verbose("  unable to load CSG, RCT1 path not set");
            return false;
        }

        char pathHeader[MAX_PATH];
        safe_strcpy(pathHeader, gConfigGeneral.rct1_path, sizeof(pathHeader));
        safe_strcat_path(pathHeader, "Data", sizeof(pathHeader));
        safe_strcat_path(pathHeader, "csg1i.dat", sizeof(pathHeader));

        // csg1.1 and csg1.dat are the same file.
        // In the CD version, it's called csg1.1 on the CD and csg1.dat on the disk.
        // In the GOG version, it's always called csg1.1.
        // In the Steam version, it's always called csg1.dat.
        char pathData[MAX_PATH];
        safe_strcpy(pathData, gConfigGeneral.rct1_path, sizeof(pathData));
        safe_strcat_path(pathData, "Data", sizeof(pathData));
        safe_strcat_path(pathData, "csg1.1", sizeof(pathData));

        if (!File::Exists(pathData))
        {
            safe_strcpy(pathData, gConfigGeneral.rct1_path, sizeof(pathData));
            safe_strcat_path(pathData, "Data", sizeof(pathData));
            safe_strcat_path(pathData, "csg1.dat", sizeof(pathData));
        }

        try
        {
            auto fileHeader = FileStream(pathHeader, FILE_MODE_OPEN);
            auto fileData = FileStream(pathData, FILE_MODE_OPEN);
            size_t fileHeaderSize = fileHeader.GetLength();
            size_t fileDataSize = fileData.GetLength();

            _csg.header.num_entries = (uint32)(fileHeaderSize / sizeof(rct_g1_element_32bit));
            _csg.header.total_size = (uint32)fileDataSize;

            // Read element headers
            _csg.elements = Memory::AllocateArray<rct_g1_element>(_csg.header.num_entries);
            read_and_convert_gxdat(&fileHeader, _csg.header.num_entries, _csg.elements);

            // Read element data
            _csg.data = fileData.ReadArray<uint8>(_csg.header.total_size);

            // Fix entry data offsets
            for (uint32 i = 0; i < _csg.header.num_entries; i++)
            {
                _csg.elements[i].offset += (uintptr_t)_csg.data;
                // RCT1 used zoomed offsets that counted from the beginning of the file, rather than from the current sprite.
                _csg.elements[i].zoomed_offset = i - (SPR_CSG_BEGIN + _csg.elements[i].zoomed_offset);
            }
            _csgLoaded = true;
            return true;
        }
        catch (const Exception &)
        {
            log_error("Unable to load csg graphics");
            return false;
        }
    }
Exemplo n.º 8
0
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;
}
Exemplo n.º 9
0
/**
 * A shared entry point to OpenRCT2. The command lines must be parsed before any further action is done. Invalid command lines
 * will then terminate before any initialisation has even been done.
 * @returns 1 if the game should run, otherwise 0.
 */
int cmdline_run(const char **argv, int argc)
{
	//
	int version = 0, headless = 0, verbose = 0, width = 0, height = 0, port = 0;
	char *server = NULL;
	char *userDataPath = NULL;

	argparse_option_t options[] = {
		OPT_HELP(),
		OPT_BOOLEAN('v', "version", &version, "show version information and exit"),
		OPT_BOOLEAN(0, "headless", &headless, "run OpenRCT2 headless"),
		OPT_BOOLEAN(0, "verbose", &verbose, "log verbose messages"),
		OPT_INTEGER('m', "mode", &sprite_mode, "the type of sprite conversion. 0 = default, 1 = simple closest pixel match, 2 = dithering"),
		OPT_STRING(0, "server", &server, "server to connect to"),
		OPT_INTEGER(0, "port", &port, "port"),
		OPT_STRING(0, "user-data-path", &userDataPath, "path to the user data directory (containing config.ini)"),
		OPT_END()
	};

	argparse_t argparse;
	argparse_init(&argparse, options, usage, 0);
	argc = argparse_parse(&argparse, argc, argv);

	if (version) {
		print_version();
		return 0;
	}

	if (headless)
		gOpenRCT2Headless = true;

	if (verbose)
		_log_levels[DIAGNOSTIC_LEVEL_VERBOSE] = 1;

	if (userDataPath != NULL) {
		safe_strncpy(gCustomUserDataPath, userDataPath, sizeof(gCustomUserDataPath));
	}

#ifndef DISABLE_NETWORK
	if (port != 0) {
		gNetworkStart = NETWORK_MODE_SERVER;
		gNetworkStartPort = port;
	}

	if (server != NULL) {
		gNetworkStart = NETWORK_MODE_CLIENT;
		safe_strncpy(gNetworkStartHost, server, sizeof(gNetworkStartHost));
	}
#endif // DISABLE_NETWORK

	if (argc != 0) {
		gExitCode = cmdline_call_action(argv, argc);
		if (gExitCode != 0) {
			return 0;
		}
	}

	// Headless mode requires a park to open
	if (gOpenRCT2Headless) {
		if (str_is_null_or_empty(gOpenRCT2StartupActionPath)) {
			printf("You must specify a park to open in headless mode.\n");
			gExitCode = -1;
			return 0;
		}
	}

	if (verbose) {
		print_launch_information();
	}
	return 1;
}
Exemplo n.º 10
0
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;
}