Netplay sync state fixes.
This commit is contained in:
parent
9f8310bbe1
commit
e7d234136c
|
@ -404,6 +404,32 @@ int NetPlayServer::sendStateSyncReq( NetPlayClient *client )
|
||||||
resp.stateSize = em.size();
|
resp.stateSize = em.size();
|
||||||
resp.opsCrc32 = opsCrc32;
|
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());
|
printf("Sending ROM Sync Request: %zu\n", em.size());
|
||||||
FCEUI_SetEmulationPaused(EMULATIONPAUSED_PAUSED);
|
FCEUI_SetEmulationPaused(EMULATIONPAUSED_PAUSED);
|
||||||
|
|
||||||
|
@ -556,6 +582,13 @@ void NetPlayServer::resyncClient( NetPlayClient *client )
|
||||||
void NetPlayServer::resyncAllClients()
|
void NetPlayServer::resyncAllClients()
|
||||||
{
|
{
|
||||||
FCEU_WRAPPER_LOCK();
|
FCEU_WRAPPER_LOCK();
|
||||||
|
|
||||||
|
opsCrc32 = 0;
|
||||||
|
netPlayFrameData.reset();
|
||||||
|
|
||||||
|
inputClear();
|
||||||
|
inputFrameCount = static_cast<uint32_t>(currFrameCounter);
|
||||||
|
|
||||||
for (auto& client : clientList )
|
for (auto& client : clientList )
|
||||||
{
|
{
|
||||||
resyncClient( client );
|
resyncClient( client );
|
||||||
|
@ -632,10 +665,9 @@ void NetPlayServer::serverProcessMessage( NetPlayClient *client, void *msgBuf, s
|
||||||
{
|
{
|
||||||
client->userName = msg->userName;
|
client->userName = msg->userName;
|
||||||
FCEU_WRAPPER_LOCK();
|
FCEU_WRAPPER_LOCK();
|
||||||
sendRomLoadReq( client );
|
resyncClient(client);
|
||||||
sendStateSyncReq( client );
|
|
||||||
FCEU_WRAPPER_UNLOCK();
|
|
||||||
client->state = 1;
|
client->state = 1;
|
||||||
|
FCEU_WRAPPER_UNLOCK();
|
||||||
FCEU_DispMessage("%s Joined",0, client->userName.toLocal8Bit().constData());
|
FCEU_DispMessage("%s Joined",0, client->userName.toLocal8Bit().constData());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -681,7 +713,8 @@ void NetPlayServer::serverProcessMessage( NetPlayClient *client, void *msgBuf, s
|
||||||
|
|
||||||
if (!client->syncOk)
|
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++;
|
client->desyncCount++;
|
||||||
|
|
||||||
if (client->desyncCount > forceResyncCount)
|
if (client->desyncCount > forceResyncCount)
|
||||||
|
@ -1685,6 +1718,10 @@ void NetPlayClient::clientProcessMessage( void *msgBuf, size_t msgSize )
|
||||||
FCEU_WRAPPER_LOCK();
|
FCEU_WRAPPER_LOCK();
|
||||||
LoadGame( filepath.toLocal8Bit().constData(), true, true );
|
LoadGame( filepath.toLocal8Bit().constData(), true, true );
|
||||||
FCEUI_SetEmulationPaused(EMULATIONPAUSED_PAUSED);
|
FCEUI_SetEmulationPaused(EMULATIONPAUSED_PAUSED);
|
||||||
|
|
||||||
|
opsCrc32 = 0;
|
||||||
|
netPlayFrameData.reset();
|
||||||
|
inputClear();
|
||||||
FCEU_WRAPPER_UNLOCK();
|
FCEU_WRAPPER_UNLOCK();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1711,11 +1748,34 @@ void NetPlayClient::clientProcessMessage( void *msgBuf, size_t msgSize )
|
||||||
serverRequestedStateLoad = true;
|
serverRequestedStateLoad = true;
|
||||||
FCEUSS_LoadFP( &em, SSLOADPARAM_NOBACKUP );
|
FCEUSS_LoadFP( &em, SSLOADPARAM_NOBACKUP );
|
||||||
serverRequestedStateLoad = false;
|
serverRequestedStateLoad = false;
|
||||||
FCEU_WRAPPER_UNLOCK();
|
|
||||||
|
|
||||||
opsCrc32 = msg->opsCrc32;
|
opsCrc32 = msg->opsCrc32;
|
||||||
netPlayFrameData.reset();
|
netPlayFrameData.reset();
|
||||||
|
|
||||||
|
NetPlayFrameData data;
|
||||||
|
data.frameNum = msg->lastFrame.num;
|
||||||
|
data.opsCrc32 = msg->lastFrame.opsCrc32;
|
||||||
|
data.ramCrc32 = msg->lastFrame.ramCrc32;
|
||||||
|
|
||||||
|
netPlayFrameData.push( data );
|
||||||
|
|
||||||
inputClear();
|
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;
|
break;
|
||||||
case NETPLAY_RUN_FRAME_REQ:
|
case NETPLAY_RUN_FRAME_REQ:
|
||||||
|
|
|
@ -263,23 +263,58 @@ struct netPlayLoadStateResp
|
||||||
uint32_t stateSize;
|
uint32_t stateSize;
|
||||||
uint32_t opsCrc32;
|
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)
|
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()
|
void toHostByteOrder()
|
||||||
{
|
{
|
||||||
hdr.toHostByteOrder();
|
hdr.toHostByteOrder();
|
||||||
stateSize = netPlayByteSwap(stateSize);
|
stateSize = netPlayByteSwap(stateSize);
|
||||||
opsCrc32 = netPlayByteSwap(opsCrc32);
|
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()
|
void toNetworkByteOrder()
|
||||||
{
|
{
|
||||||
hdr.toNetworkByteOrder();
|
hdr.toNetworkByteOrder();
|
||||||
stateSize = netPlayByteSwap(stateSize);
|
stateSize = netPlayByteSwap(stateSize);
|
||||||
opsCrc32 = netPlayByteSwap(opsCrc32);
|
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()
|
char* stateDataBuf()
|
||||||
|
|
Loading…
Reference in New Issue