diff --git a/openrct2.vcxproj b/openrct2.vcxproj
index 3b5ae319ce..db5e3b08b4 100644
--- a/openrct2.vcxproj
+++ b/openrct2.vcxproj
@@ -87,6 +87,7 @@
+
@@ -261,6 +262,7 @@
+
@@ -329,20 +331,21 @@
- $(SolutionDir)lib\include;$(SolutionDir)lib\include\libspeex;$(SolutionDir)lib\include\sdl;$(SolutionDir)lib\include\jansson;$(SolutionDir)lib\include\sdl_ttf;$(SolutionDir)lib\include\libpng;$(SolutionDir)lib\include\zlib;$(IncludePath)
+ $(SolutionDir)lib\include;$(SolutionDir)lib\include\breakpad;$(SolutionDir)lib\include\libspeex;$(SolutionDir)lib\include\sdl;$(SolutionDir)lib\include\jansson;$(SolutionDir)lib\include\sdl_ttf;$(SolutionDir)lib\include\libpng;$(SolutionDir)lib\include\zlib;$(IncludePath)
$(SolutionDir)lib;$(LibraryPath)
$(SolutionDir)bin\
$(SolutionDir)obj\$(ProjectName)\$(Configuration)\
- $(SolutionDir)lib\include;$(SolutionDir)lib\include\libspeex;$(SolutionDir)lib\include\sdl;$(SolutionDir)lib\include\jansson;$(SolutionDir)lib\include\sdl_ttf;$(SolutionDir)lib\include\libpng;$(SolutionDir)lib\include\zlib;$(IncludePath)
+ $(SolutionDir)lib\include;$(SolutionDir)lib\include\breakpad;$(SolutionDir)lib\include\libspeex;$(SolutionDir)lib\include\sdl;$(SolutionDir)lib\include\jansson;$(SolutionDir)lib\include\sdl_ttf;$(SolutionDir)lib\include\libpng;$(SolutionDir)lib\include\zlib;$(IncludePath)
$(SolutionDir)lib;$(LibraryPath)
$(SolutionDir)bin\
$(SolutionDir)obj\$(ProjectName)\$(Configuration)\
+ 4091;%(DisableSpecificWarnings)
Level3
Disabled
true
@@ -363,6 +366,7 @@
+ 4091;%(DisableSpecificWarnings)
Level3
Full
true
@@ -388,4 +392,4 @@
-
\ No newline at end of file
+
diff --git a/openrct2.vcxproj.filters b/openrct2.vcxproj.filters
index 333e9eccff..07a3682284 100644
--- a/openrct2.vcxproj.filters
+++ b/openrct2.vcxproj.filters
@@ -587,6 +587,7 @@
Source\Core
+
@@ -896,5 +897,6 @@
Source\Core
+
-
\ No newline at end of file
+
diff --git a/scripts/ps/install.ps1 b/scripts/ps/install.ps1
index 7b87a2176a..016e181e65 100644
--- a/scripts/ps/install.ps1
+++ b/scripts/ps/install.ps1
@@ -14,7 +14,7 @@ Import-Module "$scriptsPath\common.psm1" -DisableNameChecking
# Constants
$libsUrl = "https://openrct2.website/files/openrct2-libs-vs2015.zip"
-$libsVersion = 6
+$libsVersion = 7
# Get paths
$rootPath = Get-RootPath
diff --git a/src/openrct2.c b/src/openrct2.c
index b5c6648374..5d9bf0973e 100644
--- a/src/openrct2.c
+++ b/src/openrct2.c
@@ -39,7 +39,7 @@
#include "util/sawyercoding.h"
#include "util/util.h"
#include "world/mapgen.h"
-#include "platform/breakpad.h"
+#include "platform/crash.h"
#if defined(__unix__)
#include
@@ -185,6 +185,12 @@ bool openrct2_initialise()
return false;
}
+ // Exception handling - breakpad
+ // Uses user data directory for storing dumps
+ CExceptionHandler eh;
+ // never free
+ eh = newCExceptionHandlerSimple();
+
if (!openrct2_setup_rct2_segment()) {
log_fatal("Unable to load RCT2 data sector");
return false;
@@ -264,12 +270,6 @@ bool openrct2_initialise()
*/
void openrct2_launch()
{
-#ifdef USE_BREAKPAD
- CExceptionHandler eh;
- // never free
- eh = newCExceptionHandlerSimple();
-#endif // USE_BREAKPAD
-
if (openrct2_initialise()) {
RCT2_GLOBAL(RCT2_ADDRESS_RUN_INTRO_TICK_PART, uint8) = 0;
if((gOpenRCT2StartupAction == STARTUP_ACTION_TITLE) && gConfigGeneral.play_intro)
diff --git a/src/platform/breakpad.cpp b/src/platform/breakpad.cpp
deleted file mode 100644
index a4241019cf..0000000000
--- a/src/platform/breakpad.cpp
+++ /dev/null
@@ -1,19 +0,0 @@
-#include "breakpad.h"
-
-#ifdef USE_BREAKPAD
-#include "client/linux/handler/exception_handler.h"
-#include
-
-static bool dumpCallback(const google_breakpad::MinidumpDescriptor& descriptor, void* context, bool succeeded) {
- printf("Dump path: %s\n", descriptor.path());
- return succeeded;
-}
-
-extern "C" CExceptionHandler newCExceptionHandlerSimple(void)
-{
- printf("init Simple breakpad\n");
- google_breakpad::MinidumpDescriptor descriptor("/tmp");
- //google_breakpad::ExceptionHandler eh(descriptor, NULL, dumpCallback, NULL, true, -1);
- return reinterpret_cast(new google_breakpad::ExceptionHandler(descriptor, NULL, dumpCallback, NULL, true, -1));
-}
-#endif // USE_BREAKPAD
diff --git a/src/platform/crash.cpp b/src/platform/crash.cpp
new file mode 100644
index 0000000000..9f114b0080
--- /dev/null
+++ b/src/platform/crash.cpp
@@ -0,0 +1,105 @@
+extern "C" {
+#include "platform.h"
+#include "../localisation/language.h"
+#include "../scenario.h"
+}
+
+#include "crash.h"
+#include
+
+#ifdef USE_BREAKPAD
+#include
+
+#ifdef __WINDOWS__
+#include
+#include
+#include
+#define BREAKPAD_PATH "."
+#else
+#error Breakpad support not implemented yet for this platform
+#endif __WINDOWS__
+
+#ifdef __LINUX__
+#include
+#define BREAKPAD_PATH "/tmp"
+#endif __LINUX__
+
+
+static bool dumpCallback(const wchar_t *dump_path, const wchar_t *minidump_id, void* context, EXCEPTION_POINTERS* exinfo, MDRawAssertionInfo* assertion, bool succeeded) {
+ if (!succeeded) {
+ const char *msg = "Failed to create the dump. Nothing left to do. Please file an issue with OpenRCT2 on Github and provide latest save.";
+ log_fatal(msg);
+ MessageBoxA(NULL, msg, "OpenRCT2", MB_OK);
+ return succeeded;
+ }
+ char *buffer_path = widechar_to_utf8(dump_path);
+ char *buffer_minidump = widechar_to_utf8(minidump_id);
+ char dump_file_path[MAX_PATH];
+ char save_file_path[MAX_PATH];
+ sprintf(dump_file_path, "%s%s.dmp", buffer_path, buffer_minidump);
+ sprintf(save_file_path, "%s%s.sv6", buffer_path, buffer_minidump);
+ log_fatal("Dump path: %s", buffer_path);
+ log_fatal("minidump id: %s", buffer_minidump);
+ log_fatal("Version: %s", OPENRCT2_VERSION);
+ log_fatal("Commit: %s", OPENRCT2_COMMIT_SHA1_SHORT);
+ SDL_RWops* rw = SDL_RWFromFile(save_file_path, "wb+");
+ bool saved = false;
+ if (rw != NULL) {
+ scenario_save(rw, 0x80000000);
+ saved = true;
+ SDL_RWclose(rw);
+ }
+ char message[MAX_PATH * 2];
+ sprintf(message, "A crash has occurred and dump was created at %s. Please create an issue with OpenRCT2 on Github and provide the dump and %s. Version: %s, Commit: %s",
+ dump_file_path, saved ? save_file_path : "latest save", OPENRCT2_VERSION, OPENRCT2_COMMIT_SHA1_SHORT);
+ // Cannot use platform_show_messagebox here, it tries to set parent window already dead.
+ MessageBoxA(NULL, message, "OpenRCT2", MB_OK);
+ HRESULT coinit_result = CoInitialize(NULL);
+ if (coinit_result == S_OK) {
+ //ShellExecute(NULL, "explore", message, NULL, NULL, 5);
+ ITEMIDLIST *pidl = ILCreateFromPath(buffer_path);
+ ITEMIDLIST *files[2];
+ files[0] = ILCreateFromPath(dump_file_path);
+ int files_count = 1;
+ if (saved) {
+ files[1] = ILCreateFromPath(save_file_path);
+ files_count = 2;
+ }
+ if (pidl) {
+ HRESULT res = SHOpenFolderAndSelectItems(pidl, files_count, (LPCITEMIDLIST *)files, 0);
+ ILFree(pidl);
+ ILFree(files[0]);
+ if (saved) {
+ ILFree(files[1]);
+ }
+ }
+ CoUninitialize();
+ }
+ free(buffer_path);
+ free(buffer_minidump);
+ return succeeded;
+}
+#endif // USE_BREAKPAD
+
+extern "C" CExceptionHandler newCExceptionHandlerSimple(void)
+{
+#ifdef USE_BREAKPAD
+ char path[MAX_PATH];
+ platform_get_user_directory(path, NULL);
+ wchar_t *wpath_buffer = utf8_to_widechar(path);
+ std::wstring wpath(wpath_buffer);
+ free(wpath_buffer);
+ // Path must exist and be RW!
+ return reinterpret_cast(new google_breakpad::ExceptionHandler(
+ wpath,
+ 0,
+ dumpCallback,
+ 0,
+ google_breakpad::ExceptionHandler::HANDLER_ALL,
+ MiniDumpNormal,
+ L"openrct2-bpad", // using non-null pipe name here lets breakpad try setting OOP crash handling
+ 0 ));
+#else // USE_BREAKPAD
+ return nullptr;
+#endif // USE_BREAKPAD
+}
diff --git a/src/platform/breakpad.h b/src/platform/crash.h
similarity index 53%
rename from src/platform/breakpad.h
rename to src/platform/crash.h
index 31e358a4a5..0b9938a285 100644
--- a/src/platform/breakpad.h
+++ b/src/platform/crash.h
@@ -1,7 +1,6 @@
-#ifndef _OPENRCT2_BREAKPAD_
-#define _OPENRCT2_BREAKPAD_
+#ifndef _OPENRCT2_CRASH_
+#define _OPENRCT2_CRASH_
-#ifdef USE_BREAKPAD
typedef void* CExceptionHandler;
#ifdef __cplusplus
@@ -12,6 +11,5 @@ CExceptionHandler newCExceptionHandlerSimple(void);
#ifdef __cplusplus
}
#endif
-#endif // USE_BREAKPAD
-#endif /* _OPENRCT2_BREAKPAD_ */
+#endif /* _OPENRCT2_CRASH_ */
diff --git a/src/platform/shared.c b/src/platform/shared.c
index 1a8bfc935f..8749755954 100644
--- a/src/platform/shared.c
+++ b/src/platform/shared.c
@@ -811,7 +811,7 @@ void platform_free()
SDL_Quit();
}
-void platform_start_text_input(char* buffer, int max_length)
+void platform_start_text_input(utf8* buffer, int max_length)
{
// TODO This doesn't work, and position could be improved to where text entry is
SDL_Rect rect = { 10, 10, 100, 100 };
diff --git a/src/platform/windows.c b/src/platform/windows.c
index 2f57d3b2c7..deb82e5859 100644
--- a/src/platform/windows.c
+++ b/src/platform/windows.c
@@ -573,7 +573,7 @@ void platform_get_user_directory(utf8 *outPath, const utf8 *subDirectory)
}
}
-void platform_show_messagebox(char *message)
+void platform_show_messagebox(utf8 *message)
{
MessageBoxA(windows_get_window_handle(), message, "OpenRCT2", MB_OK);
}