diff --git a/Common/Log.cpp b/Common/Log.cpp index 58ebd509e6..9778fc77ab 100644 --- a/Common/Log.cpp +++ b/Common/Log.cpp @@ -45,6 +45,25 @@ static bool g_exitOnAssert; static AssertNoCallbackFunc g_assertCancelCallback = 0; static void *g_assertCancelCallbackUserData = 0; +u8 g_debugCounters[8]; + +void SetDebugValue(DebugCounter counter, int value) { + if (value > 15) + value = 15; + if (value < 0) + value = 0; + g_debugCounters[(int)counter] = value; +} + +void IncrementDebugCounter(DebugCounter counter) { + int value = g_debugCounters[(int)counter] + 1; + if (value > 15) + value = 15; + if (value < 0) + value = 0; + g_debugCounters[(int)counter] = value; +} + void SetAssertDialogParent(void *handle) { #if PPSSPP_PLATFORM(WINDOWS) // I thought this would be nice, but for some reason the dialog becomes invisible. @@ -87,7 +106,11 @@ bool HandleAssert(const char *function, const char *file, int line, const char * { std::lock_guard guard(g_extraAssertInfoMutex); double delta = time_now_d() - g_assertInfoTime; - snprintf(formatted, sizeof(formatted), "(%s:%s:%d): [%s] (%s, %0.1fs) %s", file, function, line, expression, g_extraAssertInfo.c_str(), delta, text); + u32 debugCounters = 0; + for (int i = 0; i < 8; i++) { + debugCounters |= g_debugCounters[7 - i] << (i * 4); + } + snprintf(formatted, sizeof(formatted), "(%s:%s:%d:%08x): [%s] (%s, %0.1fs) %s", file, function, line, debugCounters, expression, g_extraAssertInfo.c_str(), delta, text); } // Normal logging (will also log to Android log) diff --git a/Common/Log.h b/Common/Log.h index 8b6a20d87e..809ac060ad 100644 --- a/Common/Log.h +++ b/Common/Log.h @@ -136,9 +136,19 @@ __attribute__((format(printf, 5, 6))) #endif ; +// These allow us to get a small amount of information into assert messages. +// They can have a value between 0 and 15. +enum class DebugCounter { + APP_BOOT = 0, + GAME_BOOT = 0, + GAME_SHUTDOWN = 0, +}; + bool HitAnyAsserts(); void ResetHitAnyAsserts(); void SetExtraAssertInfo(const char *info); +void SetDebugValue(DebugCounter counter, int value); +void IncrementDebugCounter(DebugCounter counter); typedef void (*AssertNoCallbackFunc)(const char *message, void *userdata); void SetAssertCancelCallback(AssertNoCallbackFunc callback, void *userdata); void SetCleanExitOnAssert(); diff --git a/Core/System.cpp b/Core/System.cpp index becec1408f..c5871176ee 100644 --- a/Core/System.cpp +++ b/Core/System.cpp @@ -546,6 +546,8 @@ bool PSP_InitStart(const CoreParameter &coreParam) { return false; } + IncrementDebugCounter(DebugCounter::GAME_BOOT); + g_bootState = BootState::Booting; GraphicsContext *temp = g_CoreParameter.graphicsContext; @@ -678,6 +680,7 @@ void PSP_Shutdown(bool success) { // Do nothing if we never inited. if (g_bootState == BootState::Off) { + ERROR_LOG(Log::Loader, "Unexpected PSP_Shutdown"); return; } @@ -710,6 +713,8 @@ void PSP_Shutdown(bool success) { if (success) { g_bootState = BootState::Off; } + + IncrementDebugCounter(DebugCounter::GAME_SHUTDOWN); } BootState PSP_Reboot(std::string *error_string) { diff --git a/UI/DevScreens.cpp b/UI/DevScreens.cpp index 00aeea5639..55a20e6adf 100644 --- a/UI/DevScreens.cpp +++ b/UI/DevScreens.cpp @@ -1022,6 +1022,13 @@ void SystemInfoScreen::CreateInternalsTab(UI::ViewGroup *internals) { internals->Add(new ItemHeader(ac->T("Notifications"))); internals->Add(new PopupMultiChoice(&g_Config.iAchievementsLeaderboardTrackerPos, ac->T("Leaderboard tracker"), positions, 0, ARRAY_SIZE(positions), I18NCat::DIALOG, screenManager()))->SetEnabledPtr(&g_Config.bAchievementsEnable); +#ifdef _DEBUG + // Untranslated string because this is debug mode only, only for PPSSPP developers. + internals->Add(new Choice("Assert"))->OnClick.Add([=](UI::EventParams &) { + _dbg_assert_msg_(false, "Test assert message"); + return UI::EVENT_DONE; + }); +#endif #if PPSSPP_PLATFORM(ANDROID) internals->Add(new Choice(si->T("Exception")))->OnClick.Add([&](UI::EventParams &) { System_Notify(SystemNotification::TEST_JAVA_EXCEPTION); diff --git a/UI/NativeApp.cpp b/UI/NativeApp.cpp index 7c56a383df..e99cfc4ca1 100644 --- a/UI/NativeApp.cpp +++ b/UI/NativeApp.cpp @@ -350,6 +350,8 @@ static void ClearFailedGPUBackends() { void NativeInit(int argc, const char *argv[], const char *savegame_dir, const char *external_dir, const char *cache_dir) { net::Init(); // This needs to happen before we load the config. So on Windows we also run it in Main. It's fine to call multiple times. + IncrementDebugCounter(DebugCounter::APP_BOOT); + // Probably an excessive timeout. it only causes delays on shutdown, though. __UPnPInit(2000);