From 5ade15cdc5acfc039f7daba60c03936f59f7b13b Mon Sep 17 00:00:00 2001 From: toaster Date: Wed, 12 Apr 2023 14:54:42 +0100 Subject: [PATCH] I_ShowErrorMessageBox for SDL interface Handles showing the error message box on quit. - Polite communication that the game fell over and that you (probably) didn't do anything wrong - Accomodates pointing you to UNIXBACKTRACE and _WIN32 exchndl crash logs if relevant - Points you to the specific dated and timed log file that contains the error - Tells you that the vague and often confusing error message (like I_Error) is for a programmer, server host, or add-on creator - Hee Ho! --- src/sdl/i_system.c | 102 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 83 insertions(+), 19 deletions(-) diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index cd71c7d4f..7e04745dd 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -294,6 +294,87 @@ static void write_backtrace(INT32 signal) #undef CRASHLOG_STDERR_WRITE #endif // UNIXBACKTRACE +static void I_ShowErrorMessageBox(const char *messagefordevelopers, boolean dumpmade) +{ + static char finalmessage[1024]; + size_t firstimpressionsline = 3; // "Dr Robotnik's Ring Racers" has encountered... + + if (M_CheckParm("-dedicated")) + return; + + snprintf( + finalmessage, + sizeof(finalmessage), + "\"SRB2Kart V2\" has encountered an unrecoverable error and needs to close.\n" + "The %s log file is located at (%s).\n" + "\n" + "\n" + "%s", + dumpmade ? +#if defined (UNIXBACKTRACE) + "crash-log.txt" +#elif defined (_WIN32) + ".rpt crash dump" +#endif + : "", + logfilename, + messagefordevelopers); + + // Rudementary word wrapping. + // Simple and effective. Does not handle nonuniform letter sizes, etc. but who cares. + { + size_t max = 0, maxatstart = 0, start = 0, width = 0, i; + + for (i = 0; finalmessage[i]; i++) + { + if (finalmessage[i] == ' ') + { + start = i; + max += 4; + maxatstart = max; + } + else if (finalmessage[i] == '\n') + { + if (firstimpressionsline > 0) + { + firstimpressionsline--; + if (firstimpressionsline == 0) + { + width = max; + } + } + start = 0; + max = 0; + maxatstart = 0; + continue; + } + else + max += 8; + + // Start trying to wrap if presumed length exceeds the space we want. + if (width > 0 && max >= width && start > 0) + { + finalmessage[start] = '\n'; + max -= maxatstart; + start = 0; + } + } + } + + // Implement message box with SDL_ShowSimpleMessageBox, + // which should fail gracefully if it can't put a message box up + // on the target system + SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, + "Dr. Robotnik's Ring Racers "VERSIONSTRING" Error", + finalmessage, NULL); + + // Note that SDL_ShowSimpleMessageBox does *not* require SDL to be + // initialized at the time, so calling it after SDL_Quit() is + // perfectly okay! In addition, we do this on purpose so the + // fullscreen window is closed before displaying the error message + // in case the fullscreen window blocks it for some absurd reason. +} + static void I_ReportSignal(int num, int coredumped) { //static char msg[] = "oh no! back to reality!\r\n"; @@ -342,12 +423,7 @@ static void I_ReportSignal(int num, int coredumped) I_OutputMsg("\nProcess killed by signal: %s\n\n", sigmsg); - if (!M_CheckParm("-dedicated")) - SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, - "Process killed by signal", - sigmsg, NULL); - - I_Error(sigmsg, + I_ShowErrorMessageBox(sigmsg, #if defined (UNIXBACKTRACE) true #elif defined (_WIN32) @@ -2000,13 +2076,7 @@ void I_Error(const char *error, ...) I_ShutdownGraphics(); I_ShutdownInput(); - // Implement message box with SDL_ShowSimpleMessageBox, - // which should fail gracefully if it can't put a message box up - // on the target system - if (!M_CheckParm("-dedicated")) - SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, - "SRB2Kart "VERSIONSTRING" Error", - buffer, NULL); + I_ShowErrorMessageBox(buffer, false); // We wait until now to do this so the funny sound can be heard I_ShutdownSound(); @@ -2014,12 +2084,6 @@ void I_Error(const char *error, ...) I_ShutdownSystem(); SDL_Quit(); - // Note that SDL_ShowSimpleMessageBox does *not* require SDL to be - // initialized at the time, so calling it after SDL_Quit() is - // perfectly okay! In addition, we do this on purpose so the - // fullscreen window is closed before displaying the error message - // in case the fullscreen window blocks it for some absurd reason. - W_Shutdown(); #if defined (PARANOIA) && defined (__CYGWIN__)