/** * * rct2: 0x0066F7C0 */ void window_editor_bottom_toolbar_jump_forward_to_save_scenario() { rct_s6_info *s6Info = (rct_s6_info*)0x0141F570; int parkFlagsBackup, success; char path[256]; 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)); gfx_invalidate_screen(); return; } window_close_all(); 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_set_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; } }
static void window_loadsave_select(rct_window *w, const char *path) { SDL_RWops* rw; switch (_loadsaveType & 0x0F) { case (LOADSAVETYPE_LOAD | LOADSAVETYPE_GAME) : if (gLoadSaveTitleSequenceSave) { utf8 newName[MAX_PATH]; char *extension = (char*)path_get_extension(path); safe_strcpy(newName, path_get_filename(path), MAX_PATH); if (_stricmp(extension, ".sv6") != 0 && _stricmp(extension, ".sc6") != 0) strcat(newName, ".sv6"); if (title_sequence_save_exists(gCurrentTitleSequence, newName)) { RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS + 0, uint32) = (uint32)&_listItems[w->selected_list_item].name; window_text_input_open(w, WIDX_SCROLL, 5435, 5404, 1170, (uint32)_listItems[w->selected_list_item].name, TITLE_SEQUENCE_MAX_SAVE_LENGTH - 1); } else { title_sequence_add_save(gCurrentTitleSequence, path, newName); window_close(w); } window_loadsave_invoke_callback(MODAL_RESULT_OK); } else if (game_load_save(path)) { safe_strcpy(gScenarioSavePath, path, MAX_PATH); gFirstTimeSave = 0; window_close(w); gfx_invalidate_screen(); window_loadsave_invoke_callback(MODAL_RESULT_OK); } else { // 1050, not the best message... window_error_open(STR_LOAD_GAME, 1050); window_loadsave_invoke_callback(MODAL_RESULT_FAIL); } break; case (LOADSAVETYPE_SAVE | LOADSAVETYPE_GAME) : rw = SDL_RWFromFile(path, "wb+"); if (rw != NULL) { int success = scenario_save(rw, gConfigGeneral.save_plugin_data ? 1 : 0); SDL_RWclose(rw); if (success) { safe_strcpy(gScenarioSavePath, path, MAX_PATH); gFirstTimeSave = 0; window_close_by_class(WC_LOADSAVE); gfx_invalidate_screen(); window_loadsave_invoke_callback(MODAL_RESULT_OK); } else { window_error_open(STR_SAVE_GAME, 1047); window_loadsave_invoke_callback(MODAL_RESULT_FAIL); } } else { window_error_open(STR_SAVE_GAME, 1047); window_loadsave_invoke_callback(MODAL_RESULT_FAIL); } break; case (LOADSAVETYPE_LOAD | LOADSAVETYPE_LANDSCAPE) : if (editor_load_landscape(path)) { gfx_invalidate_screen(); window_loadsave_invoke_callback(MODAL_RESULT_OK); } else { // 1050, not the best message... window_error_open(STR_LOAD_LANDSCAPE, 1050); window_loadsave_invoke_callback(MODAL_RESULT_FAIL); } break; case (LOADSAVETYPE_SAVE | LOADSAVETYPE_LANDSCAPE) : rw = SDL_RWFromFile(path, "wb+"); if (rw != NULL) { scenario_set_filename(path); int success = scenario_save(rw, gConfigGeneral.save_plugin_data ? 3 : 2); SDL_RWclose(rw); if (success) { window_close_by_class(WC_LOADSAVE); gfx_invalidate_screen(); window_loadsave_invoke_callback(MODAL_RESULT_OK); } else { window_error_open(STR_SAVE_LANDSCAPE, 1049); window_loadsave_invoke_callback(MODAL_RESULT_FAIL); } } else { window_error_open(STR_SAVE_LANDSCAPE, 1049); window_loadsave_invoke_callback(MODAL_RESULT_FAIL); } break; case (LOADSAVETYPE_SAVE | LOADSAVETYPE_SCENARIO) : { rct_s6_info *s6Info = (rct_s6_info*)0x0141F570; int parkFlagsBackup = RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32); RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) &= ~PARK_FLAGS_18; s6Info->editor_step = 255; rw = SDL_RWFromFile(path, "wb+"); int success = 0; if (rw != NULL) { scenario_set_filename(path); success = scenario_save(rw, gConfigGeneral.save_plugin_data ? 3 : 2); SDL_RWclose(rw); } RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) = parkFlagsBackup; if (success) { window_close_by_class(WC_LOADSAVE); window_loadsave_invoke_callback(MODAL_RESULT_OK); title_load(); } else { window_error_open(STR_FILE_DIALOG_TITLE_SAVE_SCENARIO, STR_SCENARIO_SAVE_FAILED); s6Info->editor_step = EDITOR_STEP_OBJECTIVE_SELECTION; window_loadsave_invoke_callback(MODAL_RESULT_FAIL); } break; } case (LOADSAVETYPE_LOAD | LOADSAVETYPE_TRACK) : window_install_track_open(path); window_close_by_class(WC_LOADSAVE); window_loadsave_invoke_callback(MODAL_RESULT_OK); break; } }
static bool OnCrash(const wchar_t * dumpPath, const wchar_t * miniDumpId, void * context, EXCEPTION_POINTERS * exinfo, MDRawAssertionInfo * assertion, bool succeeded) { if (!succeeded) { constexpr const char * DumpFailedMessage = "Failed to create the dump. Please file an issue with OpenRCT2 on GitHub and provide latest save, and provide information about what you did before the crash occured."; printf("%s\n", DumpFailedMessage); if (!gOpenRCT2SilentBreakpad) { MessageBoxA(NULL, DumpFailedMessage, OPENRCT2_NAME, MB_OK | MB_ICONERROR); } return succeeded; } // Get filenames wchar_t dumpFilePath[MAX_PATH]; wchar_t saveFilePath[MAX_PATH]; swprintf_s(dumpFilePath, sizeof(dumpFilePath), L"%s%s.dmp", dumpPath, miniDumpId); swprintf_s(saveFilePath, sizeof(saveFilePath), L"%s%s.sv6", dumpPath, miniDumpId); // Try to rename the files wchar_t dumpFilePathNew[MAX_PATH]; swprintf_s(dumpFilePathNew, sizeof(dumpFilePathNew), L"%s%s(%s_%s).dmp", dumpPath, miniDumpId, _wszCommitSha1Short, _wszArchitecture); if (_wrename(dumpFilePath, dumpFilePathNew) == 0) { std::wcscpy(dumpFilePath, dumpFilePathNew); } // Log information to output wprintf(L"Dump Path: %s\n", dumpPath); wprintf(L"Dump File Path: %s\n", dumpFilePath); wprintf(L"Dump Id: %s\n", miniDumpId); wprintf(L"Version: %s\n", WSZ(OPENRCT2_VERSION)); wprintf(L"Commit: %s\n", _wszCommitSha1Short); utf8 * saveFilePathUTF8 = widechar_to_utf8(saveFilePath); SDL_RWops * rw = SDL_RWFromFile(saveFilePathUTF8, "wb+"); free(saveFilePathUTF8); bool savedGameDumped = false; if (rw != NULL) { scenario_save(rw, 0x80000000); savedGameDumped = true; SDL_RWclose(rw); } if (gOpenRCT2SilentBreakpad) { return succeeded; } constexpr const wchar_t * MessageFormat = L"A crash has occurred and a dump was created at\n%s.\n\nPlease file an issue with OpenRCT2 on GitHub, and provide the dump and saved game there.\n\nVersion: %s\nCommit: %s"; wchar_t message[MAX_PATH * 2]; swprintf_s(message, MessageFormat, dumpFilePath, WSZ(OPENRCT2_VERSION), _wszCommitSha1Short); // Cannot use platform_show_messagebox here, it tries to set parent window already dead. MessageBoxW(NULL, message, WSZ(OPENRCT2_NAME), MB_OK | MB_ICONERROR); HRESULT coInitializeResult = CoInitialize(NULL); if (SUCCEEDED(coInitializeResult)) { LPITEMIDLIST pidl = ILCreateFromPathW(dumpPath); LPITEMIDLIST files[2]; uint32 numFiles = 0; files[numFiles++] = ILCreateFromPathW(dumpFilePath); if (savedGameDumped) { files[numFiles++] = ILCreateFromPathW(saveFilePath); } if (pidl != nullptr) { HRESULT result = SHOpenFolderAndSelectItems(pidl, numFiles, (LPCITEMIDLIST *)files, 0); ILFree(pidl); for (uint32 i = 0; i < numFiles; i++) { ILFree(files[i]); } } CoUninitialize(); } // Return whether the dump was successful return succeeded; }