Skip to content

Commit

Permalink
Merge pull request #15331 from ANR2ME/adhoc_matching
Browse files Browse the repository at this point in the history
[AdhocMatching] Fix timing issue
  • Loading branch information
hrydgard committed Jan 19, 2022
2 parents d081dac + fbb1246 commit c9dee44
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 12 deletions.
3 changes: 2 additions & 1 deletion Core/HLE/proAdhoc.cpp
Expand Up @@ -1241,7 +1241,7 @@ void notifyMatchingHandler(SceNetAdhocMatchingContext * context, ThreadMessage *
// Don't share buffer address space with other mipscall in the queue since mipscalls aren't immediately executed
MatchingArgs argsNew = { 0 };
u32_le dataBufLen = msg->optlen + 8; //max(bufLen, msg->optlen + 8);
u32_le dataBufAddr = userMemory.Alloc(dataBufLen); // We will free this memory after returning from mipscall
u32_le dataBufAddr = userMemory.Alloc(dataBufLen); // We will free this memory after returning from mipscall. FIXME: Are these buffers supposed to be taken/pre-allocated from the memory pool during sceNetAdhocMatchingInit?
uint8_t * dataPtr = Memory::GetPointer(dataBufAddr);
if (dataPtr) {
memcpy(dataPtr, &msg->mac, sizeof(msg->mac));
Expand All @@ -1255,6 +1255,7 @@ void notifyMatchingHandler(SceNetAdhocMatchingContext * context, ThreadMessage *
}
else {
argsNew.data[1] = PSP_ADHOC_MATCHING_EVENT_ERROR; // not sure where to put the error code for EVENT_ERROR tho
//argsNew.data[2] = dataBufAddr; // FIXME: Is the MAC address mandatory (ie. can't be null pointer) even for EVENT_ERROR? Where should we put this MAC data in the case we failed to allocate the memory? may be on the memory pool?
}
argsNew.data[0] = context->id;
argsNew.data[5] = context->handler.entryPoint; //not part of callback argument, just borrowing a space to store callback address so i don't need to search the context first later
Expand Down
2 changes: 1 addition & 1 deletion Core/HLE/proAdhoc.h
Expand Up @@ -732,7 +732,7 @@ enum {
#define PSP_ADHOC_MATCHING_MODE_P2P 3

// Matching Events
#define PSP_ADHOC_MATCHING_EVENT_HELLO 1
#define PSP_ADHOC_MATCHING_EVENT_HELLO 1 // Should be ignored when Join Request is in progress ?
#define PSP_ADHOC_MATCHING_EVENT_REQUEST 2
#define PSP_ADHOC_MATCHING_EVENT_LEAVE 3
#define PSP_ADHOC_MATCHING_EVENT_DENY 4
Expand Down
29 changes: 20 additions & 9 deletions Core/HLE/sceNetAdhoc.cpp
Expand Up @@ -4674,7 +4674,7 @@ int sceNetAdhocMatchingDelete(int matchingId) {
}

int sceNetAdhocMatchingInit(u32 memsize) {
WARN_LOG(SCENET, "sceNetAdhocMatchingInit(%d) at %08x", memsize, currentMIPS->pc);
WARN_LOG_REPORT_ONCE(sceNetAdhocMatchingInit, SCENET, "sceNetAdhocMatchingInit(%d) at %08x", memsize, currentMIPS->pc);

// Uninitialized Library
if (netAdhocMatchingInited)
Expand Down Expand Up @@ -5746,23 +5746,34 @@ void __NetMatchingCallbacks() //(int matchingId)
{
std::lock_guard<std::recursive_mutex> adhocGuard(adhocEvtMtx);
hleSkipDeadbeef();
int delayus = adhocDefaultDelay;
// Note: Super Pocket Tennis / Thrillville Off the Rails seems to have a very short timeout (ie. ~5ms) while waiting for the event to arrived on the callback handler, but Lord of Arcana may not work well with 5ms (~3m or ~10ms seems to be good)
// Games with 4-players or more (ie. Gundam: Senjou No Kizuna Portable) will also need lower delay/latency (ie. ~3ms seems to be good, 2ms or lower doesn't work well) so MatchingEvents can be processed faster, thus won't be piling up in the queue.
// Using 3ms seems to fix Player list issue on StarWars The Force Unleashed.
int delayus = 3000;

auto params = matchingEvents.begin();
if (params != matchingEvents.end()) {
u32_le *args = params->data;
//auto context = findMatchingContext(args[0]);
auto context = findMatchingContext(args[0]);

if (actionAfterMatchingMipsCall < 0) {
actionAfterMatchingMipsCall = __KernelRegisterActionType(AfterMatchingMipsCall::Create);
}
DEBUG_LOG(SCENET, "AdhocMatching - Remaining Events: %zu", matchingEvents.size());
DEBUG_LOG(SCENET, "AdhocMatchingCallback: [ID=%i][EVENT=%i][%s]", args[0], args[1], mac2str((SceNetEtherAddr *)Memory::GetPointer(args[2])).c_str());
AfterMatchingMipsCall *after = (AfterMatchingMipsCall *)__KernelCreateAction(actionAfterMatchingMipsCall);
after->SetData(args[0], args[1], args[2]);
hleEnqueueCall(args[5], 5, args, after);
matchingEvents.pop_front();
delayus = adhocMatchingEventDelay; // Add extra delay to prevent I/O Timing method from causing disconnection, but delaying too long may cause matchingEvents to pile up
auto peer = findPeer(context, (SceNetEtherAddr*)Memory::GetPointer(args[2]));
// Discard HELLO Events when in the middle of joining, as some games (ie. Super Pocket Tennis) might tried to join again (TODO: Need to confirm whether sceNetAdhocMatchingSelectTarget supposed to be blocking the current thread or not)
if (peer == NULL || (args[1] != PSP_ADHOC_MATCHING_EVENT_HELLO || (peer->state != PSP_ADHOC_MATCHING_PEER_OUTGOING_REQUEST && peer->state != PSP_ADHOC_MATCHING_PEER_INCOMING_REQUEST))) {
DEBUG_LOG(SCENET, "AdhocMatchingCallback: [ID=%i][EVENT=%i][%s]", args[0], args[1], mac2str((SceNetEtherAddr *)Memory::GetPointer(args[2])).c_str());

AfterMatchingMipsCall* after = (AfterMatchingMipsCall*)__KernelCreateAction(actionAfterMatchingMipsCall);
after->SetData(args[0], args[1], args[2]);
hleEnqueueCall(args[5], 5, args, after);
matchingEvents.pop_front();
}
else {
DEBUG_LOG(SCENET, "AdhocMatching - Discarding Callback: [ID=%i][EVENT=%i][%s]", args[0], args[1], mac2str((SceNetEtherAddr*)Memory::GetPointer(args[2])).c_str());
matchingEvents.pop_front();
}
}

// Must be delayed long enough whenever there is a pending callback. Should it be 10-100ms for Matching Events? or Not Less than the delays on sceNetAdhocMatching HLE?
Expand Down
2 changes: 1 addition & 1 deletion Core/HLE/sceNetAdhoc.h
Expand Up @@ -24,7 +24,7 @@
#pragma pack(push,1)
#endif
typedef struct MatchingArgs {
u32_le data[6]; //ContextID, Opcode, bufAddr[ to MAC], OptLen, OptAddr[, EntryPoint]
u32_le data[6]; // ContextID, EventID, bufAddr[ to MAC], OptLen, OptAddr[, EntryPoint]
} PACK MatchingArgs;

typedef struct SceNetAdhocDiscoverParam {
Expand Down

0 comments on commit c9dee44

Please sign in to comment.