From 639427ee9cd93700db6dac817146df3956099ee2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 11 Nov 2026 11:33:54 +0100 Subject: [PATCH 1/3] Crash screen: Show the GPU model and the graphics API Co-Authored-By: Claude Opus 5.5 --- UI/DebugOverlay.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/UI/DebugOverlay.cpp b/UI/DebugOverlay.cpp index 495ab33b0d..c60d18f0cf 100644 --- a/UI/DebugOverlay.cpp +++ b/UI/DebugOverlay.cpp @@ -408,6 +408,10 @@ void DrawCrashDump(UIContext *ctx, const Path &gamePath) { std::string sysName = System_GetProperty(SYSPROP_NAME); int sysVersion = System_GetPropertyInt(SYSPROP_SYSTEMVERSION); + Draw::DrawContext *draw = ctx->GetDrawContext(); + // On most APIs the vendor string is the GPU model. + std::string gpuName = draw->GetInfoString(Draw::InfoField::VENDORSTRING); + std::string apiName = draw->GetInfoString(Draw::InfoField::APINAME); // First column y += 65; @@ -423,18 +427,20 @@ void DrawCrashDump(UIContext *ctx, const Path &gamePath) { %s (%s) %s (%s) %s v%d (%s) +%s (%s) %s )", ExceptionTypeAsString(info.type), discID.c_str(), g_paramSFO.GetValueString("TITLE").c_str(), versionString, build, sysName.c_str(), sysVersion, GetCompilerABI(), +gpuName.c_str(), apiName.c_str(), crcStr ); ctx->Draw()->SetFontScale(.7f, .7f); ctx->Draw()->DrawTextShadow(ubuntu24, statbuf, x, y, 0xFFFFFFFF); - y += 160; + y += 185; if (info.type == MIPSExceptionType::MEMORY) { snprintf(statbuf, sizeof(statbuf), R"( From f1f87f7f982712cb567749990e312cbf9d11c418 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 11 Nov 2026 11:35:43 +0100 Subject: [PATCH 2/3] Crash screen: Space the blocks by their measured height The fixed offsets left big gaps after short blocks. Co-Authored-By: Claude Opus 5.5 --- UI/DebugOverlay.cpp | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/UI/DebugOverlay.cpp b/UI/DebugOverlay.cpp index c60d18f0cf..7d3c859571 100644 --- a/UI/DebugOverlay.cpp +++ b/UI/DebugOverlay.cpp @@ -340,6 +340,15 @@ static const char *CPUCoreAsString(int core) { } } +// Draws a block of lines, and returns where the next block goes. +static int DrawCrashTextBlock(UIContext *ctx, FontID font, std::string_view text, int x, int y) { + text = StripSpaces(text); + ctx->Draw()->DrawTextShadow(font, text, x, y, 0xFFFFFFFF); + float w, h; + ctx->Draw()->MeasureText(font, text, &w, &h); + return y + (int)h + 15; +} + void DrawCrashDump(UIContext *ctx, const Path &gamePath) { const MIPSExceptionInfo &info = Core_GetExceptionInfo(); @@ -439,8 +448,7 @@ crcStr ); ctx->Draw()->SetFontScale(.7f, .7f); - ctx->Draw()->DrawTextShadow(ubuntu24, statbuf, x, y, 0xFFFFFFFF); - y += 185; + y = DrawCrashTextBlock(ctx, ubuntu24, statbuf, x, y); if (info.type == MIPSExceptionType::MEMORY) { snprintf(statbuf, sizeof(statbuf), R"( @@ -452,8 +460,6 @@ info.address, info.accessSize, info.pc, info.info.c_str()); - ctx->Draw()->DrawTextShadow(ubuntu24, statbuf, x, y, 0xFFFFFFFF); - y += 180; } else if (info.type == MIPSExceptionType::BAD_EXEC_ADDR) { snprintf(statbuf, sizeof(statbuf), R"( Destination: %s to %08x @@ -463,36 +469,27 @@ ExecExceptionTypeAsString(info.exec_type), info.address, info.pc, info.ra); - ctx->Draw()->DrawTextShadow(ubuntu24, statbuf, x, y, 0xFFFFFFFF); - y += 180; } else if (info.type == MIPSExceptionType::FPU) { snprintf(statbuf, sizeof(statbuf), R"( FPU: %s PC: %08x )", FPUExceptionTypeAsString(info.fpu_type), info.pc); - ctx->Draw()->DrawTextShadow(ubuntu24, statbuf, x, y, 0xFFFFFFFF); - y += 180; } else if (info.type == MIPSExceptionType::BREAK) { snprintf(statbuf, sizeof(statbuf), R"( BREAK PC: %08x )", info.pc); - ctx->Draw()->DrawTextShadow(ubuntu24, statbuf, x, y, 0xFFFFFFFF); - y += 180; } else if (info.type == MIPSExceptionType::HLE) { snprintf(statbuf, sizeof(statbuf), R"( %s PC: %08x RA: %08x)", info.info.c_str(), info.pc, info.ra); - ctx->Draw()->DrawTextShadow(ubuntu24, statbuf, x, y, 0xFFFFFFFF); - y += 180; } else { snprintf(statbuf, sizeof(statbuf), R"( Invalid / Unknown (%d) )", (int)info.type); - ctx->Draw()->DrawTextShadow(ubuntu24, statbuf, x, y, 0xFFFFFFFF); - y += 180; } + y = DrawCrashTextBlock(ctx, ubuntu24, statbuf, x, y); std::string kernelState = __KernelStateSummary(); From a7209dc8323b6777b7c2611d70edfe9f57079e2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 11 Nov 2026 11:39:01 +0100 Subject: [PATCH 3/3] Crash screen: Show the emulated time Co-Authored-By: Claude Opus 5.5 --- UI/DebugOverlay.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/UI/DebugOverlay.cpp b/UI/DebugOverlay.cpp index 7d3c859571..763fbcbf6e 100644 --- a/UI/DebugOverlay.cpp +++ b/UI/DebugOverlay.cpp @@ -5,6 +5,7 @@ #include "Common/CPUDetect.h" #include "Common/StringUtils.h" #include "Common/Data/Text/StringWriter.h" +#include "Common/Data/Text/Parsers.h" #include "Core/MIPS/MIPS.h" #include "Core/MIPS/JitCommon/JitCommon.h" @@ -20,6 +21,7 @@ #include "Core/Reporting.h" #include "Core/CwCheat.h" #include "Core/Core.h" +#include "Core/CoreTiming.h" #include "Core/ELF/ParamSFO.h" #include "Core/System.h" #include "Core/Util/GameDB.h" @@ -421,6 +423,8 @@ void DrawCrashDump(UIContext *ctx, const Path &gamePath) { // On most APIs the vendor string is the GPU model. std::string gpuName = draw->GetInfoString(Draw::InfoField::VENDORSTRING); std::string apiName = draw->GetInfoString(Draw::InfoField::APINAME); + // Off the CPU thread, so peek. + std::string emulatedTime = NiceTimeFormat((int)(CoreTiming::PeekGlobalTimeUs() / 1000000)); // First column y += 65; @@ -437,6 +441,7 @@ void DrawCrashDump(UIContext *ctx, const Path &gamePath) { %s (%s) %s v%d (%s) %s (%s) +Emulated time: %s %s )", ExceptionTypeAsString(info.type), @@ -444,6 +449,7 @@ discID.c_str(), g_paramSFO.GetValueString("TITLE").c_str(), versionString, build, sysName.c_str(), sysVersion, GetCompilerABI(), gpuName.c_str(), apiName.c_str(), +emulatedTime.c_str(), crcStr );