diff --git a/src/console/c_console.cpp b/src/console/c_console.cpp index de2f1467982..0d5e9cc1e11 100644 --- a/src/console/c_console.cpp +++ b/src/console/c_console.cpp @@ -917,7 +917,7 @@ int PrintString (int iprintlevel, const char *outline) return 0; // Don't waste time on calculating this if nothing at all was printed... } -extern bool gameisdead; +bool gameisdead; int VPrintf (int printlevel, const char *format, va_list parms) { diff --git a/src/d_main.cpp b/src/d_main.cpp index ebc938604a4..c5535bee604 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -2326,6 +2326,11 @@ void I_FatalError(const char *error, ...) std::terminate(); // recursive I_FatalErrors must immediately terminate. } +static void NewFailure () +{ + I_FatalError ("Failed to allocate memory from system heap"); +} + //========================================================================== // // I_Quit @@ -2348,7 +2353,7 @@ void I_Quit() // //========================================================================== -void D_DoomMain (void) +static void D_DoomMain_Internal (void) { int p; const char *v; @@ -2357,6 +2362,8 @@ void D_DoomMain (void) FString *args; int argcount; FIWadManager *iwad_man; + + std::set_new_handler(NewFailure); const char *batchout = Args->CheckValue("-errorlog"); C_InitConsole(80*8, 25*8, false); @@ -2739,7 +2746,7 @@ void D_DoomMain (void) if (Args->CheckParm("-norun") || batchrun) { - throw CNoRunExit(); + return; } V_Init2(); @@ -2830,6 +2837,25 @@ void D_DoomMain (void) while (1); } +int D_DoomMain() +{ + int ret = 0; + try + { + D_DoomMain_Internal(); + ret = 1337; + } + catch (std::exception &error) + { + I_ShowFatalError(error.what()); + ret = -1; + } + // Unless something really bad happened, the game should only exit through this single point in the code. + // No more 'exit', please. + // Todo: Move all engine cleanup here instead of using exit handlers and replace the scattered 'exit' calls with a special exception. + return ret; +} + //========================================================================== // // clean up the resources diff --git a/src/d_main.h b/src/d_main.h index f19aa667143..16468f5da94 100644 --- a/src/d_main.h +++ b/src/d_main.h @@ -45,7 +45,7 @@ struct CRestartException char dummy; }; -void D_DoomMain (void); +int D_DoomMain (void); void D_Display (); diff --git a/src/posix/cocoa/i_main.mm b/src/posix/cocoa/i_main.mm index 489906a9d80..ba4d72b78f8 100644 --- a/src/posix/cocoa/i_main.mm +++ b/src/posix/cocoa/i_main.mm @@ -141,11 +141,7 @@ void I_DetectOS() FArgs* Args; // command line arguments -// Newer versions of GCC than 4.2 have a bug with C++ exceptions in Objective-C++ code. -// To work around we'll implement the try and catch in standard C++. -// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61759 -void OriginalMainExcept(int argc, char** argv); -void OriginalMainTry(int argc, char** argv) +int OriginalMainTry(int argc, char** argv) { Args = new FArgs(argc, argv); @@ -155,7 +151,7 @@ void OriginalMainTry(int argc, char** argv) progdir = [[exePath stringByDeletingLastPathComponent] UTF8String]; progdir += "/"; - D_DoomMain(); + return D_DoomMain(); } namespace @@ -163,19 +159,12 @@ void OriginalMainTry(int argc, char** argv) TArray s_argv; - -void NewFailure() -{ - I_FatalError("Failed to allocate memory from system heap"); -} - int OriginalMain(int argc, char** argv) { printf(GAMENAME" %s - %s - Cocoa version\nCompiled on %s\n\n", GetVersionString(), GetGitTime(), __DATE__); seteuid(getuid()); - std::set_new_handler(NewFailure); // Set LC_NUMERIC environment variable in case some library decides to // clear the setlocale call at least this will be correct. @@ -190,9 +179,7 @@ int OriginalMain(int argc, char** argv) vid_defheight = static_cast(screenSize.height); vid_vsync = true; - OriginalMainExcept(argc, argv); - - return 0; + return OriginalMainTry(argc, argv); } } // unnamed namespace diff --git a/src/posix/cocoa/i_main_except.cpp b/src/posix/cocoa/i_main_except.cpp index e67914a0e3a..5c136adca8f 100644 --- a/src/posix/cocoa/i_main_except.cpp +++ b/src/posix/cocoa/i_main_except.cpp @@ -39,41 +39,10 @@ #include "atterm.h" // Import some functions from i_main.mm -void Mac_I_FatalError(const char* const message); + void OriginalMainTry(int argc, char** argv); void OriginalMainExcept(int argc, char** argv) { - try - { - OriginalMainTry(argc, argv); - } - catch(const std::exception& error) - { - const char* const message = error.what(); - - if (strcmp(message, "NoRunExit")) - { - if (CVMAbortException::stacktrace.IsNotEmpty()) - { - Printf("%s", CVMAbortException::stacktrace.GetChars()); - } - - if (batchrun) - { - Printf("%s\n", message); - } - else - { - Mac_I_FatalError(message); - } - } - - exit(-1); - } - catch(...) - { - call_terms(); - throw; - } + OriginalMainTry(argc, argv); } diff --git a/src/posix/cocoa/i_system.mm b/src/posix/cocoa/i_system.mm index d626f1f75c7..08ecb4a25ca 100644 --- a/src/posix/cocoa/i_system.mm +++ b/src/posix/cocoa/i_system.mm @@ -147,6 +147,14 @@ void I_PrintStr(const char* const message) } +void Mac_I_FatalError(const char* const message); + +void I_ShowFatalError(const char *message) +{ + Mac_I_FatalError(message); +} + + int I_PickIWad(WadStuff* const wads, const int numwads, const bool showwin, const int defaultiwad) { if (!showwin) diff --git a/src/posix/sdl/i_main.cpp b/src/posix/sdl/i_main.cpp index 6f14b6e3c6c..c3954b96bae 100644 --- a/src/posix/sdl/i_main.cpp +++ b/src/posix/sdl/i_main.cpp @@ -94,10 +94,6 @@ FArgs *Args; // CODE -------------------------------------------------------------------- -static void NewFailure () -{ - I_FatalError ("Failed to allocate memory from system heap"); -} static int DoomSpecificInfo (char *buffer, char *end) { @@ -170,8 +166,6 @@ int main (int argc, char **argv) GetVersionString(), GetGitTime(), __DATE__); seteuid (getuid ()); - std::set_new_handler (NewFailure); - // Set LC_NUMERIC environment variable in case some library decides to // clear the setlocale call at least this will be correct. // Note that the LANG environment variable is overridden by LC_* @@ -205,6 +199,5 @@ int main (int argc, char **argv) } I_StartupJoysticks(); - D_DoomMain (); - return 0; + return D_DoomMain (); } diff --git a/src/posix/sdl/i_system.cpp b/src/posix/sdl/i_system.cpp index d25b06937c4..530fdb2b259 100644 --- a/src/posix/sdl/i_system.cpp +++ b/src/posix/sdl/i_system.cpp @@ -103,7 +103,6 @@ void I_Init (void) // I_Error // extern FILE *Logfile; -bool gameisdead; #ifdef __APPLE__ void Mac_I_FatalError(const char* errortext); diff --git a/src/utility/doomerrors.h b/src/utility/doomerrors.h index faf9a263d4d..fc04ee0016c 100644 --- a/src/utility/doomerrors.h +++ b/src/utility/doomerrors.h @@ -82,13 +82,6 @@ class CDoomError : public std::exception char m_Message[MAX_ERRORTEXT]; }; -class CNoRunExit : public std::runtime_error -{ -public: - CNoRunExit() : std::runtime_error("NoRunExit") - { - } -}; class CRecoverableError : public CDoomError { diff --git a/src/win32/i_main.cpp b/src/win32/i_main.cpp index 141caeb2f69..cf6c7de61ea 100644 --- a/src/win32/i_main.cpp +++ b/src/win32/i_main.cpp @@ -145,15 +145,6 @@ static HMODULE hwtsapi32; // handle to wtsapi32.dll // CODE -------------------------------------------------------------------- - -#ifdef _MSC_VER -static int NewFailure (size_t size) -{ - I_FatalError ("Failed to allocate %d bytes from process heap", size); - return 0; -} -#endif - //========================================================================== // // UnCOM @@ -765,214 +756,213 @@ void DoMain (HINSTANCE hInstance) RECT cRect; TIMECAPS tc; DEVMODE displaysettings; - - try + + // Do not use the multibyte __argv here because we want UTF-8 arguments + // and those can only be done by converting the Unicode variants. + Args = new FArgs(); + auto argc = __argc; + auto wargv = __wargv; + for (int i = 0; i < argc; i++) { -#ifdef _MSC_VER - _set_new_handler (NewFailure); -#endif - - // Do not use the multibyte __argv here because we want UTF-8 arguments - // and those can only be done by converting the Unicode variants. - Args = new FArgs(); - auto argc = __argc; - auto wargv = __wargv; - for (int i = 0; i < argc; i++) + Args->AppendArg(FString(wargv[i])); + } + + // Load Win32 modules + Kernel32Module.Load({"kernel32.dll"}); + Shell32Module.Load({"shell32.dll"}); + User32Module.Load({"user32.dll"}); + + // Under XP, get our session ID so we can know when the user changes/locks sessions. + // Since we need to remain binary compatible with older versions of Windows, we + // need to extract the ProcessIdToSessionId function from kernel32.dll manually. + HMODULE kernel = GetModuleHandleA ("kernel32.dll"); + + if (Args->CheckParm("-stdout")) + { + // As a GUI application, we don't normally get a console when we start. + // If we were run from the shell and are on XP+, we can attach to its + // console. Otherwise, we can create a new one. If we already have a + // stdout handle, then we have been redirected and should just use that + // handle instead of creating a console window. + + StdOut = GetStdHandle(STD_OUTPUT_HANDLE); + if (StdOut != NULL) { - Args->AppendArg(FString(wargv[i])); + // It seems that running from a shell always creates a std output + // for us, even if it doesn't go anywhere. (Running from Explorer + // does not.) If we can get file information for this handle, it's + // a file or pipe, so use it. Otherwise, pretend it wasn't there + // and find a console to use instead. + BY_HANDLE_FILE_INFORMATION info; + if (!GetFileInformationByHandle(StdOut, &info)) + { + StdOut = NULL; + } } - - // Load Win32 modules - Kernel32Module.Load({"kernel32.dll"}); - Shell32Module.Load({"shell32.dll"}); - User32Module.Load({"user32.dll"}); - - // Under XP, get our session ID so we can know when the user changes/locks sessions. - // Since we need to remain binary compatible with older versions of Windows, we - // need to extract the ProcessIdToSessionId function from kernel32.dll manually. - HMODULE kernel = GetModuleHandleA ("kernel32.dll"); - - if (Args->CheckParm("-stdout")) + if (StdOut == NULL) { - // As a GUI application, we don't normally get a console when we start. - // If we were run from the shell and are on XP+, we can attach to its - // console. Otherwise, we can create a new one. If we already have a - // stdout handle, then we have been redirected and should just use that - // handle instead of creating a console window. - - StdOut = GetStdHandle(STD_OUTPUT_HANDLE); - if (StdOut != NULL) + if (AttachConsole(ATTACH_PARENT_PROCESS)) { - // It seems that running from a shell always creates a std output - // for us, even if it doesn't go anywhere. (Running from Explorer - // does not.) If we can get file information for this handle, it's - // a file or pipe, so use it. Otherwise, pretend it wasn't there - // and find a console to use instead. - BY_HANDLE_FILE_INFORMATION info; - if (!GetFileInformationByHandle(StdOut, &info)) - { - StdOut = NULL; - } + StdOut = GetStdHandle(STD_OUTPUT_HANDLE); + DWORD foo; WriteFile(StdOut, "\n", 1, &foo, NULL); + AttachedStdOut = true; } - if (StdOut == NULL) + if (StdOut == NULL && AllocConsole()) { - if (AttachConsole(ATTACH_PARENT_PROCESS)) - { - StdOut = GetStdHandle(STD_OUTPUT_HANDLE); - DWORD foo; WriteFile(StdOut, "\n", 1, &foo, NULL); - AttachedStdOut = true; - } - if (StdOut == NULL && AllocConsole()) - { - StdOut = GetStdHandle(STD_OUTPUT_HANDLE); - } - - // These two functions do not exist in Windows XP. - BOOL (WINAPI* p_GetCurrentConsoleFontEx)(HANDLE hConsoleOutput, BOOL bMaximumWindow, PCONSOLE_FONT_INFOEX lpConsoleCurrentFontEx); - BOOL (WINAPI* p_SetCurrentConsoleFontEx)(HANDLE hConsoleOutput, BOOL bMaximumWindow, PCONSOLE_FONT_INFOEX lpConsoleCurrentFontEx); - - p_SetCurrentConsoleFontEx = (decltype(p_SetCurrentConsoleFontEx))GetProcAddress(kernel, "SetCurrentConsoleFontEx"); - p_GetCurrentConsoleFontEx = (decltype(p_GetCurrentConsoleFontEx))GetProcAddress(kernel, "GetCurrentConsoleFontEx"); - if (p_SetCurrentConsoleFontEx && p_GetCurrentConsoleFontEx) + StdOut = GetStdHandle(STD_OUTPUT_HANDLE); + } + + // These two functions do not exist in Windows XP. + BOOL (WINAPI* p_GetCurrentConsoleFontEx)(HANDLE hConsoleOutput, BOOL bMaximumWindow, PCONSOLE_FONT_INFOEX lpConsoleCurrentFontEx); + BOOL (WINAPI* p_SetCurrentConsoleFontEx)(HANDLE hConsoleOutput, BOOL bMaximumWindow, PCONSOLE_FONT_INFOEX lpConsoleCurrentFontEx); + + p_SetCurrentConsoleFontEx = (decltype(p_SetCurrentConsoleFontEx))GetProcAddress(kernel, "SetCurrentConsoleFontEx"); + p_GetCurrentConsoleFontEx = (decltype(p_GetCurrentConsoleFontEx))GetProcAddress(kernel, "GetCurrentConsoleFontEx"); + if (p_SetCurrentConsoleFontEx && p_GetCurrentConsoleFontEx) + { + CONSOLE_FONT_INFOEX cfi; + cfi.cbSize = sizeof(cfi); + + if (p_GetCurrentConsoleFontEx(StdOut, false, &cfi)) { - CONSOLE_FONT_INFOEX cfi; - cfi.cbSize = sizeof(cfi); - - if (p_GetCurrentConsoleFontEx(StdOut, false, &cfi)) + if (*cfi.FaceName == 0) // If the face name is empty, the default (useless) raster font is actoive. { - if (*cfi.FaceName == 0) // If the face name is empty, the default (useless) raster font is actoive. - { - //cfi.dwFontSize = { 8, 14 }; - wcscpy(cfi.FaceName, L"Lucida Console"); - cfi.FontFamily = FF_DONTCARE; - p_SetCurrentConsoleFontEx(StdOut, false, &cfi); - } + //cfi.dwFontSize = { 8, 14 }; + wcscpy(cfi.FaceName, L"Lucida Console"); + cfi.FontFamily = FF_DONTCARE; + p_SetCurrentConsoleFontEx(StdOut, false, &cfi); } } - FancyStdOut = true; } + FancyStdOut = true; } - - // Set the timer to be as accurate as possible - if (timeGetDevCaps (&tc, sizeof(tc)) != TIMERR_NOERROR) - TimerPeriod = 1; // Assume minimum resolution of 1 ms - else - TimerPeriod = tc.wPeriodMin; - - timeBeginPeriod (TimerPeriod); - atexit(UnTbp); - - atexit (call_terms); - - // Figure out what directory the program resides in. - WCHAR progbuff[1024]; - if (GetModuleFileNameW(nullptr, progbuff, sizeof progbuff) == 0) - { - I_FatalError("Could not determine program location."); - } - progbuff[1023] = '\0'; - if (auto lastsep = wcsrchr(progbuff, '\\')) - { - lastsep[1] = '\0'; - } - - progdir = progbuff; - FixPathSeperator(progdir); - - HDC screenDC = GetDC(0); - int dpi = GetDeviceCaps(screenDC, LOGPIXELSX); - ReleaseDC(0, screenDC); - width = (512 * dpi + 96 / 2) / 96; - height = (384 * dpi + 96 / 2) / 96; - - // Many Windows structures that specify their size do so with the first - // element. DEVMODE is not one of those structures. - memset (&displaysettings, 0, sizeof(displaysettings)); - displaysettings.dmSize = sizeof(displaysettings); - EnumDisplaySettings (NULL, ENUM_CURRENT_SETTINGS, &displaysettings); - x = (displaysettings.dmPelsWidth - width) / 2; - y = (displaysettings.dmPelsHeight - height) / 2; - - if (Args->CheckParm ("-0")) - { - x = y = 0; - } - - WNDCLASS WndClass; - WndClass.style = 0; - WndClass.lpfnWndProc = LConProc; - WndClass.cbClsExtra = 0; - WndClass.cbWndExtra = 0; - WndClass.hInstance = hInstance; - WndClass.hIcon = LoadIcon (hInstance, MAKEINTRESOURCE(IDI_ICON1)); - WndClass.hCursor = LoadCursor (NULL, IDC_ARROW); - WndClass.hbrBackground = NULL; - WndClass.lpszMenuName = NULL; - WndClass.lpszClassName = WinClassName; - - /* register this new class with Windows */ - if (!RegisterClass((LPWNDCLASS)&WndClass)) - I_FatalError ("Could not register window class"); - - /* create window */ - FStringf caption("" GAMESIG " %s " X64 " (%s)", GetVersionString(), GetGitTime()); - std::wstring wcaption = caption.WideString(); - Window = CreateWindowExW( - WS_EX_APPWINDOW, - WinClassName, - wcaption.c_str(), - WS_OVERLAPPEDWINDOW | WS_VISIBLE | WS_CLIPCHILDREN, - x, y, width, height, - (HWND) NULL, - (HMENU) NULL, - hInstance, - NULL); - - if (!Window) - { - MessageBoxA(nullptr, "Unable to create main window", "Fatal", MB_ICONEXCLAMATION|MB_OK); - exit(-1); - } - - if (kernel != NULL) + } + + // Set the timer to be as accurate as possible + if (timeGetDevCaps (&tc, sizeof(tc)) != TIMERR_NOERROR) + TimerPeriod = 1; // Assume minimum resolution of 1 ms + else + TimerPeriod = tc.wPeriodMin; + + timeBeginPeriod (TimerPeriod); + atexit(UnTbp); + + atexit (call_terms); + + // Figure out what directory the program resides in. + WCHAR progbuff[1024]; + if (GetModuleFileNameW(nullptr, progbuff, sizeof progbuff) == 0) + { + MessageBoc(nullptr, "Fatal", "Could not determine program location.", MB_ICONEXCLAMATION|MB_OK); + exit(-1); + } + + progbuff[1023] = '\0'; + if (auto lastsep = wcsrchr(progbuff, '\\')) + { + lastsep[1] = '\0'; + } + + progdir = progbuff; + FixPathSeperator(progdir); + + HDC screenDC = GetDC(0); + int dpi = GetDeviceCaps(screenDC, LOGPIXELSX); + ReleaseDC(0, screenDC); + width = (512 * dpi + 96 / 2) / 96; + height = (384 * dpi + 96 / 2) / 96; + + // Many Windows structures that specify their size do so with the first + // element. DEVMODE is not one of those structures. + memset (&displaysettings, 0, sizeof(displaysettings)); + displaysettings.dmSize = sizeof(displaysettings); + EnumDisplaySettings (NULL, ENUM_CURRENT_SETTINGS, &displaysettings); + x = (displaysettings.dmPelsWidth - width) / 2; + y = (displaysettings.dmPelsHeight - height) / 2; + + if (Args->CheckParm ("-0")) + { + x = y = 0; + } + + WNDCLASS WndClass; + WndClass.style = 0; + WndClass.lpfnWndProc = LConProc; + WndClass.cbClsExtra = 0; + WndClass.cbWndExtra = 0; + WndClass.hInstance = hInstance; + WndClass.hIcon = LoadIcon (hInstance, MAKEINTRESOURCE(IDI_ICON1)); + WndClass.hCursor = LoadCursor (NULL, IDC_ARROW); + WndClass.hbrBackground = NULL; + WndClass.lpszMenuName = NULL; + WndClass.lpszClassName = WinClassName; + + /* register this new class with Windows */ + if (!RegisterClass((LPWNDCLASS)&WndClass)) + { + MessageBoxA(nullptr, "Could not register window class", "Fatal", MB_ICONEXCLAMATION|MB_OK); + exit(-1); + } + + /* create window */ + FStringf caption("" GAMESIG " %s " X64 " (%s)", GetVersionString(), GetGitTime()); + std::wstring wcaption = caption.WideString(); + Window = CreateWindowExW( + WS_EX_APPWINDOW, + WinClassName, + wcaption.c_str(), + WS_OVERLAPPEDWINDOW | WS_VISIBLE | WS_CLIPCHILDREN, + x, y, width, height, + (HWND) NULL, + (HMENU) NULL, + hInstance, + NULL); + + if (!Window) + { + MessageBoxA(nullptr, "Unable to create main window", "Fatal", MB_ICONEXCLAMATION|MB_OK); + exit(-1); + } + + if (kernel != NULL) + { + typedef BOOL (WINAPI *pts)(DWORD, DWORD *); + pts pidsid = (pts)GetProcAddress (kernel, "ProcessIdToSessionId"); + if (pidsid != 0) { - typedef BOOL (WINAPI *pts)(DWORD, DWORD *); - pts pidsid = (pts)GetProcAddress (kernel, "ProcessIdToSessionId"); - if (pidsid != 0) + if (!pidsid (GetCurrentProcessId(), &SessionID)) { - if (!pidsid (GetCurrentProcessId(), &SessionID)) + SessionID = 0; + } + hwtsapi32 = LoadLibraryA ("wtsapi32.dll"); + if (hwtsapi32 != 0) + { + FARPROC reg = GetProcAddress (hwtsapi32, "WTSRegisterSessionNotification"); + if (reg == 0 || !((BOOL(WINAPI *)(HWND, DWORD))reg) (Window, NOTIFY_FOR_THIS_SESSION)) { - SessionID = 0; + FreeLibrary (hwtsapi32); + hwtsapi32 = 0; } - hwtsapi32 = LoadLibraryA ("wtsapi32.dll"); - if (hwtsapi32 != 0) + else { - FARPROC reg = GetProcAddress (hwtsapi32, "WTSRegisterSessionNotification"); - if (reg == 0 || !((BOOL(WINAPI *)(HWND, DWORD))reg) (Window, NOTIFY_FOR_THIS_SESSION)) - { - FreeLibrary (hwtsapi32); - hwtsapi32 = 0; - } - else - { - atexit (UnWTS); - } + atexit (UnWTS); } } } - - GetClientRect (Window, &cRect); - - WinWidth = cRect.right; - WinHeight = cRect.bottom; - - CoInitialize (NULL); - atexit (UnCOM); - - D_DoomMain (); } - catch (class CNoRunExit &) + + GetClientRect (Window, &cRect); + + WinWidth = cRect.right; + WinHeight = cRect.bottom; + + CoInitialize (NULL); + atexit (UnCOM); + + int ret = D_DoomMain (); + if (ret == 1337) // special exit code for 'norun'. { + // The only way D_DoomMain can exit regularly is by executing a -norun startup, which was previously handled via exception. I_ShutdownGraphics(); if (!batchrun) { @@ -980,7 +970,7 @@ void DoMain (HINSTANCE hInstance) { // Outputting to a new console window: Wait for a keypress before quitting. DWORD bytes; HANDLE stdinput = GetStdHandle(STD_INPUT_HANDLE); - + ShowWindow(Window, SW_HIDE); WriteFile(StdOut, "Press any key to exit...", 24, &bytes, NULL); FlushConsoleInputBuffer(stdinput); @@ -992,32 +982,30 @@ void DoMain (HINSTANCE hInstance) ShowErrorPane(NULL); } } - exit(0); } - catch (std::exception &error) - { - I_ShutdownGraphics (); - RestoreConView (); - S_StopMusic(true); - I_FlushBufferedConsoleStuff(); - auto msg = error.what(); - if (strcmp(msg, "NoRunExit")) - { - if (CVMAbortException::stacktrace.IsNotEmpty()) - { - Printf("%s", CVMAbortException::stacktrace.GetChars()); - } + return ret; +} - if (!batchrun) - { - ShowErrorPane(msg); - } - else - { - Printf("%s\n", msg); - } - } - exit(-1); +void I_ShowFatalError(const char *msg) +{ + I_ShutdownGraphics (); + RestoreConView (); + S_StopMusic(true); + I_FlushBufferedConsoleStuff(); + auto msg = error.what(); + + if (CVMAbortException::stacktrace.IsNotEmpty()) + { + Printf("%s", CVMAbortException::stacktrace.GetChars()); + } + + if (!batchrun) + { + ShowErrorPane(msg); + } + else + { + Printf("%s\n", msg); } } diff --git a/src/win32/i_system.cpp b/src/win32/i_system.cpp index 2620c495223..4c9218cb93c 100644 --- a/src/win32/i_system.cpp +++ b/src/win32/i_system.cpp @@ -137,7 +137,6 @@ double PerfToSec, PerfToMillisec; UINT TimerPeriod; -bool gameisdead; int sys_ostype = 0; // PRIVATE DATA DEFINITIONS ------------------------------------------------