From 1b8a79c64eaacaa762cb8cf278d2e890a2e3ac98 Mon Sep 17 00:00:00 2001 From: Goober5000 Date: Fri, 15 May 2026 21:00:30 -0400 Subject: [PATCH] two fixes for issue 6793 1. more robust handling of missing fireball graphics 2. fix handling of error dialogs on Linux so that the engine doesn't silently continue on an error! Fixes #6793. --- code/fireball/fireballs.cpp | 29 +++++++++++++------------ code/osapi/dialogs.cpp | 43 +++++++++++++++++++++++++------------ 2 files changed, 44 insertions(+), 28 deletions(-) diff --git a/code/fireball/fireballs.cpp b/code/fireball/fireballs.cpp index c786b57dcb2..43962ac1dff 100644 --- a/code/fireball/fireballs.cpp +++ b/code/fireball/fireballs.cpp @@ -920,19 +920,7 @@ int fireball_create(vec3d *pos, int fireball_type, int render_type, int parent_o return -1; } - - if (!Unused_fireball_indices.empty()) { - n = Unused_fireball_indices.back(); - Unused_fireball_indices.pop_back(); - } - else { - n = static_cast(Fireballs.size()); - Fireballs.emplace_back(); - } - - fireball* new_fireball = &Fireballs[n]; - - // get an lod to use + // get an lod to use fb_lod = fireball_get_lod(pos, fd, size); // change lod if low res is desired @@ -947,8 +935,21 @@ int fireball_create(vec3d *pos, int fireball_type, int render_type, int parent_o } fl = &fd->lod[fb_lod]; - new_fireball->lod = (char)fb_lod; + // don't create a fireball without usable graphics + if (fl->bitmap_id < 0 || fl->fps <= 0 || fl->num_frames <= 0) { + return -1; + } + + if (!Unused_fireball_indices.empty()) { + n = Unused_fireball_indices.back(); + Unused_fireball_indices.pop_back(); + } else { + n = sz2i(Fireballs.size()); + Fireballs.emplace_back(); + } + auto new_fireball = &Fireballs[n]; + new_fireball->lod = (char)fb_lod; new_fireball->flags = extra_flags; new_fireball->warp_open_sound_index = warp_open_sound; new_fireball->warp_close_sound_index = warp_close_sound; diff --git a/code/osapi/dialogs.cpp b/code/osapi/dialogs.cpp index 287880b94d6..308146c4dff 100644 --- a/code/osapi/dialogs.cpp +++ b/code/osapi/dialogs.cpp @@ -238,22 +238,23 @@ namespace os gr_activate(0); - int buttonId; + int buttonId = -1; // if dialog is silently suppressed if (SDL_ShowMessageBox(&boxData, &buttonId) < 0) { // Call failed - buttonId = 1; // No action + buttonId = 1; } switch (buttonId) { - case 2: + case 2: // Exit abort(); - case 0: + case 0: // Debug Int3(); break; + case 1: // Continue default: break; } @@ -283,6 +284,12 @@ namespace os { mprintf(("\n%s\n", text)); + // also output to stderr so the message is visible if the dialog is suppressed + // (e.g., the SDL message box is dismissed silently by the window manager when the + // game is fullscreen on Linux) + fprintf(stderr, "\n%s\n", text); + fflush(stderr); + if (running_unittests) { throw ErrorException(text); } @@ -322,21 +329,22 @@ namespace os gr_activate(0); - int buttonId; + int buttonId = -1; // if dialog is silently suppressed if (SDL_ShowMessageBox(&boxData, &buttonId) < 0) { // Call failed - abort(); + buttonId = 1; } switch (buttonId) { - case 1: - abort(); - - default: + case 0: // Debug Int3(); break; + + case 1: // Exit + default: + abort(); } gr_activate(1); } @@ -349,6 +357,12 @@ namespace os // output to the debug log before anything else (so that we have a complete record) mprintf(("WARNING: \"%s\" at %s:%d\n", text.c_str(), filename, line)); + // also output to stderr so the message is visible if the dialog is suppressed + // (e.g., the SDL message box is dismissed silently by the window manager when the + // game is fullscreen on Linux) + fprintf(stderr, "WARNING: \"%s\" at %s:%d\n", text.c_str(), filename, line); + fflush(stderr); + if (running_unittests) { throw WarningException(text); } @@ -390,22 +404,23 @@ namespace os gr_activate(0); - int buttonId; + int buttonId = -1; // if dialog is silently suppressed if (SDL_ShowMessageBox(&boxData, &buttonId) < 0) { // Call failed - buttonId = 1; // No action + buttonId = 1; } switch (buttonId) { - case 2: + case 2: // Exit abort(); - case 0: + case 0: // Debug Int3(); break; + case 1: // Continue default: break; }