Skip to content

Commit 1cc41f2

Browse files
committed
xrCore/xrDebug: support for SDL2
1 parent d405c89 commit 1cc41f2

File tree

4 files changed

+124
-31
lines changed

4 files changed

+124
-31
lines changed

src/xrCore/xrDebug.cpp

Lines changed: 110 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
#include "stdafx.h"
22
#pragma hdrstop
33

4+
#include <SDL.h>
5+
#include <SDL_syswm.h>
6+
47
#include "xrDebug.h"
58
#include "os_clipboard.h"
69
#include "log.h"
@@ -58,11 +61,11 @@ static BOOL bException = FALSE;
5861
#endif
5962

6063
#if defined XR_X64
61-
# define MACHINE_TYPE IMAGE_FILE_MACHINE_AMD64
64+
#define MACHINE_TYPE IMAGE_FILE_MACHINE_AMD64
6265
#elif defined XR_X86
63-
# define MACHINE_TYPE IMAGE_FILE_MACHINE_I386
66+
#define MACHINE_TYPE IMAGE_FILE_MACHINE_I386
6467
#else
65-
# error CPU architecture is not supported.
68+
#error CPU architecture is not supported.
6669
#endif
6770

6871
namespace
@@ -92,6 +95,83 @@ ICN void* GetInstructionPtr()
9295
}
9396
}
9497

98+
enum MessageBoxResult
99+
{
100+
resultUndefined = -1,
101+
resultContinue = 0,
102+
resultTryAgain = 1,
103+
resultCancel = 2
104+
};
105+
106+
constexpr SDL_MessageBoxButtonData buttons[] =
107+
{
108+
/* .flags, .buttonid, .text */
109+
{ 0, resultContinue, "Continue" },
110+
{ 0, resultTryAgain, "Try again" },
111+
{ SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT |
112+
SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT,
113+
resultCancel, "Cancel" }
114+
};
115+
116+
SDL_MessageBoxData messageboxdata =
117+
{
118+
SDL_MESSAGEBOX_ERROR,
119+
nullptr,
120+
"Fatal error",
121+
"Vse clomalocb, tashite novyy dvizhok",
122+
SDL_arraysize(buttons),
123+
buttons,
124+
nullptr
125+
};
126+
127+
int xrDebug::ShowMessage(pcstr title, pcstr message, bool simple)
128+
{
129+
#ifdef WINDOWS // because Windows default Message box is fancy
130+
HWND hwnd = nullptr;
131+
132+
if (applicationWindow)
133+
{
134+
SDL_SysWMinfo info;
135+
SDL_VERSION(&info.version);
136+
if (SDL_GetWindowWMInfo(applicationWindow, &info))
137+
{
138+
switch (info.subsystem)
139+
{
140+
case SDL_SYSWM_WINDOWS:
141+
hwnd = info.info.win.window;
142+
break;
143+
default: break;
144+
}
145+
}
146+
}
147+
148+
if (simple)
149+
return MessageBox(hwnd, message, title, MB_OK | MB_ICONERROR | MB_SYSTEMMODAL);
150+
151+
const int result = MessageBox(hwnd, message, title,
152+
MB_CANCELTRYCONTINUE | MB_ICONERROR | MB_SYSTEMMODAL);
153+
154+
switch (result)
155+
{
156+
case IDCANCEL: return resultCancel;
157+
case IDTRYAGAIN: return resultTryAgain;
158+
case IDCONTINUE: return resultContinue;
159+
default: return resultUndefined;
160+
}
161+
#else
162+
if (simple)
163+
return SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, title, message, applicationWindow);
164+
165+
messageboxdata.window = applicationWindow;
166+
messageboxdata.title = title;
167+
messageboxdata.message = message;
168+
int button = resultUndefined;
169+
SDL_ShowMessageBox(&messageboxdata, &button);
170+
return button;
171+
#endif
172+
}
173+
174+
SDL_Window* xrDebug::applicationWindow = nullptr;
95175
xrDebug::UnhandledExceptionFilter xrDebug::PrevFilter = nullptr;
96176
xrDebug::OutOfMemoryCallbackFunc xrDebug::OutOfMemoryCallback = nullptr;
97177
xrDebug::CrashHandler xrDebug::OnCrash = nullptr;
@@ -103,9 +183,9 @@ bool xrDebug::symEngineInitialized = false;
103183
Lock xrDebug::dbgHelpLock;
104184

105185
#if defined(WINDOWS)
106-
void xrDebug::SetBugReportFile(const char* fileName) { strcpy_s(BugReportFile, fileName); }
186+
void xrDebug::SetBugReportFile(const char* fileName) { xr_strcpy(BugReportFile, fileName); }
107187
#elif defined(LINUX)
108-
void xrDebug::SetBugReportFile(const char* fileName) { strcpy_s(BugReportFile, 0, fileName); }
188+
void xrDebug::SetBugReportFile(const char* fileName) { xr_strcpy(BugReportFile, 0, fileName); }
109189
#endif
110190

111191
#if defined(WINDOWS)
@@ -245,7 +325,7 @@ xr_vector<xr_string> xrDebug::BuildStackTrace(PCONTEXT threadCtx, u16 maxFramesC
245325
stackFrame.AddrFrame.Mode = AddrModeFlat;
246326
stackFrame.AddrFrame.Offset = threadCtx->Ebp;
247327
#else
248-
# error CPU architecture is not supported.
328+
#error CPU architecture is not supported.
249329
#endif
250330

251331
while (GetNextStackFrameString(&stackFrame, threadCtx, frameStr) && traceResult.size() <= maxFramesCount)
@@ -377,7 +457,7 @@ void xrDebug::Fail(bool& ignoreAlways, const ErrorLocation& loc, const char* exp
377457
string4096 assertionInfo;
378458
GatherInfo(assertionInfo, loc, expr, desc, arg1, arg2);
379459
#ifdef USE_OWN_ERROR_MESSAGE_WINDOW
380-
strcat(assertionInfo,
460+
xr_strcat(assertionInfo,
381461
"\r\n"
382462
"Press CANCEL to abort execution\r\n"
383463
"Press TRY AGAIN to continue execution\r\n"
@@ -389,25 +469,29 @@ void xrDebug::Fail(bool& ignoreAlways, const ErrorLocation& loc, const char* exp
389469
if (OnDialog)
390470
OnDialog(true);
391471
FlushLog();
392-
#if defined(WINDOWS)
393472
if (Core.PluginMode)
394-
MessageBox(NULL, assertionInfo, "X-Ray error", MB_OK | MB_ICONERROR | MB_SYSTEMMODAL);
473+
ShowMessage("X-Ray error", assertionInfo);
395474
else
396475
{
397476
#ifdef USE_OWN_ERROR_MESSAGE_WINDOW
398-
int result = MessageBox(NULL, assertionInfo, "Fatal error",
399-
MB_CANCELTRYCONTINUE | MB_ICONERROR | MB_SYSTEMMODAL);
400-
switch (result)
477+
switch (ShowMessage("Fatal error", assertionInfo, false))
401478
{
402-
case IDCANCEL:
479+
case resultUndefined:
480+
xr_strcat(assertionInfo, SDL_GetError());
481+
[[fallthrough]];
482+
483+
case resultCancel:
403484
#ifdef USE_BUG_TRAP
404485
BT_SetUserMessage(assertionInfo);
405486
#endif
406487
DEBUG_BREAK;
407488
break;
408-
case IDTRYAGAIN: ErrorAfterDialog = false;
489+
490+
case resultTryAgain:
491+
ErrorAfterDialog = false;
409492
break;
410-
case IDCONTINUE:
493+
494+
case resultContinue:
411495
ErrorAfterDialog = false;
412496
ignoreAlways = true;
413497
break;
@@ -420,7 +504,6 @@ void xrDebug::Fail(bool& ignoreAlways, const ErrorLocation& loc, const char* exp
420504
DEBUG_BREAK;
421505
#endif
422506
}
423-
#endif
424507
if (OnDialog)
425508
OnDialog(false);
426509

@@ -436,8 +519,8 @@ void xrDebug::Fail(bool& ignoreAlways, const ErrorLocation& loc, const char* exp
436519
void xrDebug::DoExit(const std::string& message)
437520
{
438521
FlushLog();
522+
ShowMessage("Error", message.c_str());
439523
#if defined(WINDOWS)
440-
MessageBox(NULL, message.c_str(), "Error", MB_OK | MB_ICONERROR | MB_SYSTEMMODAL);
441524
TerminateProcess(GetCurrentProcess(), 1);
442525
#endif
443526
}
@@ -491,13 +574,13 @@ void WINAPI xrDebug::PreErrorHandler(INT_PTR)
491574
string256 currentDir;
492575
_getcwd(currentDir, sizeof(currentDir));
493576
string256 relDir;
494-
strcpy_s(relDir, logDir);
577+
xr_strcpy(relDir, logDir);
495578
strconcat(sizeof(logDir), logDir, currentDir, "\\", relDir);
496579
}
497580
}
498581
__except (EXCEPTION_EXECUTE_HANDLER)
499582
{
500-
strcpy_s(logDir, "logs");
583+
xr_strcpy(logDir, "logs");
501584
}
502585
string_path temp;
503586
strconcat(sizeof(temp), temp, logDir, log_name());
@@ -573,7 +656,7 @@ void xrDebug::SaveMiniDump(EXCEPTION_POINTERS *exPtrs)
573656
__except (EXCEPTION_EXECUTE_HANDLER)
574657
{
575658
string_path temp;
576-
strcpy_s(temp, dumpPath);
659+
xr_strcpy(temp, dumpPath);
577660
sprintf(dumpPath, "logs/%s", temp);
578661
}
579662
WriteMiniDump(MINIDUMP_TYPE(MiniDumpFilterMemory | MiniDumpScanMemory), dumpPath, GetCurrentThreadId(), exPtrs);
@@ -628,7 +711,7 @@ LONG WINAPI xrDebug::UnhandledFilter(EXCEPTION_POINTERS* exPtrs)
628711
{
629712
if (shared_str_initialized)
630713
Msg("\n%s", errMsg);
631-
strcat(errMsg, "\r\n");
714+
xr_strcat(errMsg, "\r\n");
632715
#ifdef DEBUG
633716
if (!IsDebuggerPresent())
634717
os_clipboard::update_clipboard(buffer);
@@ -646,10 +729,9 @@ LONG WINAPI xrDebug::UnhandledFilter(EXCEPTION_POINTERS* exPtrs)
646729
{
647730
if (OnDialog)
648731
OnDialog(true);
649-
MessageBox(NULL,
650-
"Fatal error occurred\n\n"
651-
"Press OK to abort program execution",
652-
"Fatal error", MB_OK | MB_ICONERROR | MB_SYSTEMMODAL);
732+
constexpr pcstr msg = "Fatal error occurred\n\n"
733+
"Press OK to abort program execution";
734+
ShowMessage("Fatal error", msg);
653735
}
654736
#endif
655737
ReportFault(exPtrs, 0);
@@ -671,11 +753,11 @@ void _terminate()
671753
#if defined(WINDOWS)
672754
if (strstr(GetCommandLine(), "-silent_error_mode"))
673755
exit(-1);
756+
#endif
674757
string4096 assertionInfo;
675758
xrDebug::GatherInfo(assertionInfo, DEBUG_INFO, nullptr, "Unexpected application termination");
676-
strcat(assertionInfo, "Press OK to abort execution\r\n");
677-
MessageBox(GetTopWindow(NULL), assertionInfo, "Fatal Error", MB_OK | MB_ICONERROR | MB_SYSTEMMODAL);
678-
#endif
759+
xr_strcat(assertionInfo, "Press OK to abort execution\r\n");
760+
ShowMessage("Fatal Error", assertionInfo);
679761
exit(-1);
680762
}
681763
#endif // USE_BUG_TRAP

src/xrCore/xrDebug.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#pragma warning(pop)
1515
#endif
1616

17+
struct SDL_Window;
1718
class ErrorLocation
1819
{
1920
public:
@@ -46,6 +47,7 @@ class XRCORE_API xrDebug
4647
using UnhandledExceptionFilter = LONG(WINAPI*)(EXCEPTION_POINTERS* exPtrs);
4748

4849
private:
50+
static SDL_Window* applicationWindow;
4951
static UnhandledExceptionFilter PrevFilter;
5052
static OutOfMemoryCallbackFunc OutOfMemoryCallback;
5153
static CrashHandler OnCrash;
@@ -58,6 +60,9 @@ class XRCORE_API xrDebug
5860
static void Initialize(const bool& dedicated);
5961
static void Destroy();
6062
static void OnThreadSpawn();
63+
64+
static SDL_Window* GetApplicationWindow() { return applicationWindow; }
65+
static void SetApplicationWindow(SDL_Window* window) { applicationWindow = window; }
6166
static OutOfMemoryCallbackFunc GetOutOfMemoryCallback() { return OutOfMemoryCallback; }
6267
static void SetOutOfMemoryCallback(OutOfMemoryCallbackFunc cb) { OutOfMemoryCallback = cb; }
6368
static CrashHandler GetCrashHandler() { return OnCrash; }
@@ -77,6 +82,8 @@ class XRCORE_API xrDebug
7782
const char* arg1 = nullptr, const char* arg2 = nullptr);
7883
static void DoExit(const std::string& message);
7984

85+
static int ShowMessage(pcstr title, pcstr message, bool simple = true);
86+
8087
static void LogStackTrace(const char* header);
8188
static xr_vector<xr_string> BuildStackTrace(u16 maxFramesCount = 512);
8289
private:

src/xrEngine/Device_Initialize.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ void CRenderDevice::Initialize()
5353
R_ASSERT3(m_sdlWnd, "Unable to create SDL window", SDL_GetError());
5454
SDL_SetWindowHitTest(m_sdlWnd, WindowHitTest, nullptr);
5555
SDL_SetWindowMinimumSize(m_sdlWnd, 256, 192);
56+
xrDebug::SetApplicationWindow(m_sdlWnd);
5657
}
5758
}
5859

src/xrEngine/xr_input.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,14 @@ static void on_error_dialog(bool before)
3030

3131
if (before)
3232
{
33+
pInput->ClipCursor(false);
3334
pInput->unacquire();
34-
return;
3535
}
36-
37-
pInput->acquire(true);
36+
else
37+
{
38+
pInput->ClipCursor(true);
39+
pInput->acquire(true);
40+
}
3841
}
3942

4043
CInput::CInput(bool exclusive, int deviceForInit)

0 commit comments

Comments
 (0)