// serverId: 0 on 0x0103/0x0104/0x0105/0x0107/0x0108/0x0109/0x010a/0x010b/0x010c/0x010d (ie. when already joined to a server?)
// unk1~unk5 usually 0,
// unk1: 1st 32-bit of LeaveRoom/etc's Arg2 on 0x0103/0x0104/0x0105/0x0107/0x0108/0x0109/0x010a/0x010b/0x010c/0x010d/0x010e
// unk2: 2nd 32-bit of LeaveRoom/etc's Arg2 on 0x0103/0x0104/0x0105/0x0107/0x0108/0x0109/0x010a/0x010b/0x010c/0x010d/0x010e
// unk5: 1 on 0x0002/0x0003/0x0005/0x0006/0x0007/0x0101/0x0102/0x0106
// unk6 (new state?): 8-bit?(masked with 0xff) 0x01 on 0x0001, 0x03 on 0x0002, 0x04 on 0x0003, 0x05 on 0x0004, 0x06 on 0x0005, 0x07 on 0x0006, 0x08 on 0x0007,
// 0x09 on 0x0101, 0x0A on 0x0102, 0x0C on 0x0103, 0x0D on 0x0104, 0x0E on 0x0105, 0x0F on 0x0106, 0x10 on 0x0107, 0x11 on 0x0108,
// 0x12 on 0x0109, 0x13 on 0x010a, 0x14 on 0x010b, 0x15 on 0x010c, 0x16 on 0x010d, 0x17 on 0x010e, 0x18 on 0xa102
// Returning 0x805508A6 (error code inherited from sceNpService_76867C01 which check server availability) if can't check server availability (ie. Fat Princess (US) through http://static-resource.np.community.playstation.net/np/resource/psp-title/NPWR00670_00/matching/NPWR00670_00-matching.xml using User-Agent: "PS3Community-agent/1.0.0 libhttp/1.0.0")
return0;
}
staticintsceNpMatching2ContextStop(intctxId)
{
ERROR_LOG(SCENET,"UNIMPL %s(%d) at %08x",__FUNCTION__,ctxId,currentMIPS->pc);
// callback struct have 57 * u32? where [0]=0, [40]=flags, [55]=callbackFunc, and [56]=callbackArgs?
//hleEnqueueCall(callbackFunctionAddr, 7, (u32*)Memory::GetPointer(callbackArgument), nullptr); // 7 args? since the callback handler is trying to use t2 register
returnhleLogError(SCENET,SCE_NP_MATCHING2_ERROR_CONTEXT_MAX);// Should be SCE_NP_MATCHING2_ERROR_INVALID_ARGUMENT ?
// Server ID is a 16-bit variable according to JPCSP
intserverId=Memory::Read_U16(serverIdPtr);
if(serverId==0)
returnhleLogError(SCENET,0x80550CBF);// Should be SCE_NP_MATCHING2_ERROR_INVALID_SERVER_ID ?
// Output to unknown1(infoBuffer)? and unknown2(infoLength or flags)?
// Patapon 3 is using serverId at 09FFF2F4, unknown1 at 09FFF2E4, unknown2 at 09FFF2E0, which mean unknown1's can only fit upto 16-bytes
// Patapon 3 seems to be copying data from unknown1 with a fixed size of 20-bytes?
// input unknown1 struct: based on Fat Princess (US)
// 0000 32-bit function address (callback?) 0x08A08B40
// 0004 32-bit pointer to a struct? (callback args?) 0x09888158 (contains 32-bit (-1) + 32-bit (1) + 16-bit ctxId(0001) + 32bit 0x06913801? + 16-bit serverId(1234), so on), probably only 2x 32-bit struct?
// 0008 32-bit set to 0
// 000a 16-bit set to 0
//
u32cbFunc=Memory::Read_U32(unknown1Ptr);
u32cbArg=Memory::Read_U32(unknown1Ptr+0x04);
// Notify callback handler
if(Memory::IsValidAddress(cbFunc)){
// The cbFunc seems to be storing s0~s4(s0 pointing to 0x0996DD58 containing data similar to 0x09888158 above on the 1st 2x 32-bit data, s1 seems to be ctxId, s2~s4=0xdeadbeef) into stack and use a0~t1 (6 args?):
// Arg1(a0) & Arg3(a2) are being masked with 0xffff (16-bit id?)
// This callback tried to load data from address 0x08BD4860+8 (not part of arg? which being set using content of unknown2 not long after returning from sceNpMatching2GetServerInfo, so we may need to give some delay before calling this callback)
// and comparing it with Arg2(a1), repeated by increasing the address 0x08BD4860 by 288 bytes on each loop for 64 times or until it found a matching one.
// When a match is found the callback will process the address further, otherwise exit the callback.
// Matching address struct: (zeroed before calling sceNpMatching2GetServerInfo? and set after returning from sceNpMatching2GetServerInfo?)
// 0008 32-bit value from unknown2 content, being set not long after returning from sceNpMatching2GetServerInfo
// 000c 32-bit unknown
// 0010 8-bit status to indicate not updated from callback yet? initially 0, set to 1 not long after returning from sceNpMatching2GetServerInfo (along with unknown2 content)
//
// There args are supposed to be constructed in the stack and the data need to be available even after returning from this function, so these args + optional data probably copied to somewhere
NpMatching2Argsargs={};
args.data[0]=PSP_NP_MATCHING2_EVENT_0001;
args.data[1]=PSP_NP_MATCHING2_STATE_1001;// or size of data?
args.data[2]=serverIdPtr;// serverId or was it pointing to optional data at last arg (ie. args[10] where serverId is stored)?
args.data[3]=unknown1Ptr;
//args.data[4] = a boolean(0/1) related to a u8 value from the struct at args[9] (value XOR 0x04 == 0)
args.data[5]=unknown2Ptr;
args.data[6]=0;
//args.data[8] = 0 or a pointer to a struct related to context?
//args.data[9] = 0 or a pointer to a struct related to context and matched serverId?
Memory::Write_U32(args.data[1],unknown2Ptr);// server status or flags?
}
// After returning, Fat Princess will loop for 64 times (increasing the address by 288 bytes on each loop) or until found a zero status byte (0x08BD4860 + 0x10), looking for empty/available entry to set?
returnhleLogError(SCENET,SCE_NP_MATCHING2_ERROR_CONTEXT_MAX);// Should be SCE_NP_MATCHING2_ERROR_INVALID_ARGUMENT ?
u32cbFunc=Memory::Read_U32(reqParamPtr);
u32cbArg=Memory::Read_U32(reqParamPtr+0x04);
// Notify callback handler
if(Memory::IsValidAddress(cbFunc)){
// There args are supposed to be constructed in the stack and the data need to be available even after returning from this function, so these args + optional data probably copied to somewhere
NpMatching2Argsargs={};
args.data[0]=PSP_NP_MATCHING2_EVENT_0103;
args.data[1]=PSP_NP_MATCHING2_STATE_3202;
//args.data[2] = pointer to arg[8], where the 1st 20 bytes copied from (reqParamPtr+0x08), the rest of the struct are zeroed
args.data[3]=optParamPtr;
args.data[4]=0;
args.data[5]=assignedReqIdPtr;
args.data[6]=0;
//args.data[8] = an initially zeroed struct of 536 bytes where the 1st 20 bytes were taken from reqParam offset 0x08
// After returning, Fat Princess will loop for 64 times (increasing the address by 288 bytes on each loop) or until found a zero status byte (0x08BD4860 + 0x10), looking for empty/available entry to set?
returnhleLogError(SCENET,SCE_NP_MATCHING2_ERROR_CONTEXT_MAX);// Should be SCE_NP_MATCHING2_ERROR_INVALID_ARGUMENT ?
// Server ID is a 16-bit variable according to JPCSP
intserverId=Memory::Read_U16(reqParamPtr+0x06);
if(serverId==0)
returnhleLogError(SCENET,0x80550CBF);// Should be SCE_NP_MATCHING2_ERROR_INVALID_SERVER_ID ?
u32cbFunc=Memory::Read_U32(reqParamPtr);
u32cbArg=Memory::Read_U32(reqParamPtr+0x04);
// Notify callback handler
if(Memory::IsValidAddress(cbFunc)){
// There args are supposed to be constructed in the stack and the data need to be available even after returning from this function, so these args + optional data probably copied to somewhere
NpMatching2Argsargs={};
args.data[0]=PSP_NP_MATCHING2_EVENT_0102;
args.data[1]=PSP_NP_MATCHING2_STATE_1209;
//args.data[2] = pointer to arg[8] (optional data?)
args.data[3]=optParamPtr;
args.data[4]=0;
args.data[5]=assignedReqIdPtr;
args.data[6]=0;
// Followed by optional data?
args.data[8]=reqParamPtr;// an initially zeroed struct of 1224 bytes, where the 1st 32bit is set to reqParamPtr
// After returning, Fat Princess will loop for 64 times (increasing the address by 288 bytes on each loop) or until found a zero status byte (0x08BD4860 + 0x10), looking for empty/available entry to set?
returnhleLogError(SCENET,SCE_NP_MATCHING2_ERROR_CONTEXT_MAX);// Should be SCE_NP_MATCHING2_ERROR_INVALID_ARGUMENT ?
u32cbFunc=Memory::Read_U32(reqParamPtr);
u32cbArg=Memory::Read_U32(reqParamPtr+0x04);
// Notify callback handler
if(Memory::IsValidAddress(cbFunc)){
// There args are supposed to be constructed in the stack and the data need to be available even after returning from this function, so these args + optional data probably copied to somewhere
NpMatching2Argsargs={};
// TODO: Set the correct callback args
Memory::Write_U32(args.data[1],assignedReqIdPtr);// server status or flags?
returnhleLogError(SCENET,SCE_NP_MATCHING2_ERROR_CONTEXT_MAX);// Should be SCE_NP_MATCHING2_ERROR_INVALID_ARGUMENT ?
u32cbFunc=Memory::Read_U32(reqParamPtr);
u32cbArg=Memory::Read_U32(reqParamPtr+0x04);
// Notify callback handler
if(Memory::IsValidAddress(cbFunc)){
// There args are supposed to be constructed in the stack and the data need to be available even after returning from this function, so these args + optional data probably copied to somewhere
Memory::Write_U32(args.data[1],assignedReqIdPtr);// server status or flags?
}
// After returning, Fat Princess will loop for 64 times (increasing the address by 288 bytes on each loop) or until found a zero status byte (0x08BD4860 + 0x10), looking for empty/available entry to set?