diff --git a/UI/DevScreens.cpp b/UI/DevScreens.cpp index 90a0377514..e0e45a7425 100644 --- a/UI/DevScreens.cpp +++ b/UI/DevScreens.cpp @@ -82,6 +82,7 @@ #include "UI/ControlMappingScreen.h" #include "UI/GameSettingsScreen.h" #include "UI/JitCompareScreen.h" +#include "UI/ShareFiles.h" #include "android/jni/app-android.h" @@ -121,17 +122,44 @@ void AddOverlayList(UI::ViewGroup *items, ScreenManager *screenManager) { } } +// Zipped, so apps that only take known file types accept it. The zip import recognizes it too. +static void ShareFrameDump(const Path &dumpPath) { + std::string name = dumpPath.GetFilename(); + if (endsWithNoCase(name, ".ppdmp")) { + name.resize(name.size() - strlen(".ppdmp")); + } + if (!ShareFilesAsZip(name, { { dumpPath, "" } })) { + auto sy = GetI18NCategory(I18NCat::SYSTEM); + g_OSD.Show(OSDType::MESSAGE_ERROR, sy->T("Failed")); + } +} + +void OnFrameDumpCreated(const Path &dumpPath, bool openNow) { + NOTICE_LOG(Log::System, "Frame dump created at '%s'", dumpPath.c_str()); + std::function open; + if (System_GetPropertyBool(SYSPROP_CAN_SHOW_FILE)) { + open = [dumpPath]() { System_ShowFileInFolder(dumpPath); }; + } else if (CanShareFiles()) { + open = [dumpPath]() { ShareFrameDump(dumpPath); }; + } + g_OSD.Show(OSDType::MESSAGE_SUCCESS, GetFriendlyPath(dumpPath), 7.0f, "framedump"); + if (!open) { + return; + } + if (openNow) { + // The recorder calls back on the emulation thread. + System_RunOnMainThread(open); + } else { + g_OSD.SetClickCallback("framedump", open); + } +} + void SaveFrameDump() { if (!gpu) { return; } gpu->GetRecorder()->RecordNextFrame([](const Path &dumpPath) { - NOTICE_LOG(Log::System, "Frame dump created at '%s'", dumpPath.c_str()); - if (System_GetPropertyBool(SYSPROP_CAN_SHOW_FILE)) { - System_ShowFileInFolder(dumpPath); - } else { - g_OSD.Show(OSDType::MESSAGE_SUCCESS, GetFriendlyPath(dumpPath), 7.0f); - } + OnFrameDumpCreated(dumpPath, true); }); } diff --git a/UI/DevScreens.h b/UI/DevScreens.h index fc4f2fae61..9240e12c04 100644 --- a/UI/DevScreens.h +++ b/UI/DevScreens.h @@ -213,3 +213,7 @@ public: void DrawProfile(UIContext &ui); void AddOverlayList(UI::ViewGroup *items, ScreenManager *screenManager); + +// Tells the user where the dump went. With openNow, shows it in its folder (or shares it, where +// folders can't be shown) right away, otherwise when the message is clicked. Callable from any thread. +void OnFrameDumpCreated(const Path &dumpPath, bool openNow); diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index 075d1bdfd1..35c0368260 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -771,14 +771,9 @@ void EmuScreen::ProcessVKey(VirtKey virtKey, bool down) { if (!gpu) { return; } + // Not opened right away, which would interrupt the game. gpu->GetRecorder()->RecordNextFrame([](const Path &dumpPath) { - NOTICE_LOG(Log::System, "Frame dump created at '%s'", dumpPath.c_str()); - g_OSD.Show(OSDType::MESSAGE_SUCCESS, GetFriendlyPath(dumpPath), 7.0f, "framedump"); - if (System_GetPropertyBool(SYSPROP_CAN_SHOW_FILE)) { - g_OSD.SetClickCallback("framedump", [dumpPath]() { - System_ShowFileInFolder(dumpPath); - }); - } + OnFrameDumpCreated(dumpPath, false); }); } break;