Merge pull request #15950 from unknownbrackets/memstruct-cleanup

Remove Memory::WriteStruct() and ReadStruct()
This commit is contained in:
Unknown W. Brackets 2022-09-03 11:25:04 -07:00 committed by GitHub
commit 91ff603fd7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
28 changed files with 519 additions and 487 deletions

View File

@ -116,9 +116,9 @@ int PSPGamedataInstallDialog::Update(int animSpeed) {
WriteSfoFile();
// TODO: What is this? Should one of these update per file or anything?
request.unknownResult1 = readFiles;
request.unknownResult2 = readFiles;
Memory::WriteStruct(param.ptr, &request);
param->unknownResult1 = readFiles;
param->unknownResult2 = readFiles;
param.NotifyWrite("DialogResult");
ChangeStatus(SCE_UTILITY_STATUS_FINISHED, 0);
}
@ -250,8 +250,9 @@ void PSPGamedataInstallDialog::UpdateProgress() {
progressValue = (int)((allReadSize * 100) / allFilesSize);
else
progressValue = 100;
request.progress = progressValue;
Memory::WriteStruct(param.ptr, &request);
param->progress = progressValue;
param.NotifyWrite("DialogResult");
}
void PSPGamedataInstallDialog::DoState(PointerWrap &p) {

View File

@ -214,13 +214,12 @@ static int sub_17A8(u8* data)
return -261;
}
static int sceSdGetLastIndex(u32 addressCtx, u32 addressHash, u32 addressKey)
{
pspChnnlsvContext1 ctx;
Memory::ReadStruct(addressCtx, &ctx);
int res = sceSdGetLastIndex_(ctx, Memory::GetPointerWrite(addressHash), Memory::GetPointerWrite(addressKey));
Memory::WriteStruct(addressCtx, &ctx);
return res;
static int sceSdGetLastIndex(u32 addressCtx, u32 addressHash, u32 addressKey) {
auto ctx = PSPPointer<pspChnnlsvContext1>::Create(addressCtx);
u8 *hash = Memory::GetPointerWrite(addressHash);
if (!ctx.IsValid() || !hash)
return hleLogError(SCEMISC, 0, "Invalid pointer");
return hleLogSuccessI(SCEMISC, sceSdGetLastIndex_(*ctx, hash, Memory::GetPointerWrite(addressKey)));
}
int sceSdGetLastIndex_(pspChnnlsvContext1& ctx, u8* in_hash, u8* in_key)
@ -325,13 +324,11 @@ int sceSdGetLastIndex_(pspChnnlsvContext1& ctx, u8* in_hash, u8* in_key)
return 0;
}
static int sceSdSetIndex(u32 addressCtx, int value)
{
pspChnnlsvContext1 ctx;
Memory::ReadStruct(addressCtx,&ctx);
int res = sceSdSetIndex_(ctx, value);
Memory::WriteStruct(addressCtx,&ctx);
return res;
static int sceSdSetIndex(u32 addressCtx, int value) {
auto ctx = PSPPointer<pspChnnlsvContext1>::Create(addressCtx);
if (!ctx.IsValid())
return hleLogError(SCEMISC, 0, "Invalid pointer");
return hleLogSuccessI(SCEMISC, sceSdSetIndex_(*ctx, value));
}
int sceSdSetIndex_(pspChnnlsvContext1& ctx, int value)
@ -344,14 +341,11 @@ int sceSdSetIndex_(pspChnnlsvContext1& ctx, int value)
}
static int sceSdRemoveValue(u32 addressCtx, u32 addressData, int length)
{
pspChnnlsvContext1 ctx;
Memory::ReadStruct(addressCtx, &ctx);
int res = sceSdRemoveValue_(ctx, Memory::GetPointerWrite(addressData), length);
Memory::WriteStruct(addressCtx, &ctx);
return res;
static int sceSdRemoveValue(u32 addressCtx, u32 addressData, int length) {
auto ctx = PSPPointer<pspChnnlsvContext1>::Create(addressCtx);
if (!ctx.IsValid() || !Memory::IsValidAddress(addressData))
return hleLogError(SCEMISC, 0, "Invalid pointer");
return hleLogSuccessI(SCEMISC, sceSdRemoveValue_(*ctx, Memory::GetPointerWrite(addressData), length));
}
int sceSdRemoveValue_(pspChnnlsvContext1& ctx, u8* data, int length)
@ -396,18 +390,14 @@ int sceSdRemoveValue_(pspChnnlsvContext1& ctx, u8* data, int length)
return 0;
}
static int sceSdCreateList(u32 ctx2Addr, int mode, int unkwn, u32 dataAddr, u32 cryptkeyAddr)
{
pspChnnlsvContext2 ctx2;
Memory::ReadStruct(ctx2Addr, &ctx2);
static int sceSdCreateList(u32 ctx2Addr, int mode, int unkwn, u32 dataAddr, u32 cryptkeyAddr) {
auto ctx2 = PSPPointer<pspChnnlsvContext2>::Create(ctx2Addr);
u8* data = Memory::GetPointerWrite(dataAddr);
u8* cryptkey = Memory::GetPointerWrite(cryptkeyAddr);
if (!ctx2.IsValid() || !data)
return hleLogError(SCEMISC, 0, "Invalid pointer");
int res = sceSdCreateList_(ctx2, mode, unkwn, data, cryptkey);
Memory::WriteStruct(ctx2Addr, &ctx2);
return res;
return hleLogSuccessI(SCEMISC, sceSdCreateList_(*ctx2, mode, unkwn, data, cryptkey));
}
int sceSdCreateList_(pspChnnlsvContext2& ctx2, int mode, int uknw, u8* data, u8* cryptkey)
@ -464,17 +454,13 @@ int sceSdCreateList_(pspChnnlsvContext2& ctx2, int mode, int uknw, u8* data, u8*
return 0;
}
static int sceSdSetMember(u32 ctxAddr, u32 dataAddr, int alignedLen)
{
pspChnnlsvContext2 ctx;
Memory::ReadStruct(ctxAddr, &ctx);
u8* data = Memory::GetPointerWrite(dataAddr);
static int sceSdSetMember(u32 ctxAddr, u32 dataAddr, int alignedLen) {
auto ctx = PSPPointer<pspChnnlsvContext2>::Create(ctxAddr);
u8 *data = Memory::GetPointerWrite(dataAddr);
if (!ctx.IsValid() || !data)
return hleLogError(SCEMISC, 0, "Invalid pointer");
int res = sceSdSetMember_(ctx, data, alignedLen);
Memory::WriteStruct(ctxAddr, &ctx);
return res;
return hleLogSuccessI(SCEMISC, sceSdSetMember_(*ctx, data, alignedLen));
}
int sceSdSetMember_(pspChnnlsvContext2& ctx, u8* data, int alignedLen)
@ -511,15 +497,11 @@ int sceSdSetMember_(pspChnnlsvContext2& ctx, u8* data, int alignedLen)
return res;
}
static int sceChnnlsv_21BE78B4(u32 ctxAddr)
{
pspChnnlsvContext2 ctx;
Memory::ReadStruct(ctxAddr, &ctx);
int res = sceChnnlsv_21BE78B4_(ctx);
Memory::WriteStruct(ctxAddr, &ctx);
return res;
static int sceChnnlsv_21BE78B4(u32 ctxAddr) {
auto ctx = PSPPointer<pspChnnlsvContext2>::Create(ctxAddr);
if (!ctx.IsValid())
return hleLogError(SCEMISC, 0, "Invalid pointer");
return hleLogSuccessI(SCEMISC, sceChnnlsv_21BE78B4_(*ctx));
}
int sceChnnlsv_21BE78B4_(pspChnnlsvContext2& ctx)

View File

@ -486,8 +486,8 @@ public:
// For save states only.
}
FontLib(u32 paramPtr, u32 errorCodePtr) {
Memory::ReadStruct(paramPtr, &params_);
FontLib(FontNewLibParams *params, u32 errorCodePtr) {
params_ = *params;
if (params_.numFonts > 9) {
params_.numFonts = 9;
}
@ -998,7 +998,7 @@ static u32 sceFontNewLib(u32 paramPtr, u32 errorCodePtr) {
INFO_LOG(SCEFONT, "sceFontNewLib(%08x, %08x)", paramPtr, errorCodePtr);
*errorCode = 0;
FontLib *newLib = new FontLib(paramPtr, errorCodePtr);
FontLib *newLib = new FontLib(params, errorCodePtr);
fontLibList.push_back(newLib);
// 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

View File

@ -427,8 +427,6 @@ static int sceGeBreak(u32 mode, u32 unknownPtr) {
}
static u32 sceGeSetCallback(u32 structAddr) {
DEBUG_LOG(SCEGE, "sceGeSetCallback(struct=%08x)", structAddr);
int cbID = -1;
for (size_t i = 0; i < ARRAY_SIZE(ge_used_callbacks); ++i) {
if (!ge_used_callbacks[i]) {
@ -438,12 +436,13 @@ static u32 sceGeSetCallback(u32 structAddr) {
}
if (cbID == -1) {
WARN_LOG(SCEGE, "sceGeSetCallback(): out of callback ids");
return SCE_KERNEL_ERROR_OUT_OF_MEMORY;
return hleLogWarning(SCEGE, SCE_KERNEL_ERROR_OUT_OF_MEMORY, "out of callback ids");
}
ge_used_callbacks[cbID] = true;
Memory::ReadStruct(structAddr, &ge_callback_data[cbID]);
auto callbackData = PSPPointer<PspGeCallbackData>::Create(structAddr);
ge_callback_data[cbID] = *callbackData;
callbackData.NotifyRead("GeSetCallback");
int subIntrBase = __GeSubIntrBase(cbID);
@ -458,7 +457,7 @@ static u32 sceGeSetCallback(u32 structAddr) {
sceKernelEnableSubIntr(PSP_GE_INTR, subIntrBase | PSP_GE_SUBINTR_SIGNAL);
}
return cbID;
return hleLogSuccessI(SCEGE, cbID);
}
static int sceGeUnsetCallback(u32 cbID) {
@ -603,7 +602,7 @@ const HLEFunction sceGe_user[] = {
{0XB287BD61, &WrapU_U<sceGeDrawSync>, "sceGeDrawSync", 'x', "x" },
{0XB448EC0D, &WrapI_UU<sceGeBreak>, "sceGeBreak", 'i', "xx" },
{0X4C06E472, &WrapI_V<sceGeContinue>, "sceGeContinue", 'i', "" },
{0XA4FC06A4, &WrapU_U<sceGeSetCallback>, "sceGeSetCallback", 'x', "x" },
{0XA4FC06A4, &WrapU_U<sceGeSetCallback>, "sceGeSetCallback", 'i', "p" },
{0X05DB22CE, &WrapI_U<sceGeUnsetCallback>, "sceGeUnsetCallback", 'i', "x" },
{0X1F6752AD, &WrapU_V<sceGeEdramGetSize>, "sceGeEdramGetSize", 'x', "" },
{0XB77905EA, &WrapU_I<sceGeEdramSetAddrTranslation>, "sceGeEdramSetAddrTranslation", 'x', "i" },

View File

@ -931,12 +931,12 @@ static u32 sceIoGetstat(const char *filename, u32 addr) {
// TODO: Improve timing (although this seems normally slow..)
int usec = 1000;
SceIoStat stat;
auto stat = PSPPointer<SceIoStat>::Create(addr);
PSPFileInfo info = pspFileSystem.GetFileInfo(filename);
if (info.exists) {
__IoGetStat(&stat, info);
if (Memory::IsValidAddress(addr)) {
Memory::WriteStruct(addr, &stat);
if (stat.IsValid()) {
__IoGetStat(stat, info);
stat.NotifyWrite("IoGetstat");
DEBUG_LOG(SCEIO, "sceIoGetstat(%s, %08x) : sector = %08x", filename, addr, info.startSector);
return hleDelayResult(0, "io getstat", usec);
} else {
@ -1798,19 +1798,23 @@ static u32 sceIoDevctl(const char *name, int cmd, u32 argAddr, int argLen, u32 o
return 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
u32 pointer = Memory::Read_U32(argAddr);
if (Memory::IsValidRange(argAddr, 4) && argLen >= 4) { // NOTE: not outPtr
u32 pointer = Memory::ReadUnchecked_U32(argAddr);
u32 sectorSize = 0x200;
u32 memStickSectorSize = 32 * 1024;
u32 sectorCount = memStickSectorSize / sectorSize;
u64 freeSize = 1 * 1024 * 1024 * 1024;
DeviceSize deviceSize;
deviceSize.maxClusters = (u32)((freeSize * 95 / 100) / (sectorSize * sectorCount));
deviceSize.freeClusters = deviceSize.maxClusters;
deviceSize.maxSectors = deviceSize.maxClusters;
deviceSize.sectorSize = sectorSize;
deviceSize.sectorCount = sectorCount;
Memory::WriteStruct(pointer, &deviceSize);
auto deviceSize = PSPPointer<DeviceSize>::Create(pointer);
if (deviceSize.IsValid()) {
deviceSize->maxClusters = (u32)((freeSize * 95 / 100) / (sectorSize * sectorCount));
deviceSize->freeClusters = deviceSize->maxClusters;
deviceSize->maxSectors = deviceSize->maxClusters;
deviceSize->sectorSize = sectorSize;
deviceSize->sectorCount = sectorCount;
deviceSize.NotifyWrite("ms0:02425818");
}
return 0;
} else {
return ERROR_MEMSTICK_DEVCTL_BAD_PARAMS;
@ -1821,8 +1825,8 @@ static u32 sceIoDevctl(const char *name, int cmd, u32 argAddr, int argLen, u32 o
if (MemoryStick_State() != PSP_MEMORYSTICK_STATE_INSERTED) {
return SCE_KERNEL_ERROR_ERRNO_DEVICE_NOT_FOUND;
}
if (Memory::IsValidAddress(outPtr) && outLen == 4) {
Memory::Write_U32(0, outPtr);
if (Memory::IsValidRange(outPtr, 4) && outLen == 4) {
Memory::WriteUnchecked_U32(0, outPtr);
return 0;
} else {
ERROR_LOG(SCEIO, "Failed 0x02425824 fat");
@ -1939,13 +1943,16 @@ static u32 sceIoDevctl(const char *name, int cmd, u32 argAddr, int argLen, u32 o
u32 memStickSectorSize = 32 * 1024;
u32 sectorCount = memStickSectorSize / sectorSize;
u64 freeSize = 1 * 1024 * 1024 * 1024;
DeviceSize deviceSize;
deviceSize.maxClusters = (u32)((freeSize * 95 / 100) / (sectorSize * sectorCount));
deviceSize.freeClusters = deviceSize.maxClusters;
deviceSize.maxSectors = deviceSize.maxClusters;
deviceSize.sectorSize = sectorSize;
deviceSize.sectorCount = sectorCount;
Memory::WriteStruct(pointer, &deviceSize);
auto deviceSize = PSPPointer<DeviceSize>::Create(pointer);
if (deviceSize.IsValid()) {
deviceSize->maxClusters = (u32)((freeSize * 95 / 100) / (sectorSize * sectorCount));
deviceSize->freeClusters = deviceSize->maxClusters;
deviceSize->maxSectors = deviceSize->maxClusters;
deviceSize->sectorSize = sectorSize;
deviceSize->sectorCount = sectorCount;
deviceSize.NotifyWrite("fatms0:02425818");
}
return 0;
} else {
return ERROR_MEMSTICK_DEVCTL_BAD_PARAMS;

View File

@ -646,12 +646,12 @@ struct SystemStatus {
static int sceKernelReferSystemStatus(u32 statusPtr) {
DEBUG_LOG(SCEKERNEL, "sceKernelReferSystemStatus(%08x)", statusPtr);
if (Memory::IsValidAddress(statusPtr)) {
SystemStatus status;
memset(&status, 0, sizeof(SystemStatus));
status.size = sizeof(SystemStatus);
auto status = PSPPointer<SystemStatus>::Create(statusPtr);
if (status.IsValid()) {
memset((SystemStatus *)status, 0, sizeof(SystemStatus));
status->size = sizeof(SystemStatus);
// TODO: Fill in the struct!
Memory::WriteStruct(statusPtr, &status);
status.NotifyWrite("SystemStatus");
}
return 0;
}
@ -684,11 +684,11 @@ static u32 sceKernelReferThreadProfiler(u32 statusPtr) {
// Can we confirm that the struct above is the right struct?
// If so, re-enable this code.
//DebugProfilerRegs regs;
//memset(&regs, 0, sizeof(regs));
//auto regs = PSPPointer<DebugProfilerRegs>::Create(statusPtr);
// TODO: fill the struct.
//if (Memory::IsValidAddress(statusPtr)) {
// Memory::WriteStruct(statusPtr, &regs);
//if (regs.IsValid()) {
// memset((DebugProfilerRegs *)regs, 0, sizeof(DebugProfilerRegs));
// regs.NotifyWrite("ThreadProfiler");
//}
return 0;
}
@ -715,14 +715,14 @@ const HLEFunction ThreadManForUser[] =
{0XD6DA4BA1, &WrapI_CUIIU<sceKernelCreateSema>, "sceKernelCreateSema", 'i', "sxiix" },
{0X28B6489C, &WrapI_I<sceKernelDeleteSema>, "sceKernelDeleteSema", 'i', "i" },
{0X58B1F937, &WrapI_II<sceKernelPollSema>, "sceKernelPollSema", 'i', "ii" },
{0XBC6FEBC5, &WrapI_IU<sceKernelReferSemaStatus>, "sceKernelReferSemaStatus", 'i', "ix" },
{0XBC6FEBC5, &WrapI_IU<sceKernelReferSemaStatus>, "sceKernelReferSemaStatus", 'i', "ip" },
{0X3F53E640, &WrapI_II<sceKernelSignalSema>, "sceKernelSignalSema", 'i', "ii" },
{0X4E3A1105, &WrapI_IIU<sceKernelWaitSema>, "sceKernelWaitSema", 'i', "iix", HLE_NOT_IN_INTERRUPT | HLE_NOT_DISPATCH_SUSPENDED },
{0X6D212BAC, &WrapI_IIU<sceKernelWaitSemaCB>, "sceKernelWaitSemaCB", 'i', "iix", HLE_NOT_IN_INTERRUPT | HLE_NOT_DISPATCH_SUSPENDED },
{0X60107536, &WrapI_U<sceKernelDeleteLwMutex>, "sceKernelDeleteLwMutex", 'i', "x" },
{0X19CFF145, &WrapI_UCUIU<sceKernelCreateLwMutex>, "sceKernelCreateLwMutex", 'i', "xsxix" },
{0X4C145944, &WrapI_IU<sceKernelReferLwMutexStatusByID>, "sceKernelReferLwMutexStatusByID", 'i', "ix" },
{0X4C145944, &WrapI_IU<sceKernelReferLwMutexStatusByID>, "sceKernelReferLwMutexStatusByID", 'i', "xp" },
// NOTE: LockLwMutex, UnlockLwMutex, and ReferLwMutexStatus are in Kernel_Library, see sceKernelInterrupt.cpp.
// The below should not be called directly.
//{0x71040D5C, nullptr, "_sceKernelTryLockLwMutex", '?', "" },
@ -736,7 +736,7 @@ const HLEFunction ThreadManForUser[] =
{0X6B30100F, &WrapI_II<sceKernelUnlockMutex>, "sceKernelUnlockMutex", 'i', "ii" },
{0XB7D098C6, &WrapI_CUIU<sceKernelCreateMutex>, "sceKernelCreateMutex", 'i', "sxix" },
{0X0DDCD2C9, &WrapI_II<sceKernelTryLockMutex>, "sceKernelTryLockMutex", 'i', "ii" },
{0XA9C2CB9A, &WrapI_IU<sceKernelReferMutexStatus>, "sceKernelReferMutexStatus", 'i', "ix" },
{0XA9C2CB9A, &WrapI_IU<sceKernelReferMutexStatus>, "sceKernelReferMutexStatus", 'i', "ip" },
{0X87D9223C, &WrapI_IIU<sceKernelCancelMutex>, "sceKernelCancelMutex", 'i', "iix" },
{0XFCCFAD26, &WrapI_I<sceKernelCancelWakeupThread>, "sceKernelCancelWakeupThread", 'i', "i" },
@ -818,7 +818,7 @@ const HLEFunction ThreadManForUser[] =
{0XF3986382, &WrapI_IUU<sceKernelReceiveMbxCB>, "sceKernelReceiveMbxCB", 'i', "ixx", HLE_NOT_IN_INTERRUPT | HLE_NOT_DISPATCH_SUSPENDED },
{0X0D81716A, &WrapI_IU<sceKernelPollMbx>, "sceKernelPollMbx", 'i', "ix" },
{0X87D4DD36, &WrapI_IU<sceKernelCancelReceiveMbx>, "sceKernelCancelReceiveMbx", 'i', "ix" },
{0XA8E8C846, &WrapI_IU<sceKernelReferMbxStatus>, "sceKernelReferMbxStatus", 'i', "ix" },
{0XA8E8C846, &WrapI_IU<sceKernelReferMbxStatus>, "sceKernelReferMbxStatus", 'i', "ip" },
{0X7C0DC2A0, &WrapI_CIUUU<sceKernelCreateMsgPipe>, "sceKernelCreateMsgPipe", 'i', "sixxx" },
{0XF0B7DA1C, &WrapI_I<sceKernelDeleteMsgPipe>, "sceKernelDeleteMsgPipe", 'i', "i" },
@ -829,7 +829,7 @@ const HLEFunction ThreadManForUser[] =
{0XFBFA697D, &WrapI_IUUUUU<sceKernelReceiveMsgPipeCB>, "sceKernelReceiveMsgPipeCB", 'i', "ixxxxx" },
{0XDF52098F, &WrapI_IUUUU<sceKernelTryReceiveMsgPipe>, "sceKernelTryReceiveMsgPipe", 'i', "ixxxx" },
{0X349B864D, &WrapI_IUU<sceKernelCancelMsgPipe>, "sceKernelCancelMsgPipe", 'i', "ixx" },
{0X33BE4024, &WrapI_IU<sceKernelReferMsgPipeStatus>, "sceKernelReferMsgPipeStatus", 'i', "ix" },
{0X33BE4024, &WrapI_IU<sceKernelReferMsgPipeStatus>, "sceKernelReferMsgPipeStatus", 'i', "ip" },
{0X56C039B5, &WrapI_CIUUU<sceKernelCreateVpl>, "sceKernelCreateVpl", 'i', "sixxx" },
{0X89B3D48C, &WrapI_I<sceKernelDeleteVpl>, "sceKernelDeleteVpl", 'i', "i" },
@ -838,7 +838,7 @@ const HLEFunction ThreadManForUser[] =
{0XAF36D708, &WrapI_IUU<sceKernelTryAllocateVpl>, "sceKernelTryAllocateVpl", 'i', "ixx" },
{0XB736E9FF, &WrapI_IU<sceKernelFreeVpl>, "sceKernelFreeVpl", 'i', "ix" },
{0X1D371B8A, &WrapI_IU<sceKernelCancelVpl>, "sceKernelCancelVpl", 'i', "ix" },
{0X39810265, &WrapI_IU<sceKernelReferVplStatus>, "sceKernelReferVplStatus", 'i', "ix" },
{0X39810265, &WrapI_IU<sceKernelReferVplStatus>, "sceKernelReferVplStatus", 'i', "ip" },
{0XC07BB470, &WrapI_CUUUUU<sceKernelCreateFpl>, "sceKernelCreateFpl", 'i', "sxxxxx" },
{0XED1410E0, &WrapI_I<sceKernelDeleteFpl>, "sceKernelDeleteFpl", 'i', "i" },
@ -847,7 +847,7 @@ const HLEFunction ThreadManForUser[] =
{0X623AE665, &WrapI_IU<sceKernelTryAllocateFpl>, "sceKernelTryAllocateFpl", 'i', "ix" },
{0XF6414A71, &WrapI_IU<sceKernelFreeFpl>, "sceKernelFreeFpl", 'i', "ix" },
{0XA8AA591F, &WrapI_IU<sceKernelCancelFpl>, "sceKernelCancelFpl", 'i', "ix" },
{0XD8199E4C, &WrapI_IU<sceKernelReferFplStatus>, "sceKernelReferFplStatus", 'i', "ix" },
{0XD8199E4C, &WrapI_IU<sceKernelReferFplStatus>, "sceKernelReferFplStatus", 'i', "ip" },
{0X20FFF560, &WrapU_CU<sceKernelCreateVTimer>, "sceKernelCreateVTimer", 'x', "sx", HLE_NOT_IN_INTERRUPT },
{0X328F9E52, &WrapU_I<sceKernelDeleteVTimer>, "sceKernelDeleteVTimer", 'x', "i", HLE_NOT_IN_INTERRUPT },
@ -866,7 +866,7 @@ const HLEFunction ThreadManForUser[] =
{0X8DAFF657, &WrapI_CUUUUU<sceKernelCreateTlspl>, "sceKernelCreateTlspl", 'i', "sxxxxx" },
{0X32BF938E, &WrapI_I<sceKernelDeleteTlspl>, "sceKernelDeleteTlspl", 'i', "i" },
{0X721067F3, &WrapI_IU<sceKernelReferTlsplStatus>, "sceKernelReferTlsplStatus", 'i', "ix" },
{0X721067F3, &WrapI_IU<sceKernelReferTlsplStatus>, "sceKernelReferTlsplStatus", 'i', "xp" },
// Not completely certain about args.
{0X4A719FB2, &WrapI_I<sceKernelFreeTlspl>, "sceKernelFreeTlspl", 'i', "i" },
// Internal. Takes (uid, &addr) as parameters... probably.
@ -931,7 +931,7 @@ const HLEFunction ThreadManForKernel[] =
{0xF3986382, &WrapI_IUU<sceKernelReceiveMbxCB>, "sceKernelReceiveMbxCB", 'i', "ixx", HLE_KERNEL_SYSCALL | HLE_NOT_IN_INTERRUPT | HLE_NOT_DISPATCH_SUSPENDED },
{0x0D81716A, &WrapI_IU<sceKernelPollMbx>, "sceKernelPollMbx", 'i', "ix", HLE_KERNEL_SYSCALL },
{0x87D4DD36, &WrapI_IU<sceKernelCancelReceiveMbx>, "sceKernelCancelReceiveMbx", 'i', "ix", HLE_KERNEL_SYSCALL },
{0xA8E8C846, &WrapI_IU<sceKernelReferMbxStatus>, "sceKernelReferMbxStatus", 'i', "ix", HLE_KERNEL_SYSCALL },
{0xA8E8C846, &WrapI_IU<sceKernelReferMbxStatus>, "sceKernelReferMbxStatus", 'i', "ip", HLE_KERNEL_SYSCALL },
{0x56C039B5, &WrapI_CIUUU<sceKernelCreateVpl>, "sceKernelCreateVpl", 'i', "sixxx", HLE_KERNEL_SYSCALL },
{0x89B3D48C, &WrapI_I<sceKernelDeleteVpl>, "sceKernelDeleteVpl", 'i', "i", HLE_KERNEL_SYSCALL },
{0xBED27435, &WrapI_IUUU<sceKernelAllocateVpl>, "sceKernelAllocateVpl", 'i', "ixxx", HLE_KERNEL_SYSCALL | HLE_NOT_IN_INTERRUPT | HLE_NOT_DISPATCH_SUSPENDED },
@ -939,7 +939,7 @@ const HLEFunction ThreadManForKernel[] =
{0xAF36D708, &WrapI_IUU<sceKernelTryAllocateVpl>, "sceKernelTryAllocateVpl", 'i', "ixx", HLE_KERNEL_SYSCALL },
{0xB736E9FF, &WrapI_IU<sceKernelFreeVpl>, "sceKernelFreeVpl", 'i', "ix", HLE_KERNEL_SYSCALL },
{0x1D371B8A, &WrapI_IU<sceKernelCancelVpl>, "sceKernelCancelVpl", 'i', "ix", HLE_KERNEL_SYSCALL },
{0x39810265, &WrapI_IU<sceKernelReferVplStatus>, "sceKernelReferVplStatus", 'i', "ix", HLE_KERNEL_SYSCALL },
{0x39810265, &WrapI_IU<sceKernelReferVplStatus>, "sceKernelReferVplStatus", 'i', "ip", HLE_KERNEL_SYSCALL },
};
void Register_ThreadManForUser()

View File

@ -522,14 +522,17 @@ u32 sceKernelReferEventFlagStatus(SceUID id, u32 statusPtr) {
u32 error;
EventFlag *e = kernelObjects.Get<EventFlag>(id, error);
if (e) {
if (!Memory::IsValidAddress(statusPtr))
auto status = PSPPointer<NativeEventFlag>::Create(statusPtr);
if (!status.IsValid())
return hleLogWarning(SCEKERNEL, -1, "invalid ptr");
HLEKernel::CleanupWaitingThreads(WAITTYPE_EVENTFLAG, id, e->waitingThreads);
e->nef.numWaitThreads = (int) e->waitingThreads.size();
if (Memory::Read_U32(statusPtr) != 0)
Memory::WriteStruct(statusPtr, &e->nef);
if (status->size != 0) {
*status = e->nef;
status.NotifyWrite("EventFlagStatus");
}
return hleLogSuccessI(SCEKERNEL, 0);
} else {
return hleLogDebug(SCEKERNEL, error, "invalid event flag");

View File

@ -677,7 +677,7 @@ const HLEFunction Kernel_Library[] =
{0XBEA46419, &WrapI_UIU<sceKernelLockLwMutex>, "sceKernelLockLwMutex", 'i', "xix", HLE_NOT_IN_INTERRUPT | HLE_NOT_DISPATCH_SUSPENDED },
{0X1FC64E09, &WrapI_UIU<sceKernelLockLwMutexCB>, "sceKernelLockLwMutexCB", 'i', "xix", HLE_NOT_IN_INTERRUPT | HLE_NOT_DISPATCH_SUSPENDED },
{0X15B6446B, &WrapI_UI<sceKernelUnlockLwMutex>, "sceKernelUnlockLwMutex", 'i', "xi" },
{0XC1734599, &WrapI_UU<sceKernelReferLwMutexStatus>, "sceKernelReferLwMutexStatus", 'i', "xx" },
{0XC1734599, &WrapI_UU<sceKernelReferLwMutexStatus>, "sceKernelReferLwMutexStatus", 'i', "xp" },
{0X293B45B8, &WrapI_V<sceKernelGetThreadId>, "sceKernelGetThreadId", 'i', "" },
{0XD13BDE95, &WrapI_V<sceKernelCheckThreadStack>, "sceKernelCheckThreadStack", 'i', "" },
{0X1839852A, &WrapU_UUU<sceKernelMemcpy>, "sceKernelMemcpy", 'x', "xxx" },

View File

@ -552,19 +552,17 @@ int sceKernelCancelReceiveMbx(SceUID id, u32 numWaitingThreadsAddr)
return 0;
}
int sceKernelReferMbxStatus(SceUID id, u32 infoAddr)
{
int sceKernelReferMbxStatus(SceUID id, u32 infoAddr) {
u32 error;
Mbx *m = kernelObjects.Get<Mbx>(id, error);
if (!m)
{
ERROR_LOG(SCEKERNEL, "sceKernelReferMbxStatus(%i, %08x): invalid mbx id", id, infoAddr);
return error;
if (!m) {
return hleLogError(SCEKERNEL, error, "invalid mbx id");
}
// Should we crash the thread somehow?
if (!Memory::IsValidAddress(infoAddr))
return -1;
auto info = PSPPointer<NativeMbx>::Create(infoAddr);
if (!info.IsValid())
return hleLogError(SCEKERNEL, -1, "invalid pointer");
for (int i = 0, n = m->nmb.numMessages; i < n; ++i)
m->nmb.packetListHead = Memory::Read_U32(m->nmb.packetListHead);
@ -572,10 +570,10 @@ int sceKernelReferMbxStatus(SceUID id, u32 infoAddr)
HLEKernel::CleanupWaitingThreads(WAITTYPE_MBX, id, m->waitingThreads);
// For whatever reason, it won't write if the size (first member) is 0.
if (Memory::Read_U32(infoAddr) != 0)
{
if (info->size != 0) {
m->nmb.numWaitThreads = (int) m->waitingThreads.size();
Memory::WriteStruct<NativeMbx>(infoAddr, &m->nmb);
*info = m->nmb;
info.NotifyWrite("MbxStatus");
}
return 0;

View File

@ -881,30 +881,26 @@ int sceKernelCancelFpl(SceUID uid, u32 numWaitThreadsPtr)
}
}
int sceKernelReferFplStatus(SceUID uid, u32 statusPtr)
{
int sceKernelReferFplStatus(SceUID uid, u32 statusPtr) {
u32 error;
FPL *fpl = kernelObjects.Get<FPL>(uid, error);
if (fpl)
{
DEBUG_LOG(SCEKERNEL, "sceKernelReferFplStatus(%i, %08x)", uid, statusPtr);
if (fpl) {
// Refresh waiting threads and free block count.
__KernelSortFplThreads(fpl);
fpl->nf.numWaitThreads = (int) fpl->waitingThreads.size();
fpl->nf.numFreeBlocks = 0;
for (int i = 0; i < (int)fpl->nf.numBlocks; ++i)
{
for (int i = 0; i < (int)fpl->nf.numBlocks; ++i) {
if (!fpl->blocks[i])
++fpl->nf.numFreeBlocks;
}
if (Memory::Read_U32(statusPtr) != 0)
Memory::WriteStruct(statusPtr, &fpl->nf);
return 0;
}
else
{
DEBUG_LOG(SCEKERNEL, "sceKernelReferFplStatus(%i, %08x): invalid fpl", uid, statusPtr);
return error;
auto status = PSPPointer<NativeFPL>::Create(statusPtr);
if (status.IsValid() && status->size != 0) {
*status = fpl->nf;
status.NotifyWrite("FplStatus");
}
return hleLogSuccessI(SCEKERNEL, 0);
} else {
return hleLogError(SCEKERNEL, error, "invalid fpl");
}
}
@ -1782,8 +1778,6 @@ int sceKernelReferVplStatus(SceUID uid, u32 infoPtr) {
u32 error;
VPL *vpl = kernelObjects.Get<VPL>(uid, error);
if (vpl) {
DEBUG_LOG(SCEKERNEL, "sceKernelReferVplStatus(%i, %08x)", uid, infoPtr);
__KernelSortVplThreads(vpl);
vpl->nv.numWaitThreads = (int) vpl->waitingThreads.size();
if (vpl->header.IsValid()) {
@ -1791,12 +1785,14 @@ int sceKernelReferVplStatus(SceUID uid, u32 infoPtr) {
} else {
vpl->nv.freeSize = vpl->alloc.GetTotalFreeBytes();
}
if (Memory::IsValidAddress(infoPtr) && Memory::Read_U32(infoPtr) != 0) {
Memory::WriteStruct(infoPtr, &vpl->nv);
auto info = PSPPointer<SceKernelVplInfo>::Create(infoPtr);
if (info.IsValid() && info->size != 0) {
*info = vpl->nv;
info.NotifyWrite("VplStatus");
}
return 0;
return hleLogSuccessI(SCEKERNEL, 0);
} else {
return error;
return hleLogError(SCEKERNEL, error, "invalid vpl");
}
}
@ -2270,23 +2266,23 @@ int sceKernelFreeTlspl(SceUID uid)
return error;
}
int sceKernelReferTlsplStatus(SceUID uid, u32 infoPtr)
{
DEBUG_LOG(SCEKERNEL, "sceKernelReferTlsplStatus(%08x, %08x)", uid, infoPtr);
int sceKernelReferTlsplStatus(SceUID uid, u32 infoPtr) {
u32 error;
TLSPL *tls = kernelObjects.Get<TLSPL>(uid, error);
if (tls)
{
if (tls) {
// Update the waiting threads in case of deletions, etc.
__KernelSortTlsplThreads(tls);
tls->ntls.numWaitThreads = (int) tls->waitingThreads.size();
if (Memory::Read_U32(infoPtr) != 0)
Memory::WriteStruct(infoPtr, &tls->ntls);
return 0;
auto info = PSPPointer<NativeTlspl>::Create(infoPtr);
if (info.IsValid() && info->size != 0) {
*info = tls->ntls;
info.NotifyWrite("TlsplStatus");
}
return hleLogSuccessI(SCEKERNEL, 0);
} else {
return hleLogError(SCEKERNEL, error, "invalid tlspl");
}
else
return error;
}
const HLEFunction SysMemUserForUser[] = {

View File

@ -247,6 +247,10 @@ enum NativeModuleStatus {
class PSPModule : public KernelObject {
public:
PSPModule() {
modulePtr.ptr = 0;
}
~PSPModule() {
if (memoryBlockAddr) {
// If it's either below user memory, or using a high kernel bit, it's in kernel.
@ -258,9 +262,9 @@ public:
g_symbolMap->UnloadModule(memoryBlockAddr, memoryBlockSize);
}
if (modulePtr) {
if (modulePtr.ptr) {
//Only alloc at kernel memory.
kernelMemory.Free(modulePtr);
kernelMemory.Free(modulePtr.ptr);
}
}
const char *GetName() override { return nm.name; }
@ -320,7 +324,7 @@ public:
}
if (s >= 5) {
Do(p, modulePtr);
Do(p, modulePtr.ptr);
}
ModuleWaitingThread mwt = {0};
@ -454,7 +458,7 @@ public:
u32 memoryBlockAddr = 0;
u32 memoryBlockSize = 0;
u32 modulePtr = 0;
PSPPointer<NativeModule> modulePtr;
bool isFake = false;
};
@ -1616,11 +1620,13 @@ static PSPModule *__KernelLoadELFFromPtr(const u8 *ptr, size_t elfSize, u32 load
u32 moduleSize = sizeof(module->nm);
char tag[32];
snprintf(tag, sizeof(tag), "SceModule-%d", module->nm.modid);
module->modulePtr = kernelMemory.Alloc(moduleSize, true, tag);
module->modulePtr.ptr = kernelMemory.Alloc(moduleSize, true, tag);
// Fill the struct.
if (Memory::IsValidAddress(module->modulePtr))
Memory::WriteStruct(module->modulePtr, &module->nm);
if (module->modulePtr.IsValid()) {
*module->modulePtr = module->nm;
module->modulePtr.NotifyWrite("KernelModule");
}
error = 0;
return module;
@ -1763,17 +1769,18 @@ void __KernelLoadReset() {
}
bool __KernelLoadExec(const char *filename, u32 paramPtr, std::string *error_string) {
SceKernelLoadExecParam param;
SceKernelLoadExecParam param{};
PSP_SetLoading("Loading exec...");
if (paramPtr)
Memory::ReadStruct(paramPtr, &param);
else
memset(&param, 0, sizeof(SceKernelLoadExecParam));
auto paramData = PSPPointer<SceKernelLoadExecParam>::Create(paramPtr);
if (paramData.IsValid()) {
param = *paramData;
paramData.NotifyRead("KernelLoadExec");
}
u8 *param_argp = 0;
u8 *param_key = 0;
u8 *param_argp = nullptr;
u8 *param_key = nullptr;
if (param.args > 0) {
u32 argpAddr = param.argp;
param_argp = new u8[param.args];
@ -1792,10 +1799,8 @@ bool __KernelLoadExec(const char *filename, u32 paramPtr, std::string *error_str
if (!info.exists) {
ERROR_LOG(LOADER, "Failed to load executable %s - file doesn't exist", filename);
*error_string = StringFromFormat("Could not find executable %s", filename);
if (paramPtr) {
if (param_argp) delete[] param_argp;
if (param_key) delete[] param_key;
}
delete[] param_argp;
delete[] param_key;
__KernelShutdown();
return false;
}
@ -1817,10 +1822,8 @@ bool __KernelLoadExec(const char *filename, u32 paramPtr, std::string *error_str
ERROR_LOG(LOADER, "Failed to load module %s", filename);
*error_string = "Failed to load executable: " + *error_string;
delete [] temp;
if (paramPtr) {
if (param_argp) delete[] param_argp;
if (param_key) delete[] param_key;
}
delete[] param_argp;
delete[] param_key;
return false;
}
@ -1857,8 +1860,8 @@ bool __KernelLoadExec(const char *filename, u32 paramPtr, std::string *error_str
__KernelStartIdleThreads(module->GetUID());
if (param_argp) delete[] param_argp;
if (param_key) delete[] param_key;
delete[] param_argp;
delete[] param_key;
hleSkipDeadbeef();
return true;
@ -1989,11 +1992,13 @@ u32 sceKernelLoadModule(const char *name, u32 flags, u32 optionAddr) {
u32 moduleSize = sizeof(module->nm);
char tag[32];
snprintf(tag, sizeof(tag), "SceModule-%d", module->nm.modid);
module->modulePtr = kernelMemory.Alloc(moduleSize, true, tag);
module->modulePtr.ptr = kernelMemory.Alloc(moduleSize, true, tag);
// Fill the struct.
if(Memory::IsValidAddress(module->modulePtr))
Memory::WriteStruct(module->modulePtr, &module->nm);
if (module->modulePtr.IsValid()) {
*module->modulePtr = module->nm;
module->modulePtr.NotifyWrite("KernelModule");
}
// TODO: It would be more ideal to allocate memory for this module.
@ -2147,10 +2152,7 @@ int KernelStartModule(SceUID moduleId, u32 argsize, u32 argAddr, u32 returnValue
static void sceKernelStartModule(u32 moduleId, u32 argsize, u32 argAddr, u32 returnValueAddr, u32 optionAddr)
{
SceKernelSMOption smoption = {0};
if (optionAddr) {
Memory::ReadStruct(optionAddr, &smoption);
}
auto smoption = PSPPointer<SceKernelSMOption>::Create(optionAddr);
u32 error;
PSPModule *module = kernelObjects.Get<PSPModule>(moduleId, error);
if (!module) {
@ -2176,7 +2178,7 @@ static void sceKernelStartModule(u32 moduleId, u32 argsize, u32 argAddr, u32 ret
moduleId,argsize,argAddr,returnValueAddr,optionAddr);
bool needsWait;
int ret = KernelStartModule(moduleId, argsize, argAddr, returnValueAddr, optionAddr ? &smoption : nullptr, &needsWait);
int ret = KernelStartModule(moduleId, argsize, argAddr, returnValueAddr, smoption.PtrOrNull(), &needsWait);
if (needsWait) {
__KernelWaitCurThread(WAITTYPE_MODULE, moduleId, 1, 0, false, "started module");
@ -2464,8 +2466,8 @@ u32 sceKernelFindModuleByUID(u32 uid)
ERROR_LOG(SCEMODULE, "0 = sceKernelFindModuleByUID(%d): Module Not Found or Fake", uid);
return 0;
}
INFO_LOG(SCEMODULE, "%d = sceKernelFindModuleByUID(%d)", module->modulePtr, uid);
return module->modulePtr;
INFO_LOG(SCEMODULE, "%d = sceKernelFindModuleByUID(%d)", module->modulePtr.ptr, uid);
return module->modulePtr.ptr;
}
u32 sceKernelFindModuleByName(const char *name)
@ -2477,8 +2479,8 @@ u32 sceKernelFindModuleByName(const char *name)
continue;
if (strcmp(name, module->nm.name) == 0) {
if (!module->isFake) {
INFO_LOG(SCEMODULE, "%d = sceKernelFindModuleByName(%s)", module->modulePtr, name);
return module->modulePtr;
INFO_LOG(SCEMODULE, "%d = sceKernelFindModuleByName(%s)", module->modulePtr.ptr, name);
return module->modulePtr.ptr;
}
else {
WARN_LOG(SCEMODULE, "0 = sceKernelFindModuleByName(%s): Module Fake", name);

View File

@ -1006,33 +1006,27 @@ int sceKernelCancelMsgPipe(SceUID uid, u32 numSendThreadsAddr, u32 numReceiveThr
return 0;
}
int sceKernelReferMsgPipeStatus(SceUID uid, u32 statusPtr)
{
int sceKernelReferMsgPipeStatus(SceUID uid, u32 statusPtr) {
u32 error;
MsgPipe *m = kernelObjects.Get<MsgPipe>(uid, error);
if (m)
{
if (!Memory::IsValidAddress(statusPtr))
{
ERROR_LOG(SCEKERNEL, "sceKernelReferMsgPipeStatus(%i, %08x): invalid address", uid, statusPtr);
return -1;
if (m) {
auto status = PSPPointer<NativeMsgPipe>::Create(statusPtr);
if (!status.IsValid()) {
return hleLogError(SCEKERNEL, -1, "invalid address");
}
DEBUG_LOG(SCEKERNEL, "sceKernelReferMsgPipeStatus(%i, %08x)", uid, statusPtr);
// Clean up any that have timed out.
m->SortReceiveThreads();
m->SortSendThreads();
m->nmp.numSendWaitThreads = (int) m->sendWaitingThreads.size();
m->nmp.numReceiveWaitThreads = (int) m->receiveWaitingThreads.size();
if (Memory::Read_U32(statusPtr) != 0)
Memory::WriteStruct(statusPtr, &m->nmp);
return 0;
}
else
{
DEBUG_LOG(SCEKERNEL, "sceKernelReferMsgPipeStatus(%i, %08x): bad message pipe", uid, statusPtr);
return error;
if (status->size != 0) {
*status = m->nmp;
status.NotifyWrite("MsgPipeStatus");
}
return hleLogSuccessI(SCEKERNEL, 0);
} else {
return hleLogError(SCEKERNEL, error, "bad message pipe");
}
}

View File

@ -664,31 +664,27 @@ int sceKernelUnlockMutex(SceUID id, int count)
return 0;
}
int sceKernelReferMutexStatus(SceUID id, u32 infoAddr)
{
int sceKernelReferMutexStatus(SceUID id, u32 infoAddr) {
u32 error;
PSPMutex *m = kernelObjects.Get<PSPMutex>(id, error);
if (!m)
{
ERROR_LOG(SCEKERNEL, "sceKernelReferMutexStatus(%i, %08x): invalid mutex id", id, infoAddr);
return error;
if (!m) {
return hleLogError(SCEKERNEL, error, "invalid mutex id");
}
DEBUG_LOG(SCEKERNEL, "sceKernelReferMutexStatus(%08x, %08x)", id, infoAddr);
// Should we crash the thread somehow?
if (!Memory::IsValidAddress(infoAddr))
return -1;
auto info = PSPPointer<NativeMutex>::Create(infoAddr);
if (!info.IsValid())
return hleLogError(SCEKERNEL, -1, "invalid pointer");
// Don't write if the size is 0. Anything else is A-OK, though, apparently.
if (Memory::Read_U32(infoAddr) != 0)
{
if (info->size != 0) {
HLEKernel::CleanupWaitingThreads(WAITTYPE_MUTEX, id, m->waitingThreads);
m->nm.numWaitThreads = (int) m->waitingThreads.size();
Memory::WriteStruct(infoAddr, &m->nm);
*info = m->nm;
info.NotifyWrite("MutexStatus");
}
return 0;
return hleLogSuccessI(SCEKERNEL, 0);
}
int sceKernelCreateLwMutex(u32 workareaPtr, const char *name, u32 attr, int initialCount, u32 optionsPtr)
@ -1075,18 +1071,18 @@ int sceKernelUnlockLwMutex(u32 workareaPtr, int count)
return 0;
}
static int __KernelReferLwMutexStatus(SceUID uid, u32 infoPtr)
{
static int __KernelReferLwMutexStatus(SceUID uid, u32 infoPtr) {
u32 error;
LwMutex *m = kernelObjects.Get<LwMutex>(uid, error);
if (!m)
return error;
return hleLogError(SCEKERNEL, error, "invalid id");
// Should we crash the thread somehow?
if (!Memory::IsValidAddress(infoPtr))
return -1;
auto info = PSPPointer<NativeLwMutex>::Create(infoPtr);
if (!info.IsValid())
return hleLogError(SCEKERNEL, -1, "invalid pointer");
if (Memory::Read_U32(infoPtr) != 0)
if (info->size != 0)
{
auto workarea = m->nm.workarea;
@ -1096,44 +1092,21 @@ static int __KernelReferLwMutexStatus(SceUID uid, u32 infoPtr)
m->nm.currentCount = workarea->lockLevel;
m->nm.lockThread = workarea->lockThread == 0 ? SceUID_le(-1) : workarea->lockThread;
m->nm.numWaitThreads = (int) m->waitingThreads.size();
Memory::WriteStruct(infoPtr, &m->nm);
*info = m->nm;
info.NotifyWrite("LwMutexStatus");
}
return 0;
return hleLogSuccessI(SCEKERNEL, 0);
}
int sceKernelReferLwMutexStatusByID(SceUID uid, u32 infoPtr)
{
int error = __KernelReferLwMutexStatus(uid, infoPtr);
if (error >= 0)
{
DEBUG_LOG(SCEKERNEL, "sceKernelReferLwMutexStatusByID(%08x, %08x)", uid, infoPtr);
return error;
}
else
{
ERROR_LOG(SCEKERNEL, "%08x=sceKernelReferLwMutexStatusByID(%08x, %08x)", error, uid, infoPtr);
return error;
}
int sceKernelReferLwMutexStatusByID(SceUID uid, u32 infoPtr) {
return __KernelReferLwMutexStatus(uid, infoPtr);
}
int sceKernelReferLwMutexStatus(u32 workareaPtr, u32 infoPtr)
{
if (!Memory::IsValidAddress(workareaPtr)) {
ERROR_LOG(SCEKERNEL, "Bad workarea pointer for LwMutex");
return SCE_KERNEL_ERROR_ACCESS_ERROR;
}
int sceKernelReferLwMutexStatus(u32 workareaPtr, u32 infoPtr) {
auto workarea = PSPPointer<NativeLwMutexWorkarea>::Create(workareaPtr);
if (!workarea.IsValid()) {
return hleLogError(SCEKERNEL, SCE_KERNEL_ERROR_ACCESS_ERROR, "bad workarea pointer for LwMutex");
}
int error = __KernelReferLwMutexStatus(workarea->uid, infoPtr);
if (error >= 0)
{
DEBUG_LOG(SCEKERNEL, "sceKernelReferLwMutexStatus(%08x, %08x)", workareaPtr, infoPtr);
return error;
}
else
{
ERROR_LOG(SCEKERNEL, "%08x=sceKernelReferLwMutexStatus(%08x, %08x)", error, workareaPtr, infoPtr);
return error;
}
return __KernelReferLwMutexStatus(workarea->uid, infoPtr);
}

View File

@ -263,28 +263,24 @@ int sceKernelDeleteSema(SceUID id)
}
}
int sceKernelReferSemaStatus(SceUID id, u32 infoPtr)
{
int sceKernelReferSemaStatus(SceUID id, u32 infoPtr) {
u32 error;
PSPSemaphore *s = kernelObjects.Get<PSPSemaphore>(id, error);
if (s)
{
DEBUG_LOG(SCEKERNEL, "sceKernelReferSemaStatus(%i, %08x)", id, infoPtr);
if (!Memory::IsValidAddress(infoPtr))
return -1;
if (s) {
auto info = PSPPointer<NativeSemaphore>::Create(infoPtr);
if (!info.IsValid())
return hleLogWarning(SCEKERNEL, -1, "invalid pointer");
HLEKernel::CleanupWaitingThreads(WAITTYPE_SEMA, id, s->waitingThreads);
s->ns.numWaitThreads = (int) s->waitingThreads.size();
if (Memory::Read_U32(infoPtr) != 0)
Memory::WriteStruct(infoPtr, &s->ns);
return 0;
}
else
{
ERROR_LOG(SCEKERNEL, "sceKernelReferSemaStatus: error %08x", error);
return error;
if (info->size != 0) {
*info = s->ns;
info.NotifyWrite("SemaStatus");
}
return hleLogSuccessI(SCEKERNEL, 0);
} else {
return hleLogError(SCEKERNEL, error);
}
}

View File

@ -2902,13 +2902,14 @@ int sceKernelGetCallbackCount(SceUID cbId)
}
}
int sceKernelReferCallbackStatus(SceUID cbId, u32 statusAddr)
{
int sceKernelReferCallbackStatus(SceUID cbId, u32 statusAddr) {
u32 error;
PSPCallback *c = kernelObjects.Get<PSPCallback>(cbId, error);
if (c) {
if (Memory::IsValidAddress(statusAddr) && Memory::Read_U32(statusAddr) != 0) {
Memory::WriteStruct(statusAddr, &c->nc);
auto status = PSPPointer<NativeCallback>::Create(statusAddr);
if (status.IsValid() && status->size != 0) {
*status = c->nc;
status.NotifyWrite("CallbackStatus");
return hleLogSuccessI(SCEKERNEL, 0);
} else {
return hleLogDebug(SCEKERNEL, 0, "struct size was 0");
@ -3789,8 +3790,10 @@ int sceKernelReferThreadEventHandlerStatus(SceUID uid, u32 infoPtr) {
return hleReportError(SCEKERNEL, error, "bad handler id");
}
if (Memory::IsValidAddress(infoPtr) && Memory::Read_U32(infoPtr) != 0) {
Memory::WriteStruct(infoPtr, &teh->nteh);
auto info = PSPPointer<NativeThreadEventHandler>::Create(infoPtr);
if (info.IsValid() && info->size != 0) {
*info = teh->nteh;
info.NotifyWrite("ThreadEventHandlerStatus");
return hleLogSuccessI(SCEKERNEL, 0);
} else {
return hleLogDebug(SCEKERNEL, 0, "struct size was 0");

View File

@ -125,7 +125,7 @@ struct SceMpegLLI
};
void SceMpegAu::read(u32 addr) {
Memory::ReadStruct(addr, this);
Memory::Memcpy(this, addr, sizeof(this), "SceMpegAu");
pts = (pts & 0xFFFFFFFFULL) << 32 | (((u64)pts) >> 32);
dts = (dts & 0xFFFFFFFFULL) << 32 | (((u64)dts) >> 32);
}
@ -133,7 +133,7 @@ void SceMpegAu::read(u32 addr) {
void SceMpegAu::write(u32 addr) {
pts = (pts & 0xFFFFFFFFULL) << 32 | (((u64)pts) >> 32);
dts = (dts & 0xFFFFFFFFULL) << 32 | (((u64)dts) >> 32);
Memory::WriteStruct(addr, this);
Memory::Memcpy(addr, this, sizeof(this), "SceMpegAu");
}
/*
@ -2410,15 +2410,15 @@ static u32 sceMpegBasePESpacketCopy(u32 p)
{
pmp_videoSource = p;
pmp_nBlocks = 0;
SceMpegLLI lli;
while (1){
Memory::ReadStruct(p, &lli);
auto lli = PSPPointer<SceMpegLLI>::Create(p);
while (lli.IsValid()) {
pmp_nBlocks++;
// lli.Next ==0 for last block
if (lli.Next == 0){
if (lli->Next == 0){
break;
}
p = p + sizeof(SceMpegLLI);
++lli;
}
DEBUG_LOG(ME, "sceMpegBasePESpacketCopy(%08x), received %d block(s)", pmp_videoSource, pmp_nBlocks);

View File

@ -785,11 +785,12 @@ static void sceNetEtherStrton(u32 bufferPtr, u32 macPtr) {
// Write static data since we don't actually manage any memory for sceNet* yet.
static int sceNetGetMallocStat(u32 statPtr) {
VERBOSE_LOG(SCENET, "UNTESTED sceNetGetMallocStat(%x) at %08x", statPtr, currentMIPS->pc);
if(Memory::IsValidAddress(statPtr))
Memory::WriteStruct(statPtr, &netMallocStat);
else
ERROR_LOG(SCENET, "UNTESTED sceNetGetMallocStat(%x): tried to request invalid address!", statPtr);
auto stat = PSPPointer<SceNetMallocStat>::Create(statPtr);
if (!stat.IsValid())
return hleLogError(SCENET, 0, "invalid address");
*stat = netMallocStat;
stat.NotifyWrite("sceNetGetMallocStat");
return 0;
}
@ -893,77 +894,128 @@ static int sceNetApctlGetInfo(int code, u32 pInfoAddr) {
if (!netApctlInited)
return hleLogError(SCENET, ERROR_NET_APCTL_NOT_IN_BSS, "apctl not in bss"); // Only have valid info after joining an AP and got an IP, right?
if (!Memory::IsValidAddress(pInfoAddr))
return hleLogError(SCENET, -1, "apctl invalid arg");
u8* info = Memory::GetPointerWrite(pInfoAddr); // FIXME: Points to a union instead of a struct thus each field have the same address
switch (code) {
case PSP_NET_APCTL_INFO_PROFILE_NAME:
Memory::WriteStruct(pInfoAddr, &netApctlInfo.name);
if (!Memory::IsValidRange(pInfoAddr, APCTL_PROFILENAME_MAXLEN))
return hleLogError(SCENET, -1, "apctl invalid arg");
Memory::MemcpyUnchecked(pInfoAddr, netApctlInfo.name, APCTL_PROFILENAME_MAXLEN);
NotifyMemInfo(MemBlockFlags::WRITE, pInfoAddr, APCTL_PROFILENAME_MAXLEN, "NetApctlGetInfo");
DEBUG_LOG(SCENET, "ApctlInfo - ProfileName: %s", netApctlInfo.name);
break;
case PSP_NET_APCTL_INFO_BSSID:
Memory::WriteStruct(pInfoAddr, &netApctlInfo.bssid);
if (!Memory::IsValidRange(pInfoAddr, ETHER_ADDR_LEN))
return hleLogError(SCENET, -1, "apctl invalid arg");
Memory::MemcpyUnchecked(pInfoAddr, netApctlInfo.bssid, ETHER_ADDR_LEN);
DEBUG_LOG(SCENET, "ApctlInfo - BSSID: %s", mac2str((SceNetEtherAddr*)&netApctlInfo.bssid).c_str());
NotifyMemInfo(MemBlockFlags::WRITE, pInfoAddr, ETHER_ADDR_LEN, "NetApctlGetInfo");
break;
case PSP_NET_APCTL_INFO_SSID:
Memory::WriteStruct(pInfoAddr, &netApctlInfo.ssid);
if (!Memory::IsValidRange(pInfoAddr, APCTL_SSID_MAXLEN))
return hleLogError(SCENET, -1, "apctl invalid arg");
Memory::MemcpyUnchecked(pInfoAddr, netApctlInfo.ssid, APCTL_SSID_MAXLEN);
NotifyMemInfo(MemBlockFlags::WRITE, pInfoAddr, APCTL_SSID_MAXLEN, "NetApctlGetInfo");
DEBUG_LOG(SCENET, "ApctlInfo - SSID: %s", netApctlInfo.ssid);
break;
case PSP_NET_APCTL_INFO_SSID_LENGTH:
Memory::WriteStruct(pInfoAddr, &netApctlInfo.ssidLength);
if (!Memory::IsValidRange(pInfoAddr, 4))
return hleLogError(SCENET, -1, "apctl invalid arg");
Memory::WriteUnchecked_U32(netApctlInfo.ssidLength, pInfoAddr);
NotifyMemInfo(MemBlockFlags::WRITE, pInfoAddr, 4, "NetApctlGetInfo");
break;
case PSP_NET_APCTL_INFO_SECURITY_TYPE:
Memory::WriteStruct(pInfoAddr, &netApctlInfo.securityType);
if (!Memory::IsValidRange(pInfoAddr, 4))
return hleLogError(SCENET, -1, "apctl invalid arg");
Memory::WriteUnchecked_U32(netApctlInfo.securityType, pInfoAddr);
NotifyMemInfo(MemBlockFlags::WRITE, pInfoAddr, 4, "NetApctlGetInfo");
break;
case PSP_NET_APCTL_INFO_STRENGTH:
Memory::WriteStruct(pInfoAddr, &netApctlInfo.strength);
if (!Memory::IsValidRange(pInfoAddr, 1))
return hleLogError(SCENET, -1, "apctl invalid arg");
Memory::WriteUnchecked_U8(netApctlInfo.strength, pInfoAddr);
NotifyMemInfo(MemBlockFlags::WRITE, pInfoAddr, 1, "NetApctlGetInfo");
break;
case PSP_NET_APCTL_INFO_CHANNEL:
Memory::WriteStruct(pInfoAddr, &netApctlInfo.channel);
if (!Memory::IsValidRange(pInfoAddr, 1))
return hleLogError(SCENET, -1, "apctl invalid arg");
Memory::WriteUnchecked_U8(netApctlInfo.channel, pInfoAddr);
NotifyMemInfo(MemBlockFlags::WRITE, pInfoAddr, 1, "NetApctlGetInfo");
break;
case PSP_NET_APCTL_INFO_POWER_SAVE:
Memory::WriteStruct(pInfoAddr, &netApctlInfo.powerSave);
if (!Memory::IsValidRange(pInfoAddr, 1))
return hleLogError(SCENET, -1, "apctl invalid arg");
Memory::WriteUnchecked_U8(netApctlInfo.powerSave, pInfoAddr);
NotifyMemInfo(MemBlockFlags::WRITE, pInfoAddr, 1, "NetApctlGetInfo");
break;
case PSP_NET_APCTL_INFO_IP:
Memory::WriteStruct(pInfoAddr, &netApctlInfo.ip);
if (!Memory::IsValidRange(pInfoAddr, APCTL_IPADDR_MAXLEN))
return hleLogError(SCENET, -1, "apctl invalid arg");
Memory::MemcpyUnchecked(pInfoAddr, netApctlInfo.ip, APCTL_IPADDR_MAXLEN);
NotifyMemInfo(MemBlockFlags::WRITE, pInfoAddr, APCTL_IPADDR_MAXLEN, "NetApctlGetInfo");
DEBUG_LOG(SCENET, "ApctlInfo - IP: %s", netApctlInfo.ip);
break;
case PSP_NET_APCTL_INFO_SUBNETMASK:
Memory::WriteStruct(pInfoAddr, &netApctlInfo.subNetMask);
if (!Memory::IsValidRange(pInfoAddr, APCTL_IPADDR_MAXLEN))
return hleLogError(SCENET, -1, "apctl invalid arg");
Memory::MemcpyUnchecked(pInfoAddr, netApctlInfo.subNetMask, APCTL_IPADDR_MAXLEN);
NotifyMemInfo(MemBlockFlags::WRITE, pInfoAddr, APCTL_IPADDR_MAXLEN, "NetApctlGetInfo");
DEBUG_LOG(SCENET, "ApctlInfo - SubNet Mask: %s", netApctlInfo.subNetMask);
break;
case PSP_NET_APCTL_INFO_GATEWAY:
Memory::WriteStruct(pInfoAddr, &netApctlInfo.gateway);
if (!Memory::IsValidRange(pInfoAddr, APCTL_IPADDR_MAXLEN))
return hleLogError(SCENET, -1, "apctl invalid arg");
Memory::MemcpyUnchecked(pInfoAddr, netApctlInfo.gateway, APCTL_IPADDR_MAXLEN);
DEBUG_LOG(SCENET, "ApctlInfo - Gateway IP: %s", netApctlInfo.gateway);
break;
case PSP_NET_APCTL_INFO_PRIMDNS:
Memory::WriteStruct(pInfoAddr, &netApctlInfo.primaryDns);
if (!Memory::IsValidRange(pInfoAddr, APCTL_IPADDR_MAXLEN))
return hleLogError(SCENET, -1, "apctl invalid arg");
Memory::MemcpyUnchecked(pInfoAddr, netApctlInfo.primaryDns, APCTL_IPADDR_MAXLEN);
NotifyMemInfo(MemBlockFlags::WRITE, pInfoAddr, APCTL_IPADDR_MAXLEN, "NetApctlGetInfo");
DEBUG_LOG(SCENET, "ApctlInfo - Primary DNS: %s", netApctlInfo.primaryDns);
break;
case PSP_NET_APCTL_INFO_SECDNS:
Memory::WriteStruct(pInfoAddr, &netApctlInfo.secondaryDns);
if (!Memory::IsValidRange(pInfoAddr, APCTL_IPADDR_MAXLEN))
return hleLogError(SCENET, -1, "apctl invalid arg");
Memory::MemcpyUnchecked(pInfoAddr, netApctlInfo.secondaryDns, APCTL_IPADDR_MAXLEN);
NotifyMemInfo(MemBlockFlags::WRITE, pInfoAddr, APCTL_IPADDR_MAXLEN, "NetApctlGetInfo");
DEBUG_LOG(SCENET, "ApctlInfo - Secondary DNS: %s", netApctlInfo.secondaryDns);
break;
case PSP_NET_APCTL_INFO_USE_PROXY:
Memory::WriteStruct(pInfoAddr, &netApctlInfo.useProxy);
if (!Memory::IsValidRange(pInfoAddr, 4))
return hleLogError(SCENET, -1, "apctl invalid arg");
Memory::WriteUnchecked_U32(netApctlInfo.useProxy, pInfoAddr);
NotifyMemInfo(MemBlockFlags::WRITE, pInfoAddr, 4, "NetApctlGetInfo");
break;
case PSP_NET_APCTL_INFO_PROXY_URL:
Memory::WriteStruct(pInfoAddr, &netApctlInfo.proxyUrl);
if (!Memory::IsValidRange(pInfoAddr, APCTL_URL_MAXLEN))
return hleLogError(SCENET, -1, "apctl invalid arg");
Memory::MemcpyUnchecked(pInfoAddr, netApctlInfo.proxyUrl, APCTL_URL_MAXLEN);
NotifyMemInfo(MemBlockFlags::WRITE, pInfoAddr, APCTL_URL_MAXLEN, "NetApctlGetInfo");
DEBUG_LOG(SCENET, "ApctlInfo - Proxy URL: %s", netApctlInfo.proxyUrl);
break;
case PSP_NET_APCTL_INFO_PROXY_PORT:
Memory::WriteStruct(pInfoAddr, &netApctlInfo.proxyPort);
if (!Memory::IsValidRange(pInfoAddr, 2))
return hleLogError(SCENET, -1, "apctl invalid arg");
Memory::WriteUnchecked_U16(netApctlInfo.proxyPort, pInfoAddr);
NotifyMemInfo(MemBlockFlags::WRITE, pInfoAddr, 2, "NetApctlGetInfo");
break;
case PSP_NET_APCTL_INFO_8021_EAP_TYPE:
Memory::WriteStruct(pInfoAddr, &netApctlInfo.eapType);
if (!Memory::IsValidRange(pInfoAddr, 4))
return hleLogError(SCENET, -1, "apctl invalid arg");
Memory::WriteUnchecked_U32(netApctlInfo.eapType, pInfoAddr);
NotifyMemInfo(MemBlockFlags::WRITE, pInfoAddr, 4, "NetApctlGetInfo");
break;
case PSP_NET_APCTL_INFO_START_BROWSER:
Memory::WriteStruct(pInfoAddr, &netApctlInfo.startBrowser);
if (!Memory::IsValidRange(pInfoAddr, 4))
return hleLogError(SCENET, -1, "apctl invalid arg");
Memory::WriteUnchecked_U32(netApctlInfo.startBrowser, pInfoAddr);
NotifyMemInfo(MemBlockFlags::WRITE, pInfoAddr, 4, "NetApctlGetInfo");
break;
case PSP_NET_APCTL_INFO_WIFISP:
Memory::WriteStruct(pInfoAddr, &netApctlInfo.wifisp);
if (!Memory::IsValidRange(pInfoAddr, 4))
return hleLogError(SCENET, -1, "apctl invalid arg");
Memory::WriteUnchecked_U32(netApctlInfo.wifisp, pInfoAddr);
NotifyMemInfo(MemBlockFlags::WRITE, pInfoAddr, 4, "NetApctlGetInfo");
break;
default:
return hleLogError(SCENET, ERROR_NET_APCTL_INVALID_CODE, "apctl invalid code");
@ -1234,28 +1286,28 @@ int NetApctl_GetBSSDescEntryUser(int entryId, int infoId, u32 resultAddr) {
switch (infoId) {
case PSP_NET_APCTL_DESC_IBSS: // IBSS, 6 bytes
if (entryId == 0)
Memory::WriteStruct(resultAddr, &netApctlInfo.bssid);
Memory::Memcpy(resultAddr, netApctlInfo.bssid, sizeof(netApctlInfo.bssid), "GetBSSDescEntryUser");
else {
// Generate a BSSID/MAC address
char dummyMAC[ETHER_ADDR_LEN];
memset(dummyMAC, entryId, sizeof(dummyMAC));
// Making sure the 1st 2-bits on the 1st byte of OUI are zero to prevent issue with some games (ie. Gran Turismo)
dummyMAC[0] &= 0xfc;
Memory::WriteStruct(resultAddr, &dummyMAC);
Memory::Memcpy(resultAddr, dummyMAC, sizeof(dummyMAC), "GetBSSDescEntryUser");
}
break;
case PSP_NET_APCTL_DESC_SSID_NAME:
// Return 32 bytes
if (entryId == 0)
Memory::WriteStruct(resultAddr, &netApctlInfo.ssid);
Memory::Memcpy(resultAddr, netApctlInfo.ssid, sizeof(netApctlInfo.ssid), "GetBSSDescEntryUser");
else {
Memory::WriteStruct(resultAddr, &dummySSID);
Memory::Memcpy(resultAddr, dummySSID, sizeof(dummySSID), "GetBSSDescEntryUser");
}
break;
case PSP_NET_APCTL_DESC_SSID_NAME_LENGTH:
// Return one 32-bit value
if (entryId == 0)
Memory::WriteStruct(resultAddr, &netApctlInfo.ssidLength);
Memory::Write_U32(netApctlInfo.ssidLength, resultAddr);
else {
// Calculate the SSID length
Memory::Write_U32((u32)strlen(dummySSID), resultAddr);
@ -1264,7 +1316,7 @@ int NetApctl_GetBSSDescEntryUser(int entryId, int infoId, u32 resultAddr) {
case PSP_NET_APCTL_DESC_CHANNEL:
// FIXME: Return one 1 byte value or may be 32-bit if this is not a channel?
if (entryId == 0)
Memory::WriteStruct(resultAddr, &netApctlInfo.channel);
Memory::Write_U8(netApctlInfo.channel, resultAddr);
else {
// Generate channel for testing purposes, not even sure whether this is channel or not, MGS:PW seems to treat the data as u8
Memory::Write_U8(entryId, resultAddr);
@ -1273,7 +1325,7 @@ int NetApctl_GetBSSDescEntryUser(int entryId, int infoId, u32 resultAddr) {
case PSP_NET_APCTL_DESC_SIGNAL_STRENGTH:
// Return 1 byte
if (entryId == 0)
Memory::WriteStruct(resultAddr, &netApctlInfo.strength);
Memory::Write_U8(netApctlInfo.strength, resultAddr);
else {
// Randomize signal strength between 1%~99% since games like MGS:PW are using signal strength to determine the strength of the recruit
Memory::Write_U8((int)(((float)rand() / (float)RAND_MAX) * 99.0 + 1.0), resultAddr);
@ -1281,7 +1333,7 @@ int NetApctl_GetBSSDescEntryUser(int entryId, int infoId, u32 resultAddr) {
break;
case PSP_NET_APCTL_DESC_SECURITY:
// Return one 32-bit value
Memory::WriteStruct(resultAddr, &netApctlInfo.securityType);
Memory::Write_U32(netApctlInfo.securityType, resultAddr);
break;
default:
return hleLogError(SCENET, ERROR_NET_APCTL_INVALID_CODE, "unknown info id");
@ -1432,7 +1484,7 @@ const HLEFunction sceNet[] = {
{0XD27961C9, &WrapV_UU<sceNetEtherStrton>, "sceNetEtherStrton", 'v', "xx" },
{0X0BF0A3AE, &WrapU_U<sceNetGetLocalEtherAddr>, "sceNetGetLocalEtherAddr", 'x', "x" },
{0X50647530, &WrapI_I<sceNetFreeThreadinfo>, "sceNetFreeThreadinfo", 'i', "i" },
{0XCC393E48, &WrapI_U<sceNetGetMallocStat>, "sceNetGetMallocStat", 'i', "x" },
{0XCC393E48, &WrapI_U<sceNetGetMallocStat>, "sceNetGetMallocStat", 'i', "p" },
{0XAD6844C6, &WrapI_I<sceNetThreadAbort>, "sceNetThreadAbort", 'i', "i" },
};

View File

@ -1303,8 +1303,10 @@ static u32 sceNetAdhocctlInit(int stackSize, int prio, u32 productAddr) {
if (netAdhocctlInited)
return ERROR_NET_ADHOCCTL_ALREADY_INITIALIZED;
if (Memory::IsValidAddress(productAddr)) {
Memory::ReadStruct(productAddr, &product_code);
auto product = PSPPointer<SceNetAdhocctlAdhocId>::Create(productAddr);
if (product.IsValid()) {
product_code = *product;
product.NotifyRead("NetAdhocctlInit");
}
adhocctlEvents.clear();
@ -1539,21 +1541,17 @@ static int sceNetAdhocctlGetParameter(u32 paramAddr) {
}
// Library initialized
if (netAdhocctlInited) {
// Valid Arguments
if (Memory::IsValidAddress(paramAddr)) {
// Copy Parameter
Memory::WriteStruct(paramAddr,&parameter);
// Return Success
return 0;
}
// Invalid Arguments
return ERROR_NET_ADHOCCTL_INVALID_ARG;
if (!netAdhocctlInited) {
return hleLogError(SCENET, ERROR_NET_ADHOCCTL_NOT_INITIALIZED);
}
// Library uninitialized
return ERROR_NET_ADHOCCTL_NOT_INITIALIZED;
auto ptr = PSPPointer<SceNetAdhocctlParameter>::Create(paramAddr);
if (!ptr.IsValid())
return hleLogError(SCENET, ERROR_NET_ADHOCCTL_INVALID_ARG);
*ptr = parameter;
ptr.NotifyWrite("NetAdhocctlGetParameter");
return 0;
}
/**
@ -2258,25 +2256,17 @@ static int sceNetAdhocPdpDelete(int id, int unknown) {
static int sceNetAdhocctlGetAdhocId(u32 productStructAddr) {
INFO_LOG(SCENET, "sceNetAdhocctlGetAdhocId(%08x) at %08x", productStructAddr, currentMIPS->pc);
// Library initialized
if (netAdhocctlInited)
{
// Valid Arguments
if (Memory::IsValidAddress(productStructAddr))
{
// Copy Product ID
Memory::WriteStruct(productStructAddr, &product_code);
if (!netAdhocctlInited)
return hleLogDebug(SCENET, ERROR_NET_ADHOCCTL_NOT_INITIALIZED, "not initialized");
// Return Success
return hleLogDebug(SCENET, 0, "type = %d, code = %s", product_code.type, product_code.data);
}
// Invalid Arguments
auto productStruct = PSPPointer<SceNetAdhocctlAdhocId>::Create(productStructAddr);
if (!productStruct.IsValid())
return hleLogDebug(SCENET, ERROR_NET_ADHOCCTL_INVALID_ARG, "invalid arg");
}
// Library uninitialized
return hleLogDebug(SCENET, ERROR_NET_ADHOCCTL_NOT_INITIALIZED, "not initialized");
*productStruct = product_code;
productStruct.NotifyWrite("NetAdhocctlGetAdhocId");
return hleLogDebug(SCENET, 0, "type = %d, code = %s", product_code.type, product_code.data);
}
// FIXME: Scan probably not a blocking function since there is ADHOCCTL_STATE_SCANNING state that can be polled by the game, right? But apparently it need to be delayed for Naruto Shippuden Ultimate Ninja Heroes 3

View File

@ -154,15 +154,15 @@ static int sceNpGetOnlineId(u32 idPtr)
{
WARN_LOG(SCENET, "UNTESTED %s(%08x)", __FUNCTION__, idPtr);
if (!Memory::IsValidAddress(idPtr))
auto id = PSPPointer<SceNpOnlineId>::Create(idPtr);
if (!id.IsValid())
return hleLogError(SCENET, SCE_NP_ERROR_INVALID_ARGUMENT, "invalid arg");
SceNpOnlineId dummyOnlineId{};
truncate_cpy(dummyOnlineId.data, sizeof(dummyOnlineId.data), npOnlineId.c_str());
memset((SceNpOnlineId *)id, 0, sizeof(SceNpOnlineId));
truncate_cpy(id->data, sizeof(id->data), npOnlineId.c_str());
id.NotifyWrite("NpGetOnlineId");
INFO_LOG(SCENET, "%s - Online ID: %s", __FUNCTION__, dummyOnlineId.data);
Memory::WriteStruct(idPtr, &dummyOnlineId);
INFO_LOG(SCENET, "%s - Online ID: %s", __FUNCTION__, id->data);
return 0;
}
@ -177,20 +177,21 @@ static int sceNpGetNpId(u32 idPtr)
{
WARN_LOG(SCENET, "UNTESTED %s(%08x)", __FUNCTION__, idPtr);
if (!Memory::IsValidAddress(idPtr))
auto id = PSPPointer<SceNpId>::Create(idPtr);
if (!id.IsValid())
return hleLogError(SCENET, SCE_NP_ERROR_INVALID_ARGUMENT, "invalid arg");
SceNpId dummyNpId{};
int retval = NpGetNpId(&dummyNpId);
memset((SceNpId *)id, 0, sizeof(SceNpId));
int retval = NpGetNpId(id);
if (retval < 0)
return hleLogError(SCENET, retval);
INFO_LOG(SCENET, "%s - Online ID: %s", __FUNCTION__, dummyNpId.handle.data);
INFO_LOG(SCENET, "%s - Online ID: %s", __FUNCTION__, id->handle.data);
std::string datahex;
DataToHexString(dummyNpId.opt, sizeof(dummyNpId.opt), &datahex);
DataToHexString(id->opt, sizeof(id->opt), &datahex);
INFO_LOG(SCENET, "%s - Options?: %s", __FUNCTION__, datahex.c_str());
Memory::WriteStruct(idPtr, &dummyNpId);
id.NotifyWrite("NpGetNpId");
return 0;
}
@ -199,19 +200,21 @@ static int sceNpGetAccountRegion(u32 countryCodePtr, u32 regionCodePtr)
{
WARN_LOG(SCENET, "UNTESTED %s(%08x, %08x)", __FUNCTION__, countryCodePtr, regionCodePtr);
if (!Memory::IsValidAddress(countryCodePtr) || !Memory::IsValidAddress(regionCodePtr))
auto countryCode = PSPPointer<SceNpCountryCode>::Create(countryCodePtr);
auto regionCode = PSPPointer<SceNpCountryCode>::Create(regionCodePtr);
if (!countryCode.IsValid() || !regionCode.IsValid())
return hleLogError(SCENET, SCE_NP_ERROR_INVALID_ARGUMENT, "invalid arg");
SceNpCountryCode dummyCountryCode{};
memcpy(dummyCountryCode.data, npCountryCode, sizeof(dummyCountryCode.data));
SceNpCountryCode dummyRegionCode{};
memcpy(dummyRegionCode.data, npRegionCode, sizeof(dummyRegionCode.data));
memset((SceNpCountryCode *)countryCode, 0, sizeof(SceNpCountryCode));
memcpy(countryCode->data, npCountryCode, sizeof(countryCode->data));
memset((SceNpCountryCode *)regionCode, 0, sizeof(SceNpCountryCode));
memcpy(regionCode->data, npRegionCode, sizeof(regionCode->data));
INFO_LOG(SCENET, "%s - Country Code: %s", __FUNCTION__, dummyCountryCode.data);
INFO_LOG(SCENET, "%s - Region? Code: %s", __FUNCTION__, dummyRegionCode.data);
INFO_LOG(SCENET, "%s - Country Code: %s", __FUNCTION__, countryCode->data);
INFO_LOG(SCENET, "%s - Region? Code: %s", __FUNCTION__, regionCode->data);
Memory::WriteStruct(countryCodePtr, &dummyCountryCode);
Memory::WriteStruct(regionCodePtr, &dummyRegionCode);
countryCode.NotifyWrite("NpGetAccountRegion");
regionCode.NotifyWrite("NpGetAccountRegion");
return 0;
}
@ -220,14 +223,16 @@ static int sceNpGetMyLanguages(u32 langListPtr)
{
WARN_LOG(SCENET, "UNTESTED %s(%08x)", __FUNCTION__, langListPtr);
if (!Memory::IsValidAddress(langListPtr))
auto langList = PSPPointer<SceNpMyLanguages>::Create(langListPtr);
if (!langList.IsValid())
return hleLogError(SCENET, SCE_NP_ERROR_INVALID_ARGUMENT, "invalid arg");
INFO_LOG(SCENET, "%s - Language1 Code: %d", __FUNCTION__, npMyLangList.language1);
INFO_LOG(SCENET, "%s - Language2 Code: %d", __FUNCTION__, npMyLangList.language2);
INFO_LOG(SCENET, "%s - Language3 Code: %d", __FUNCTION__, npMyLangList.language3);
Memory::WriteStruct(langListPtr, &npMyLangList);
*langList = npMyLangList;
langList.NotifyWrite("NpGetMyLanguages");
return 0;
}
@ -236,20 +241,21 @@ static int sceNpGetUserProfile(u32 profilePtr)
{
WARN_LOG(SCENET, "UNTESTED %s(%08x)", __FUNCTION__, profilePtr);
auto profile = PSPPointer<SceNpUserInformation>::Create(profilePtr);
if (!Memory::IsValidAddress(profilePtr))
return hleLogError(SCENET, SCE_NP_ERROR_INVALID_ARGUMENT, "invalid arg");
SceNpUserInformation dummyProfile{};
truncate_cpy(dummyProfile.userId.handle.data, sizeof(dummyProfile.userId.handle.data), npOnlineId.c_str());
truncate_cpy(dummyProfile.icon.data, sizeof(dummyProfile.icon.data), npAvatarUrl.c_str());
memset((SceNpUserInformation *)profile, 0, sizeof(SceNpUserInformation));
truncate_cpy(profile->userId.handle.data, sizeof(profile->userId.handle.data), npOnlineId.c_str());
truncate_cpy(profile->icon.data, sizeof(profile->icon.data), npAvatarUrl.c_str());
INFO_LOG(SCENET, "%s - Online ID: %s", __FUNCTION__, dummyProfile.userId.handle.data);
INFO_LOG(SCENET, "%s - Online ID: %s", __FUNCTION__, profile->userId.handle.data);
std::string datahex;
DataToHexString(dummyProfile.userId.opt, sizeof(dummyProfile.userId.opt), &datahex);
DataToHexString(profile->userId.opt, sizeof(profile->userId.opt), &datahex);
INFO_LOG(SCENET, "%s - Options?: %s", __FUNCTION__, datahex.c_str());
INFO_LOG(SCENET, "%s - Avatar URL: %s", __FUNCTION__, dummyProfile.icon.data);
INFO_LOG(SCENET, "%s - Avatar URL: %s", __FUNCTION__, profile->icon.data);
Memory::WriteStruct(profilePtr, &dummyProfile);
profile.NotifyWrite("NpGetUserProfile");
return 0;
}
@ -295,10 +301,12 @@ int sceNpAuthGetMemoryStat(u32 memStatAddr)
{
ERROR_LOG(SCENET, "UNIMPL %s(%08x)", __FUNCTION__, memStatAddr);
if (!Memory::IsValidAddress(memStatAddr))
auto memStat = PSPPointer<SceNpAuthMemoryStat>::Create(memStatAddr);
if (!memStat.IsValid())
return hleLogError(SCENET, SCE_NP_AUTH_ERROR_INVALID_ARGUMENT, "invalid arg");
Memory::WriteStruct(memStatAddr, &npAuthMemStat);
*memStat = npAuthMemStat;
memStat.NotifyWrite("NpAuthGetMemoryStat");
return 0;
}
@ -386,7 +394,7 @@ int sceNpAuthGetTicket(u32 requestId, u32 bufferAddr, u32 length)
return hleLogError(SCENET, SCE_NP_AUTH_ERROR_INVALID_ARGUMENT, "invalid arg");
int result = length;
Memory::Memset(bufferAddr, 0, length);
Memory::Memset(bufferAddr, 0, length, "NpAuthGetTicket");
SceNpTicket ticket = {};
// Dummy Login ticket returned as Login response. Dummy ticket contents were taken from https://www.psdevwiki.com/ps3/X-I-5-Ticket
ticket.header.version = TICKET_VER_2_1;
@ -415,14 +423,14 @@ int sceNpAuthGetTicket(u32 requestId, u32 bufferAddr, u32 length)
ofs += writeTicketParam(buf + ofs, PARAM_TYPE_NULL);
ticket.section.type = SECTION_TYPE_BODY;
ticket.section.size = ofs;
Memory::WriteStruct(bufferAddr, &ticket);
Memory::Memcpy(bufferAddr, &ticket, sizeof(SceNpTicket), "NpAuthGetTicket");
SceNpTicketSection footer = { SECTION_TYPE_FOOTER, 32 }; // footer section? ie. 32-bytes on version 2.1 containing 4-chars ASCII + 20-chars ASCII
Memory::WriteStruct(bufferAddr + sizeof(ticket) + ofs, &footer);
Memory::Memcpy(bufferAddr + sizeof(ticket) + ofs, &footer, sizeof(SceNpTicketSection), "NpAuthGetTicket");
ofs += sizeof(footer);
ofs += writeTicketParam(buf + ofs, PARAM_TYPE_STRING_ASCII, "\x34\xcd\x3c\xa9", 4);
ofs += writeTicketParam(buf + ofs, PARAM_TYPE_STRING_ASCII, "\x3a\x4b\x42\x66\x92\xda\x6b\x7c\xb7\x4c\xe8\xd9\x4f\x2b\x77\x15\x91\xb8\xa4\xa9", 20); // 20 random letters, token key or SceNpSignature?
u8 unknownBytes[36] = {}; // includes Language list?
Memory::WriteStruct(bufferAddr + sizeof(ticket) + ofs, unknownBytes);
// includes Language list?
Memory::Memset(bufferAddr + sizeof(ticket) + ofs, 0, 36);
result = ticket.header.size + sizeof(ticket.header); // dummy ticket is 248 bytes

View File

@ -280,10 +280,12 @@ static int sceNpMatching2GetMemoryStat(u32 memStatPtr)
if (!npMatching2Inited)
return hleLogError(SCENET, SCE_NP_MATCHING2_ERROR_NOT_INITIALIZED);
if (!Memory::IsValidAddress(memStatPtr))
auto memStat = PSPPointer<SceNpAuthMemoryStat>::Create(memStatPtr);
if (!memStat.IsValid())
return hleLogError(SCENET, SCE_NP_MATCHING2_ERROR_INVALID_ARGUMENT);
Memory::WriteStruct(memStatPtr, &npMatching2MemStat);
*memStat = npMatching2MemStat;
memStat.NotifyWrite("NpMatching2GetMemoryStat");
return 0;
}

View File

@ -38,9 +38,10 @@ static int sceOpenPSIDGetOpenPSID(u32 OpenPSIDPtr)
{
WARN_LOG(HLE, "UNTESTED %s(%08x)", __FUNCTION__, OpenPSIDPtr);
if (Memory::IsValidAddress(OpenPSIDPtr))
{
Memory::WriteStruct(OpenPSIDPtr, &dummyOpenPSID);
auto ptr = PSPPointer<SceOpenPSID>::Create(OpenPSIDPtr);
if (ptr.IsValid()) {
*ptr = dummyOpenPSID;
ptr.NotifyWrite("OpenPSIDGetOpenPSID");
}
return 0;
}
@ -49,9 +50,10 @@ static int sceOpenPSIDGetPSID(u32 OpenPSIDPtr,u32 unknown)
{
WARN_LOG(HLE, "UNTESTED %s(%08x, %08x)", __FUNCTION__, OpenPSIDPtr, unknown);
if (Memory::IsValidAddress(OpenPSIDPtr))
{
Memory::WriteStruct(OpenPSIDPtr, &dummyOpenPSID);
auto ptr = PSPPointer<SceOpenPSID>::Create(OpenPSIDPtr);
if (ptr.IsValid()) {
*ptr = dummyOpenPSID;
ptr.NotifyWrite("OpenPSIDGetPSID");
}
return 0;
}

View File

@ -766,20 +766,21 @@ static u32 scePsmfSetPsmf(u32 psmfStruct, u32 psmfData) {
// Note: this structure changes between versions.
// TODO: These values are not right, but games probably don't read them.
PsmfData data = {0};
data.version = psmf->version;
data.headerSize = 0x800;
data.streamSize = psmf->streamSize;
auto data = PSPPointer<PsmfData>::Create(psmfStruct);
memset((PsmfData *)data, 0, sizeof(PsmfData));
data->version = psmf->version;
data->headerSize = 0x800;
data->streamSize = psmf->streamSize;
// This should be and needs to be the current stream.
data.streamNum = psmf->currentStreamNum;
data.headerOffset = psmf->headerOffset;
Memory::WriteStruct(psmfStruct, &data);
data->streamNum = psmf->currentStreamNum;
data->headerOffset = psmf->headerOffset;
data.NotifyWrite("PsmfSetPsmf");
// Because the Psmf struct is sometimes copied, we use a value inside as an id.
auto iter = psmfMap.find(data.headerOffset);
auto iter = psmfMap.find(data->headerOffset);
if (iter != psmfMap.end())
delete iter->second;
psmfMap[data.headerOffset] = psmf;
psmfMap[data->headerOffset] = psmf;
return hleLogSuccessI(ME, 0);
}
@ -1046,45 +1047,43 @@ static u32 scePsmfGetEPWithId(u32 psmfStruct, int epid, u32 entryAddr)
{
Psmf *psmf = getPsmf(psmfStruct);
if (!psmf) {
ERROR_LOG(ME, "scePsmfGetEPWithId(%08x, %i, %08x): invalid psmf", psmfStruct, epid, entryAddr);
return ERROR_PSMF_NOT_INITIALIZED;
return hleLogError(ME, ERROR_PSMF_NOT_INITIALIZED, "invalid psmf");
}
DEBUG_LOG(ME, "scePsmfGetEPWithId(%08x, %i, %08x)", psmfStruct, epid, entryAddr);
if (epid < 0 || epid >= (int)psmf->EPMap.size()) {
ERROR_LOG(ME, "scePsmfGetEPWithId(%08x, %i): invalid id", psmfStruct, epid);
return ERROR_PSMF_NOT_FOUND;
return hleLogError(ME, ERROR_PSMF_NOT_FOUND, "invalid id");
}
if (Memory::IsValidAddress(entryAddr)) {
Memory::WriteStruct(entryAddr, &psmf->EPMap[epid]);
auto entry = PSPPointer<PsmfEntry>::Create(entryAddr);
if (entry.IsValid()) {
*entry = psmf->EPMap[epid];
entry.NotifyWrite("PsmfGetEPWithId");
}
return 0;
return hleLogSuccessI(ME, 0);
}
static u32 scePsmfGetEPWithTimestamp(u32 psmfStruct, u32 ts, u32 entryAddr)
{
Psmf *psmf = getPsmf(psmfStruct);
if (!psmf) {
ERROR_LOG(ME, "scePsmfGetEPWithTimestamp(%08x, %i, %08x): invalid psmf", psmfStruct, ts, entryAddr);
return ERROR_PSMF_NOT_INITIALIZED;
return hleLogError(ME, ERROR_PSMF_NOT_INITIALIZED, "invalid psmf");
}
DEBUG_LOG(ME, "scePsmfGetEPWithTimestamp(%08x, %i, %08x)", psmfStruct, ts, entryAddr);
if (ts < psmf->presentationStartTime) {
ERROR_LOG(ME, "scePsmfGetEPWithTimestamp(%08x, %i): invalid timestamp", psmfStruct, ts);
return ERROR_PSMF_NOT_FOUND;
return hleLogError(ME, ERROR_PSMF_NOT_FOUND, "invalid timestamp");
}
int epid = psmf->FindEPWithTimestamp(ts);
if (epid < 0 || epid >= (int)psmf->EPMap.size()) {
ERROR_LOG(ME, "scePsmfGetEPWithTimestamp(%08x, %i): invalid id", psmfStruct, epid);
return ERROR_PSMF_NOT_FOUND;
return hleLogError(ME, ERROR_PSMF_NOT_FOUND, "invalid id");
}
if (Memory::IsValidAddress(entryAddr)) {
Memory::WriteStruct(entryAddr, &psmf->EPMap[epid]);
auto entry = PSPPointer<PsmfEntry>::Create(entryAddr);
if (entry.IsValid()) {
*entry = psmf->EPMap[epid];
entry.NotifyWrite("PsmfGetEPWithTimestamp");
}
return 0;
return hleLogSuccessI(ME, 0);
}
static u32 scePsmfGetEPidWithTimestamp(u32 psmfStruct, u32 ts)

View File

@ -113,11 +113,12 @@ static int getCameraResolution(Camera::ConfigType type, int *width, int *height)
static int sceUsbCamSetupMic(u32 paramAddr, u32 workareaAddr, int wasize) {
INFO_LOG(HLE, "sceUsbCamSetupMic");
if (Memory::IsValidRange(paramAddr, sizeof(PspUsbCamSetupMicParam))) {
Memory::ReadStruct(paramAddr, &config->micParam);
auto param = PSPPointer<PspUsbCamSetupMicParam>::Create(paramAddr);
if (param.IsValid()) {
config->micParam = *param;
param.NotifyRead("UsbCamSetupMic");
}
return 0;
return hleLogSuccessInfoI(SCEMISC, 0);
}
static int sceUsbCamStartMic() {
@ -155,16 +156,20 @@ static int sceUsbCamGetMicDataLength() {
}
static int sceUsbCamSetupVideo(u32 paramAddr, u32 workareaAddr, int wasize) {
if (Memory::IsValidRange(paramAddr, sizeof(PspUsbCamSetupVideoParam))) {
Memory::ReadStruct(paramAddr, &config->videoParam);
auto param = PSPPointer<PspUsbCamSetupVideoParam>::Create(paramAddr);
if (param.IsValid()) {
config->videoParam = *param;
param.NotifyRead("UsbCamSetupVideo");
}
config->type = Camera::ConfigType::CfVideo;
return 0;
}
static int sceUsbCamSetupVideoEx(u32 paramAddr, u32 workareaAddr, int wasize) {
if (Memory::IsValidRange(paramAddr, sizeof(PspUsbCamSetupVideoExParam))) {
Memory::ReadStruct(paramAddr, &config->videoExParam);
auto param = PSPPointer<PspUsbCamSetupVideoExParam>::Create(paramAddr);
if (param.IsValid()) {
config->videoExParam = *param;
param.NotifyRead("UsbCamSetupVideoEx");
}
config->type = Camera::ConfigType::CfVideoEx;
return 0;
@ -222,8 +227,10 @@ static int sceUsbCamPollReadVideoFrameEnd() {
static int sceUsbCamSetupStill(u32 paramAddr) {
INFO_LOG(HLE, "UNIMPL sceUsbCamSetupStill");
if (Memory::IsValidRange(paramAddr, sizeof(PspUsbCamSetupStillParam))) {
Memory::ReadStruct(paramAddr, &config->stillParam);
auto param = PSPPointer<PspUsbCamSetupStillParam>::Create(paramAddr);
if (param.IsValid()) {
config->stillParam = *param;
param.NotifyRead("UsbCamSetupStill");
}
config->type = Camera::ConfigType::CfStill;
return 0;
@ -231,8 +238,10 @@ static int sceUsbCamSetupStill(u32 paramAddr) {
static int sceUsbCamSetupStillEx(u32 paramAddr) {
INFO_LOG(HLE, "UNIMPL sceUsbCamSetupStillEx");
if (Memory::IsValidRange(paramAddr, sizeof(PspUsbCamSetupStillExParam))) {
Memory::ReadStruct(paramAddr, &config->stillExParam);
auto param = PSPPointer<PspUsbCamSetupStillExParam>::Create(paramAddr);
if (param.IsValid()) {
config->stillExParam = *param;
param.NotifyRead("UsbCamSetupStillEx");
}
config->type = Camera::ConfigType::CfStillEx;
return 0;

View File

@ -59,8 +59,8 @@ static int sceUsbGpsGetInitDataLocation(u32 addr) {
}
static int sceUsbGpsGetState(u32 stateAddr) {
if (Memory::IsValidAddress(stateAddr)) {
Memory::Write_U32(gpsStatus, stateAddr);
if (Memory::IsValidRange(stateAddr, 4)) {
Memory::WriteUnchecked_U32(gpsStatus, stateAddr);
}
return 0;
}
@ -81,11 +81,15 @@ static int sceUsbGpsClose() {
}
static int sceUsbGpsGetData(u32 gpsDataAddr, u32 satDataAddr) {
if (Memory::IsValidRange(gpsDataAddr, sizeof(GpsData))) {
Memory::WriteStruct(gpsDataAddr, GPS::getGpsData());
auto gpsData = PSPPointer<GpsData>::Create(gpsDataAddr);
if (gpsData.IsValid()) {
*gpsData = *GPS::getGpsData();
gpsData.NotifyWrite("UsbGpsGetData");
}
if (Memory::IsValidRange(satDataAddr, sizeof(SatData))) {
Memory::WriteStruct(satDataAddr, GPS::getSatData());
auto satData = PSPPointer<SatData>::Create(satDataAddr);
if (satData.IsValid()) {
*satData = *GPS::getSatData();
gpsData.NotifyWrite("UsbGpsGetData");
}
return 0;
}

View File

@ -490,3 +490,12 @@ void Memset(const u32 _Address, const u8 _iValue, const u32 _iLength, const char
}
} // namespace
void PSPPointerNotifyRW(int rw, uint32_t ptr, uint32_t bytes, const char * tag, size_t tagLen) {
if (MemBlockInfoDetailed(bytes)) {
if (rw & 1)
NotifyMemInfo(MemBlockFlags::WRITE, ptr, bytes, tag, tagLen);
if (rw & 2)
NotifyMemInfo(MemBlockFlags::READ, ptr, bytes, tag, tagLen);
}
}

View File

@ -328,6 +328,9 @@ inline bool IsValidRange(const u32 address, const u32 size) {
} // namespace Memory
// Avoiding a global include for NotifyMemInfo.
void PSPPointerNotifyRW(int rw, uint32_t ptr, uint32_t bytes, const char *tag, size_t tagLen);
template <typename T>
struct PSPPointer
{
@ -438,9 +441,30 @@ struct PSPPointer
#endif
}
bool IsValid() const
{
return Memory::IsValidAddress(ptr);
bool IsValid() const {
return Memory::IsValidRange(ptr, (u32)sizeof(T));
}
T *PtrOrNull() {
if (IsValid())
return (T *)*this;
return nullptr;
}
const T *PtrOrNull() const {
if (IsValid())
return (const T *)*this;
return nullptr;
}
template <size_t tagLen>
void NotifyWrite(const char(&tag)[tagLen]) const {
PSPPointerNotifyRW(1, (uint32_t)ptr, (uint32_t)sizeof(T), tag, tagLen - 1);
}
template <size_t tagLen>
void NotifyRead(const char(&tag)[tagLen]) const {
PSPPointerNotifyRW(2, (uint32_t)ptr, (uint32_t)sizeof(T), tag, tagLen - 1);
}
static PSPPointer<T> Create(u32 ptr) {

View File

@ -109,31 +109,4 @@ inline void Memcpy(const u32 to_address, const u32 from_address, const u32 len)
void Memset(const u32 _Address, const u8 _Data, const u32 _iLength, const char *tag = "Memset");
template<class T>
void ReadStruct(u32 address, T *ptr)
{
const u32 sz = (u32)sizeof(*ptr);
Memcpy(ptr, address, sz);
}
template<class T>
void ReadStructUnchecked(u32 address, T *ptr)
{
const u32 sz = (u32)sizeof(*ptr);
MemcpyUnchecked(ptr, address, sz);
}
template<class T>
void WriteStruct(u32 address, T *ptr)
{
const u32 sz = (u32)sizeof(*ptr);
Memcpy(address, ptr, sz);
}
template<class T>
void WriteStructUnchecked(u32 address, T *ptr)
{
const u32 sz = (u32)sizeof(*ptr);
MemcpyUnchecked(address, ptr, sz);
}
}

View File

@ -178,18 +178,16 @@ static void BeginVertexData() {
static void Vertex(float x, float y, float u, float v, int tw, int th, u32 color = 0xFFFFFFFF) {
if (g_RemasterMode) {
PPGeRemasterVertex vtx;
vtx.x = x; vtx.y = y; vtx.z = 0;
vtx.u = u * tw; vtx.v = v * th;
vtx.color = color;
Memory::WriteStruct(dataWritePtr, &vtx);
auto vtx = PSPPointer<PPGeRemasterVertex>::Create(dataWritePtr);
vtx->x = x; vtx->y = y; vtx->z = 0;
vtx->u = u * tw; vtx->v = v * th;
vtx->color = color;
dataWritePtr += sizeof(vtx);
} else {
PPGeVertex vtx;
vtx.x = x; vtx.y = y; vtx.z = 0;
vtx.u = u * tw; vtx.v = v * th;
vtx.color = color;
Memory::WriteStruct(dataWritePtr, &vtx);
auto vtx = PSPPointer<PPGeVertex>::Create(dataWritePtr);
vtx->x = x; vtx->y = y; vtx->z = 0;
vtx->u = u * tw; vtx->v = v * th;
vtx->color = color;
dataWritePtr += sizeof(vtx);
}
_dbg_assert_(dataWritePtr <= dataPtr + dataSize);
@ -197,8 +195,11 @@ static void Vertex(float x, float y, float u, float v, int tw, int th, u32 color
}
static void EndVertexDataAndDraw(int prim) {
_assert_msg_(vertexStart != 0, "Missing matching call to BeginVertexData()");
NotifyMemInfo(MemBlockFlags::WRITE, vertexStart, dataWritePtr - vertexStart, "PPGe Vertex");
WriteCmdAddrWithBase(GE_CMD_VADDR, vertexStart);
WriteCmd(GE_CMD_PRIM, (prim << 16) | vertexCount);
vertexStart = 0;
}
bool PPGeIsFontTextureAddress(u32 addr) {
@ -272,6 +273,7 @@ void __PPGeInit() {
int val = i;
palette[i] = (val << 12) | 0xFFF;
}
NotifyMemInfo(MemBlockFlags::WRITE, palette.ptr, 16 * sizeof(u16_le), "PPGe Palette");
const u32_le *imagePtr = (u32_le *)imageData[0];
u8 *ramPtr = atlasPtr == 0 ? nullptr : (u8 *)Memory::GetPointer(atlasPtr);
@ -286,7 +288,10 @@ void __PPGeInit() {
u8 cval = (a2 << 4) | a1;
ramPtr[i] = cval;
}
atlasHash = XXH3_64bits(ramPtr, atlasWidth * atlasHeight / 2);
if (atlasPtr != 0) {
atlasHash = XXH3_64bits(ramPtr, atlasSize);
NotifyMemInfo(MemBlockFlags::WRITE, atlasPtr, atlasSize, "PPGe Atlas");
}
free(imageData[0]);
@ -457,6 +462,7 @@ void PPGeEnd()
if (dataWritePtr > dataPtr) {
// We actually drew something
gpu->EnableInterrupts(false);
NotifyMemInfo(MemBlockFlags::WRITE, dlPtr, dlWritePtr - dlPtr, "PPGe ListCmds");
u32 list = sceGeListEnQueue(dlPtr, dlWritePtr, -1, listArgs.ptr);
DEBUG_LOG(SCEGE, "PPGe enqueued display list %i", list);
gpu->EnableInterrupts(true);