From ffe70067c2bd59a980a16eb527856b45828faba5 Mon Sep 17 00:00:00 2001 From: HeatXD <45072324+HeatXD@users.noreply.github.com> Date: Tue, 2 May 2023 21:35:22 +0200 Subject: [PATCH] Netplay: Ok After more testing it doesnt seem to be the CDROM. so im reveting this change. its weird tho its seems to be fine in the first session created but after when a new session is created it is prone to desync. this doesnt happen when starting the session with an identical savestate for both players tho. GGPO: Changed the size of the checksums from u16 to u32. --- dep/ggpo-x/include/ggponet.h | 4 ++-- dep/ggpo-x/src/backends/p2p.cpp | 7 +++---- dep/ggpo-x/src/backends/p2p.h | 6 +++--- dep/ggpo-x/src/game_input.h | 2 +- dep/ggpo-x/src/network/udp_msg.h | 2 +- dep/ggpo-x/src/network/udp_proto.cpp | 4 ++-- dep/ggpo-x/src/network/udp_proto.h | 4 ++-- src/core/netplay.cpp | 14 +++++--------- 8 files changed, 19 insertions(+), 24 deletions(-) diff --git a/dep/ggpo-x/include/ggponet.h b/dep/ggpo-x/include/ggponet.h index 188dfcaba..cb306fa1b 100644 --- a/dep/ggpo-x/include/ggponet.h +++ b/dep/ggpo-x/include/ggponet.h @@ -196,8 +196,8 @@ typedef struct { } chat; struct { int nFrameOfDesync; - uint16_t ourCheckSum; - uint16_t remoteChecksum; + uint32_t ourCheckSum; + uint32_t remoteChecksum; } desync; } u; } GGPOEvent; diff --git a/dep/ggpo-x/src/backends/p2p.cpp b/dep/ggpo-x/src/backends/p2p.cpp index 4224270c5..0bc8a388b 100644 --- a/dep/ggpo-x/src/backends/p2p.cpp +++ b/dep/ggpo-x/src/backends/p2p.cpp @@ -431,9 +431,8 @@ Peer2PeerBackend::IncrementFrame(uint16_t checksum1) { auto currentFrame = _sync.GetFrameCount(); _sync.IncrementFrame(); - checksum1 = _sync.GetLastSavedFrame().checksum; + uint32 cSum = _sync.GetLastSavedFrame().checksum; char buf[256]; - uint16_t cSum = checksum1; Log("End of frame (%d)...\n", currentFrame); static int maxDif = 0; if (_pendingCheckSums.count(currentFrame)) @@ -510,7 +509,7 @@ Peer2PeerBackend::PollUdpProtocolEvents(void) //} } -void Peer2PeerBackend::CheckRemoteChecksum(int framenumber, uint16 cs) +void Peer2PeerBackend::CheckRemoteChecksum(int framenumber, uint32 cs) { if (framenumber <= _sync.MaxPredictionFrames()) return; @@ -521,7 +520,7 @@ void Peer2PeerBackend::CheckRemoteChecksum(int framenumber, uint16 cs) int Peer2PeerBackend::HowFarBackForChecksums()const { - return 16; + return 32; }/* uint16 Peer2PeerBackend::GetChecksumForConfirmedFrame(int frameNumber) const { diff --git a/dep/ggpo-x/src/backends/p2p.h b/dep/ggpo-x/src/backends/p2p.h index 100df7dc6..7835a0cb9 100644 --- a/dep/ggpo-x/src/backends/p2p.h +++ b/dep/ggpo-x/src/backends/p2p.h @@ -82,11 +82,11 @@ protected: int nFrame; int checkSum;; }; - std::map _pendingCheckSums; - std::map _confirmedCheckSums; + std::map _pendingCheckSums; + std::map _confirmedCheckSums; // uint16 GetChecksumForConfirmedFrame(int frameNumber) const; - void CheckRemoteChecksum(int framenumber, uint16 cs); + void CheckRemoteChecksum(int framenumber, uint32 cs); int HowFarBackForChecksums()const; int _confirmedCheckSumFrame = -500; void CheckDesync(); diff --git a/dep/ggpo-x/src/game_input.h b/dep/ggpo-x/src/game_input.h index a19b834ba..834a0d7f3 100644 --- a/dep/ggpo-x/src/game_input.h +++ b/dep/ggpo-x/src/game_input.h @@ -24,7 +24,7 @@ struct GameInput { int frame; int size; /* size in bytes of the entire input for all players */ char bits[GAMEINPUT_MAX_BYTES * GAMEINPUT_MAX_PLAYERS]; - uint16 checksum; + uint32 checksum; bool is_null() { return frame == NullFrame; } void init(int frame, char *bits, int size, int offset); void init(int frame, char *bits, int size); diff --git a/dep/ggpo-x/src/network/udp_msg.h b/dep/ggpo-x/src/network/udp_msg.h index e21d24f2a..1a4b6e4ff 100644 --- a/dep/ggpo-x/src/network/udp_msg.h +++ b/dep/ggpo-x/src/network/udp_msg.h @@ -67,7 +67,7 @@ struct UdpMsg int ack_frame:31; uint16 num_bits; - uint16 checksum16; + uint32 checksum32; uint8 input_size; // XXX: shouldn't be in every single packet! uint8 bits[MAX_COMPRESSED_BITS]; /* must be last */ } input; diff --git a/dep/ggpo-x/src/network/udp_proto.cpp b/dep/ggpo-x/src/network/udp_proto.cpp index bfee20fde..1197ddccb 100644 --- a/dep/ggpo-x/src/network/udp_proto.cpp +++ b/dep/ggpo-x/src/network/udp_proto.cpp @@ -134,7 +134,7 @@ UdpProtocol::SendPendingOutput() ASSERT(last.frame == -1 || last.frame + 1 == msg->u.input.start_frame); for (j = 0; j < _pending_output.size(); j++) { GameInput ¤t = _pending_output.item(j); - msg->u.input.checksum16 = current.checksum; + msg->u.input.checksum32 = current.checksum; if (memcmp(current.bits, last.bits, current.size) != 0) { ASSERT((GAMEINPUT_MAX_BYTES * GAMEINPUT_MAX_PLAYERS * 8) < (1 << BITVECTOR_NIBBLE_SIZE)); for (i = 0; i < current.size * 8; i++) { @@ -627,7 +627,7 @@ UdpProtocol::OnInput(UdpMsg *msg, int len) char desc[1024]; ASSERT(currentFrame == _last_received_input.frame + 1); _last_received_input.frame = currentFrame; - _last_received_input.checksum = msg->u.input.checksum16; + _last_received_input.checksum = msg->u.input.checksum32; /* * Send the event to the emualtor */ diff --git a/dep/ggpo-x/src/network/udp_proto.h b/dep/ggpo-x/src/network/udp_proto.h index 14947e27f..086beda1c 100644 --- a/dep/ggpo-x/src/network/udp_proto.h +++ b/dep/ggpo-x/src/network/udp_proto.h @@ -94,8 +94,8 @@ public: void ApplyToEvents(std::function cb); void StartPollLoop(); void EndPollLoop(); - std::map _remoteCheckSums; - std::map _remoteCheckSumsThisFrame; + std::map _remoteCheckSums; + std::map _remoteCheckSumsThisFrame; protected: enum State { Syncing, diff --git a/src/core/netplay.cpp b/src/core/netplay.cpp index 47ddd7873..a052c03c6 100644 --- a/src/core/netplay.cpp +++ b/src/core/netplay.cpp @@ -112,7 +112,7 @@ s32 Netplay::Start(s32 lhandle, u16 lport, std::string& raddr, u16 rport, s32 ld ggpo_start_session(&s_ggpo, &cb, "Duckstation-Netplay", 2, sizeof(Netplay::Input), lport, MAX_ROLLBACK_FRAMES); // result = ggpo_start_synctest(&s_ggpo, &cb, (char*)"asdf", 2, sizeof(Netplay::Input), 1); - ggpo_set_disconnect_timeout(s_ggpo, 3000); + ggpo_set_disconnect_timeout(s_ggpo, 2000); ggpo_set_disconnect_notify_start(s_ggpo, 1000); for (int i = 1; i <= 2; i++) @@ -184,10 +184,6 @@ void Netplay::SetSettings() // no block linking, it degrades savestate loading performance si.SetBoolValue("CPU", "RecompilerBlockLinking", false); - // for some games CDROM async readahead seems to cause desyncs (most notable during testing were the tekken games) - // so for now disabling it seems like the only option - si.SetIntValue("CDROM", "ReadaheadSectors", 0); - Host::Internal::SetNetplaySettingsLayer(&si); } @@ -215,7 +211,7 @@ void Netplay::HandleTimeSyncEvent(float frame_delta, int update_interval) // Distribute the frame difference over the next N * 0.75 frames. // only part of the interval time is used since we want to come back to normal speed. // otherwise we will keep spiraling into unplayable gameplay. - float total_time = (frame_delta * s_frame_period) / 8; + float total_time = (frame_delta * s_frame_period) / 4; float mun_timesync_frames = update_interval * 0.75f; float added_time_per_frame = -(total_time / mun_timesync_frames); float iterations_per_frame = 1.0f / s_frame_period; @@ -279,7 +275,7 @@ void Netplay::GenerateChecksumForFrame(int* checksum, int frame, unsigned char* const u32 num_group_of_pages = buffer_size / sliding_window_size; const u32 start_position = (frame % num_group_of_pages) * sliding_window_size; *checksum = XXH32(buffer + start_position, sliding_window_size, frame); - // Log_InfoPrintf("check: f:%d c:%u", frame, *checksum); + Log_VerbosePrintf("Netplay Checksum: f:%d wf:%d c:%u", frame, frame % num_group_of_pages, *checksum); } void Netplay::AdvanceFrame(u16 checksum) @@ -332,7 +328,7 @@ Netplay::Input Netplay::ReadLocalInput() Netplay::Input inp{0}; for (u32 i = 0; i < (u32)DigitalController::Button::Count; i++) { - if (s_net_input[0][i] >= 0.4f) + if (s_net_input[0][i] >= 0.25f) inp.button_data |= 1 << i; } return inp; @@ -432,7 +428,7 @@ bool Netplay::NpBeginGameCb(void* ctx, const char* game_name) System::ShutdownSystem(false); // fast boot the selected game and wait for the other player auto param = SystemBootParameters(s_game_path); - param.override_fast_boot = true; + // param.save_state = EmuFolders::SaveStates + "/SLUS-00402_2.sav"; if (!System::BootSystem(param)) { StopNetplaySession();