More Qt netplay updates.
This commit is contained in:
parent
84c2591d3f
commit
cb45321433
|
@ -1670,6 +1670,7 @@ void consoleWin_t::createMainMenu(void)
|
||||||
//act->setShortcut( QKeySequence(tr("Shift+F7")));
|
//act->setShortcut( QKeySequence(tr("Shift+F7")));
|
||||||
act->setStatusTip(tr("Host Game Window"));
|
act->setStatusTip(tr("Host Game Window"));
|
||||||
connect(act, SIGNAL(triggered()), this, SLOT(openNetPlayHostWindow(void)) );
|
connect(act, SIGNAL(triggered()), this, SLOT(openNetPlayHostWindow(void)) );
|
||||||
|
netPlayHostAct = act;
|
||||||
|
|
||||||
netPlayMenu->addAction(act);
|
netPlayMenu->addAction(act);
|
||||||
|
|
||||||
|
@ -1678,10 +1679,20 @@ void consoleWin_t::createMainMenu(void)
|
||||||
//act->setShortcut( QKeySequence(tr("Shift+F7")));
|
//act->setShortcut( QKeySequence(tr("Shift+F7")));
|
||||||
act->setStatusTip(tr("Join Game Window"));
|
act->setStatusTip(tr("Join Game Window"));
|
||||||
connect(act, SIGNAL(triggered()), this, SLOT(openNetPlayJoinWindow(void)) );
|
connect(act, SIGNAL(triggered()), this, SLOT(openNetPlayJoinWindow(void)) );
|
||||||
|
netPlayJoinAct = act;
|
||||||
|
|
||||||
netPlayMenu->addAction(act);
|
netPlayMenu->addAction(act);
|
||||||
|
|
||||||
netPlayMenu->setEnabled(false);
|
// NetPlay -> End Game / Disconnect
|
||||||
|
act = new QAction(tr("&Disconnect/End Game"), this);
|
||||||
|
//act->setShortcut( QKeySequence(tr("Shift+F7")));
|
||||||
|
act->setStatusTip(tr("Disconnect Netplay Game"));
|
||||||
|
connect(act, SIGNAL(triggered()), this, SLOT(closeNetPlaySession(void)) );
|
||||||
|
netPlayDiscAct = act;
|
||||||
|
|
||||||
|
netPlayMenu->addAction(act);
|
||||||
|
|
||||||
|
//netPlayMenu->setEnabled(false);
|
||||||
//-----------------------------------------------------------------------
|
//-----------------------------------------------------------------------
|
||||||
// Tools
|
// Tools
|
||||||
|
|
||||||
|
@ -3159,6 +3170,11 @@ void consoleWin_t::openNetPlayJoinWindow(void)
|
||||||
win->show();
|
win->show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void consoleWin_t::closeNetPlaySession(void)
|
||||||
|
{
|
||||||
|
NetPlayCloseSession();
|
||||||
|
}
|
||||||
|
|
||||||
void consoleWin_t::openAviRiffViewer(void)
|
void consoleWin_t::openAviRiffViewer(void)
|
||||||
{
|
{
|
||||||
AviRiffViewerDialog *win;
|
AviRiffViewerDialog *win;
|
||||||
|
@ -4717,6 +4733,12 @@ void consoleWin_t::updatePeriodic(void)
|
||||||
recAsWavAct->setEnabled( FCEU_IsValidUI( FCEUI_RECORDMOVIE ) && !FCEUI_WaveRecordRunning() );
|
recAsWavAct->setEnabled( FCEU_IsValidUI( FCEUI_RECORDMOVIE ) && !FCEUI_WaveRecordRunning() );
|
||||||
stopWavAct->setEnabled( FCEUI_WaveRecordRunning() );
|
stopWavAct->setEnabled( FCEUI_WaveRecordRunning() );
|
||||||
tasEditorAct->setEnabled( FCEU_IsValidUI(FCEUI_TASEDITOR) );
|
tasEditorAct->setEnabled( FCEU_IsValidUI(FCEUI_TASEDITOR) );
|
||||||
|
|
||||||
|
bool netPlayactv = NetPlayActive();
|
||||||
|
|
||||||
|
netPlayHostAct->setEnabled( !netPlayactv );
|
||||||
|
netPlayJoinAct->setEnabled( !netPlayactv );
|
||||||
|
netPlayDiscAct->setEnabled( netPlayactv );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( errorMsgValid )
|
if ( errorMsgValid )
|
||||||
|
|
|
@ -260,6 +260,9 @@ class consoleWin_t : public QMainWindow
|
||||||
QAction *recAsWavAct;
|
QAction *recAsWavAct;
|
||||||
QAction *stopWavAct;
|
QAction *stopWavAct;
|
||||||
QAction *tasEditorAct;
|
QAction *tasEditorAct;
|
||||||
|
QAction *netPlayHostAct;
|
||||||
|
QAction *netPlayJoinAct;
|
||||||
|
QAction *netPlayDiscAct;
|
||||||
//QAction *aviHudAct;
|
//QAction *aviHudAct;
|
||||||
//QAction *aviMsgAct;
|
//QAction *aviMsgAct;
|
||||||
|
|
||||||
|
@ -354,6 +357,7 @@ class consoleWin_t : public QMainWindow
|
||||||
void openPaletteEditorWin(void);
|
void openPaletteEditorWin(void);
|
||||||
void openNetPlayHostWindow(void);
|
void openNetPlayHostWindow(void);
|
||||||
void openNetPlayJoinWindow(void);
|
void openNetPlayJoinWindow(void);
|
||||||
|
void closeNetPlaySession(void);
|
||||||
void openAviRiffViewer(void);
|
void openAviRiffViewer(void);
|
||||||
void openTimingStatWin(void);
|
void openTimingStatWin(void);
|
||||||
void openMovieOptWin(void);
|
void openMovieOptWin(void);
|
||||||
|
|
|
@ -69,6 +69,17 @@ int NetPlayServer::Create(QObject *parent)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int NetPlayServer::Destroy()
|
||||||
|
{
|
||||||
|
NetPlayServer* server = NetPlayServer::GetInstance();
|
||||||
|
if (server != nullptr)
|
||||||
|
{
|
||||||
|
delete server;
|
||||||
|
server = nullptr;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void NetPlayServer::newConnectionRdy(void)
|
void NetPlayServer::newConnectionRdy(void)
|
||||||
{
|
{
|
||||||
printf("New Connection Ready!\n");
|
printf("New Connection Ready!\n");
|
||||||
|
@ -82,7 +93,7 @@ void NetPlayServer::processPendingConnections(void)
|
||||||
|
|
||||||
newSock = nextPendingConnection();
|
newSock = nextPendingConnection();
|
||||||
|
|
||||||
while (newSock)
|
while (newSock != nullptr)
|
||||||
{
|
{
|
||||||
NetPlayClient *client = new NetPlayClient(this);
|
NetPlayClient *client = new NetPlayClient(this);
|
||||||
|
|
||||||
|
@ -100,47 +111,20 @@ void NetPlayServer::processPendingConnections(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NetPlayServer::removeClient(NetPlayClient *client, bool markForDelete)
|
|
||||||
{
|
|
||||||
bool removed = false;
|
|
||||||
std::list <NetPlayClient*>::iterator it;
|
|
||||||
|
|
||||||
it = clientList.begin();
|
|
||||||
|
|
||||||
while (it != clientList.end())
|
|
||||||
{
|
|
||||||
if (client == *it)
|
|
||||||
{
|
|
||||||
if (markForDelete)
|
|
||||||
{
|
|
||||||
client->deleteLater();
|
|
||||||
}
|
|
||||||
|
|
||||||
it = clientList.erase(it);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
it++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i=0; i<4; i++)
|
|
||||||
{
|
|
||||||
if (clientPlayer[i] == client)
|
|
||||||
{
|
|
||||||
clientPlayer[i] = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return removed;
|
|
||||||
}
|
|
||||||
|
|
||||||
int NetPlayServer::closeAllConnections(void)
|
int NetPlayServer::closeAllConnections(void)
|
||||||
{
|
{
|
||||||
std::list <NetPlayClient*>::iterator it;
|
std::list <NetPlayClient*>::iterator it;
|
||||||
|
|
||||||
|
for (int i=0; i<4; i++)
|
||||||
|
{
|
||||||
|
clientPlayer[i] = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
for (it = clientList.begin(); it != clientList.end(); it++)
|
for (it = clientList.begin(); it != clientList.end(); it++)
|
||||||
{
|
{
|
||||||
delete *it;
|
auto* client = *it;
|
||||||
|
|
||||||
|
delete client;
|
||||||
}
|
}
|
||||||
clientList.clear();
|
clientList.clear();
|
||||||
|
|
||||||
|
@ -298,31 +282,31 @@ void NetPlayServer::serverProcessMessage( NetPlayClient *client, void *msgBuf, s
|
||||||
|
|
||||||
if ( claimRole(client, msg->playerId) )
|
if ( claimRole(client, msg->playerId) )
|
||||||
{
|
{
|
||||||
|
client->userName = msg->userName;
|
||||||
sendRomLoadReq( client );
|
sendRomLoadReq( client );
|
||||||
sendStateSyncReq( client );
|
sendStateSyncReq( client );
|
||||||
client->state = 1;
|
client->state = 1;
|
||||||
|
FCEU_DispMessage("%s Joined",0, client->userName.toLocal8Bit().constData());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
netPlayErrorMsg<128> errorMsg;
|
netPlayErrorMsg<128> errorMsg;
|
||||||
|
errorMsg.setDisconnectFlag();
|
||||||
errorMsg.printf("Player %i role is not available", msg->playerId+1);
|
errorMsg.printf("Player %i role is not available", msg->playerId+1);
|
||||||
sendMsg( client, &errorMsg, errorMsg.hdr.msgSize );
|
sendMsg( client, &errorMsg, errorMsg.hdr.msgSize );
|
||||||
//client->disconnect();
|
client->flushData();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case NETPLAY_RUN_FRAME_RESP:
|
|
||||||
{
|
|
||||||
netPlayRunFrameResp *msg = static_cast<netPlayRunFrameResp*>(msgBuf);
|
|
||||||
|
|
||||||
client->currentFrame = msg->frameRun;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case NETPLAY_CLIENT_STATE:
|
case NETPLAY_CLIENT_STATE:
|
||||||
{
|
{
|
||||||
netPlayClientState *msg = static_cast<netPlayClientState*>(msgBuf);
|
netPlayClientState *msg = static_cast<netPlayClientState*>(msgBuf);
|
||||||
|
|
||||||
client->currentFrame = msg->frameRun;
|
client->currentFrame = msg->frameRun;
|
||||||
|
client->gpData[0] = msg->ctrlState[0];
|
||||||
|
client->gpData[1] = msg->ctrlState[1];
|
||||||
|
client->gpData[2] = msg->ctrlState[2];
|
||||||
|
client->gpData[3] = msg->ctrlState[3];
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -342,26 +326,65 @@ void NetPlayServer::update(void)
|
||||||
const uint32_t leadFrame = currFrame + maxLead;
|
const uint32_t leadFrame = currFrame + maxLead;
|
||||||
const uint32_t lastFrame = inputFrameBack();
|
const uint32_t lastFrame = inputFrameBack();
|
||||||
uint32_t lagFrame = 0;
|
uint32_t lagFrame = 0;
|
||||||
|
uint8_t localGP[4] = { 0 };
|
||||||
|
uint8_t gpData[4] = { 0 };
|
||||||
|
|
||||||
if (currFrame > maxLead)
|
if (currFrame > maxLead)
|
||||||
{
|
{
|
||||||
lagFrame = currFrame - maxLead;
|
lagFrame = currFrame - maxLead;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t ctlrData = GetGamepadPressedImmediate();
|
||||||
|
localGP[0] = (ctlrData ) & 0x000000ff;
|
||||||
|
localGP[1] = (ctlrData >> 8) & 0x000000ff;
|
||||||
|
localGP[2] = (ctlrData >> 16) & 0x000000ff;
|
||||||
|
localGP[3] = (ctlrData >> 24) & 0x000000ff;
|
||||||
|
|
||||||
|
if ( (role >= NETPLAY_PLAYER1) && (role <= NETPLAY_PLAYER4) )
|
||||||
|
{
|
||||||
|
gpData[role] = localGP[role];
|
||||||
|
}
|
||||||
|
|
||||||
// Input Processing
|
// Input Processing
|
||||||
for (auto it = clientList.begin(); it != clientList.end(); it++)
|
for (auto it = clientList.begin(); it != clientList.end(); )
|
||||||
{
|
{
|
||||||
NetPlayClient *client = *it;
|
NetPlayClient *client = *it;
|
||||||
|
|
||||||
client->readMessages( serverMessageCallback, client );
|
client->readMessages( serverMessageCallback, client );
|
||||||
|
|
||||||
if (client->currentFrame < clientMinFrame)
|
if (client->isAuthenticated())
|
||||||
{
|
{
|
||||||
clientMinFrame = client->currentFrame;
|
if (client->currentFrame < clientMinFrame)
|
||||||
|
{
|
||||||
|
clientMinFrame = client->currentFrame;
|
||||||
|
}
|
||||||
|
if (client->currentFrame > clientMaxFrame)
|
||||||
|
{
|
||||||
|
clientMaxFrame = client->currentFrame;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (client->isPlayerRole())
|
||||||
|
{
|
||||||
|
gpData[client->role] = client->gpData[client->role];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (client->currentFrame > clientMaxFrame)
|
|
||||||
|
|
||||||
|
if (client->shouldDestroy())
|
||||||
{
|
{
|
||||||
clientMaxFrame = client->currentFrame;
|
it = clientList.erase(it);
|
||||||
|
for (int i=0; i<4; i++)
|
||||||
|
{
|
||||||
|
if (client == clientPlayer[i])
|
||||||
|
{
|
||||||
|
clientPlayer[i] = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete client;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
it++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -378,13 +401,11 @@ void NetPlayServer::update(void)
|
||||||
NetPlayFrameInput inputFrame;
|
NetPlayFrameInput inputFrame;
|
||||||
netPlayRunFrameReq runFrameReq;
|
netPlayRunFrameReq runFrameReq;
|
||||||
|
|
||||||
uint32_t ctlrData = GetGamepadPressedImmediate();
|
|
||||||
|
|
||||||
inputFrame.frameCounter = static_cast<uint32_t>(currFrameCounter) + 1;
|
inputFrame.frameCounter = static_cast<uint32_t>(currFrameCounter) + 1;
|
||||||
inputFrame.ctrl[0] = (ctlrData ) & 0x000000ff;
|
inputFrame.ctrl[0] = gpData[0];
|
||||||
inputFrame.ctrl[1] = (ctlrData >> 8) & 0x000000ff;
|
inputFrame.ctrl[1] = gpData[1];
|
||||||
inputFrame.ctrl[2] = (ctlrData >> 16) & 0x000000ff;
|
inputFrame.ctrl[2] = gpData[2];
|
||||||
inputFrame.ctrl[3] = (ctlrData >> 24) & 0x000000ff;
|
inputFrame.ctrl[3] = gpData[3];
|
||||||
|
|
||||||
runFrameReq.frameNum = inputFrame.frameCounter;
|
runFrameReq.frameNum = inputFrame.frameCounter;
|
||||||
runFrameReq.ctrlState[0] = inputFrame.ctrl[0];
|
runFrameReq.ctrlState[0] = inputFrame.ctrl[0];
|
||||||
|
@ -438,6 +459,7 @@ NetPlayClient::~NetPlayClient(void)
|
||||||
|
|
||||||
if (sock != nullptr)
|
if (sock != nullptr)
|
||||||
{
|
{
|
||||||
|
sock->close();
|
||||||
delete sock; sock = nullptr;
|
delete sock; sock = nullptr;
|
||||||
}
|
}
|
||||||
if (recvMsgBuf)
|
if (recvMsgBuf)
|
||||||
|
@ -460,10 +482,43 @@ int NetPlayClient::Create(QObject *parent)
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
void NetPlayClient::disconnect()
|
int NetPlayClient::Destroy()
|
||||||
{
|
{
|
||||||
sock->close();
|
NetPlayClient* client = NetPlayClient::GetInstance();
|
||||||
|
if (client != nullptr)
|
||||||
|
{
|
||||||
|
delete client;
|
||||||
|
client = nullptr;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void NetPlayClient::forceDisconnect()
|
||||||
|
{
|
||||||
|
disconnectPending = true;
|
||||||
|
needsDestroy = true;
|
||||||
|
}
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
bool NetPlayClient::isAuthenticated()
|
||||||
|
{
|
||||||
|
return state > 0;
|
||||||
|
}
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
bool NetPlayClient::isPlayerRole()
|
||||||
|
{
|
||||||
|
return (role >= NETPLAY_PLAYER1) && (role <= NETPLAY_PLAYER4);
|
||||||
|
}
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
bool NetPlayClient::flushData()
|
||||||
|
{
|
||||||
|
bool success = false;
|
||||||
|
|
||||||
|
if (sock != nullptr)
|
||||||
|
{
|
||||||
|
success = sock->flush();
|
||||||
|
}
|
||||||
|
return success;
|
||||||
}
|
}
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void NetPlayClient::setSocket(QTcpSocket *s)
|
void NetPlayClient::setSocket(QTcpSocket *s)
|
||||||
|
@ -486,6 +541,7 @@ int NetPlayClient::createSocket(void)
|
||||||
|
|
||||||
connect(sock, SIGNAL(connected(void)) , this, SLOT(onConnect(void)));
|
connect(sock, SIGNAL(connected(void)) , this, SLOT(onConnect(void)));
|
||||||
connect(sock, SIGNAL(disconnected(void)), this, SLOT(onDisconnect(void)));
|
connect(sock, SIGNAL(disconnected(void)), this, SLOT(onDisconnect(void)));
|
||||||
|
connect(sock, SIGNAL(errorOccurred(QAbstractSocket::SocketError)), this, SLOT(onSocketError(QAbstractSocket::SocketError)));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -512,6 +568,8 @@ int NetPlayClient::connectToHost( const QString host, int port )
|
||||||
void NetPlayClient::onConnect(void)
|
void NetPlayClient::onConnect(void)
|
||||||
{
|
{
|
||||||
printf("Client Connected!!!\n");
|
printf("Client Connected!!!\n");
|
||||||
|
FCEU_DispMessage("Joined Host",0);
|
||||||
|
connected = true;
|
||||||
}
|
}
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void NetPlayClient::onDisconnect(void)
|
void NetPlayClient::onDisconnect(void)
|
||||||
|
@ -522,11 +580,23 @@ void NetPlayClient::onDisconnect(void)
|
||||||
|
|
||||||
if (server)
|
if (server)
|
||||||
{
|
{
|
||||||
if (server->removeClient(this))
|
FCEU_DispMessage("%s Disconnected",0, userName.toLocal8Bit().constData());
|
||||||
{
|
|
||||||
deleteLater();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FCEU_DispMessage("Host Disconnected",0);
|
||||||
|
}
|
||||||
|
needsDestroy = true;
|
||||||
|
}
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void NetPlayClient::onSocketError(QAbstractSocket::SocketError error)
|
||||||
|
{
|
||||||
|
FCEU_DispMessage("Socket Error",0);
|
||||||
|
|
||||||
|
QString errorMsg = sock->errorString();
|
||||||
|
printf("Error: %s\n", errorMsg.toLocal8Bit().constData());
|
||||||
|
|
||||||
|
FCEU_DispMessage("%s", 0, errorMsg.toLocal8Bit().constData());
|
||||||
}
|
}
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
static void clientMessageCallback( void *userData, void *msgBuf, size_t msgSize )
|
static void clientMessageCallback( void *userData, void *msgBuf, size_t msgSize )
|
||||||
|
@ -540,20 +610,22 @@ void NetPlayClient::update(void)
|
||||||
{
|
{
|
||||||
readMessages( clientMessageCallback, this );
|
readMessages( clientMessageCallback, this );
|
||||||
|
|
||||||
uint32_t ctlrData = GetGamepadPressedImmediate();
|
if (connected)
|
||||||
uint32_t currFrame = static_cast<uint32_t>(currFrameCounter);
|
{
|
||||||
|
uint32_t ctlrData = GetGamepadPressedImmediate();
|
||||||
|
uint32_t currFrame = static_cast<uint32_t>(currFrameCounter);
|
||||||
|
|
||||||
netPlayClientState statusMsg;
|
netPlayClientState statusMsg;
|
||||||
statusMsg.flags = 0;
|
statusMsg.flags = 0;
|
||||||
statusMsg.frameRdy = inputFrameBack();
|
statusMsg.frameRdy = inputFrameBack();
|
||||||
statusMsg.frameRun = currFrame;
|
statusMsg.frameRun = currFrame;
|
||||||
statusMsg.ctrlState[0] = (ctlrData ) & 0x000000ff;
|
statusMsg.ctrlState[0] = (ctlrData ) & 0x000000ff;
|
||||||
statusMsg.ctrlState[1] = (ctlrData >> 8) & 0x000000ff;
|
statusMsg.ctrlState[1] = (ctlrData >> 8) & 0x000000ff;
|
||||||
statusMsg.ctrlState[2] = (ctlrData >> 16) & 0x000000ff;
|
statusMsg.ctrlState[2] = (ctlrData >> 16) & 0x000000ff;
|
||||||
statusMsg.ctrlState[3] = (ctlrData >> 24) & 0x000000ff;
|
statusMsg.ctrlState[3] = (ctlrData >> 24) & 0x000000ff;
|
||||||
|
|
||||||
sock->write( reinterpret_cast<const char*>(&statusMsg), sizeof(statusMsg) );
|
|
||||||
|
|
||||||
|
sock->write( reinterpret_cast<const char*>(&statusMsg), sizeof(statusMsg) );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
int NetPlayClient::readMessages( void (*msgCallback)( void *userData, void *msgBuf, size_t msgSize ), void *userData )
|
int NetPlayClient::readMessages( void (*msgCallback)( void *userData, void *msgBuf, size_t msgSize ), void *userData )
|
||||||
|
@ -633,11 +705,24 @@ void NetPlayClient::clientProcessMessage( void *msgBuf, size_t msgSize )
|
||||||
|
|
||||||
switch (hdr->msgId)
|
switch (hdr->msgId)
|
||||||
{
|
{
|
||||||
|
case NETPLAY_ERROR_MSG:
|
||||||
|
{
|
||||||
|
auto *msg = static_cast<netPlayErrorMsg<256>*>(msgBuf);
|
||||||
|
printf("Error: 0x%X %s\n", msg->code, msg->getBuffer());
|
||||||
|
|
||||||
|
if (msg->isDisconnectFlagSet())
|
||||||
|
{
|
||||||
|
sock->disconnectFromHost();
|
||||||
|
}
|
||||||
|
FCEU_DispMessage("Host connect failed",0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case NETPLAY_AUTH_REQ:
|
case NETPLAY_AUTH_REQ:
|
||||||
{
|
{
|
||||||
netPlayAuthResp msg;
|
netPlayAuthResp msg;
|
||||||
msg.playerId = role;
|
msg.playerId = role;
|
||||||
strncpy( msg.pswd, "TODO: Dummy Password", sizeof(msg.pswd) );
|
strncpy( msg.userName, userName.toLocal8Bit().constData(), sizeof(msg.userName));
|
||||||
|
strncpy( msg.pswd, password.toLocal8Bit().constData(), sizeof(msg.pswd) );
|
||||||
|
|
||||||
sock->write( (const char*)&msg, sizeof(netPlayAuthResp) );
|
sock->write( (const char*)&msg, sizeof(netPlayAuthResp) );
|
||||||
}
|
}
|
||||||
|
@ -682,8 +767,6 @@ void NetPlayClient::clientProcessMessage( void *msgBuf, size_t msgSize )
|
||||||
NetPlayFrameInput inputFrame;
|
NetPlayFrameInput inputFrame;
|
||||||
netPlayRunFrameReq *msg = static_cast<netPlayRunFrameReq*>(msgBuf);
|
netPlayRunFrameReq *msg = static_cast<netPlayRunFrameReq*>(msgBuf);
|
||||||
|
|
||||||
uint32_t currFrame = static_cast<uint32_t>(currFrameCounter);
|
|
||||||
|
|
||||||
inputFrame.frameCounter = msg->frameNum;
|
inputFrame.frameCounter = msg->frameNum;
|
||||||
inputFrame.ctrl[0] = msg->ctrlState[0];
|
inputFrame.ctrl[0] = msg->ctrlState[0];
|
||||||
inputFrame.ctrl[1] = msg->ctrlState[1];
|
inputFrame.ctrl[1] = msg->ctrlState[1];
|
||||||
|
@ -694,17 +777,6 @@ void NetPlayClient::clientProcessMessage( void *msgBuf, size_t msgSize )
|
||||||
{
|
{
|
||||||
pushBackInput( inputFrame );
|
pushBackInput( inputFrame );
|
||||||
}
|
}
|
||||||
|
|
||||||
netPlayRunFrameResp resp;
|
|
||||||
resp.flags = msg->flags;
|
|
||||||
resp.frameNum = msg->frameNum;
|
|
||||||
resp.frameRun = currFrame;
|
|
||||||
resp.ctrlState[0] = msg->ctrlState[0];
|
|
||||||
resp.ctrlState[1] = msg->ctrlState[1];
|
|
||||||
resp.ctrlState[2] = msg->ctrlState[2];
|
|
||||||
resp.ctrlState[3] = msg->ctrlState[3];
|
|
||||||
|
|
||||||
sock->write( reinterpret_cast<const char*>(&resp), sizeof(resp) );
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -828,7 +900,7 @@ NetPlayJoinDialog::NetPlayJoinDialog(QWidget *parent)
|
||||||
QPushButton *cancelButton, *startButton;
|
QPushButton *cancelButton, *startButton;
|
||||||
QLabel *lbl;
|
QLabel *lbl;
|
||||||
|
|
||||||
setWindowTitle("NetPlay Host Game");
|
setWindowTitle("NetPlay Join Game");
|
||||||
|
|
||||||
mainLayout = new QVBoxLayout();
|
mainLayout = new QVBoxLayout();
|
||||||
grid = new QGridLayout();
|
grid = new QGridLayout();
|
||||||
|
@ -860,6 +932,26 @@ NetPlayJoinDialog::NetPlayJoinDialog(QWidget *parent)
|
||||||
playerRoleBox->setCurrentIndex(2);
|
playerRoleBox->setCurrentIndex(2);
|
||||||
grid->addWidget( playerRoleBox, 2, 1 );
|
grid->addWidget( playerRoleBox, 2, 1 );
|
||||||
|
|
||||||
|
lbl = new QLabel( tr("User:") );
|
||||||
|
grid->addWidget( lbl, 3, 0 );
|
||||||
|
|
||||||
|
QString name = qgetenv("USER");
|
||||||
|
if (name.isEmpty())
|
||||||
|
{
|
||||||
|
name = qgetenv("USERNAME");
|
||||||
|
}
|
||||||
|
userNameEntry = new QLineEdit();
|
||||||
|
userNameEntry->setMaxLength(63);
|
||||||
|
userNameEntry->setText(name);
|
||||||
|
grid->addWidget( userNameEntry, 3, 1 );
|
||||||
|
|
||||||
|
lbl = new QLabel( tr("Password:") );
|
||||||
|
grid->addWidget( lbl, 4, 0 );
|
||||||
|
|
||||||
|
passwordEntry = new QLineEdit();
|
||||||
|
passwordEntry->setMaxLength(64);
|
||||||
|
grid->addWidget( passwordEntry, 4, 1 );
|
||||||
|
|
||||||
mainLayout->addLayout(grid);
|
mainLayout->addLayout(grid);
|
||||||
|
|
||||||
startButton = new QPushButton( tr("Join") );
|
startButton = new QPushButton( tr("Join") );
|
||||||
|
@ -912,10 +1004,12 @@ void NetPlayJoinDialog::onJoinClicked(void)
|
||||||
|
|
||||||
client = NetPlayClient::GetInstance();
|
client = NetPlayClient::GetInstance();
|
||||||
client->role = playerRoleBox->currentData().toInt();
|
client->role = playerRoleBox->currentData().toInt();
|
||||||
|
client->userName = userNameEntry->text();
|
||||||
|
client->password = passwordEntry->text();
|
||||||
|
|
||||||
if (client->connectToHost( hostEntry->text(), portEntry->value() ))
|
if (client->connectToHost( hostEntry->text(), portEntry->value() ))
|
||||||
{
|
{
|
||||||
printf("Failed to connect to Host\n");
|
FCEU_DispMessage("Host connect failed",0);
|
||||||
}
|
}
|
||||||
|
|
||||||
//printf("Close Window\n");
|
//printf("Close Window\n");
|
||||||
|
@ -930,6 +1024,11 @@ bool NetPlayActive(void)
|
||||||
return (NetPlayClient::GetInstance() != nullptr) || (NetPlayServer::GetInstance() != nullptr);
|
return (NetPlayClient::GetInstance() != nullptr) || (NetPlayServer::GetInstance() != nullptr);
|
||||||
}
|
}
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
bool isNetPlayHost(void)
|
||||||
|
{
|
||||||
|
return (NetPlayServer::GetInstance() != nullptr);
|
||||||
|
}
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
void NetPlayPeriodicUpdate(void)
|
void NetPlayPeriodicUpdate(void)
|
||||||
{
|
{
|
||||||
NetPlayClient *client = NetPlayClient::GetInstance();
|
NetPlayClient *client = NetPlayClient::GetInstance();
|
||||||
|
@ -1007,3 +1106,9 @@ void NetPlayReadInputFrame(uint8_t* joy)
|
||||||
joy[3] = netPlayInputFrame.ctrl[3];
|
joy[3] = netPlayInputFrame.ctrl[3];
|
||||||
}
|
}
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
void NetPlayCloseSession(void)
|
||||||
|
{
|
||||||
|
NetPlayClient::Destroy();
|
||||||
|
NetPlayServer::Destroy();
|
||||||
|
}
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
|
@ -70,8 +70,7 @@ class NetPlayServer : public QTcpServer
|
||||||
static NetPlayServer *GetInstance(void){ return instance; };
|
static NetPlayServer *GetInstance(void){ return instance; };
|
||||||
|
|
||||||
static int Create(QObject *parent = 0);
|
static int Create(QObject *parent = 0);
|
||||||
|
static int Destroy();
|
||||||
bool removeClient(NetPlayClient *client, bool markForDelete = false);
|
|
||||||
|
|
||||||
int closeAllConnections(void);
|
int closeAllConnections(void);
|
||||||
|
|
||||||
|
@ -148,11 +147,14 @@ class NetPlayClient : public QObject
|
||||||
static NetPlayClient *GetInstance(void){ return instance; };
|
static NetPlayClient *GetInstance(void){ return instance; };
|
||||||
|
|
||||||
static int Create(QObject *parent = 0);
|
static int Create(QObject *parent = 0);
|
||||||
|
static int Destroy();
|
||||||
|
|
||||||
int connectToHost( const QString host, int port );
|
int connectToHost( const QString host, int port );
|
||||||
|
|
||||||
bool isConnected(void);
|
bool isConnected(void);
|
||||||
void disconnect();
|
bool disconnectRequested(){ return disconnectPending; }
|
||||||
|
void forceDisconnect();
|
||||||
|
bool flushData();
|
||||||
|
|
||||||
void setSocket(QTcpSocket *s);
|
void setSocket(QTcpSocket *s);
|
||||||
QTcpSocket* getSocket(void){ return sock; };
|
QTcpSocket* getSocket(void){ return sock; };
|
||||||
|
@ -197,23 +199,31 @@ class NetPlayClient : public QObject
|
||||||
return frame;
|
return frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isAuthenticated();
|
||||||
|
bool isPlayerRole();
|
||||||
|
bool shouldDestroy(){ return needsDestroy; }
|
||||||
|
|
||||||
QString userName;
|
QString userName;
|
||||||
int role;
|
QString password;
|
||||||
int state;
|
int role = -1;
|
||||||
unsigned int currentFrame;
|
int state = 0;
|
||||||
|
unsigned int currentFrame = 0;
|
||||||
|
uint8_t gpData[4];
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int createSocket(void);
|
int createSocket(void);
|
||||||
|
|
||||||
static NetPlayClient *instance;
|
static NetPlayClient *instance;
|
||||||
|
|
||||||
QTcpSocket *sock;
|
QTcpSocket *sock = nullptr;
|
||||||
int recvMsgId;
|
int recvMsgId = 0;
|
||||||
int recvMsgSize;
|
int recvMsgSize = 0;
|
||||||
int recvMsgBytesLeft;
|
int recvMsgBytesLeft = 0;
|
||||||
int recvMsgByteIndex;
|
int recvMsgByteIndex = 0;
|
||||||
char *recvMsgBuf;
|
char *recvMsgBuf = nullptr;
|
||||||
|
bool disconnectPending = false;
|
||||||
|
bool needsDestroy = false;
|
||||||
|
bool connected = false;
|
||||||
|
|
||||||
std::list <NetPlayFrameInput> input;
|
std::list <NetPlayFrameInput> input;
|
||||||
FCEU::mutex inputMtx;
|
FCEU::mutex inputMtx;
|
||||||
|
@ -223,6 +233,7 @@ class NetPlayClient : public QObject
|
||||||
public slots:
|
public slots:
|
||||||
void onConnect(void);
|
void onConnect(void);
|
||||||
void onDisconnect(void);
|
void onDisconnect(void);
|
||||||
|
void onSocketError(QAbstractSocket::SocketError);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -261,6 +272,8 @@ protected:
|
||||||
QLineEdit *hostEntry;
|
QLineEdit *hostEntry;
|
||||||
QSpinBox *portEntry;
|
QSpinBox *portEntry;
|
||||||
QComboBox *playerRoleBox;
|
QComboBox *playerRoleBox;
|
||||||
|
QLineEdit *userNameEntry;
|
||||||
|
QLineEdit *passwordEntry;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void closeWindow(void);
|
void closeWindow(void);
|
||||||
|
@ -269,7 +282,9 @@ public slots:
|
||||||
};
|
};
|
||||||
|
|
||||||
bool NetPlayActive(void);
|
bool NetPlayActive(void);
|
||||||
|
bool isNetPlayHost(void);
|
||||||
void NetPlayPeriodicUpdate(void);
|
void NetPlayPeriodicUpdate(void);
|
||||||
bool NetPlaySkipWait(void);
|
bool NetPlaySkipWait(void);
|
||||||
int NetPlayFrameWait(void);
|
int NetPlayFrameWait(void);
|
||||||
void NetPlayReadInputFrame(uint8_t* joy);
|
void NetPlayReadInputFrame(uint8_t* joy);
|
||||||
|
void NetPlayCloseSession(void);
|
||||||
|
|
|
@ -14,7 +14,6 @@ enum netPlayMsgType
|
||||||
NETPLAY_LOAD_ROM_REQ,
|
NETPLAY_LOAD_ROM_REQ,
|
||||||
NETPLAY_SYNC_STATE,
|
NETPLAY_SYNC_STATE,
|
||||||
NETPLAY_RUN_FRAME_REQ,
|
NETPLAY_RUN_FRAME_REQ,
|
||||||
NETPLAY_RUN_FRAME_RESP,
|
|
||||||
NETPLAY_CLIENT_STATE,
|
NETPLAY_CLIENT_STATE,
|
||||||
NETPLAY_ERROR_MSG,
|
NETPLAY_ERROR_MSG,
|
||||||
};
|
};
|
||||||
|
@ -61,7 +60,8 @@ struct netPlayAuthResp
|
||||||
netPlayMsgHdr hdr;
|
netPlayMsgHdr hdr;
|
||||||
|
|
||||||
char playerId;
|
char playerId;
|
||||||
char pswd[128];
|
char userName[64];
|
||||||
|
char pswd[72];
|
||||||
|
|
||||||
netPlayAuthResp(void)
|
netPlayAuthResp(void)
|
||||||
: hdr(NETPLAY_AUTH_RESP, sizeof(netPlayAuthResp)), playerId(NETPLAY_SPECTATOR)
|
: hdr(NETPLAY_AUTH_RESP, sizeof(netPlayAuthResp)), playerId(NETPLAY_SPECTATOR)
|
||||||
|
@ -75,14 +75,29 @@ struct netPlayErrorMsg
|
||||||
{
|
{
|
||||||
netPlayMsgHdr hdr;
|
netPlayMsgHdr hdr;
|
||||||
|
|
||||||
|
unsigned short code;
|
||||||
|
unsigned short flags;
|
||||||
char data[N];
|
char data[N];
|
||||||
|
|
||||||
|
static const uint32_t DISCONNECT_FLAG = 0x00000001;
|
||||||
|
|
||||||
netPlayErrorMsg(void)
|
netPlayErrorMsg(void)
|
||||||
: hdr(NETPLAY_ERROR_MSG, sizeof(netPlayErrorMsg))
|
: hdr(NETPLAY_ERROR_MSG, sizeof(netPlayErrorMsg)), code(0), flags(0)
|
||||||
{
|
{
|
||||||
|
memset(data, 0, N);
|
||||||
}
|
}
|
||||||
|
|
||||||
char *getMsgBuffer()
|
void setDisconnectFlag()
|
||||||
|
{
|
||||||
|
flags |= DISCONNECT_FLAG;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isDisconnectFlagSet()
|
||||||
|
{
|
||||||
|
return (flags & DISCONNECT_FLAG) ? true : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *getBuffer()
|
||||||
{
|
{
|
||||||
return &data[0];
|
return &data[0];
|
||||||
}
|
}
|
||||||
|
@ -95,7 +110,7 @@ struct netPlayErrorMsg
|
||||||
retval = ::vsnprintf(data, sizeof(data), format, args);
|
retval = ::vsnprintf(data, sizeof(data), format, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
|
|
||||||
hdr.msgSize = sizeof(netPlayMsgHdr) + strlen(data);
|
hdr.msgSize = sizeof(netPlayErrorMsg) - N + strlen(data) + 1;
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
@ -131,22 +146,6 @@ struct netPlayRunFrameReq
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct netPlayRunFrameResp
|
|
||||||
{
|
|
||||||
netPlayMsgHdr hdr;
|
|
||||||
|
|
||||||
uint32_t flags;
|
|
||||||
uint32_t frameNum;
|
|
||||||
uint32_t frameRun;
|
|
||||||
uint8_t ctrlState[4];
|
|
||||||
|
|
||||||
netPlayRunFrameResp(void)
|
|
||||||
: hdr(NETPLAY_RUN_FRAME_RESP, sizeof(netPlayRunFrameResp)), flags(0), frameNum(0), frameRun(0)
|
|
||||||
{
|
|
||||||
memset( ctrlState, 0, sizeof(ctrlState) );
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct netPlayClientState
|
struct netPlayClientState
|
||||||
{
|
{
|
||||||
netPlayMsgHdr hdr;
|
netPlayMsgHdr hdr;
|
||||||
|
|
Loading…
Reference in New Issue