Fix Falcom games (ie. Ys vs. Sora no Kiseki, Vantage Master Portable)

This commit is contained in:
ANR2ME committed 2020-10-09 23:45:12 +07:00
1 parent e475a0e6fa
commit d628eb2ebd
4 files changed
+46 -30

No files matched your search

+1 -1
View File
@@ -1985,7 +1985,7 @@ int getNicknameCount(const char * nickname)
for (; peer != NULL; peer = peer->next)
{
// Match found
if (strncmp((char *)&peer->nickname.data, nickname, ADHOCCTL_NICKNAME_LEN) == 0) count++;
if (peer->last_recv != 0 && strncmp((char *)&peer->nickname.data, nickname, ADHOCCTL_NICKNAME_LEN) == 0) count++;
}
// Return Result
+8 -4
View File
@@ -207,9 +207,9 @@ extern uint8_t broadcastMAC[ETHER_ADDR_LEN];
// Malloc Pool Information
typedef struct SceNetMallocStat {
s32_le pool; // Pointer to the pool? // This should be the poolSize isn't?
s32_le maximum; // Maximum size of the pool? Maximum usage (ie. pool- free) ?
s32_le free; // How much memory is free
s32_le pool; // On Vantage Master Portable this is 0x1ffe0 on sceNetGetMallocStat, while the poolSize arg on sceNetInit was 0x20000
s32_le maximum; // On Vantage Master Portable this is 0x4050, Footprint of Highest amount allocated so far?
s32_le free; // On Vantage Master Portable this is 0x1f300, VMP compares this value with required size before sending data
} PACK SceNetMallocStat;
// Adhoc Virtual Network Name
@@ -352,10 +352,14 @@ typedef struct AdhocSocket {
s32_le type; // SOCK_PDP/SOCK_PTP
s32_le flags; // Socket Alert Flags
s32_le alerted_flags; // Socket Alerted Flags
s32_le nonblocking; // last non-blocking flag
u32 buffer_size;
u32 send_timeout; // default connect timeout
u32 recv_timeout; // default accept timeout
s32 retry_count; // combined with timeout to be used on keepalive
s32 retry_interval; // related to keepalive
s32 retry_count; // multiply with retry interval to be used as keepalive timeout
s32 attemptCount; // connect/accept attempts
u64 lastAttempt; // timestamp to retry again
union {
SceNetAdhocPdpStat pdp;
SceNetAdhocPtpStat ptp;
+7 -6
View File
@@ -641,14 +641,15 @@ static int sceNetInit(u32 poolSize, u32 calloutPri, u32 calloutStack, u32 netini
}
WARN_LOG(SCENET, "sceNetInit(poolsize=%d, calloutpri=%i, calloutstack=%d, netintrpri=%i, netintrstack=%d) at %08x", poolSize, calloutPri, calloutStack, netinitPri, netinitStack, currentMIPS->pc);
netInited = true;
netMallocStat.pool = poolSize; // This should be the poolSize isn't?
netMallocStat.maximum = poolSize/2; // According to JPCSP's sceNetGetMallocStat this is Currently Used size = (poolSize - free), faked to half the pool
netMallocStat.free = poolSize - netMallocStat.maximum;
netMallocStat.pool = poolSize - 0x20; // On Vantage Master Portable this is slightly (32 bytes) smaller than the poolSize arg when tested with JPCSP + prx files
netMallocStat.maximum = 0x4050; // Dummy maximum foot print
netMallocStat.free = netMallocStat.pool; // Dummy free size, we should set this high enough to prevent any issue (ie. Vantage Master Portable), this is probably the only field being checked by games?
// Clear Socket Translator Memory
memset(&adhocSockets, 0, sizeof(adhocSockets));
netInited = true;
return hleLogSuccessI(SCENET, 0);
}
@@ -770,7 +771,7 @@ 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)", statPtr);
VERBOSE_LOG(SCENET, "UNTESTED sceNetGetMallocStat(%x) at %08x", statPtr, currentMIPS->pc);
if(Memory::IsValidAddress(statPtr))
Memory::WriteStruct(statPtr, &netMallocStat);
else
+30 -19
View File
@@ -75,6 +75,7 @@ int adhocExtraDelay = 20000; //20000
int adhocEventPollDelay = 100000; //100000; // Same timings with PSP_ADHOCCTL_RECV_TIMEOUT ?
int adhocMatchingEventDelay = 30000; //30000
int adhocEventDelay = 1000000; //1000000
u32 defaultLastRecvDelta = 10000; //10000 usec worked well for games published by Falcom (ie. Ys vs Sora Kiseki, Vantage Master Portable)
SceUID threadAdhocID;
@@ -2270,7 +2271,7 @@ static int sceNetAdhocctlGetNameByAddr(const char *mac, u32 nameAddr) {
for (; peer != NULL; peer = peer->next)
{
// Match found
if (isMacMatch(&peer->mac_addr, (const SceNetEtherAddr*)mac))
if (peer->last_recv != 0 && isMacMatch(&peer->mac_addr, (const SceNetEtherAddr*)mac))
{
// Write Data
*nickname = peer->nickname;
@@ -2316,7 +2317,7 @@ int sceNetAdhocctlGetPeerInfo(const char *mac, int size, u32 peerInfoAddr) {
if (netAdhocctlInited) {
if ((size < (int)sizeof(SceNetAdhocctlPeerInfoEmu)) || (buf == NULL)) return ERROR_NET_ADHOCCTL_INVALID_ARG;
int retval = ERROR_NET_ADHOCCTL_INVALID_ARG; // -1;
int retval = ERROR_NET_ADHOC_NO_ENTRY; // -1;
// Local MAC
if (isLocalMAC(maddr)) {
@@ -2329,7 +2330,7 @@ int sceNetAdhocctlGetPeerInfo(const char *mac, int size, u32 peerInfoAddr) {
buf->mac_addr = *maddr;
buf->flags = 0x0400;
buf->padding = 0;
buf->last_recv = CoreTiming::GetGlobalTimeUsScaled() - 1;
buf->last_recv = CoreTiming::GetGlobalTimeUsScaled() - defaultLastRecvDelta;
// Success
retval = 0;
@@ -2341,12 +2342,11 @@ int sceNetAdhocctlGetPeerInfo(const char *mac, int size, u32 peerInfoAddr) {
peerlock.lock();
SceNetAdhocctlPeerInfo * peer = findFriend(maddr);
if (peer != NULL) {
if (peer != NULL && peer->last_recv != 0) {
// Fake Receive Time
if (peer->last_recv != 0)
peer->last_recv = CoreTiming::GetGlobalTimeUsScaled() - 1;
peer->last_recv = std::max(peer->last_recv, CoreTiming::GetGlobalTimeUsScaled() - defaultLastRecvDelta);
//buf->next = 0;
buf->next = 0;
buf->nickname = peer->nickname;
buf->nickname.data[ADHOCCTL_NICKNAME_LEN - 1] = 0; // last char need to be null-terminated char
buf->mac_addr = *maddr;
@@ -5386,7 +5386,7 @@ static int sceNetAdhocctlGetPeerList(u32 sizeAddr, u32 bufAddr) {
if (!excludeTimedout || peer->last_recv != 0) {
// Faking Last Receive Time
if (peer->last_recv != 0)
peer->last_recv = CoreTiming::GetGlobalTimeUsScaled() - 1;
peer->last_recv = std::max(peer->last_recv, CoreTiming::GetGlobalTimeUsScaled() - defaultLastRecvDelta);
// Copy Peer Info
buf[discovered].nickname = peer->nickname;
@@ -5418,7 +5418,7 @@ static int sceNetAdhocctlGetPeerList(u32 sizeAddr, u32 bufAddr) {
peerlock.unlock();
// Return Success
return 0;
return hleDelayResult(0, "delay 1 ~ 10ms", 1000); // seems to have different thread running within the delay duration
}
// Invalid Arguments
@@ -5437,7 +5437,7 @@ static int sceNetAdhocctlGetAddrByName(const char *nickName, u32 sizeAddr, u32 b
memcpy(nckName, nickName, ADHOCCTL_NICKNAME_LEN); // Copied to null-terminated var to prevent unexpected behaviour on Logs
nckName[ADHOCCTL_NICKNAME_LEN - 1] = 0;
WARN_LOG(SCENET, "UNTESTED sceNetAdhocctlGetAddrByName(%s, [%08x]=%d/%zu, %08x)", nckName, sizeAddr, buflen ? *buflen : -1, sizeof(SceNetAdhocctlPeerInfoEmu), bufAddr);
WARN_LOG_REPORT_ONCE(sceNetAdhocctlGetAddrByName, SCENET, "UNTESTED sceNetAdhocctlGetAddrByName(%s, [%08x]=%d/%zu, %08x) at %08x", nckName, sizeAddr, buflen ? *buflen : -1, sizeof(SceNetAdhocctlPeerInfoEmu), bufAddr, currentMIPS->pc);
// Library initialized
if (netAdhocctlInited)
@@ -5452,8 +5452,11 @@ static int sceNetAdhocctlGetAddrByName(const char *nickName, u32 sizeAddr, u32 b
peerlock.lock();
// Length Calculation Mode
if (buf == NULL) *buflen = getNicknameCount(nickName) * sizeof(SceNetAdhocctlPeerInfoEmu);
if (buf == NULL) {
int foundName = getNicknameCount(nickName);
*buflen = foundName * sizeof(SceNetAdhocctlPeerInfoEmu);
DEBUG_LOG(SCENET, "PeerNameList [%s: %i]", nickName, foundName);
}
// Normal Information Mode
else
{
@@ -5474,13 +5477,18 @@ static int sceNetAdhocctlGetAddrByName(const char *nickName, u32 sizeAddr, u32 b
{
// Get Local IP Address
sockaddr_in addr;
SceNetEtherAddr mac;
getLocalIp(&addr);
buf[discovered].nickname = parameter.nickname;
buf[discovered].nickname.data[ADHOCCTL_NICKNAME_LEN - 1] = 0; // last char need to be null-terminated char
getLocalMac(&buf[discovered].mac_addr);
getLocalMac(&mac);
buf[discovered].mac_addr = mac;
buf[discovered].flags = 0x0400;
buf[discovered++].last_recv = CoreTiming::GetGlobalTimeUsScaled() - 1;
u64 lastrecv = CoreTiming::GetGlobalTimeUsScaled() - defaultLastRecvDelta;
buf[discovered++].last_recv = lastrecv;
DEBUG_LOG(SCENET, "Peer [%s][%s][%s][%llu]", mac2str(&mac).c_str(), inet_ntoa(addr.sin_addr), nickName, lastrecv);
}
// Peer Reference
@@ -5490,11 +5498,10 @@ static int sceNetAdhocctlGetAddrByName(const char *nickName, u32 sizeAddr, u32 b
for (; peer != NULL && discovered < requestcount; peer = peer->next)
{
// Match found
if (strncmp((char *)&peer->nickname.data, nickName, ADHOCCTL_NICKNAME_LEN) == 0)
if (peer->last_recv != 0 && strncmp((char *)&peer->nickname.data, nickName, ADHOCCTL_NICKNAME_LEN) == 0)
{
// Fake Receive Time
if (peer->last_recv != 0)
peer->last_recv = CoreTiming::GetGlobalTimeUsScaled() - 1;
peer->last_recv = std::max(peer->last_recv, CoreTiming::GetGlobalTimeUsScaled() - defaultLastRecvDelta);
// Copy Peer Info
buf[discovered].nickname = peer->nickname;
@@ -5502,6 +5509,9 @@ static int sceNetAdhocctlGetAddrByName(const char *nickName, u32 sizeAddr, u32 b
buf[discovered].mac_addr = peer->mac_addr;
buf[discovered].flags = 0x0400;
buf[discovered++].last_recv = peer->last_recv;
u32_le ipaddr = peer->ip_addr;
DEBUG_LOG(SCENET, "Peer [%s][%s][%s][%llu]", mac2str(&peer->mac_addr).c_str(), inet_ntoa(*(in_addr*)&ipaddr), (const char*)&peer->nickname.data, peer->last_recv);
}
}
@@ -5518,13 +5528,14 @@ static int sceNetAdhocctlGetAddrByName(const char *nickName, u32 sizeAddr, u32 b
// Fix Buffer Size
*buflen = discovered * sizeof(SceNetAdhocctlPeerInfoEmu);
DEBUG_LOG(SCENET, "PeerNameList [%s][Requested: %i][Discovered: %i]", nickName, requestcount, discovered);
}
// Multithreading Unlock
peerlock.unlock();
// Return Success
return 0;
return hleLogDebug(SCENET, hleDelayResult(0, "delay 1 ~ 10ms", 1000), "success"); // FIXME: Might have similar delay with GetPeerList? need to know which games using this tho
}
// Invalid Arguments
@@ -6867,7 +6878,7 @@ int matchingInputThread(int matchingId) // TODO: The MatchingInput thread is usi
now = CoreTiming::GetGlobalTimeUsScaled();
u64_le delta = now - peer->last_recv;
DEBUG_LOG(SCENET, "Timestamp Delta: %llu (%llu - %llu) from %s", delta, now, peer->last_recv, mac2str(&sendermac).c_str());
if (/*context->rxbuf[0] > 0 &&*/ peer->last_recv != 0) peer->last_recv = now - 1; // - context->keepalive_int; // May need to deduce by ping interval to prevent Dissidia 012 unable to see other players (ie. disappearing issue)
if (peer->last_recv != 0) peer->last_recv = now - defaultLastRecvDelta;
}
else {
WARN_LOG(SCENET, "InputLoop[%d]: Unknown Peer[%s:%u] (Recved=%i, Length=%i)", matchingId, mac2str(&sendermac).c_str(), senderport, recvresult, rxbuflen);