diff --git a/Source/Core/Core/HLE/HLE.cpp b/Source/Core/Core/HLE/HLE.cpp index c03fa54398..cc166768da 100644 --- a/Source/Core/Core/HLE/HLE.cpp +++ b/Source/Core/Core/HLE/HLE.cpp @@ -64,6 +64,8 @@ static const SPatch OSPatches[] = { {"printf", HLE_OS::HLE_GeneralDebugPrint, HLE_HOOK_START, HLE_TYPE_DEBUG}, {"vdprintf", HLE_OS::HLE_LogVDPrint, HLE_HOOK_START, HLE_TYPE_DEBUG}, {"dprintf", HLE_OS::HLE_LogDPrint, HLE_HOOK_START, HLE_TYPE_DEBUG}, + {"vfprintf", HLE_OS::HLE_LogVFPrint, HLE_HOOK_START, HLE_TYPE_DEBUG}, + {"fprintf", HLE_OS::HLE_LogFPrint, HLE_HOOK_START, HLE_TYPE_DEBUG}, {"nlPrintf", HLE_OS::HLE_GeneralDebugPrint, HLE_HOOK_START, HLE_TYPE_DEBUG}, {"puts", HLE_OS::HLE_GeneralDebugPrint, HLE_HOOK_START, HLE_TYPE_DEBUG}, // gcc-optimized printf? {"___blank", HLE_OS::HLE_GeneralDebugPrint, HLE_HOOK_START, HLE_TYPE_DEBUG}, // used for early init things (normally) diff --git a/Source/Core/Core/HLE/HLE_OS.cpp b/Source/Core/Core/HLE/HLE_OS.cpp index 74d2a8ec4f..bcdc9d67d5 100644 --- a/Source/Core/Core/HLE/HLE_OS.cpp +++ b/Source/Core/Core/HLE/HLE_OS.cpp @@ -136,6 +136,45 @@ void HLE_LogVDPrint() HLE_LogDPrint(ParameterType::VariableArgumentList); } +// Log (v)fprintf message if FILE is stdout or stderr +void HLE_LogFPrint(ParameterType parameter_type) +{ + NPC = LR; + + // The structure FILE is implementation defined. + // Both libogc and Dolphin SDK seem to store the fd at the same address. + int fd = -1; + if (PowerPC::HostIsRAMAddress(GPR(3)) && PowerPC::HostIsRAMAddress(GPR(3) + 0xF)) + { + // The fd is stored as a short at FILE+0xE. + fd = static_cast(PowerPC::HostRead_U16(GPR(3) + 0xE)); + } + if (fd != 1 && fd != 2) + { + // On RVL SDK it seems stored at FILE+0x2. + fd = static_cast(PowerPC::HostRead_U16(GPR(3) + 0x2)); + } + if (fd != 1 && fd != 2) + return; + + std::string report_message = GetStringVA(4, parameter_type); + NOTICE_LOG(OSREPORT, "%08x->%08x| %s", LR, PC, SHIFTJISToUTF8(report_message).c_str()); +} + +// Log fprintf message +// -> int fprintf(FILE* stream, const char* format, ...); +void HLE_LogFPrint() +{ + HLE_LogFPrint(ParameterType::ParameterList); +} + +// Log vfprintf message +// -> int vfprintf(FILE* stream, const char* format, va_list ap); +void HLE_LogVFPrint() +{ + HLE_LogFPrint(ParameterType::VariableArgumentList); +} + std::string GetStringVA(u32 str_reg, ParameterType parameter_type) { std::string ArgumentBuffer; diff --git a/Source/Core/Core/HLE/HLE_OS.h b/Source/Core/Core/HLE/HLE_OS.h index 55f3687eb2..af3abb3139 100644 --- a/Source/Core/Core/HLE/HLE_OS.h +++ b/Source/Core/Core/HLE/HLE_OS.h @@ -12,4 +12,6 @@ void HLE_write_console(); void HLE_OSPanic(); void HLE_LogDPrint(); void HLE_LogVDPrint(); +void HLE_LogFPrint(); +void HLE_LogVFPrint(); }