mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-23 21:39:52 +00:00
Merge pull request #15950 from unknownbrackets/memstruct-cleanup
Remove Memory::WriteStruct() and ReadStruct()
This commit is contained in:
commit
91ff603fd7
@ -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) {
|
||||
|
@ -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)
|
||||
|
@ -486,8 +486,8 @@ public:
|
||||
// For save states only.
|
||||
}
|
||||
|
||||
FontLib(u32 paramPtr, u32 errorCodePtr) {
|
||||
Memory::ReadStruct(paramPtr, ¶ms_);
|
||||
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
|
||||
|
@ -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" },
|
||||
|
@ -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;
|
||||
|
@ -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(®s, 0, sizeof(regs));
|
||||
//auto regs = PSPPointer<DebugProfilerRegs>::Create(statusPtr);
|
||||
// TODO: fill the struct.
|
||||
//if (Memory::IsValidAddress(statusPtr)) {
|
||||
// Memory::WriteStruct(statusPtr, ®s);
|
||||
//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()
|
||||
|
@ -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");
|
||||
|
@ -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" },
|
||||
|
@ -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;
|
||||
|
@ -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[] = {
|
||||
|
@ -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, ¶m);
|
||||
else
|
||||
memset(¶m, 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);
|
||||
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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");
|
||||
|
@ -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);
|
||||
|
@ -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" },
|
||||
};
|
||||
|
||||
|
@ -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,¶meter);
|
||||
// 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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user