More Qt netplay updates.

This commit is contained in:
harry 2024-02-19 15:53:11 -05:00
parent 84c2591d3f
commit cb45321433
5 changed files with 269 additions and 124 deletions

View File

@ -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 )

View File

@ -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);

View File

@ -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,19 +326,34 @@ 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->isAuthenticated())
{
if (client->currentFrame < clientMinFrame) if (client->currentFrame < clientMinFrame)
{ {
clientMinFrame = client->currentFrame; clientMinFrame = client->currentFrame;
@ -363,6 +362,30 @@ void NetPlayServer::update(void)
{ {
clientMaxFrame = client->currentFrame; clientMaxFrame = client->currentFrame;
} }
if (client->isPlayerRole())
{
gpData[client->role] = client->gpData[client->role];
}
}
if (client->shouldDestroy())
{
it = clientList.erase(it);
for (int i=0; i<4; i++)
{
if (client == clientPlayer[i])
{
clientPlayer[i] = nullptr;
}
}
delete client;
}
else
{
it++;
}
} }
shouldRunFrame = (clientMinFrame != 0xFFFFFFFF) && shouldRunFrame = (clientMinFrame != 0xFFFFFFFF) &&
@ -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());
}
else
{ {
deleteLater(); 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,6 +610,8 @@ void NetPlayClient::update(void)
{ {
readMessages( clientMessageCallback, this ); readMessages( clientMessageCallback, this );
if (connected)
{
uint32_t ctlrData = GetGamepadPressedImmediate(); uint32_t ctlrData = GetGamepadPressedImmediate();
uint32_t currFrame = static_cast<uint32_t>(currFrameCounter); uint32_t currFrame = static_cast<uint32_t>(currFrameCounter);
@ -553,7 +625,7 @@ void NetPlayClient::update(void)
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();
}
//----------------------------------------------------------------------------

View File

@ -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);

View File

@ -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;