diff --git a/src/drivers/Qt/ConsoleWindow.h b/src/drivers/Qt/ConsoleWindow.h index a89d742b..0082bbbc 100644 --- a/src/drivers/Qt/ConsoleWindow.h +++ b/src/drivers/Qt/ConsoleWindow.h @@ -328,6 +328,7 @@ class consoleWin_t : public QMainWindow public: signals: void romLoaded(void); + void romUnload(void); void stateLoaded(void); void nesResetOccurred(void); diff --git a/src/drivers/Qt/NetPlay.cpp b/src/drivers/Qt/NetPlay.cpp index df3a41e7..b9bb934e 100644 --- a/src/drivers/Qt/NetPlay.cpp +++ b/src/drivers/Qt/NetPlay.cpp @@ -22,6 +22,7 @@ #include #include "../../fceu.h" +#include "../../cart.h" #include "../../state.h" #include "../../movie.h" #include "../../debug.h" @@ -181,6 +182,11 @@ NetPlayServer::NetPlayServer(QObject *parent) FCEU_WRAPPER_LOCK(); inputFrameCount = static_cast(currFrameCounter); + + if (currCartInfo != nullptr) + { + romCrc32 = currCartInfo->CRC32; + } FCEU_WRAPPER_UNLOCK(); } @@ -443,6 +449,11 @@ void NetPlayServer::onRomLoad() //printf("New ROM Loaded!\n"); FCEU_WRAPPER_LOCK(); + if (currCartInfo != nullptr) + { + romCrc32 = currCartInfo->CRC32; + } + opsCrc32 = 0; netPlayFrameData.reset(); @@ -618,6 +629,8 @@ void NetPlayServer::serverProcessMessage( NetPlayClient *client, void *msgBuf, s client->setPaused( (msg->flags & netPlayClientState::PAUSE_FLAG ) ? true : false ); client->setDesync( (msg->flags & netPlayClientState::DESYNC_FLAG) ? true : false ); + client->romMatch = (romCrc32 == msg->romCrc32); + NetPlayFrameData data; if ( (msg->opsFrame == 0) || netPlayFrameData.find( msg->opsFrame, data ) ) { @@ -638,12 +651,11 @@ void NetPlayServer::serverProcessMessage( NetPlayClient *client, void *msgBuf, s if (client->desyncCount > forceResyncCount) { FCEU_WRAPPER_LOCK(); - sendStateSyncReq( client ); + resyncClient( client ); FCEU_WRAPPER_UNLOCK(); client->desyncCount = 0; } - } else { @@ -962,6 +974,19 @@ NetPlayClient::NetPlayClient(QObject *parent, bool outGoing) { printf("Error: NetPlayClient failed to allocate recvMsgBuf\n"); } + + if (outGoing) + { + connect(consoleWindow, SIGNAL(romLoaded(void)), this, SLOT(onRomLoad(void))); + connect(consoleWindow, SIGNAL(romUnload(void)), this, SLOT(onRomUnload(void))); + + FCEU_WRAPPER_LOCK(); + if (currCartInfo != nullptr) + { + romCrc32 = currCartInfo->CRC32; + } + FCEU_WRAPPER_UNLOCK(); + } } @@ -1025,6 +1050,25 @@ int NetPlayClient::Destroy() return 0; } //----------------------------------------------------------------------------- +void NetPlayClient::onRomLoad() +{ + FCEU_WRAPPER_LOCK(); + if (currCartInfo != nullptr) + { + romCrc32 = currCartInfo->CRC32; + } + else + { + romCrc32 = 0; + } + FCEU_WRAPPER_UNLOCK(); +} +//----------------------------------------------------------------------------- +void NetPlayClient::onRomUnload() +{ + romCrc32 = 0; +} +//----------------------------------------------------------------------------- void NetPlayClient::forceDisconnect() { disconnectPending = true; @@ -1272,6 +1316,7 @@ void NetPlayClient::update(void) statusMsg.opsFrame = lastFrameData.frameNum; statusMsg.opsChkSum = lastFrameData.opsCrc32; statusMsg.ramChkSum = lastFrameData.ramCrc32; + statusMsg.romCrc32 = romCrc32; statusMsg.ctrlState[0] = (ctlrData ) & 0x000000ff; statusMsg.ctrlState[1] = (ctlrData >> 8) & 0x000000ff; statusMsg.ctrlState[2] = (ctlrData >> 16) & 0x000000ff; @@ -1343,6 +1388,12 @@ int NetPlayClient::readMessages( void (*msgCallback)( void *userData, void *msgB recvMsgSize = netPlayByteSwap(hdr->msgSize) - sizeof(netPlayMsgHdr); recvMsgBytesLeft = recvMsgSize; + if ( (netPlayByteSwap(hdr->magic[0]) != NETPLAY_MAGIC_NUMBER) || + (netPlayByteSwap(hdr->magic[1]) != NETPLAY_MAGIC_NUMBER) ) + { + printf("Error: Message Header Validity Check Failed: %08X\n", recvMsgId); + } + if (netPlayByteSwap(hdr->msgSize) > recvMsgBufSize) { printf("Error: Message size too large: %08X\n", recvMsgId); @@ -2122,6 +2173,10 @@ void NetPlayClientTreeItem::updateData() { state += QObject::tr(",Desync"); } + if (!client->romMatch) + { + state += QObject::tr(",ROM Mismatch"); + } setText( 0, client->userName ); setText( 1, QObject::tr(roleString) ); diff --git a/src/drivers/Qt/NetPlay.h b/src/drivers/Qt/NetPlay.h index e9bfe382..42f66077 100644 --- a/src/drivers/Qt/NetPlay.h +++ b/src/drivers/Qt/NetPlay.h @@ -165,6 +165,7 @@ class NetPlayServer : public QTcpServer uint32_t maxLeadFrames = 10u; uint32_t clientWaitCounter = 0; uint32_t inputFrameCount = 0; + uint32_t romCrc32 = 0; bool enforceAppVersionCheck = true; bool allowClientRomLoadReq = false; bool allowClientStateLoadReq = false; @@ -276,6 +277,7 @@ class NetPlayClient : public QObject int state = 0; int desyncCount = 0; bool syncOk = false; + bool romMatch = false; unsigned int currentFrame = 0; unsigned int readyFrame = 0; unsigned int catchUpThreshold = 10; @@ -301,6 +303,7 @@ class NetPlayClient : public QObject uint64_t pingDelaySum = 0; uint64_t pingDelayLast = 0; uint64_t pingNumSamples = 0; + uint32_t romCrc32 = 0; std::list input; FCEU::mutex inputMtx; @@ -315,6 +318,8 @@ class NetPlayClient : public QObject void onConnect(void); void onDisconnect(void); void onSocketError(QAbstractSocket::SocketError); + void onRomLoad(void); + void onRomUnload(void); }; diff --git a/src/drivers/Qt/NetPlayMsgDef.h b/src/drivers/Qt/NetPlayMsgDef.h index 960505d2..abe3a376 100644 --- a/src/drivers/Qt/NetPlayMsgDef.h +++ b/src/drivers/Qt/NetPlayMsgDef.h @@ -295,6 +295,7 @@ struct netPlayClientState uint32_t opsFrame; // Last frame for ops data uint32_t opsChkSum; uint32_t ramChkSum; + uint32_t romCrc32; uint8_t ctrlState[4]; static constexpr uint32_t PAUSE_FLAG = 0x0001; @@ -302,7 +303,7 @@ struct netPlayClientState netPlayClientState(void) : hdr(NETPLAY_CLIENT_STATE, sizeof(netPlayClientState)), flags(0), - frameRdy(0), frameRun(0), opsChkSum(0), ramChkSum(0) + frameRdy(0), frameRun(0), opsChkSum(0), ramChkSum(0), romCrc32(0) { memset( ctrlState, 0, sizeof(ctrlState) ); } @@ -316,6 +317,7 @@ struct netPlayClientState opsFrame = netPlayByteSwap(opsFrame); opsChkSum = netPlayByteSwap(opsChkSum); ramChkSum = netPlayByteSwap(ramChkSum); + romCrc32 = netPlayByteSwap(romCrc32); } void toNetworkByteOrder() @@ -327,6 +329,7 @@ struct netPlayClientState opsFrame = netPlayByteSwap(opsFrame); opsChkSum = netPlayByteSwap(opsChkSum); ramChkSum = netPlayByteSwap(ramChkSum); + romCrc32 = netPlayByteSwap(romCrc32); } }; diff --git a/src/drivers/Qt/fceuWrapper.cpp b/src/drivers/Qt/fceuWrapper.cpp index 9c070728..6a92d86a 100644 --- a/src/drivers/Qt/fceuWrapper.cpp +++ b/src/drivers/Qt/fceuWrapper.cpp @@ -504,6 +504,12 @@ CloseGame(void) return(0); } + // Signal to listeners that current ROM is being unloaded + if ( consoleWindow ) + { + emit consoleWindow->romUnload(); + } + // If the emulation thread is stuck hanging at a breakpoint, // disable breakpoint debugging and wait for the thread to // complete its frame. So that it is idle with a minimal call