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