Skip to content

Commit

Permalink
Netplay sync state fixes.
Browse files Browse the repository at this point in the history
  • Loading branch information
thor2016 committed Apr 8, 2024
1 parent 9f8310b commit e7d2341
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 10 deletions.
70 changes: 65 additions & 5 deletions src/drivers/Qt/NetPlay.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,32 @@ int NetPlayServer::sendStateSyncReq( NetPlayClient *client )
resp.stateSize = em.size();
resp.opsCrc32 = opsCrc32;

NetPlayFrameData lastFrameData;
netPlayFrameData.getLast( lastFrameData );

resp.lastFrame.num = lastFrameData.frameNum;
resp.lastFrame.opsCrc32 = lastFrameData.opsCrc32;
resp.lastFrame.ramCrc32 = lastFrameData.ramCrc32;
resp.numCtrlFrames = 0;

{
int i = 0;
FCEU::autoScopedLock alock(inputMtx);
for (auto& inputFrame : input)
{
if (i < netPlayLoadStateResp::MaxCtrlFrames)
{
resp.ctrlData[i].frameNum = inputFrame.frameCounter;
resp.ctrlData[i].ctrlState[0] = inputFrame.ctrl[0];
resp.ctrlData[i].ctrlState[1] = inputFrame.ctrl[1];
resp.ctrlData[i].ctrlState[2] = inputFrame.ctrl[2];
resp.ctrlData[i].ctrlState[3] = inputFrame.ctrl[3];
i++;
}
}
resp.numCtrlFrames = i;
}

printf("Sending ROM Sync Request: %zu\n", em.size());
FCEUI_SetEmulationPaused(EMULATIONPAUSED_PAUSED);

Expand Down Expand Up @@ -556,6 +582,13 @@ void NetPlayServer::resyncClient( NetPlayClient *client )
void NetPlayServer::resyncAllClients()
{
FCEU_WRAPPER_LOCK();

opsCrc32 = 0;
netPlayFrameData.reset();

inputClear();
inputFrameCount = static_cast<uint32_t>(currFrameCounter);

for (auto& client : clientList )
{
resyncClient( client );
Expand Down Expand Up @@ -632,10 +665,9 @@ void NetPlayServer::serverProcessMessage( NetPlayClient *client, void *msgBuf, s
{
client->userName = msg->userName;
FCEU_WRAPPER_LOCK();
sendRomLoadReq( client );
sendStateSyncReq( client );
FCEU_WRAPPER_UNLOCK();
resyncClient(client);
client->state = 1;
FCEU_WRAPPER_UNLOCK();
FCEU_DispMessage("%s Joined",0, client->userName.toLocal8Bit().constData());
}
else
Expand Down Expand Up @@ -681,7 +713,8 @@ void NetPlayServer::serverProcessMessage( NetPlayClient *client, void *msgBuf, s

if (!client->syncOk)
{
printf("Frame:%u is NOT in Sync: OPS:%i RAM:%i\n", msg->frameRun, opsSync, ramSync);
printf("Client %s Frame:%u is NOT in Sync: OPS:%i RAM:%i\n",
client->userName.toLocal8Bit().constData(), msg->frameRun, opsSync, ramSync);
client->desyncCount++;

if (client->desyncCount > forceResyncCount)
Expand Down Expand Up @@ -1685,6 +1718,10 @@ void NetPlayClient::clientProcessMessage( void *msgBuf, size_t msgSize )
FCEU_WRAPPER_LOCK();
LoadGame( filepath.toLocal8Bit().constData(), true, true );
FCEUI_SetEmulationPaused(EMULATIONPAUSED_PAUSED);

opsCrc32 = 0;
netPlayFrameData.reset();
inputClear();
FCEU_WRAPPER_UNLOCK();
}
break;
Expand All @@ -1711,11 +1748,34 @@ void NetPlayClient::clientProcessMessage( void *msgBuf, size_t msgSize )
serverRequestedStateLoad = true;
FCEUSS_LoadFP( &em, SSLOADPARAM_NOBACKUP );
serverRequestedStateLoad = false;
FCEU_WRAPPER_UNLOCK();

opsCrc32 = msg->opsCrc32;
netPlayFrameData.reset();

NetPlayFrameData data;
data.frameNum = msg->lastFrame.num;
data.opsCrc32 = msg->lastFrame.opsCrc32;
data.ramCrc32 = msg->lastFrame.ramCrc32;

netPlayFrameData.push( data );

inputClear();

const int numInputFrames = msg->numCtrlFrames;
for (int i=0; i<numInputFrames; i++)
{
NetPlayFrameInput inputFrame;

inputFrame.frameCounter = msg->ctrlData[i].frameNum;
inputFrame.ctrl[0] = msg->ctrlData[i].ctrlState[0];
inputFrame.ctrl[1] = msg->ctrlData[i].ctrlState[1];
inputFrame.ctrl[2] = msg->ctrlData[i].ctrlState[2];
inputFrame.ctrl[3] = msg->ctrlData[i].ctrlState[3];

pushBackInput( inputFrame );
}
FCEU_WRAPPER_UNLOCK();

}
break;
case NETPLAY_RUN_FRAME_REQ:
Expand Down
45 changes: 40 additions & 5 deletions src/drivers/Qt/NetPlayMsgDef.h
Original file line number Diff line number Diff line change
Expand Up @@ -263,23 +263,58 @@ struct netPlayLoadStateResp
uint32_t stateSize;
uint32_t opsCrc32;

struct {
uint32_t num = 0;
uint32_t opsCrc32 = 0;
uint32_t ramCrc32 = 0;
} lastFrame;

uint32_t numCtrlFrames;

static constexpr int MaxCtrlFrames = 10;

struct {
uint32_t frameNum = 0;
uint8_t ctrlState[4] = {0};

} ctrlData[MaxCtrlFrames];

netPlayLoadStateResp(void)
: hdr(NETPLAY_SYNC_STATE_RESP, sizeof(netPlayLoadStateResp)), stateSize(0), opsCrc32(0)
: hdr(NETPLAY_SYNC_STATE_RESP, sizeof(netPlayLoadStateResp)),
stateSize(0), opsCrc32(0), numCtrlFrames(0)
{
}

void toHostByteOrder()
{
hdr.toHostByteOrder();
stateSize = netPlayByteSwap(stateSize);
opsCrc32 = netPlayByteSwap(opsCrc32);
stateSize = netPlayByteSwap(stateSize);
opsCrc32 = netPlayByteSwap(opsCrc32);
lastFrame.num = netPlayByteSwap(lastFrame.num);
lastFrame.opsCrc32 = netPlayByteSwap(lastFrame.opsCrc32);
lastFrame.ramCrc32 = netPlayByteSwap(lastFrame.ramCrc32);
numCtrlFrames = netPlayByteSwap(numCtrlFrames);

for (int i=0; i<MaxCtrlFrames; i++)
{
ctrlData[i].frameNum = netPlayByteSwap(ctrlData[i].frameNum);
}
}

void toNetworkByteOrder()
{
hdr.toNetworkByteOrder();
stateSize = netPlayByteSwap(stateSize);
opsCrc32 = netPlayByteSwap(opsCrc32);
stateSize = netPlayByteSwap(stateSize);
opsCrc32 = netPlayByteSwap(opsCrc32);
lastFrame.num = netPlayByteSwap(lastFrame.num);
lastFrame.opsCrc32 = netPlayByteSwap(lastFrame.opsCrc32);
lastFrame.ramCrc32 = netPlayByteSwap(lastFrame.ramCrc32);
numCtrlFrames = netPlayByteSwap(numCtrlFrames);

for (int i=0; i<MaxCtrlFrames; i++)
{
ctrlData[i].frameNum = netPlayByteSwap(ctrlData[i].frameNum);
}
}

char* stateDataBuf()
Expand Down

0 comments on commit e7d2341

Please sign in to comment.