diff --git a/Common/System/Request.h b/Common/System/Request.h index 173da797fb..3f7d1c0bc1 100644 --- a/Common/System/Request.h +++ b/Common/System/Request.h @@ -142,6 +142,14 @@ inline void System_SetWindowTitle(const std::string ¶m) { g_requestManager.MakeSystemRequest(SystemRequestType::SET_WINDOW_TITLE, nullptr, nullptr, param, "", 0); } +inline void System_SendDebugOutput(const std::string &string) { + g_requestManager.MakeSystemRequest(SystemRequestType::SEND_DEBUG_OUTPUT, nullptr, nullptr, string, "", 0); +} + +inline void System_SendDebugScreenshot(const std::string &data, int height) { + g_requestManager.MakeSystemRequest(SystemRequestType::SEND_DEBUG_SCREENSHOT, nullptr, nullptr, data, "", height); +} + // Non-inline to avoid including Path.h void System_CreateGameShortcut(const Path &path, const std::string &title); diff --git a/Common/System/System.h b/Common/System/System.h index 8148d099e7..8deb078966 100644 --- a/Common/System/System.h +++ b/Common/System/System.h @@ -70,6 +70,11 @@ enum class SystemRequestType { GRAPHICS_BACKEND_FAILED_ALERT, CREATE_GAME_SHORTCUT, + // Commonly ignored, used when automated tests generate output. + SEND_DEBUG_OUTPUT, + // Note: height specified as param3, width based on param1.size() / param3. + SEND_DEBUG_SCREENSHOT, + NOTIFY_UI_STATE, // Used on Android only. Not a SystemNotification since it takes a parameter. // High-level hardware control diff --git a/Core/HLE/sceIo.cpp b/Core/HLE/sceIo.cpp index e02f9e1620..55766694f0 100644 --- a/Core/HLE/sceIo.cpp +++ b/Core/HLE/sceIo.cpp @@ -29,6 +29,7 @@ #include "Common/Serialize/SerializeMap.h" #include "Common/Serialize/SerializeSet.h" #include "Common/StringUtils.h" +#include "Common/System/Request.h" #include "Core/Core.h" #include "Core/Config.h" #include "Core/ConfigValues.h" @@ -37,7 +38,6 @@ #include "Core/MemMapHelpers.h" #include "Core/System.h" #include "Core/HDRemaster.h" -#include "Core/Host.h" #include "Core/SaveState.h" #include "Core/HLE/HLE.h" #include "Core/HLE/HLEHelperThread.h" @@ -2012,8 +2012,8 @@ static u32 sceIoDevctl(const char *name, int cmd, u32 argAddr, int argLen, u32 o case EMULATOR_DEVCTL__SEND_OUTPUT: { std::string data(Memory::GetCharPointer(argAddr), argLen); - if (PSP_CoreParameter().printfEmuLog && host) { - host->SendDebugOutput(data); + if (PSP_CoreParameter().printfEmuLog) { + System_SendDebugOutput(data); } else { if (PSP_CoreParameter().collectEmuLog) { *PSP_CoreParameter().collectEmuLog += data; @@ -2040,9 +2040,7 @@ static u32 sceIoDevctl(const char *name, int cmd, u32 argAddr, int argLen, u32 o __DisplayGetFramebuf(&topaddr, &linesize, nullptr, 0); // TODO: Convert based on pixel format / mode / something? - if (host) { - host->SendDebugScreenshot(topaddr, linesize, 272); - } + System_SendDebugScreenshot(std::string((const char *)&topaddr[0], linesize * 272), 272); return 0; } case EMULATOR_DEVCTL__TOGGLE_FASTFORWARD: diff --git a/Core/HLE/sceKernelModule.cpp b/Core/HLE/sceKernelModule.cpp index 4d2d5a61ba..92db2b4efe 100644 --- a/Core/HLE/sceKernelModule.cpp +++ b/Core/HLE/sceKernelModule.cpp @@ -26,6 +26,7 @@ #include "Common/Serialize/SerializeSet.h" #include "Common/File/FileUtil.h" #include "Common/StringUtils.h" +#include "Common/System/Request.h" #include "Common/System/System.h" #include "Core/Config.h" @@ -37,7 +38,6 @@ #include "Core/HLE/ReplaceTables.h" #include "Core/HLE/sceDisplay.h" #include "Core/Reporting.h" -#include "Core/Host.h" #include "Core/Loaders.h" #include "Core/MIPS/MIPS.h" #include "Core/MIPS/MIPSAnalyst.h" @@ -1934,9 +1934,7 @@ void __KernelGPUReplay() { PSPPointer topaddr; u32 linesize = 512; __DisplayGetFramebuf(&topaddr, &linesize, nullptr, 0); - if (host) { - host->SendDebugScreenshot(topaddr, linesize, 272); - } + System_SendDebugScreenshot(std::string((const char *)&topaddr[0], linesize * 272), 272); Core_Stop(); } } diff --git a/headless/Headless.cpp b/headless/Headless.cpp index 12dbb9c456..990417f97b 100644 --- a/headless/Headless.cpp +++ b/headless/Headless.cpp @@ -14,6 +14,7 @@ #include "Common/Profiler/Profiler.h" #include "Common/System/NativeApp.h" +#include "Common/System/Request.h" #include "Common/System/System.h" #include "Common/CommonWindows.h" @@ -117,7 +118,17 @@ bool System_GetPropertyBool(SystemProperty prop) { void System_Notify(SystemNotification notification) {} void System_PostUIMessage(const std::string &message, const std::string ¶m) {} void System_NotifyUserMessage(const std::string &message, float duration, u32 color, const char *id) {} -bool System_MakeRequest(SystemRequestType type, int requestId, const std::string ¶m1, const std::string ¶m2, int param3) { return false; } +bool System_MakeRequest(SystemRequestType type, int requestId, const std::string ¶m1, const std::string ¶m2, int param3) { + switch (type) { + case SystemRequestType::SEND_DEBUG_OUTPUT: + host->SendDebugOutput(param1); + return true; + case SystemRequestType::SEND_DEBUG_SCREENSHOT: + host->SendDebugScreenshot((const u8 *)param1.data(), (uint32_t)(param1.size() / param3), param3); + return true; + } + return false; +} void System_InputBoxGetString(const std::string &title, const std::string &defaultValue, std::function cb) { cb(false, ""); } void System_AskForPermission(SystemPermission permission) {} PermissionStatus System_GetPermissionStatus(SystemPermission permission) { return PERMISSION_STATUS_GRANTED; } @@ -238,7 +249,7 @@ bool RunAutoTest(HeadlessHost *headlessHost, CoreParameter &coreParameter, const if (!opt.bench) { printf("%s", output.c_str()); - host->SendDebugOutput("TIMEOUT\n"); + System_SendDebugOutput("TIMEOUT\n"); TeamCityPrint("testFailed name='%s' message='Test timeout'", currentTestName.c_str()); GitHubActionsPrint("error", "Test timeout for %s", currentTestName.c_str()); }