Flip around so sceDelayResult is always outermost. Start using HLECall.

This commit is contained in:
Henrik Rydgård 2025-01-19 21:46:14 +01:00
parent 86fcdeeb25
commit 2523690584
20 changed files with 232 additions and 289 deletions

View file

@ -23,6 +23,7 @@
#include "Core/Config.h"
#include "Core/MemMapHelpers.h"
#include "Core/Util/PPGeDraw.h"
#include "Core/HLE/HLE.h"
#include "Core/HLE/sceKernelMemory.h"
#include "Core/HLE/sceCtrl.h"
#include "Core/HLE/sceUtility.h"
@ -176,7 +177,8 @@ int PSPNetconfDialog::Update(int animSpeed) {
else if (state == PSP_NET_APCTL_STATE_DISCONNECTED) {
// When connecting with infrastructure, simulate a connection using the first network configuration entry.
if (connResult < 0) {
connResult = sceNetApctlConnect(1);
// connResult = sceNetApctlConnect(1);
connResult = hleCall(sceNetApctl, int, sceNetApctlConnect, 1);
}
}
}

View file

@ -6,8 +6,8 @@
#include "Core/HW/Atrac3Standalone.h"
// Convenient command line:
// Windows\x64\debug\PPSSPPHeadless.exe --root pspautotests/tests/../ --compare --timeout=5 --new-atrac --graphics=software pspautotests/tests/audio/atrac/decode.prx
// Windows\x64\debug\PPSSPPHeadless.exe --root pspautotests/tests/../ -o --compare --timeout=30 --graphics=software pspautotests/tests/audio/atrac/... --ignore pspautotests/tests/audio/atrac/second/resetting.prx --ignore pspautotests/tests/audio/atrac/second/replay.prx
//
// See the big comment in sceAtrac.cpp for an overview of the different modes of operation.
//
// Test cases

View file

@ -408,9 +408,9 @@ static bool hleExecuteDebugBreak(const HLEFunction *func) {
return true;
}
// Should be used *outside* hleLogError for example. Not the other way around.
u32 hleDelayResult(u32 result, const char *reason, int usec) {
_dbg_assert_(g_stackSize > 0);
_dbg_assert_(g_stackSize == 1);
_dbg_assert_(g_stackSize == 0);
if (!__KernelIsDispatchEnabled()) {
WARN_LOG(Log::HLE, "%s: Dispatch disabled, not delaying HLE result (right thing to do?)", g_stackSize ? g_stack[0]->name : "?");
@ -425,16 +425,16 @@ u32 hleDelayResult(u32 result, const char *reason, int usec) {
}
u64 hleDelayResult(u64 result, const char *reason, int usec) {
_dbg_assert_(g_stackSize > 0);
_dbg_assert_(g_stackSize == 1);
// Note: hleDelayResult is called at the outer level, *outside* logging.
// So, we read from the entry that was just popped. This is OK.
_dbg_assert_(g_stackSize == 0);
if (!__KernelIsDispatchEnabled()) {
WARN_LOG(Log::HLE, "%s: Dispatch disabled, not delaying HLE result (right thing to do?)", g_stackSize ? g_stack[0]->name : "?");
WARN_LOG(Log::HLE, "%s: Dispatch disabled, not delaying HLE result (right thing to do?)", g_stack[0]->name);
} else {
// TODO: Defer this, so you can call this multiple times, in case of syscalls calling syscalls? Although, return values are tricky.
SceUID thread = __KernelGetCurThread();
if (KernelIsThreadWaiting(thread))
ERROR_LOG(Log::HLE, "%s: Delaying a thread that's already waiting", g_stackSize ? g_stack[0]->name : "?");
ERROR_LOG(Log::HLE, "%s: Delaying a thread that's already waiting", g_stack[0]->name);
u64 param = (result & 0xFFFFFFFF00000000) | thread;
CoreTiming::ScheduleEvent(usToCycles(usec), delayedResultEvent, param);
__KernelWaitCurThread(WAITTYPE_HLEDELAY, 1, (u32)result, 0, false, reason);
@ -841,6 +841,16 @@ void CallSyscall(MIPSOpcode op) {
}
}
void hlePushFuncDesc(std::string_view module, std::string_view funcName) {
const HLEModule *mod = GetModuleByName(module);
if (!mod) {
return;
}
const HLEFunction *func = GetFuncByName(mod, funcName);
// Push to the stack.
g_stack[g_stackSize++] = func;
}
// TODO: Also add support for argument names.
size_t hleFormatLogArgs(char *message, size_t sz, const char *argmask) {
char *p = message;

View file

@ -247,6 +247,18 @@ inline void hleNoLogVoid() {
hleLeave();
}
// TODO: See if we can search the tables with constexpr tricks!
void hlePushFuncDesc(std::string_view module, std::string_view funcName);
// Calls a syscall from another syscall, managing the logging stack.
template<class R, class F, typename... Args>
inline R hleCallImpl(std::string_view module, std::string_view funcName, F func, Args... args) {
hlePushFuncDesc(module, funcName);
return func(args...);
}
#define hleCall(module, retType, funcName, ...) hleCallImpl<retType>(#module, #funcName, funcName, __VA_ARGS__)
// This is just a quick way to force logging to be more visible for one file.
#ifdef HLE_LOG_FORCE
#define HLE_LOG_LDEBUG LNOTICE

View file

@ -279,16 +279,16 @@ static u32 sceAtracDecodeData(int atracID, u32 outAddr, u32 numSamplesAddr, u32
numSamplesAddr, numSamples,
finishFlagAddr, finish,
remainAddr, remains);
if (!ret) {
if (ret == 0) {
// decode data successfully, delay thread
return hleDelayResult(ret, "atrac decode data", atracDecodeDelay);
return hleDelayResult(hleNoLog(ret), "atrac decode data", atracDecodeDelay);
}
return ret;
return hleNoLog(ret);
}
static u32 sceAtracEndEntry() {
ERROR_LOG_REPORT(Log::ME, "UNIMPL sceAtracEndEntry()");
return 0;
return hleNoLog(0);
}
// Obtains information about what needs to be in the buffer to seek (or "reset")
@ -571,11 +571,13 @@ static u32 sceAtracResetPlayPosition(int atracID, int sample, int bytesWrittenFi
return hleDelayResult(hleLogSuccessInfoI(Log::ME, 0), "reset play pos", 3000);
}
// Allowed to log like a HLE function, only called at the end of some.
static int _AtracSetData(int atracID, u32 buffer, u32 readSize, u32 bufferSize, int outputChannels, bool needReturnAtracID) {
AtracBase *atrac = getAtrac(atracID);
// Don't use AtracValidateManaged here.
if (!atrac)
return hleLogError(Log::ME, ATRAC_ERROR_BAD_ATRACID, "invalid atrac ID");
// SetData logs like a hle function.
int ret = atrac->SetData(buffer, readSize, bufferSize, outputChannels, needReturnAtracID ? atracID : 0);
// not sure the real delay time
return hleDelayResult(ret, "atrac set data", 100);
@ -714,9 +716,8 @@ static int sceAtracReinit(int at3Count, int at3plusCount) {
// This seems to deinit things. Mostly, it cause a reschedule on next deinit (but -1, -1 does not.)
if (at3Count == 0 && at3plusCount == 0) {
INFO_LOG(Log::ME, "sceAtracReinit(%d, %d): deinit", at3Count, at3plusCount);
atracInited = false;
return hleDelayResult(0, "atrac reinit", 200);
return hleDelayResult(hleLogSuccessInfoI(Log::ME, 0, "deinit"), "atrac reinit", 200);
}
// First, ATRAC3+. These IDs seem to cost double (probably memory.)
@ -982,7 +983,7 @@ static int sceAtracLowLevelDecode(int atracID, u32 sourceAddr, u32 sourceBytesCo
*outWritten = bytesWritten;
NotifyMemInfo(MemBlockFlags::WRITE, samplesAddr, bytesWritten, "AtracLowLevelDecode");
return hleLogDebug(Log::ME, hleDelayResult(0, "low level atrac decode data", atracDecodeDelay));
return hleDelayResult(hleLogDebug(Log::ME, 0), "low level atrac decode data", atracDecodeDelay);
}
static int sceAtracSetAA3HalfwayBufferAndGetID(u32 buffer, u32 readSize, u32 bufferSize, u32 fileSize) {

View file

@ -65,9 +65,10 @@ static int __DmacMemcpy(u32 dst, u32 src, u32 size) {
// Approx. 225 MiB/s or 235929600 B/s, so let's go with 236 B/us.
int delayUs = size / 236;
dmacMemcpyDeadline = CoreTiming::GetTicks() + usToCycles(delayUs);
return hleDelayResult(0, "dmac copy", delayUs);
return delayUs;
} else {
return 0;
}
return 0;
}
static u32 sceDmacMemcpy(u32 dst, u32 src, u32 size) {
@ -88,7 +89,9 @@ static u32 sceDmacMemcpy(u32 dst, u32 src, u32 size) {
// Might matter for overlapping copies.
}
return hleLogDebug(Log::HLE, __DmacMemcpy(dst, src, size));
int delay = __DmacMemcpy(dst, src, size);
int result = hleLogDebug(Log::HLE, 0);
return delay ? hleDelayResult(result, "dmac-memcpy", delay) : delay;
}
static u32 sceDmacTryMemcpy(u32 dst, u32 src, u32 size) {
@ -106,7 +109,9 @@ static u32 sceDmacTryMemcpy(u32 dst, u32 src, u32 size) {
return hleLogDebug(Log::HLE, SCE_KERNEL_ERROR_BUSY, "busy");
}
return hleLogDebug(Log::HLE, __DmacMemcpy(dst, src, size));
int delay = __DmacMemcpy(dst, src, size);
int result = hleLogDebug(Log::HLE, 0);
return delay ? hleDelayResult(result, "dmac-memcpy", delay) : delay;
}
const HLEFunction sceDmac[] = {

View file

@ -1026,15 +1026,15 @@ static u32 sceFontNewLib(u32 paramPtr, u32 errorCodePtr) {
if (!params.IsValid() || !errorCode.IsValid()) {
ERROR_LOG_REPORT(Log::sceFont, "sceFontNewLib(%08x, %08x): invalid addresses", paramPtr, errorCodePtr);
// The PSP would crash in this situation, not a real error code.
return SCE_KERNEL_ERROR_ILLEGAL_ADDR;
return hleLogError(Log::sceFont, SCE_KERNEL_ERROR_ILLEGAL_ADDR);
}
if (!Memory::IsValidAddress(params->allocFuncAddr) || !Memory::IsValidAddress(params->freeFuncAddr)) {
ERROR_LOG_REPORT(Log::sceFont, "sceFontNewLib(%08x, %08x): missing alloc func", paramPtr, errorCodePtr);
*errorCode = ERROR_FONT_INVALID_PARAMETER;
return 0;
return hleLogError(Log::sceFont, 0);
}
INFO_LOG(Log::sceFont, "sceFontNewLib(%08x, %08x)", paramPtr, errorCodePtr);
*errorCode = 0;
FontLib *newLib = new FontLib(params, errorCodePtr);
@ -1042,7 +1042,7 @@ static u32 sceFontNewLib(u32 paramPtr, u32 errorCodePtr) {
// The game should never see this value, the return value is replaced
// by the action. Except if we disable the alloc, in this case we return
// the handle correctly here.
return hleDelayResult(newLib->handle(), "new fontlib", 30000);
return hleDelayResult(hleLogSuccessInfoI(Log::sceFont, newLib->handle()), "new fontlib", 30000);
}
static int sceFontDoneLib(u32 fontLibHandle) {
@ -1066,11 +1066,11 @@ static u32 sceFontOpen(u32 libHandle, u32 index, u32 mode, u32 errorCodePtr) {
FontLib *fontLib = GetFontLib(libHandle);
if (!fontLib) {
*errorCode = ERROR_FONT_INVALID_LIBID;
return hleLogDebug(Log::sceFont, 0, "invalid font lib");
return hleLogWarning(Log::sceFont, 0, "invalid font lib");
}
if (index >= internalFonts.size()) {
*errorCode = ERROR_FONT_INVALID_PARAMETER;
return hleLogDebug(Log::sceFont, 0, "invalid font index");
return hleLogWarning(Log::sceFont, 0, "invalid font index");
}
FontOpenMode openMode = mode != 1 ? FONT_OPEN_INTERNAL_STINGY : FONT_OPEN_INTERNAL_FULL;
@ -1121,7 +1121,7 @@ static u32 sceFontOpenUserMemory(u32 libHandle, u32 memoryFontPtr, u32 memoryFon
return hleLogSuccessX(Log::sceFont, font->Handle());
}
delete f;
return 0;
return hleNoLog(0);
}
// Open a user font in a file into a FontLib

View file

@ -490,15 +490,17 @@ static u32 sceGeSetCallback(u32 structAddr) {
int subIntrBase = __GeSubIntrBase(cbID);
// TODO: Maybe don't ignore return values of the hleCalls?
if (ge_callback_data[cbID].finish_func != 0) {
sceKernelRegisterSubIntrHandler(PSP_GE_INTR, subIntrBase | PSP_GE_SUBINTR_FINISH,
hleCall(InterruptManager, u32, sceKernelRegisterSubIntrHandler, PSP_GE_INTR, subIntrBase | PSP_GE_SUBINTR_FINISH,
ge_callback_data[cbID].finish_func, ge_callback_data[cbID].finish_arg);
sceKernelEnableSubIntr(PSP_GE_INTR, subIntrBase | PSP_GE_SUBINTR_FINISH);
hleCall(InterruptManager, u32, sceKernelEnableSubIntr, PSP_GE_INTR, subIntrBase | PSP_GE_SUBINTR_FINISH);
}
if (ge_callback_data[cbID].signal_func != 0) {
sceKernelRegisterSubIntrHandler(PSP_GE_INTR, subIntrBase | PSP_GE_SUBINTR_SIGNAL,
hleCall(InterruptManager, u32, sceKernelRegisterSubIntrHandler, PSP_GE_INTR, subIntrBase | PSP_GE_SUBINTR_SIGNAL,
ge_callback_data[cbID].signal_func, ge_callback_data[cbID].signal_arg);
sceKernelEnableSubIntr(PSP_GE_INTR, subIntrBase | PSP_GE_SUBINTR_SIGNAL);
hleCall(InterruptManager, u32, sceKernelEnableSubIntr, PSP_GE_INTR, subIntrBase | PSP_GE_SUBINTR_SIGNAL);
}
return hleLogSuccessI(Log::sceGe, cbID);
@ -515,8 +517,9 @@ static int sceGeUnsetCallback(u32 cbID) {
if (ge_used_callbacks[cbID]) {
int subIntrBase = __GeSubIntrBase(cbID);
sceKernelReleaseSubIntrHandler(PSP_GE_INTR, subIntrBase | PSP_GE_SUBINTR_FINISH);
sceKernelReleaseSubIntrHandler(PSP_GE_INTR, subIntrBase | PSP_GE_SUBINTR_SIGNAL);
// TODO: Maybe don't ignore return values?
hleCall(InterruptManager, u32, sceKernelReleaseSubIntrHandler, PSP_GE_INTR, subIntrBase | PSP_GE_SUBINTR_FINISH);
hleCall(InterruptManager, u32, sceKernelReleaseSubIntrHandler, PSP_GE_INTR, subIntrBase | PSP_GE_SUBINTR_SIGNAL);
} else {
WARN_LOG(Log::sceGe, "sceGeUnsetCallback(cbid=%08x): ignoring unregistered callback id", cbID);
}

View file

@ -972,15 +972,12 @@ static u32 sceIoGetstat(const char *filename, u32 addr) {
if (stat.IsValid()) {
__IoGetStat(stat, info);
stat.NotifyWrite("IoGetstat");
DEBUG_LOG(Log::sceIo, "sceIoGetstat(%s, %08x) : sector = %08x", filename, addr, info.startSector);
return hleDelayResult(0, "io getstat", usec);
return hleDelayResult(hleLogDebug(Log::sceIo, 0, "sector = %08x", info.startSector), "io getstat", usec);
} else {
ERROR_LOG(Log::sceIo, "sceIoGetstat(%s, %08x) : bad address", filename, addr);
return hleDelayResult(-1, "io getstat", usec);
return hleDelayResult(hleLogError(Log::sceIo, -1, "bad address"), "io getstat", usec);
}
} else {
DEBUG_LOG(Log::sceIo, "sceIoGetstat(%s, %08x) : FILE NOT FOUND", filename, addr);
return hleDelayResult(SCE_KERNEL_ERROR_ERRNO_FILE_NOT_FOUND, "io getstat", usec);
return hleDelayResult(hleLogError(Log::sceIo, SCE_KERNEL_ERROR_ERRNO_FILE_NOT_FOUND, "FILE NOT FOUND"), "io getstat", usec);
}
}
@ -1158,11 +1155,9 @@ static u32 sceIoRead(int id, u32 data_addr, int size) {
f->waitingSyncThreads.push_back(__KernelGetCurThread());
return 0;
} else if (result >= 0) {
DEBUG_LOG(Log::sceIo, "%x=sceIoRead(%d, %08x, %x)", result, id, data_addr, size);
return hleDelayResult(result, "io read", us);
return hleDelayResult(hleLogDebug(Log::ME, result), "io read", us);
} else {
WARN_LOG(Log::sceIo, "sceIoRead(%d, %08x, %x): error %08x", id, data_addr, size, result);
return result;
return hleLogWarning(Log::ME, result, "error %08x", result);
}
}
@ -1286,20 +1281,18 @@ static u32 sceIoWrite(int id, u32 data_addr, int size) {
f->waitingSyncThreads.push_back(__KernelGetCurThread());
return 0;
} else if (result >= 0) {
DEBUG_LOG(Log::sceIo, "%x=sceIoWrite(%d, %08x, %x)", result, id, data_addr, size);
if (__KernelIsDispatchEnabled()) {
// If we wrote to stdout, return an error (even though we did log it) rather than delaying.
// On actual hardware, it would just return this... we just want the log output.
if (__IsInInterrupt()) {
return SCE_KERNEL_ERROR_ILLEGAL_CONTEXT;
}
return hleDelayResult(result, "io write", us);
return hleDelayResult(hleLogDebug(Log::sceIo, result), "io write", us);
} else {
return result;
return hleLogDebug(Log::sceIo, result);
}
} else {
WARN_LOG(Log::sceIo, "sceIoWrite(%d, %08x, %x): error %08x", id, data_addr, size, result);
return result;
return hleLogWarning(Log::sceIo, result, "%08x", result);
}
}
@ -1583,7 +1576,7 @@ static u32 sceIoOpen(const char *filename, int flags, int mode) {
_assert_(error != 0);
if (error == (int)SCE_KERNEL_ERROR_NOCWD) {
// TODO: Timing is not accurate.
return hleLogError(Log::sceIo, hleDelayResult(error, "file opened", 10000), "no current working directory");
return hleDelayResult(hleLogError(Log::sceIo, error, "no current working directory"), "file opened", 10000);
} else if (error == (int)SCE_KERNEL_ERROR_NODEV) {
return hleLogError(Log::sceIo, error, "device not found");
} else if (error == (int)SCE_KERNEL_ERROR_ERRNO_FILE_NOT_FOUND) {
@ -1592,16 +1585,16 @@ static u32 sceIoOpen(const char *filename, int flags, int mode) {
// Card: Path depth matters, but typically between 10-13ms on a standard Pro Duo.
// TODO: If a UMD and spun down, this can easily take 1s+.
int delay = pspFileSystem.FlagsFromFilename(filename) & FileSystemFlags::UMD ? 6000 : 10000;
return hleLogWarning(Log::sceIo, hleDelayResult(error, "file opened", delay), "file not found");
return hleDelayResult(hleLogWarning(Log::sceIo, error, "file not found"), "file opened", delay);
} else {
return hleLogError(Log::sceIo, hleDelayResult(error, "file opened", 10000));
return hleDelayResult(hleLogError(Log::sceIo, error), "file opened", 10000);
}
}
int id = __IoAllocFd(f);
if (id < 0) {
kernelObjects.Destroy<FileNode>(f->GetUID());
return hleLogError(Log::sceIo, hleDelayResult(id, "file opened", 1000), "out of fds");
return hleDelayResult(hleLogError(Log::sceIo, id, "out of fds"), "file opened", 1000);
} else {
asyncParams[id].priority = asyncDefaultPriority;
IFileSystem *sys = pspFileSystem.GetSystemFromFilename(filename);
@ -1612,16 +1605,15 @@ static u32 sceIoOpen(const char *filename, int flags, int mode) {
// UMD: Speed varies from 1-6ms.
// Card: Path depth matters, but typically between 10-13ms on a standard Pro Duo.
int delay = pspFileSystem.FlagsFromFilename(filename) & FileSystemFlags::UMD ? 4000 : 10000;
return hleLogSuccessI(Log::sceIo, hleDelayResult(id, "file opened", delay));
return hleDelayResult(hleLogSuccessI(Log::sceIo, id), "file opened", delay);
}
}
static u32 sceIoClose(int id) {
u32 error;
DEBUG_LOG(Log::sceIo, "sceIoClose(%d)", id);
__IoFreeFd(id, error);
// Timing is not accurate, aiming low for now.
return hleDelayResult(error, "file closed", 100);
return hleDelayResult(hleLogDebug(Log::sceIo, error), "file closed", 100);
}
static u32 sceIoRemove(const char *filename) {
@ -1673,7 +1665,7 @@ static u32 sceIoDevctl(const char *name, int cmd, u32 argAddr, int argLen, u32 o
// Get UMD disc type
if (Memory::IsValidAddress(outPtr) && outLen >= 8) {
Memory::Write_U32(0x10, outPtr + 4); // Always return game disc (if present)
return 0;
return hleLogDebug(Log::sceIo, 0);
} else {
return hleLogError(Log::sceIo, ERROR_MEMSTICK_DEVCTL_BAD_PARAMS);
}
@ -1682,7 +1674,7 @@ static u32 sceIoDevctl(const char *name, int cmd, u32 argAddr, int argLen, u32 o
// Get UMD current LBA
if (Memory::IsValidAddress(outPtr) && outLen >= 4) {
Memory::Write_U32(0x10, outPtr); // Assume first sector
return 0;
return hleLogDebug(Log::sceIo, 0);
} else {
return hleLogError(Log::sceIo, ERROR_MEMSTICK_DEVCTL_BAD_PARAMS);
}
@ -1691,7 +1683,7 @@ static u32 sceIoDevctl(const char *name, int cmd, u32 argAddr, int argLen, u32 o
if (Memory::IsValidAddress(argAddr) && argLen >= 4) {
PSPFileInfo info = pspFileSystem.GetFileInfo("umd1:");
Memory::Write_U32((u32) (info.size) - 1, outPtr);
return 0;
return hleLogDebug(Log::sceIo, 0);
} else {
return hleLogError(Log::sceIo, ERROR_MEMSTICK_DEVCTL_BAD_PARAMS);
}
@ -1699,7 +1691,7 @@ static u32 sceIoDevctl(const char *name, int cmd, u32 argAddr, int argLen, u32 o
case 0x01F100A3:
// Seek UMD disc (raw)
if (Memory::IsValidAddress(argAddr) && argLen >= 4) {
return hleDelayResult(0, "dev seek", 100);
return hleDelayResult(hleLogDebug(Log::sceIo, 0), "dev seek", 100);
} else {
return hleLogError(Log::sceIo, ERROR_MEMSTICK_DEVCTL_BAD_PARAMS);
}
@ -1707,7 +1699,7 @@ static u32 sceIoDevctl(const char *name, int cmd, u32 argAddr, int argLen, u32 o
case 0x01F100A4:
// Prepare UMD data into cache.
if (Memory::IsValidAddress(argAddr) && argLen >= 4) {
return 0;
return hleLogDebug(Log::sceIo, 0);
} else {
return hleLogError(Log::sceIo, ERROR_MEMSTICK_DEVCTL_BAD_PARAMS);
}
@ -1716,7 +1708,7 @@ static u32 sceIoDevctl(const char *name, int cmd, u32 argAddr, int argLen, u32 o
// Prepare UMD data into cache and get status
if (Memory::IsValidAddress(argAddr) && argLen >= 4) {
Memory::Write_U32(1, outPtr); // Status (unitary index of the requested read, greater or equal to 1)
return 0;
return hleLogDebug(Log::sceIo, 0);
} else {
return hleLogError(Log::sceIo, ERROR_MEMSTICK_DEVCTL_BAD_PARAMS);
}
@ -1726,7 +1718,7 @@ static u32 sceIoDevctl(const char *name, int cmd, u32 argAddr, int argLen, u32 o
if (Memory::IsValidAddress(argAddr) && argLen >= 4) {
// TODO :
// Place the calling thread in wait state
return 0;
return hleLogDebug(Log::sceIo, 0);
} else {
return hleLogError(Log::sceIo, ERROR_MEMSTICK_DEVCTL_BAD_PARAMS);
}
@ -1737,7 +1729,7 @@ static u32 sceIoDevctl(const char *name, int cmd, u32 argAddr, int argLen, u32 o
// 0 - UMD data cache thread has finished
// 0x10 - UMD data cache thread is waiting
// 0x20 - UMD data cache thread is running
return 0; // Return finished
return hleLogDebug(Log::sceIo, 0); // Return finished
} else {
return hleLogError(Log::sceIo, ERROR_MEMSTICK_DEVCTL_BAD_PARAMS);
}
@ -1747,7 +1739,7 @@ static u32 sceIoDevctl(const char *name, int cmd, u32 argAddr, int argLen, u32 o
if (Memory::IsValidAddress(argAddr) && argLen >= 4) {
// TODO :
// Wake up the thread waiting for the UMD data cache handling.
return 0;
return hleLogDebug(Log::sceIo, 0);
} else {
return hleLogError(Log::sceIo, ERROR_MEMSTICK_DEVCTL_BAD_PARAMS);
}
@ -1775,7 +1767,7 @@ static u32 sceIoDevctl(const char *name, int cmd, u32 argAddr, int argLen, u32 o
} else {
Memory::Write_U32(PSP_MEMORYSTICK_STATE_DRIVER_READY, outPtr);
}
return 0;
return hleLogDebug(Log::sceIo, 0);
} else {
return hleLogError(Log::sceIo, ERROR_MEMSTICK_DEVCTL_BAD_PARAMS);
}
@ -1800,7 +1792,7 @@ static u32 sceIoDevctl(const char *name, int cmd, u32 argAddr, int argLen, u32 o
} else {
DEBUG_LOG(Log::sceIo, "sceIoDevctl: Memstick callback %i registered", cbId);
}
return 0;
return hleNoLog(0);
} else {
return SCE_KERNEL_ERROR_ERRNO_INVALID_ARGUMENT;
}
@ -1824,9 +1816,9 @@ static u32 sceIoDevctl(const char *name, int cmd, u32 argAddr, int argLen, u32 o
if (slot != (size_t)-1) {
memStickCallbacks.erase(memStickCallbacks.begin() + slot);
DEBUG_LOG(Log::sceIo, "sceIoDevctl: Unregistered memstick callback %i", cbId);
return 0;
return hleLogDebug(Log::sceIo, 0);
} else {
return SCE_KERNEL_ERROR_ERRNO_INVALID_ARGUMENT;
return hleLogError(Log::sceIo, SCE_KERNEL_ERROR_ERRNO_INVALID_ARGUMENT);
}
} else {
return hleLogError(Log::sceIo, ERROR_MEMSTICK_DEVCTL_BAD_PARAMS);
@ -1838,7 +1830,7 @@ static u32 sceIoDevctl(const char *name, int cmd, u32 argAddr, int argLen, u32 o
// 1 = Inserted.
// 2 = Not inserted.
Memory::Write_U32(MemoryStick_State(), outPtr);
return 0;
return hleLogDebug(Log::sceIo, 0);
} else {
return hleLogError(Log::sceIo, ERROR_MEMSTICK_DEVCTL_BAD_PARAMS);
}
@ -1846,7 +1838,7 @@ static u32 sceIoDevctl(const char *name, int cmd, u32 argAddr, int argLen, u32 o
case 0x02425818:
// Get MS capacity (fatms0).
if (MemoryStick_State() != PSP_MEMORYSTICK_STATE_INSERTED) {
return SCE_KERNEL_ERROR_ERRNO_DEVICE_NOT_FOUND;
return hleLogError(Log::sceIo, SCE_KERNEL_ERROR_ERRNO_DEVICE_NOT_FOUND);
}
// TODO: Pretend we have a 2GB memory stick? Should we check MemoryStick_FreeSpace?
if (Memory::IsValidRange(argAddr, 4) && argLen >= 4) { // NOTE: not outPtr
@ -1875,11 +1867,11 @@ static u32 sceIoDevctl(const char *name, int cmd, u32 argAddr, int argLen, u32 o
case 0x02425824:
// Check if write protected
if (MemoryStick_State() != PSP_MEMORYSTICK_STATE_INSERTED) {
return SCE_KERNEL_ERROR_ERRNO_DEVICE_NOT_FOUND;
return hleLogError(Log::sceIo, SCE_KERNEL_ERROR_ERRNO_DEVICE_NOT_FOUND);
}
if (Memory::IsValidRange(outPtr, 4) && outLen == 4) {
Memory::WriteUnchecked_U32(0, outPtr);
return 0;
return hleLogDebug(Log::sceIo, 0);
} else {
return hleLogError(Log::sceIo, -1, "Failed 0x02425824 fat");
}
@ -1912,7 +1904,7 @@ static u32 sceIoDevctl(const char *name, int cmd, u32 argAddr, int argLen, u32 o
} else {
DEBUG_LOG(Log::sceIo, "sceIoDevCtl: Memstick FAT callback %i registered", cbId);
}
return 0;
return hleNoLog(0);
} else {
return hleLogError(Log::sceIo, SCE_KERNEL_ERROR_ERRNO_INVALID_ARGUMENT);
}
@ -1936,7 +1928,7 @@ static u32 sceIoDevctl(const char *name, int cmd, u32 argAddr, int argLen, u32 o
if (slot != (size_t)-1) {
memStickFatCallbacks.erase(memStickFatCallbacks.begin() + slot);
DEBUG_LOG(Log::sceIo, "sceIoDevCtl: Unregistered memstick FAT callback %i", cbId);
return 0;
return hleLogDebug(Log::sceIo, 0);
} else {
return hleLogError(Log::sceIo, SCE_KERNEL_ERROR_ERRNO_INVALID_ARGUMENT);
}
@ -1946,7 +1938,7 @@ static u32 sceIoDevctl(const char *name, int cmd, u32 argAddr, int argLen, u32 o
// Set FAT as enabled
if (Memory::IsValidAddress(argAddr) && argLen == 4) {
MemoryStick_SetFatState((MemStickFatState)Memory::Read_U32(argAddr));
return 0;
return hleLogDebug(Log::sceIo, 0);
} else {
ERROR_LOG(Log::sceIo, "Failed 0x02415823 fat");
return -1;
@ -1966,7 +1958,7 @@ static u32 sceIoDevctl(const char *name, int cmd, u32 argAddr, int argLen, u32 o
// Does not care about outLen, even if it's 0.
// Note: writes 1 when inserted, 0 when not inserted.
Memory::Write_U32(MemoryStick_FatState(), outPtr);
return hleDelayResult(0, "check fat state", cyclesToUs(23500));
return hleDelayResult(hleLogDebug(Log::sceIo, 0), "check fat state", cyclesToUs(23500));
}
break;
case 0x02425824:
@ -1976,7 +1968,7 @@ static u32 sceIoDevctl(const char *name, int cmd, u32 argAddr, int argLen, u32 o
}
if (Memory::IsValidAddress(outPtr) && outLen == 4) {
Memory::Write_U32(0, outPtr);
return 0;
return hleLogDebug(Log::sceIo, 0);
} else {
return hleLogError(Log::sceIo, -1, "Failed 0x02425824 fat");
}
@ -1984,7 +1976,7 @@ static u32 sceIoDevctl(const char *name, int cmd, u32 argAddr, int argLen, u32 o
case 0x02425818:
// Get MS capacity (fatms0).
if (MemoryStick_State() != PSP_MEMORYSTICK_STATE_INSERTED) {
return SCE_KERNEL_ERROR_ERRNO_DEVICE_NOT_FOUND;
return hleLogError(Log::sceIo, SCE_KERNEL_ERROR_ERRNO_DEVICE_NOT_FOUND);
}
// TODO: Pretend we have a 2GB memory stick? Should we check MemoryStick_FreeSpace?
if (Memory::IsValidAddress(argAddr) && argLen >= 4) { // NOTE: not outPtr
@ -2003,7 +1995,7 @@ static u32 sceIoDevctl(const char *name, int cmd, u32 argAddr, int argLen, u32 o
deviceSize->sectorCount = sectorCount;
deviceSize.NotifyWrite("fatms0:02425818");
}
return 0;
return hleLogDebug(Log::sceIo, 0);
} else {
return hleLogError(Log::sceIo, ERROR_MEMSTICK_DEVCTL_BAD_PARAMS);
}
@ -2033,7 +2025,7 @@ static u32 sceIoDevctl(const char *name, int cmd, u32 argAddr, int argLen, u32 o
case EMULATOR_DEVCTL__GET_HAS_DISPLAY:
if (Memory::IsValidAddress(outPtr))
Memory::Write_U32(PSP_CoreParameter().headLess ? 0 : 1, outPtr);
return 0;
return hleLogDebug(Log::sceIo, 0);
case EMULATOR_DEVCTL__SEND_OUTPUT:
if (Memory::IsValidRange(argAddr, argLen)) {
std::string data(Memory::GetCharPointerUnchecked(argAddr), argLen);
@ -2046,12 +2038,12 @@ static u32 sceIoDevctl(const char *name, int cmd, u32 argAddr, int argLen, u32 o
case EMULATOR_DEVCTL__IS_EMULATOR:
if (Memory::IsValidAddress(outPtr))
Memory::Write_U32(1, outPtr);
return 0;
return hleLogDebug(Log::sceIo, 0);
case EMULATOR_DEVCTL__VERIFY_STATE:
// Note that this is async, and makes sure the save state matches up.
SaveState::Verify();
// TODO: Maybe save/load to a file just to be sure?
return 0;
return hleLogDebug(Log::sceIo, 0);
case EMULATOR_DEVCTL__EMIT_SCREENSHOT:
{
@ -2061,14 +2053,14 @@ 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?
System_SendDebugScreenshot(std::string((const char *)&topaddr[0], linesize * 272), 272);
return 0;
return hleLogDebug(Log::sceIo, 0);
}
case EMULATOR_DEVCTL__TOGGLE_FASTFORWARD:
if (argAddr)
PSP_CoreParameter().fastForward = true;
else
PSP_CoreParameter().fastForward = false;
return 0;
return hleLogDebug(Log::sceIo, 0);
case EMULATOR_DEVCTL__GET_ASPECT_RATIO:
if (Memory::IsValidAddress(outPtr)) {
// TODO: Share code with CalculateDisplayOutputRect to take a few more things into account.
@ -2081,7 +2073,7 @@ static u32 sceIoDevctl(const char *name, int cmd, u32 argAddr, int argLen, u32 o
}
Memory::Write_Float(ar, outPtr);
}
return 0;
return hleLogDebug(Log::sceIo, 0);
case EMULATOR_DEVCTL__GET_SCALE:
if (Memory::IsValidAddress(outPtr)) {
// TODO: Maybe do something more sophisticated taking the longest side and screen rotation
@ -2089,17 +2081,17 @@ static u32 sceIoDevctl(const char *name, int cmd, u32 argAddr, int argLen, u32 o
float scale = (float)g_display.dp_xres * g_Config.fDisplayScale / 480.0f;
Memory::Write_Float(scale, outPtr);
}
return 0;
return hleLogDebug(Log::sceIo, 0);
case EMULATOR_DEVCTL__GET_AXIS:
if (Memory::IsValidAddress(outPtr) && (argAddr >= 0 && argAddr < JOYSTICK_AXIS_MAX)) {
Memory::Write_Float(HLEPlugins::PluginDataAxis[argAddr], outPtr);
}
return 0;
return hleLogDebug(Log::sceIo, 0);
case EMULATOR_DEVCTL__GET_VKEY:
if (Memory::IsValidAddress(outPtr) && (argAddr >= 0 && argAddr < NKCODE_MAX)) {
Memory::Write_U8(HLEPlugins::GetKey(argAddr), outPtr);
}
return 0;
return hleLogDebug(Log::sceIo, 0);
}
return hleLogError(Log::sceIo, 0, "UNKNOWN PARAMETERS");
@ -2220,7 +2212,7 @@ static u32 sceIoOpenAsync(const char *filename, int flags, int mode) {
int fd = __IoAllocFd(f);
if (fd < 0) {
kernelObjects.Destroy<FileNode>(f->GetUID());
return hleLogError(Log::sceIo, hleDelayResult(fd, "file opened", 1000), "out of fds");
return hleDelayResult(hleLogError(Log::sceIo, fd, "out of fds"), "file opened", 1000);
}
auto &params = asyncParams[fd];
@ -2537,13 +2529,11 @@ static u32 sceIoDread(int id, u32 dirent_addr) {
}
}
}
DEBUG_LOG(Log::sceIo, "sceIoDread( %d %08x ) = %s", id, dirent_addr, entry->d_name);
// TODO: Improve timing. Only happens on the *first* entry read, ms and umd.
if (dir->index++ == 0) {
return hleDelayResult(1, "readdir", 1000);
return hleDelayResult(hleLogDebug(Log::sceIo, 1, "%s", entry->d_name), "readdir", 1000);
}
return 1;
return hleLogDebug(Log::sceIo, 1, "%s", entry->d_name);
} else {
return hleLogError(Log::sceIo, SCE_KERNEL_ERROR_BADF, "invalid listing");
}
@ -2554,6 +2544,7 @@ static u32 sceIoDclose(int id) {
return kernelObjects.Destroy<DirListing>(id);
}
// NOTE: Logs like a HLE function. Careful.
int __IoIoctl(u32 id, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr, u32 outlen, int &usec) {
u32 error;
FileNode *f = __IoGetFd(id, error);
@ -2809,8 +2800,7 @@ u32 sceIoIoctl(u32 id, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr, u32 ou
return result;
}
static u32 sceIoIoctlAsync(u32 id, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr, u32 outlen)
{
static u32 sceIoIoctlAsync(u32 id, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr, u32 outlen) {
u32 error;
FileNode *f = __IoGetFd(id, error);
if (f) {

View file

@ -598,7 +598,7 @@ static int sceJpegInitMJpeg() {
// If it was -1, it's from an old save state, avoid double init error but assume inited.
if (mjpegInited == 0)
mjpegInited = 1;
return hleLogSuccessI(Log::ME, hleDelayResult(0, "mjpeg init", 130));
return hleDelayResult(hleLogSuccessI(Log::ME, 0), "mjpeg init", 130);
}
static int sceJpegFinishMJpeg() {
@ -609,7 +609,7 @@ static int sceJpegFinishMJpeg() {
// Even from an old save state, if we see this we leave compat mode.
mjpegInited = 0;
return hleLogSuccessI(Log::ME, hleDelayResult(0, "mjpeg finish", 120));
return hleDelayResult(hleLogSuccessI(Log::ME, 0), "mjpeg finish", 120);
}
static int sceJpegMJpegCscWithColorOption() {

View file

@ -110,10 +110,9 @@ static void sceKernelCpuResumeIntr(u32 enable)
hleEatCycles(15);
}
static int sceKernelIsCpuIntrEnable()
{
static int sceKernelIsCpuIntrEnable() {
u32 retVal = __InterruptsEnabled();
return hleLogDebug(Log::sceIntc, retVal);
return hleLogVerbose(Log::sceIntc, retVal);
}
static int sceKernelIsCpuIntrSuspended(int flag)
@ -509,10 +508,8 @@ u32 sceKernelRegisterSubIntrHandler(u32 intrNumber, u32 subIntrNumber, u32 handl
}
} else if (error == SCE_KERNEL_ERROR_FOUND_HANDLER) {
return hleReportError(Log::sceIntc, error, "duplicate handler");
} else {
return hleReportError(Log::sceIntc, error);
}
return error;
return hleReportError(Log::sceIntc, error);
}
u32 sceKernelReleaseSubIntrHandler(u32 intrNumber, u32 subIntrNumber) {

View file

@ -1626,7 +1626,7 @@ int sceKernelAllocateVpl(SceUID uid, u32 size, u32 addrPtr, u32 timeoutPtr)
if (error == SCE_KERNEL_ERROR_NO_MEMORY)
{
if (timeoutPtr != 0 && Memory::Read_U32(timeoutPtr) == 0)
return SCE_KERNEL_ERROR_WAIT_TIMEOUT;
return hleLogError(Log::sceKernel, SCE_KERNEL_ERROR_WAIT_TIMEOUT);
if (vpl)
{
@ -1641,7 +1641,7 @@ int sceKernelAllocateVpl(SceUID uid, u32 size, u32 addrPtr, u32 timeoutPtr)
}
// If anyone else was waiting, the allocation causes a delay.
else if (error == 0 && !vpl->waitingThreads.empty())
return hleDelayResult(error, "vpl allocated", 50);
return hleDelayResult(hleLogDebug(Log::sceKernel, error), "vpl allocated", 50);
}
return error;
}
@ -1657,7 +1657,7 @@ int sceKernelAllocateVplCB(SceUID uid, u32 size, u32 addrPtr, u32 timeoutPtr)
if (error == SCE_KERNEL_ERROR_NO_MEMORY)
{
if (timeoutPtr != 0 && Memory::Read_U32(timeoutPtr) == 0)
return SCE_KERNEL_ERROR_WAIT_TIMEOUT;
return hleLogError(Log::sceKernel, SCE_KERNEL_ERROR_WAIT_TIMEOUT);
if (vpl)
{
@ -1672,7 +1672,7 @@ int sceKernelAllocateVplCB(SceUID uid, u32 size, u32 addrPtr, u32 timeoutPtr)
}
// If anyone else was waiting, the allocation causes a delay.
else if (error == 0 && !vpl->waitingThreads.empty())
return hleDelayResult(error, "vpl allocated", 50);
return hleDelayResult(hleLogDebug(Log::sceKernel, error), "vpl allocated", 50);
}
return error;
}
@ -1686,8 +1686,7 @@ int sceKernelTryAllocateVpl(SceUID uid, u32 size, u32 addrPtr)
int sceKernelFreeVpl(SceUID uid, u32 addr) {
if (addr && !Memory::IsValidAddress(addr)) {
WARN_LOG(Log::sceKernel, "%08x=sceKernelFreeVpl(%i, %08x): Invalid address", SCE_KERNEL_ERROR_ILLEGAL_ADDR, uid, addr);
return SCE_KERNEL_ERROR_ILLEGAL_ADDR;
return hleLogWarning(Log::sceKernel, SCE_KERNEL_ERROR_ILLEGAL_ADDR, "invalid address");
}
VERBOSE_LOG(Log::sceKernel, "sceKernelFreeVpl(%i, %08x)", uid, addr);
@ -1737,7 +1736,6 @@ int sceKernelCancelVpl(SceUID uid, u32 numWaitThreadsPtr)
VPL *vpl = kernelObjects.Get<VPL>(uid, error);
if (vpl)
{
DEBUG_LOG(Log::sceKernel, "sceKernelCancelVpl(%i, %08x)", uid, numWaitThreadsPtr);
vpl->nv.numWaitThreads = (int) vpl->waitingThreads.size();
if (Memory::IsValidAddress(numWaitThreadsPtr))
Memory::Write_U32(vpl->nv.numWaitThreads, numWaitThreadsPtr);
@ -1746,7 +1744,7 @@ int sceKernelCancelVpl(SceUID uid, u32 numWaitThreadsPtr)
if (wokeThreads)
hleReSchedule("vpl canceled");
return 0;
return hleLogDebug(Log::sceKernel, 0);
}
else
{
@ -1796,11 +1794,9 @@ static u32 AllocMemoryBlock(const char *pname, u32 type, u32 size, u32 paramsAdd
}
PartitionMemoryBlock *block = new PartitionMemoryBlock(&userMemory, pname, size, (MemblockType)type, 0);
if (!block->IsValid())
{
if (!block->IsValid()) {
delete block;
ERROR_LOG(Log::sceKernel, "AllocMemoryBlock(%s, %i, %08x, %08x): allocation failed", pname, type, size, paramsAddr);
return SCE_KERNEL_ERROR_MEMBLOCK_ALLOC_FAILED;
return hleLogError(Log::sceKernel, SCE_KERNEL_ERROR_MEMBLOCK_ALLOC_FAILED, "allocation failed");
}
SceUID uid = kernelObjects.Create(block);

View file

@ -2096,7 +2096,6 @@ u32 sceKernelLoadModule(const char *name, u32 flags, u32 optionAddr) {
}
// TODO: It would be more ideal to allocate memory for this module.
return hleLogSuccessInfoI(Log::Loader, module->GetUID(), "created fake module");
}
}

View file

@ -318,7 +318,7 @@ static int sceMp3InitResource() {
return hleLogSuccessI(Log::ME, 0);
}
resourceInited = true;
return hleLogSuccessI(Log::ME, hleDelayResult(0, "mp3 resource init", 200));
return hleDelayResult(hleLogSuccessI(Log::ME, 0), "mp3 resource init", 200);
}
static int sceMp3TermResource() {
@ -333,7 +333,7 @@ static int sceMp3TermResource() {
mp3Map.clear();
resourceInited = false;
return hleLogSuccessI(Log::ME, hleDelayResult(0, "mp3 resource term", 100));
return hleDelayResult(hleLogSuccessI(Log::ME, 0), "mp3 resource term", 100);
}
static int __CalculateMp3Channels(int bitval) {
@ -717,7 +717,7 @@ static u32 sceMp3LowLevelInit(u32 mp3, u32 unk) {
// Indicate that we've run low level init by setting version to 1.
ctx->Version = 1;
return hleLogSuccessInfoI(Log::ME, hleDelayResult(0, "mp3 low level", 600));
return hleDelayResult(hleLogSuccessInfoI(Log::ME, 0), "mp3 low level", 600);
}
static u32 sceMp3LowLevelDecode(u32 mp3, u32 sourceAddr, u32 sourceBytesConsumedAddr, u32 samplesAddr, u32 sampleBytesAddr) {

View file

@ -463,7 +463,7 @@ static u32 sceMpegInit() {
INFO_LOG(Log::ME, "sceMpegInit(), mpegLibVersion 0x%0x, mpegLibcrc %x", mpegLibVersion, mpegLibCrc);
}
isMpegInit = true;
return hleDelayResult(0, "mpeg init", 750);
return hleDelayResult(hleNoLog(0), "mpeg init", 750);
}
static u32 __MpegRingbufferQueryMemSize(int packets) {
@ -576,8 +576,7 @@ static u32 sceMpegCreate(u32 mpegAddr, u32 dataPtr, u32 size, u32 ringbufferAddr
ctx->isAnalyzed = false;
ctx->mediaengine = new MediaEngine();
INFO_LOG(Log::ME, "%08x=sceMpegCreate(%08x, %08x, %i, %08x, %i, %i, %i)", mpegHandle, mpegAddr, dataPtr, size, ringbufferAddr, frameWidth, mode, ddrTop);
return hleDelayResult(0, "mpeg create", 29000);
return hleDelayResult(hleLogSuccessInfoX(Log::ME, 0), "mpeg create", 29000);
}
static int sceMpegDelete(u32 mpeg)
@ -588,12 +587,10 @@ static int sceMpegDelete(u32 mpeg)
return -1;
}
DEBUG_LOG(Log::ME, "sceMpegDelete(%08x)", mpeg);
delete ctx;
mpegMap.erase(Memory::Read_U32(mpeg));
return hleDelayResult(0, "mpeg delete", 40000);
return hleDelayResult(hleLogDebug(Log::ME, 0), "mpeg delete", 40000);
}
@ -1163,8 +1160,7 @@ static u32 sceMpegAvcDecode(u32 mpeg, u32 auAddr, u32 frameWidth, u32 bufferAddr
}
if (ringbuffer->packetsRead == 0 || ctx->mediaengine->IsVideoEnd()) {
WARN_LOG(Log::ME, "sceMpegAvcDecode(%08x, %08x, %d, %08x, %08x): mpeg buffer empty", mpeg, auAddr, frameWidth, bufferAddr, initAddr);
return hleDelayResult(ERROR_MPEG_AVC_DECODE_FATAL, "mpeg buffer empty", avcEmptyDelayMs);
return hleDelayResult(hleLogWarning(Log::ME, ERROR_MPEG_AVC_DECODE_FATAL, "mpeg buffer empty"), "mpeg buffer empty", avcEmptyDelayMs);
}
s32 beforeAvail = ringbuffer->packets - ctx->mediaengine->getRemainSize() / 2048;
@ -1230,32 +1226,25 @@ static u32 sceMpegAvcDecode(u32 mpeg, u32 auAddr, u32 frameWidth, u32 bufferAddr
//return hleDelayResult(0, "mpeg decode", 200);
}
static u32 sceMpegAvcDecodeStop(u32 mpeg, u32 frameWidth, u32 bufferAddr, u32 statusAddr)
{
if (!Memory::IsValidAddress(bufferAddr) || !Memory::IsValidAddress(statusAddr)){
ERROR_LOG(Log::ME, "sceMpegAvcDecodeStop(%08x, %08x, %08x, %08x): invalid addresses", mpeg, frameWidth, bufferAddr, statusAddr);
return -1;
static u32 sceMpegAvcDecodeStop(u32 mpeg, u32 frameWidth, u32 bufferAddr, u32 statusAddr) {
if (!Memory::IsValidAddress(bufferAddr) || !Memory::IsValidAddress(statusAddr)) {
return hleLogError(Log::ME, -1, "invalid addresses");
}
MpegContext *ctx = getMpegCtx(mpeg);
if (!ctx) {
WARN_LOG(Log::ME, "sceMpegAvcDecodeStop(%08x, %08x, %08x, %08x): bad mpeg handle", mpeg, frameWidth, bufferAddr, statusAddr);
return -1;
return hleLogWarning(Log::ME, -1, "bad mpeg handle");
}
DEBUG_LOG(Log::ME, "sceMpegAvcDecodeStop(%08x, %08x, %08x, %08x)", mpeg, frameWidth, bufferAddr, statusAddr);
// No last frame generated
Memory::Write_U32(0, statusAddr);
return 0;
return hleLogDebug(Log::ME, 0);
}
static u32 sceMpegUnRegistStream(u32 mpeg, int streamUid)
{
static u32 sceMpegUnRegistStream(u32 mpeg, int streamUid) {
MpegContext *ctx = getMpegCtx(mpeg);
if (!ctx) {
WARN_LOG(Log::ME, "sceMpegUnRegistStream(%08x, %i): bad mpeg handle", mpeg, streamUid);
return -1;
return hleLogWarning(Log::ME, -1, "bad mpeg handle");
}
StreamInfo info = {0};
@ -1283,24 +1272,19 @@ static u32 sceMpegUnRegistStream(u32 mpeg, int streamUid)
info.sid = -1 ;
info.needsReset = true;
ctx->isAnalyzed = false;
return 0;
return hleNoLog(0);
}
static int sceMpegAvcDecodeDetail(u32 mpeg, u32 detailAddr)
{
if (!Memory::IsValidAddress(detailAddr)){
WARN_LOG(Log::ME, "sceMpegAvcDecodeDetail(%08x, %08x): invalid addresses", mpeg, detailAddr);
return -1;
static int sceMpegAvcDecodeDetail(u32 mpeg, u32 detailAddr) {
if (!Memory::IsValidAddress(detailAddr)) {
return hleLogError(Log::ME, -1, "invalid addresses");
}
MpegContext *ctx = getMpegCtx(mpeg);
if (!ctx) {
WARN_LOG(Log::ME, "sceMpegAvcDecodeDetail(%08x, %08x): bad mpeg handle", mpeg, detailAddr);
return -1;
return hleLogWarning(Log::ME, -1, "bad mpeg handle");
}
DEBUG_LOG(Log::ME, "sceMpegAvcDecodeDetail(%08x, %08x)", mpeg, detailAddr);
Memory::Write_U32(ctx->avc.avcDecodeResult, detailAddr + 0);
Memory::Write_U32(ctx->videoFrameCount, detailAddr + 4);
Memory::Write_U32(ctx->avc.avcDetailFrameWidth, detailAddr + 8);
@ -1310,33 +1294,29 @@ static int sceMpegAvcDecodeDetail(u32 mpeg, u32 detailAddr)
Memory::Write_U32(0, detailAddr + 24);
Memory::Write_U32(0, detailAddr + 28);
Memory::Write_U32(ctx->avc.avcFrameStatus, detailAddr + 32);
return 0;
return hleLogDebug(Log::ME, 0);
}
static u32 sceMpegAvcDecodeStopYCbCr(u32 mpeg, u32 bufferAddr, u32 statusAddr)
{
static u32 sceMpegAvcDecodeStopYCbCr(u32 mpeg, u32 bufferAddr, u32 statusAddr) {
if (!Memory::IsValidAddress(bufferAddr) || !Memory::IsValidAddress(statusAddr)) {
ERROR_LOG(Log::ME, "UNIMPL sceMpegAvcDecodeStopYCbCr(%08x, %08x, %08x): invalid addresses", mpeg, bufferAddr, statusAddr);
return -1;
return hleLogError(Log::ME, -1, "UNIMPL + invalid addresses");
}
MpegContext *ctx = getMpegCtx(mpeg);
if (!ctx) {
WARN_LOG(Log::ME, "UNIMPL sceMpegAvcDecodeStopYCbCr(%08x, %08x, %08x): bad mpeg handle", mpeg, bufferAddr, statusAddr);
return -1;
return hleLogWarning(Log::ME, -1, "UNIMPL + bad mpeg handle");
}
ERROR_LOG(Log::ME, "UNIMPL sceMpegAvcDecodeStopYCbCr(%08x, %08x, %08x)", mpeg, bufferAddr, statusAddr);
Memory::Write_U32(0, statusAddr);
return 0;
return hleNoLog(0);
}
static int sceMpegAvcDecodeYCbCr(u32 mpeg, u32 auAddr, u32 bufferAddr, u32 initAddr)
{
MpegContext *ctx = getMpegCtx(mpeg);
if (!ctx) {
WARN_LOG(Log::ME, "sceMpegAvcDecodeYCbCr(%08x, %08x, %08x, %08x): bad mpeg handle", mpeg, auAddr, bufferAddr, initAddr);
return -1;
return hleLogWarning(Log::ME, -1, "bad mpeg handle");
}
SceMpegAu avcAu;
@ -1344,13 +1324,11 @@ static int sceMpegAvcDecodeYCbCr(u32 mpeg, u32 auAddr, u32 bufferAddr, u32 initA
auto ringbuffer = PSPPointer<SceMpegRingBuffer>::Create(ctx->mpegRingbufferAddr);
if (!ringbuffer.IsValid()) {
ERROR_LOG(Log::ME, "Bogus mpegringbufferaddr");
return -1;
return hleLogError(Log::ME, -1, "Bogus mpegringbufferaddr");
}
if (ringbuffer->packetsRead == 0 || ctx->mediaengine->IsVideoEnd()) {
WARN_LOG(Log::ME, "sceMpegAvcDecodeYCbCr(%08x, %08x, %08x, %08x): mpeg buffer empty", mpeg, auAddr, bufferAddr, initAddr);
return hleDelayResult(ERROR_MPEG_AVC_DECODE_FATAL, "mpeg buffer empty", avcEmptyDelayMs);
return hleDelayResult(hleLogWarning(Log::ME, ERROR_MPEG_AVC_DECODE_FATAL, "mpeg buffer empty"), "mpeg buffer empty", avcEmptyDelayMs);
}
s32 beforeAvail = ringbuffer->packets - ctx->mediaengine->getRemainSize() / 2048;
@ -1393,41 +1371,33 @@ static int sceMpegAvcDecodeYCbCr(u32 mpeg, u32 auAddr, u32 bufferAddr, u32 initA
}
ctx->avc.avcDecodeResult = MPEG_AVC_DECODE_SUCCESS;
DEBUG_LOG(Log::ME, "sceMpegAvcDecodeYCbCr(%08x, %08x, %08x, %08x)", mpeg, auAddr, bufferAddr, initAddr);
if (ctx->videoFrameCount <= 1)
return hleDelayResult(0, "mpeg decode", avcFirstDelayMs);
return hleDelayResult(hleLogDebug(Log::ME, 0), "mpeg decode", avcFirstDelayMs);
else
return hleDelayResult(0, "mpeg decode", avcDecodeDelayMs);
return hleDelayResult(hleLogDebug(Log::ME, 0), "mpeg decode", avcDecodeDelayMs);
//hleEatMicro(3300);
//return hleDelayResult(0, "mpeg decode", 200);
}
static u32 sceMpegAvcDecodeFlush(u32 mpeg)
{
static u32 sceMpegAvcDecodeFlush(u32 mpeg) {
MpegContext *ctx = getMpegCtx(mpeg);
if (!ctx) {
WARN_LOG(Log::ME, "UNIMPL sceMpegAvcDecodeFlush(%08x): bad mpeg handle", mpeg);
return -1;
return hleLogWarning(Log::ME, -1, "UNIMPL + bad mpeg handle");
}
ERROR_LOG(Log::ME, "UNIMPL sceMpegAvcDecodeFlush(%08x)", mpeg);
if ( ctx->videoFrameCount > 0 || ctx->audioFrameCount > 0) {
//__MpegFinish();
}
return 0;
return hleLogWarning(Log::ME, 0, "UNIMPL");
}
static int sceMpegInitAu(u32 mpeg, u32 bufferAddr, u32 auPointer)
{
static int sceMpegInitAu(u32 mpeg, u32 bufferAddr, u32 auPointer) {
MpegContext *ctx = getMpegCtx(mpeg);
if (!ctx) {
WARN_LOG(Log::ME, "sceMpegInitAu(%08x, %i, %08x): bad mpeg handle", mpeg, bufferAddr, auPointer);
return -1;
return hleLogWarning(Log::ME, -1, "bad mpeg handle");
}
DEBUG_LOG(Log::ME, "sceMpegInitAu(%08x, %i, %08x)", mpeg, bufferAddr, auPointer);
SceMpegAu sceAu;
sceAu.read(auPointer);
@ -1452,42 +1422,33 @@ static int sceMpegInitAu(u32 mpeg, u32 bufferAddr, u32 auPointer)
sceAu.write(auPointer);
}
return 0;
return hleLogDebug(Log::ME, 0);
}
static int sceMpegQueryAtracEsSize(u32 mpeg, u32 esSizeAddr, u32 outSizeAddr)
{
static int sceMpegQueryAtracEsSize(u32 mpeg, u32 esSizeAddr, u32 outSizeAddr) {
if (!Memory::IsValidAddress(esSizeAddr) || !Memory::IsValidAddress(outSizeAddr)) {
ERROR_LOG(Log::ME, "sceMpegQueryAtracEsSize(%08x, %08x, %08x): invalid addresses", mpeg, esSizeAddr, outSizeAddr);
return -1;
return hleLogError(Log::ME, -1, "invalid addresses");
}
MpegContext *ctx = getMpegCtx(mpeg);
if (!ctx) {
WARN_LOG(Log::ME, "sceMpegQueryAtracEsSize(%08x, %08x, %08x): bad mpeg handle", mpeg, esSizeAddr, outSizeAddr);
return -1;
return hleLogWarning(Log::ME, -1, "bad mpeg handle");
}
DEBUG_LOG(Log::ME, "sceMpegQueryAtracEsSize(%08x, %08x, %08x)", mpeg, esSizeAddr, outSizeAddr);
Memory::Write_U32(MPEG_ATRAC_ES_SIZE, esSizeAddr);
Memory::Write_U32(MPEG_ATRAC_ES_OUTPUT_SIZE, outSizeAddr);
return 0;
return hleLogDebug(Log::ME, 0);
}
static int sceMpegRingbufferAvailableSize(u32 ringbufferAddr)
{
static int sceMpegRingbufferAvailableSize(u32 ringbufferAddr) {
auto ringbuffer = PSPPointer<SceMpegRingBuffer>::Create(ringbufferAddr);
if (!ringbuffer.IsValid()) {
ERROR_LOG(Log::ME, "sceMpegRingbufferAvailableSize(%08x): invalid ringbuffer, should crash", ringbufferAddr);
return SCE_KERNEL_ERROR_ILLEGAL_ADDRESS;
return hleLogError(Log::ME, SCE_KERNEL_ERROR_ILLEGAL_ADDRESS, "invalid ringbuffer, should crash");
}
MpegContext *ctx = getMpegCtx(ringbuffer->mpeg);
if (!ctx) {
ERROR_LOG(Log::ME, "sceMpegRingbufferAvailableSize(%08x): bad mpeg handle", ringbufferAddr);
return ERROR_MPEG_NOT_YET_INIT;
return hleLogError(Log::ME, ERROR_MPEG_NOT_YET_INIT, "bad mpeg handle");
}
ctx->mpegRingbufferAddr = ringbufferAddr;
@ -1501,7 +1462,7 @@ static int sceMpegRingbufferAvailableSize(u32 ringbufferAddr)
} else {
VERBOSE_LOG(Log::ME, "%i=sceMpegRingbufferAvailableSize(%08x)", ringbuffer->packets - ringbuffer->packetsAvail, ringbufferAddr);
}
return ringbuffer->packets - ringbuffer->packetsAvail;
return hleNoLog(ringbuffer->packets - ringbuffer->packetsAvail);
}
void PostPutAction::run(MipsCall &call) {
@ -1657,12 +1618,11 @@ static int sceMpegGetAvcAu(u32 mpeg, u32 streamId, u32 auAddr, u32 attrAddr)
avcAu.read(auAddr);
if (ringbuffer->packetsRead == 0 || ringbuffer->packetsAvail == 0) {
DEBUG_LOG(Log::ME, "ERROR_MPEG_NO_DATA=sceMpegGetAvcAu(%08x, %08x, %08x, %08x)", mpeg, streamId, auAddr, attrAddr);
avcAu.pts = -1;
avcAu.dts = -1;
avcAu.write(auAddr);
// TODO: Does this really reschedule?
return hleDelayResult(ERROR_MPEG_NO_DATA, "mpeg get avc", mpegDecodeErrorDelayMs);
return hleDelayResult(hleLogDebug(Log::ME, ERROR_MPEG_NO_DATA), "mpeg get avc", mpegDecodeErrorDelayMs);
}
auto streamInfo = ctx->streamMap.find(streamId);
@ -1708,10 +1668,9 @@ static int sceMpegGetAvcAu(u32 mpeg, u32 streamId, u32 auAddr, u32 attrAddr)
Memory::Write_U32(1, attrAddr);
}
DEBUG_LOG(Log::ME, "%x=sceMpegGetAvcAu(%08x, %08x, %08x, %08x)", result, mpeg, streamId, auAddr, attrAddr);
// TODO: sceMpegGetAvcAu seems to modify esSize, and delay when it's > 1000 or something.
// There's definitely more to it, but ultimately it seems games should expect it to delay randomly.
return hleDelayResult(result, "mpeg get avc", 100);
return hleDelayResult(hleLogDebug(Log::ME, result), "mpeg get avc", 100);
}
static u32 sceMpegFinish()
@ -1726,7 +1685,7 @@ static u32 sceMpegFinish()
}
isMpegInit = false;
//__MpegFinish();
return hleDelayResult(0, "mpeg finish", 250);
return hleDelayResult(hleLogDebug(Log::ME, 0), "mpeg finish", 250);
}
static u32 sceMpegQueryMemSize() {
@ -1737,15 +1696,13 @@ static int sceMpegGetAtracAu(u32 mpeg, u32 streamId, u32 auAddr, u32 attrAddr)
{
MpegContext *ctx = getMpegCtx(mpeg);
if (!ctx) {
WARN_LOG(Log::ME, "sceMpegGetAtracAu(%08x, %08x, %08x, %08x): bad mpeg handle", mpeg, streamId, auAddr, attrAddr);
return -1;
return hleLogWarning(Log::ME, -1, "bad mpeg handle");
}
auto ringbuffer = PSPPointer<SceMpegRingBuffer>::Create(ctx->mpegRingbufferAddr);
if (!ringbuffer.IsValid()) {
// Would have crashed before, TODO test behavior.
WARN_LOG(Log::ME, "sceMpegGetAtracAu(%08x, %08x, %08x, %08x): invalid ringbuffer address", mpeg, streamId, auAddr, attrAddr);
return -1;
return hleLogWarning(Log::ME, -1, "invalid ringbuffer address");
}
SceMpegAu atracAu;
@ -1763,9 +1720,8 @@ static int sceMpegGetAtracAu(u32 mpeg, u32 streamId, u32 auAddr, u32 attrAddr)
// The audio can end earlier than the video does.
if (ringbuffer->packetsAvail == 0) {
DEBUG_LOG(Log::ME, "ERROR_MPEG_NO_DATA=sceMpegGetAtracAu(%08x, %08x, %08x, %08x)", mpeg, streamId, auAddr, attrAddr);
// TODO: Does this really delay?
return hleDelayResult(ERROR_MPEG_NO_DATA, "mpeg get atrac", mpegDecodeErrorDelayMs);
return hleDelayResult(hleLogError(Log::ME, ERROR_MPEG_NO_DATA), "mpeg get atrac", mpegDecodeErrorDelayMs);
}
// esBuffer is the memory where this au data goes. We don't write the data to memory.
@ -1803,29 +1759,24 @@ static int sceMpegGetAtracAu(u32 mpeg, u32 streamId, u32 auAddr, u32 attrAddr)
Memory::Write_U32(0, attrAddr);
}
DEBUG_LOG(Log::ME, "%x=sceMpegGetAtracAu(%08x, %08x, %08x, %08x)", result, mpeg, streamId, auAddr, attrAddr);
// TODO: Not clear on exactly when this delays.
return hleDelayResult(result, "mpeg get atrac", 100);
return hleDelayResult(hleLogDebug(Log::ME, result), "mpeg get atrac", 100);
}
static int sceMpegQueryPcmEsSize(u32 mpeg, u32 esSizeAddr, u32 outSizeAddr)
{
if (!Memory::IsValidAddress(esSizeAddr) || !Memory::IsValidAddress(outSizeAddr)) {
ERROR_LOG(Log::ME, "sceMpegQueryPcmEsSize(%08x, %08x, %08x): invalid addresses", mpeg, esSizeAddr, outSizeAddr);
return -1;
return hleLogError(Log::ME, -1, "invalid addresses");
}
MpegContext *ctx = getMpegCtx(mpeg);
if (!ctx) {
WARN_LOG(Log::ME, "sceMpegQueryPcmEsSize(%08x, %08x, %08x): bad mpeg handle", mpeg, esSizeAddr, outSizeAddr);
return -1;
return hleLogWarning(Log::ME, -1, "bad mpeg handle");
}
ERROR_LOG(Log::ME, "sceMpegQueryPcmEsSize(%08x, %08x, %08x)", mpeg, esSizeAddr, outSizeAddr);
Memory::Write_U32(MPEG_PCM_ES_SIZE, esSizeAddr);
Memory::Write_U32(MPEG_PCM_ES_OUTPUT_SIZE, outSizeAddr);
return 0;
return hleLogError(Log::ME, 0, "UNIMPL");
}
@ -1833,8 +1784,7 @@ static u32 sceMpegChangeGetAuMode(u32 mpeg, int streamUid, int mode)
{
MpegContext *ctx = getMpegCtx(mpeg);
if (!ctx) {
WARN_LOG(Log::ME, "sceMpegChangeGetAuMode(%08x, %i, %i): bad mpeg handle", mpeg, streamUid, mode);
return ERROR_MPEG_INVALID_VALUE;
return hleLogError(Log::ME, ERROR_MPEG_INVALID_VALUE, "bad mpeg handle");
}
if (mode != MPEG_AU_MODE_DECODE && mode != MPEG_AU_MODE_SKIP) {
ERROR_LOG(Log::ME, "UNIMPL sceMpegChangeGetAuMode(%08x, %i, %i): bad mode", mpeg, streamUid, mode);
@ -1879,17 +1829,14 @@ static u32 sceMpegChangeGetAuMode(u32 mpeg, int streamUid, int mode)
return 0;
}
static u32 sceMpegChangeGetAvcAuMode(u32 mpeg, u32 stream_addr, int mode)
{
static u32 sceMpegChangeGetAvcAuMode(u32 mpeg, u32 stream_addr, int mode) {
if (!Memory::IsValidAddress(stream_addr)) {
ERROR_LOG(Log::ME, "UNIMPL sceMpegChangeGetAvcAuMode(%08x, %08x, %i): invalid addresses", mpeg, stream_addr, mode);
return -1;
return hleLogError(Log::ME, -1, "invalid addresses");
}
MpegContext *ctx = getMpegCtx(mpeg);
if (!ctx) {
WARN_LOG(Log::ME, "UNIMPL sceMpegChangeGetAvcAuMode(%08x, %08x, %i): bad mpeg handle", mpeg, stream_addr, mode);
return -1;
return hleLogWarning(Log::ME, -1, "UNIMPL + bad mpeg handle");
}
ERROR_LOG_REPORT_ONCE(mpegChangeAvcAu, Log::ME, "UNIMPL sceMpegChangeGetAvcAuMode(%08x, %08x, %i)", mpeg, stream_addr, mode);
@ -1944,12 +1891,9 @@ static u32 sceMpegFlushAllStream(u32 mpeg)
{
MpegContext *ctx = getMpegCtx(mpeg);
if (!ctx) {
WARN_LOG(Log::ME, "sceMpegFlushAllStream(%08x): bad mpeg handle", mpeg);
return -1;
return hleLogWarning(Log::ME, -1, "UNIMPL + bad mpeg handle");
}
WARN_LOG(Log::ME, "UNIMPL sceMpegFlushAllStream(%08x)", mpeg);
ctx->isAnalyzed = false;
auto ringbuffer = PSPPointer<SceMpegRingBuffer>::Create(ctx->mpegRingbufferAddr);
@ -1959,7 +1903,7 @@ static u32 sceMpegFlushAllStream(u32 mpeg)
ringbuffer->packetsWritePos = 0;
}
return 0;
return hleLogWarning(Log::ME, 0, "UNIMPL");
}
static u32 sceMpegFlushStream(u32 mpeg, int stream_addr)
@ -2002,17 +1946,13 @@ static u32 sceMpegAtracDecode(u32 mpeg, u32 auAddr, u32 bufferAddr, int init)
{
MpegContext *ctx = getMpegCtx(mpeg);
if (!ctx) {
WARN_LOG(Log::ME, "sceMpegAtracDecode(%08x, %08x, %08x, %i): bad mpeg handle", mpeg, auAddr, bufferAddr, init);
return -1;
return hleLogWarning(Log::ME, -1, "bad mpeg handle");
}
if (!Memory::IsValidAddress(bufferAddr)) {
WARN_LOG(Log::ME, "sceMpegAtracDecode(%08x, %08x, %08x, %i): invalid addresses", mpeg, auAddr, bufferAddr, init);
return -1;
return hleLogWarning(Log::ME, -1, "invalid addresses");
}
DEBUG_LOG(Log::ME, "sceMpegAtracDecode(%08x, %08x, %08x, %i)", mpeg, auAddr, bufferAddr, init);
SceMpegAu atracAu;
atracAu.read(auAddr);
@ -2025,8 +1965,7 @@ static u32 sceMpegAtracDecode(u32 mpeg, u32 auAddr, u32 bufferAddr, int init)
atracAu.write(auAddr);
return hleDelayResult(0, "mpeg atrac decode", atracDecodeDelayMs);
return hleDelayResult(hleLogDebug(Log::ME, 0), "mpeg atrac decode", atracDecodeDelayMs);
//hleEatMicro(4000);
//return hleDelayResult(0, "mpeg atrac decode", 200);
}
@ -2035,18 +1974,14 @@ static u32 sceMpegAtracDecode(u32 mpeg, u32 auAddr, u32 bufferAddr, int init)
static u32 sceMpegAvcCsc(u32 mpeg, u32 sourceAddr, u32 rangeAddr, int frameWidth, u32 destAddr)
{
if (!Memory::IsValidAddress(sourceAddr) || !Memory::IsValidAddress(rangeAddr) || !Memory::IsValidAddress(destAddr)) {
ERROR_LOG(Log::ME, "sceMpegAvcCsc(%08x, %08x, %08x, %i, %08x): invalid addresses", mpeg, sourceAddr, rangeAddr, frameWidth, destAddr);
return -1;
return hleLogError(Log::ME, -1, "invalid addresses");
}
MpegContext *ctx = getMpegCtx(mpeg);
if (!ctx) {
WARN_LOG(Log::ME, "sceMpegAvcCsc(%08x, %08x, %08x, %i, %08x): bad mpeg handle", mpeg, sourceAddr, rangeAddr, frameWidth, destAddr);
return -1;
return hleLogWarning(Log::ME, -1, "bad mpeg handle");
}
DEBUG_LOG(Log::ME, "sceMpegAvcCsc(%08x, %08x, %08x, %i, %08x)", mpeg, sourceAddr, rangeAddr, frameWidth, destAddr);
if (frameWidth == 0) {
if (!ctx->defaultFrameWidth) {
frameWidth = ctx->avc.avcDetailFrameWidth;
@ -2074,31 +2009,27 @@ static u32 sceMpegAvcCsc(u32 mpeg, u32 sourceAddr, u32 rangeAddr, int frameWidth
// If do not use DelayResult,Wil cause flickering in Dengeki no Pilot: Tenkuu no Kizuna
// https://github.com/hrydgard/ppsspp/issues/7549
return hleDelayResult(0, "mpeg avc csc", avcCscDelayMs);
return hleDelayResult(hleLogDebug(Log::ME, 0), "mpeg avc csc", avcCscDelayMs);
}
static u32 sceMpegRingbufferDestruct(u32 ringbufferAddr)
{
DEBUG_LOG(Log::ME, "sceMpegRingbufferDestruct(%08x)", ringbufferAddr);
static u32 sceMpegRingbufferDestruct(u32 ringbufferAddr) {
// Apparently, does nothing.
return 0;
return hleLogDebug(Log::ME, 0);
}
static u32 sceMpegAvcInitYCbCr(u32 mpeg, int mode, int width, int height, u32 ycbcr_addr)
{
if (!Memory::IsValidAddress(ycbcr_addr)) {
ERROR_LOG(Log::ME, "UNIMPL sceMpegAvcInitYCbCr(%08x, %i, %i, %i, %08x): invalid addresses", mpeg, mode, width, height, ycbcr_addr);
return -1;
return hleLogError(Log::ME, -1, "invalid addresses");
}
MpegContext *ctx = getMpegCtx(mpeg);
if (!ctx) {
WARN_LOG(Log::ME, "UNIMPL sceMpegAvcInitYCbCr(%08x, %i, %i, %i, %08x): bad mpeg handle", mpeg, mode, width, height, ycbcr_addr);
return -1;
return hleLogWarning(Log::ME, -1, "bad mpeg handle");
}
WARN_LOG_ONCE(sceMpegAvcInitYCbCr, Log::ME, "UNIMPL sceMpegAvcInitYCbCr(%08x, %i, %i, %i, %08x)", mpeg, mode, width, height, ycbcr_addr);
return 0;
return hleNoLog(0);
}
static int sceMpegAvcQueryYCbCrSize(u32 mpeg, u32 mode, u32 width, u32 height, u32 resultAddr)
@ -2112,7 +2043,7 @@ static int sceMpegAvcQueryYCbCrSize(u32 mpeg, u32 mode, u32 width, u32 height, u
int size = (width / 2) * (height / 2) * 6 + 128;
Memory::Write_U32(size, resultAddr);
return 0;
return hleNoLog(0);
}
static u32 sceMpegQueryUserdataEsSize(u32 mpeg, u32 esSizeAddr, u32 outSizeAddr)

View file

@ -847,7 +847,7 @@ static u32 sceWlanGetEtherAddr(u32 addrAddr) {
}
NotifyMemInfo(MemBlockFlags::WRITE, addrAddr, 6, "WlanEtherAddr");
return hleLogSuccessI(Log::sceNet, hleDelayResult(0, "get ether mac", 200));
return hleDelayResult(hleLogSuccessI(Log::sceNet, 0), "get ether mac", 200);
}
static u32 sceNetGetLocalEtherAddr(u32 addrAddr) {

View file

@ -2263,7 +2263,7 @@ int sceNetAdhocctlScan() {
// TODO: Valhalla Knights 2 need handler notification, but need to test this on games that doesn't use Adhocctl Handler too (not sure if there are games like that tho)
notifyAdhocctlHandlers(ADHOCCTL_EVENT_ERROR, ERROR_NET_ADHOCCTL_ALREADY_CONNECTED);
hleEatMicro(500);
return 0;
return hleLogDebug(Log::sceNet, 0);
}
// Only scan when in Disconnected state, otherwise AdhocServer will kick you out
@ -2281,7 +2281,7 @@ int sceNetAdhocctlScan() {
if (friendFinderRunning) {
AdhocctlRequest req = { OPCODE_SCAN, {0} };
return WaitBlockingAdhocctlSocket(req, us, "adhocctl scan");
return hleLogSuccessOrError(Log::sceNet, WaitBlockingAdhocctlSocket(req, us, "adhocctl scan"));
}
else {
adhocctlState = ADHOCCTL_STATE_DISCONNECTED;
@ -2291,7 +2291,7 @@ int sceNetAdhocctlScan() {
// Not delaying here may cause Naruto Shippuden Ultimate Ninja Heroes 3 to get disconnected when the mission started
hleEatMicro(us);
// FIXME: When tested using JPCSP + official prx files it seems sceNetAdhocctlScan switching to a different thread for at least 100ms after returning success and before executing the next line?
return hleDelayResult(0, "scan delay", adhocEventPollDelay);
return hleDelayResult(hleLogDebug(Log::sceNet, 0), "scan delay", adhocEventPollDelay);
}
// FIXME: Returning BUSY when previous adhocctl handler's callback is not fully executed yet, But returning success and notifying handler's callback with error (ie. ALREADY_CONNECTED) when previous adhocctl handler's callback is fully executed? Is there a case where error = BUSY sent through handler's callback?
@ -5033,7 +5033,7 @@ static int sceNetAdhocctlGetAddrByName(const char *nickName, u32 sizeAddr, u32 b
peerlock.unlock();
// Return Success
return hleLogDebug(Log::sceNet, hleDelayResult(0, "delay 100 ~ 1000us", 100), "success"); // FIXME: Might have similar delay with GetPeerList? need to know which games using this tho
return hleDelayResult(hleLogDebug(Log::sceNet, 0, "success"), "delay 100 ~ 1000us", 100); // FIXME: Might have similar delay with GetPeerList? need to know which games using this tho
}
// Invalid Arguments

View file

@ -316,9 +316,9 @@ int sceNetInetSelect(int nfds, u32 readfdsPtr, u32 writefdsPtr, u32 exceptfdsPtr
if (retval < 0) {
UpdateErrnoFromHost(socket_errno, __FUNCTION__);
return hleLogDebug(Log::sceNet, hleDelayResult(retval, "workaround until blocking-socket", 500)); // Using hleDelayResult as a workaround for games that need blocking-socket to be implemented (ie. Coded Arms Contagion)
return hleDelayResult(hleLogDebug(Log::sceNet, retval), "workaround until blocking-socket", 500); // Using hleDelayResult as a workaround for games that need blocking-socket to be implemented (ie. Coded Arms Contagion)
}
return hleLogSuccessI(Log::sceNet, hleDelayResult(retval, "workaround until blocking-socket", 500)); // Using hleDelayResult as a workaround for games that need blocking-socket to be implemented (ie. Coded Arms Contagion)
return hleDelayResult(hleLogSuccessI(Log::sceNet, retval), "workaround until blocking-socket", 500); // Using hleDelayResult as a workaround for games that need blocking-socket to be implemented (ie. Coded Arms Contagion)
}
int sceNetInetPoll(u32 fdsPtr, u32 nfds, int timeout) { // timeout in miliseconds just like posix poll? or in microseconds as other PSP timeout?
@ -358,7 +358,7 @@ int sceNetInetPoll(u32 fdsPtr, u32 nfds, int timeout) { // timeout in milisecond
retval = select(maxHostFd + 1, &readfds, &writefds, &exceptfds, /*(timeout<0)? NULL:*/&tmout);
if (retval < 0) {
UpdateErrnoFromHost(EINTR, __FUNCTION__);
return hleLogError(Log::sceNet, hleDelayResult(retval, "workaround until blocking-socket", 500)); // Using hleDelayResult as a workaround for games that need blocking-socket to be implemented
return hleDelayResult(hleLogError(Log::sceNet, retval), "workaround until blocking-socket", 500); // Using hleDelayResult as a workaround for games that need blocking-socket to be implemented
}
retval = 0;
@ -376,7 +376,7 @@ int sceNetInetPoll(u32 fdsPtr, u32 nfds, int timeout) { // timeout in milisecond
VERBOSE_LOG(Log::sceNet, "Poll Socket#%d Fd: %d, events: %04x, revents: %04x, availToRecv: %d", i, fdarray[i].fd, fdarray[i].events, fdarray[i].revents, (int)getAvailToRecv(fdarray[i].fd));
}
//hleEatMicro(1000);
return hleLogSuccessI(Log::sceNet, hleDelayResult(retval, "workaround until blocking-socket", 1000)); // Using hleDelayResult as a workaround for games that need blocking-socket to be implemented
return hleDelayResult(hleLogSuccessI(Log::sceNet, retval), "workaround until blocking-socket", 1000); // Using hleDelayResult as a workaround for games that need blocking-socket to be implemented
}
static int sceNetInetRecv(int socket, u32 bufPtr, u32 bufLen, u32 flags) {
@ -401,7 +401,7 @@ static int sceNetInetRecv(int socket, u32 bufPtr, u32 bufLen, u32 flags) {
DataToHexString(10, 0, Memory::GetPointer(bufPtr), retval, &datahex);
VERBOSE_LOG(Log::sceNet, "Data Dump (%d bytes):\n%s", retval, datahex.c_str());
return hleLogSuccessInfoI(Log::sceNet, hleDelayResult(retval, "workaround until blocking-socket", 500)); // Using hleDelayResult as a workaround for games that need blocking-socket to be implemented
return hleDelayResult(hleLogSuccessInfoI(Log::sceNet, retval), "workaround until blocking-socket", 500); // Using hleDelayResult as a workaround for games that need blocking-socket to be implemented
}
static int sceNetInetSend(int socket, u32 bufPtr, u32 bufLen, u32 flags) {
@ -835,8 +835,8 @@ static int sceNetInetRecvfrom(int socket, u32 bufferPtr, int len, int flags, u32
VERBOSE_LOG(Log::sceNet, "Data Dump (%d bytes):\n%s", retval, datahex.c_str());
// Using hleDelayResult as a workaround for games that need blocking-socket to be implemented (ie. Coded Arms Contagion)
return hleLogSuccessInfoI(Log::sceNet, hleDelayResult(retval, "workaround until blocking-socket", 500),
"RecvFrom: Address = %s, Port = %d", ip2str(saddr.in.sin_addr).c_str(), ntohs(saddr.in.sin_port));
return hleDelayResult(hleLogSuccessInfoI(Log::sceNet, retval,
"RecvFrom: Address = %s, Port = %d", ip2str(saddr.in.sin_addr).c_str(), ntohs(saddr.in.sin_port)), "workaround until blocking-socket", 500);
}
static int sceNetInetSendto(int socket, u32 bufferPtr, int len, int flags, u32 toPtr, int tolen) {

View file

@ -1170,7 +1170,7 @@ static int scePsmfPlayerStop(u32 psmfPlayer) {
int delayUs = 3000;
DelayPsmfStateChange(psmfPlayer, PSMF_PLAYER_STATUS_STANDBY, delayUs);
return hleLogSuccessInfoI(Log::ME, hleDelayResult(0, "psmfplayer stop", delayUs));
return hleDelayResult(hleLogSuccessInfoI(Log::ME, 0), "psmfplayer stop", delayUs);
}
static int scePsmfPlayerBreak(u32 psmfPlayer) {
@ -1230,7 +1230,7 @@ static int _PsmfPlayerSetPsmfOffset(u32 psmfPlayer, const char *filename, int of
psmfplayer->filehandle = pspFileSystem.OpenFile(filename, (FileAccess) FILEACCESS_READ);
if (psmfplayer->filehandle < 0) {
return hleLogError(Log::ME, hleDelayResult(SCE_KERNEL_ERROR_ILLEGAL_ARGUMENT, "psmfplayer set", delayUs), "invalid file data or does not exist");
return hleDelayResult(hleLogError(Log::ME, SCE_KERNEL_ERROR_ILLEGAL_ARGUMENT, "invalid file data or does not exist"), "psmfplayer set", delayUs);
}
if (offset != 0)
@ -1250,7 +1250,7 @@ static int _PsmfPlayerSetPsmfOffset(u32 psmfPlayer, const char *filename, int of
// TODO: Merge better with Psmf.
u16 numStreams = *(u16_be *)(buf + 0x80);
if (numStreams > 128) {
return hleReportError(Log::ME, hleDelayResult(SCE_KERNEL_ERROR_ILLEGAL_ARGUMENT, "psmfplayer set", delayUs), "too many streams in PSMF video, bogus data");
return hleDelayResult(hleReportError(Log::ME, SCE_KERNEL_ERROR_ILLEGAL_ARGUMENT, "too many streams in PSMF video, bogus data"), "psmfplayer set", delayUs);
}
psmfplayer->totalVideoStreams = 0;
@ -1294,7 +1294,7 @@ static int _PsmfPlayerSetPsmfOffset(u32 psmfPlayer, const char *filename, int of
psmfplayer->totalDurationTimestamp = psmfplayer->mediaengine->getLastTimeStamp();
DelayPsmfStateChange(psmfPlayer, PSMF_PLAYER_STATUS_STANDBY, delayUs);
return hleLogSuccessInfoI(Log::ME, hleDelayResult(0, "psmfplayer set", delayUs));
return hleDelayResult(hleLogSuccessInfoI(Log::ME, 0), "psmfplayer set", delayUs);
}
static int scePsmfPlayerSetPsmf(u32 psmfPlayer, const char *filename) {
@ -1463,7 +1463,7 @@ static int scePsmfPlayerStart(u32 psmfPlayer, u32 psmfPlayerData, int initPts)
psmfplayer->seekDestTimeStamp = initPts;
__PsmfPlayerContinueSeek(psmfplayer);
return delayUs == 0 ? 0 : hleDelayResult(0, "psmfplayer start", delayUs);
return delayUs == 0 ? 0 : hleDelayResult(hleNoLog(0), "psmfplayer start", delayUs);
}
static int scePsmfPlayerDelete(u32 psmfPlayer)

View file

@ -394,11 +394,11 @@ static int UtilityWorkUs(int us) {
// Simulate this by allowing a reschedule.
if (us > 1000) {
hleEatMicro(1000);
return hleDelayResult(0, "utility work", us - 1000);
return hleDelayResult(hleNoLog(0), "utility work", us - 1000);
}
hleEatMicro(us);
hleReSchedule("utility work");
return 0;
return hleNoLog(0);
}
static int UtilityInitDialog(int type) {
@ -478,10 +478,8 @@ static int sceUtilitySavedataUpdate(int animSpeed) {
return result;
}
static u32 sceUtilityLoadAvModule(u32 module)
{
if (module > 7)
{
static u32 sceUtilityLoadAvModule(u32 module) {
if (module > 7) {
ERROR_LOG_REPORT(Log::sceUtility, "sceUtilityLoadAvModule(%i): invalid module id", module);
return SCE_ERROR_AV_MODULE_BAD_ID;
}
@ -491,8 +489,7 @@ static u32 sceUtilityLoadAvModule(u32 module)
return hleDelayResult(hleLogSuccessInfoI(Log::sceUtility, 0), "utility av module loaded", 25000);
}
static u32 sceUtilityUnloadAvModule(u32 module)
{
static u32 sceUtilityUnloadAvModule(u32 module) {
if (module == 0)
JpegNotifyLoadStatus(-1);
return hleDelayResult(hleLogSuccessInfoI(Log::sceUtility, 0), "utility av module unloaded", 800);
@ -521,13 +518,12 @@ static u32 sceUtilityLoadModule(u32 module) {
// Some games, like Kamen Rider Climax Heroes OOO, require an error if dependencies aren't loaded yet.
for (const int *dep = info->dependencies; *dep != 0; ++dep) {
if (currentlyLoadedModules.find(*dep) == currentlyLoadedModules.end()) {
u32 result = hleLogError(Log::sceUtility, SCE_KERNEL_ERROR_LIBRARY_NOTFOUND, "dependent module %04x not loaded", *dep);
return hleDelayResult(result, "utility module load attempt", 25000);
return hleDelayResult(hleLogError(Log::sceUtility, SCE_KERNEL_ERROR_LIBRARY_NOTFOUND, "dependent module %04x not loaded", *dep), "utility module load attempt", 25000);
}
}
u32 allocSize = info->size;
char name[64];
char name[128];
snprintf(name, sizeof(name), "UtilityModule/%x", module);
if (allocSize != 0) {
currentlyLoadedModules[module] = userMemory.Alloc(allocSize, false, name);
@ -592,10 +588,11 @@ static int sceUtilityMsgDialogUpdate(int animSpeed) {
return hleLogWarning(Log::sceUtility, SCE_ERROR_UTILITY_WRONG_TYPE, "wrong dialog type");
}
int ret = hleLogSuccessX(Log::sceUtility, msgDialog->Update(animSpeed));
int ret = msgDialog->Update(animSpeed);
if (ret >= 0)
return hleDelayResult(ret, "msgdialog update", 800);
return ret;
return hleDelayResult(hleLogSuccessX(Log::sceUtility, ret), "msgdialog update", 800);
else
return hleLogSuccessX(Log::sceUtility, ret);
}
static int sceUtilityMsgDialogGetStatus() {