GGPO/Netplay: modified desync detection to allow retrieval of checksums from savestates instead of passing it trough a param.

This commit is contained in:
HeatXD 2023-05-02 01:50:10 +02:00
parent f89965b570
commit 4b60d69cf7
No known key found for this signature in database
GPG Key ID: BF30D71B2F1305C7
3 changed files with 25 additions and 26 deletions

View File

@ -428,21 +428,23 @@ GGPOErrorCode Peer2PeerBackend::SetManualNetworkPolling(bool value)
GGPOErrorCode
Peer2PeerBackend::IncrementFrame(uint16_t checksum1)
{
{
auto currentFrame = _sync.GetFrameCount();
_sync.IncrementFrame();
checksum1 = _sync.GetLastSavedFrame().checksum;
char buf[256];
uint16_t cSum = checksum1;
Log("End of frame (%d)...\n", _sync.GetFrameCount());
Log("End of frame (%d)...\n", currentFrame);
static int maxDif = 0;
if (_pendingCheckSums.count(_sync.GetFrameCount()))
if (_pendingCheckSums.count(currentFrame))
{
auto max = _pendingCheckSums.rbegin()->first;
auto diff = max - currentFrame;
maxDif = max(maxDif, diff);
int oldChecksum = _pendingCheckSums[_sync.GetFrameCount()];
_pendingCheckSums[_sync.GetFrameCount()] = cSum;
sprintf_s<256>(buf, "Replace local checksum for frame %d: %d with %d, newest frame is %d, max diff %d\n", _sync.GetFrameCount(), oldChecksum, _pendingCheckSums[_sync.GetFrameCount()], max, maxDif);
int oldChecksum = _pendingCheckSums[currentFrame];
_pendingCheckSums[currentFrame] = cSum;
sprintf_s<256>(buf, "Replace local checksum for frame %d: %d with %d, newest frame is %d, max diff %d\n",
currentFrame, oldChecksum, _pendingCheckSums[currentFrame], max, maxDif);
if (currentFrame <= _confirmedCheckSumFrame)
{
@ -461,16 +463,13 @@ Peer2PeerBackend::IncrementFrame(uint16_t checksum1)
}
else
{
sprintf_s<256>(buf, "Added local checksum for frame %d: %d\n", _sync.GetFrameCount(), cSum);
sprintf_s<256>(buf, "Added local checksum for frame %d: %d\n", currentFrame, cSum);
//OutputDebugStringA(buf);
}
_pendingCheckSums[_sync.GetFrameCount()]= cSum ;
_pendingCheckSums[currentFrame] = cSum;
_sync.IncrementFrame();
DoPoll();
DoPoll();
PollSyncEvents();
return GGPO_OK;

View File

@ -61,7 +61,8 @@ public:
bool GetEvent(Event& e);
int MaxPredictionFrames() const { return _max_prediction_frames; }
protected:
friend SyncTestBackend;
friend class SyncTestBackend;
friend class Peer2PeerBackend;
struct SavedFrame {
byte* buf;

View File

@ -7,6 +7,7 @@
#include "common/timer.h"
#include "digital_controller.h"
#include "ggponet.h"
#include "host.h"
#include "host_settings.h"
#include "pad.h"
#include "spu.h"
@ -14,7 +15,6 @@
#include <bitset>
#include <deque>
#include <xxhash.h>
#include "host.h"
Log_SetChannel(Netplay);
@ -84,7 +84,6 @@ static float s_target_speed = 1.0f;
static Common::Timer::Value s_frame_period = 0;
static Common::Timer::Value s_next_frame_time = 0;
static s32 s_next_timesync_recovery_frame = -1;
} // namespace Netplay
// Netplay Impl
@ -113,8 +112,8 @@ 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, 10000);
ggpo_set_disconnect_notify_start(s_ggpo, 2000);
ggpo_set_disconnect_timeout(s_ggpo, 3000);
ggpo_set_disconnect_notify_start(s_ggpo, 1000);
for (int i = 1; i <= 2; i++)
{
@ -212,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) / 4;
float total_time = (frame_delta * s_frame_period) / 8;
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;
@ -272,11 +271,11 @@ void Netplay::Throttle()
void Netplay::GenerateChecksumForFrame(int* checksum, int frame, unsigned char* buffer, int buffer_size)
{
u32 sliding_window_size = 4096;
u32 num_pages = buffer_size / sliding_window_size;
u32 start_position = (frame % num_pages) * sliding_window_size;
const u32 sliding_window_size = 4096 * 4; // 4 pages.
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_VerbosePrintf("check: f:%d c:%u", frame, *checksum);
// Log_InfoPrintf("check: f:%d c:%u", frame, *checksum);
}
void Netplay::AdvanceFrame(u16 checksum)
@ -473,9 +472,9 @@ bool Netplay::NpSaveFrameCb(void* ctx, unsigned char** buffer, int* len, int* ch
return false;
}
Netplay::GenerateChecksumForFrame(checksum, frame,
reinterpret_cast<unsigned char*>(our_buffer.get()->state_stream.get()->GetMemoryPointer()),
our_buffer.get()->state_stream.get()->GetMemorySize());
GenerateChecksumForFrame(checksum, frame,
reinterpret_cast<unsigned char*>(our_buffer.get()->state_stream.get()->GetMemoryPointer()),
our_buffer.get()->state_stream.get()->GetMemorySize());
*len = sizeof(System::MemorySaveState);
*buffer = reinterpret_cast<unsigned char*>(our_buffer.release());