Added framework for Qt netplay client status dialog.

This commit is contained in:
harry 2024-04-03 04:55:07 -04:00
parent 2fe563181e
commit 10418f551a
3 changed files with 167 additions and 15 deletions

View File

@ -646,8 +646,8 @@ void NetPlayServer::serverProcessMessage( NetPlayClient *client, void *msgBuf, s
client->gpData[2] = msg->ctrlState[2]; client->gpData[2] = msg->ctrlState[2];
client->gpData[3] = msg->ctrlState[3]; client->gpData[3] = msg->ctrlState[3];
client->setPaused( (msg->flags & netPlayClientState::PAUSE_FLAG ) ? true : false ); client->setPaused( (msg->flags & netPlayClientState::PauseFlag ) ? true : false );
client->setDesync( (msg->flags & netPlayClientState::DESYNC_FLAG) ? true : false ); client->setDesync( (msg->flags & netPlayClientState::DesyncFlag) ? true : false );
client->romMatch = (romCrc32 == msg->romCrc32); client->romMatch = (romCrc32 == msg->romCrc32);
@ -798,6 +798,13 @@ void NetPlayServer::serverProcessMessage( NetPlayClient *client, void *msgBuf, s
} }
} }
break; break;
case NETPLAY_CLIENT_SYNC_REQ:
{
FCEU_WRAPPER_LOCK();
resyncClient( client );
FCEU_WRAPPER_UNLOCK();
}
break;
default: default:
printf("Unknown Msg: %08X\n", msgId); printf("Unknown Msg: %08X\n", msgId);
break; break;
@ -1288,6 +1295,15 @@ int NetPlayClient::requestStateLoad(EMUFILE *is)
return 0; return 0;
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
int NetPlayClient::requestSync(void)
{
netPlayMsgHdr hdr(NETPLAY_CLIENT_SYNC_REQ);
hdr.toNetworkByteOrder();
sock->write( reinterpret_cast<const char*>(&hdr), sizeof(netPlayMsgHdr));
return 0;
}
//-----------------------------------------------------------------------------
void NetPlayClient::recordPingResult( uint64_t delay_ms ) void NetPlayClient::recordPingResult( uint64_t delay_ms )
{ {
pingNumSamples++; pingNumSamples++;
@ -1335,11 +1351,11 @@ void NetPlayClient::update(void)
statusMsg.flags = 0; statusMsg.flags = 0;
if (FCEUI_EmulationPaused()) if (FCEUI_EmulationPaused())
{ {
statusMsg.flags |= netPlayClientState::PAUSE_FLAG; statusMsg.flags |= netPlayClientState::PauseFlag;
} }
if (desyncCount > 0) if (desyncCount > 0)
{ {
statusMsg.flags |= netPlayClientState::DESYNC_FLAG; statusMsg.flags |= netPlayClientState::DesyncFlag;
} }
statusMsg.frameRdy = inputFrameBack(); statusMsg.frameRdy = inputFrameBack();
statusMsg.frameRun = currFrame; statusMsg.frameRun = currFrame;
@ -1994,7 +2010,116 @@ void NetPlayJoinDialog::onSocketError(const QString& errorMsg)
} }
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
//--- NetPlayJoinDialog //--- NetPlayClientStatusDialog
//-----------------------------------------------------------------------------
NetPlayClientStatusDialog* NetPlayClientStatusDialog::instance = nullptr;
//-----------------------------------------------------------------------------
NetPlayClientStatusDialog::NetPlayClientStatusDialog(QWidget *parent)
: QDialog(parent)
{
QVBoxLayout *mainLayout;
QHBoxLayout *hbox;
QGridLayout *grid;
QGroupBox *gbox;
QPushButton *closeButton;
//QLabel *lbl;
instance = this;
mainLayout = new QVBoxLayout();
grid = new QGridLayout();
gbox = new QGroupBox(tr("Connection"));
gbox->setLayout(grid);
mainLayout->addWidget(gbox);
hostStateLbl = new QLabel(tr("Unknown"));
grid->addWidget( new QLabel(tr("Host Frame:")), 0, 0 );
grid->addWidget( hostStateLbl, 0, 1 );
requestResyncButton = new QPushButton(tr("Resync State"));
grid->addWidget( requestResyncButton, 1, 0, 1, 2 );
hbox = new QHBoxLayout();
mainLayout->addLayout(hbox);
closeButton = new QPushButton( tr("Close") );
closeButton->setIcon(style()->standardIcon(QStyle::SP_DialogCloseButton));
connect(closeButton, SIGNAL(clicked(void)), this, SLOT(closeWindow(void)));
hbox->addStretch(3);
hbox->addWidget(closeButton);
setWindowTitle("NetPlay Status");
//resize( 512, 256 );
setLayout(mainLayout);
connect(requestResyncButton, SIGNAL(clicked(void)), this, SLOT(resyncButtonClicked(void)));
periodicTimer = new QTimer(this);
periodicTimer->start(200); // 5hz
connect(periodicTimer, &QTimer::timeout, this, &NetPlayClientStatusDialog::updatePeriodic);
}
//----------------------------------------------------------------------------
NetPlayClientStatusDialog::~NetPlayClientStatusDialog(void)
{
instance = nullptr;
periodicTimer->stop();
delete periodicTimer;
//printf("Destroy NetPlay Status Window\n");
}
//----------------------------------------------------------------------------
void NetPlayClientStatusDialog::closeEvent(QCloseEvent *event)
{
//printf("NetPlay Client Close Window Event\n");
done(0);
deleteLater();
event->accept();
}
//----------------------------------------------------------------------------
void NetPlayClientStatusDialog::closeWindow(void)
{
//printf("Close Window\n");
done(0);
deleteLater();
}
//----------------------------------------------------------------------------
void NetPlayClientStatusDialog::updatePeriodic()
{
updateStatusDisplay();
}
//----------------------------------------------------------------------------
void NetPlayClientStatusDialog::updateStatusDisplay()
{
NetPlayClient* client = NetPlayClient::GetInstance();
if (client == nullptr)
{
return;
}
char stmp[64];
uint32_t inputFrame = client->inputFrameBack();
if (inputFrame == 0)
{
inputFrame = static_cast<uint32_t>(currFrameCounter);
}
snprintf( stmp, sizeof(stmp), "%u", inputFrame);
hostStateLbl->setText(tr(stmp));
}
//----------------------------------------------------------------------------
void NetPlayClientStatusDialog::resyncButtonClicked()
{
NetPlayClient* client = NetPlayClient::GetInstance();
if (client == nullptr)
{
return;
}
client->requestSync();
}
//-----------------------------------------------------------------------------
//--- NetPlayHostStatusDialog
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
NetPlayHostStatusDialog* NetPlayHostStatusDialog::instance = nullptr; NetPlayHostStatusDialog* NetPlayHostStatusDialog::instance = nullptr;
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -2419,7 +2544,7 @@ void openNetPlayHostStatusDialog(QWidget* parent)
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void openNetPlayClientStatusDialog(QWidget* parent) void openNetPlayClientStatusDialog(QWidget* parent)
{ {
//openSingletonDialog<NetPlayHostStatusDialog>(parent); openSingletonDialog<NetPlayClientStatusDialog>(parent);
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
//---- Network Byte Swap Utilities //---- Network Byte Swap Utilities

View File

@ -204,6 +204,7 @@ class NetPlayClient : public QObject
bool flushData(); bool flushData();
int requestRomLoad( const char *romPath ); int requestRomLoad( const char *romPath );
int requestStateLoad(EMUFILE* is); int requestStateLoad(EMUFILE* is);
int requestSync(void);
QTcpSocket* createSocket(void); QTcpSocket* createSocket(void);
void setSocket(QTcpSocket *s); void setSocket(QTcpSocket *s);
@ -403,6 +404,31 @@ class NetPlayClientTreeItem : public QTreeWidgetItem
private: private:
}; };
class NetPlayClientStatusDialog : public QDialog
{
Q_OBJECT
public:
NetPlayClientStatusDialog(QWidget *parent = 0);
~NetPlayClientStatusDialog(void);
static NetPlayClientStatusDialog *GetInstance(void){ return instance; };
protected:
void closeEvent(QCloseEvent *event);
void updateStatusDisplay(void);
QLabel *hostStateLbl;
QTimer *periodicTimer;
QPushButton *requestResyncButton;
static NetPlayClientStatusDialog* instance;
public slots:
void closeWindow(void);
void updatePeriodic(void);
void resyncButtonClicked(void);
};
class NetPlayHostStatusDialog : public QDialog class NetPlayHostStatusDialog : public QDialog
{ {
Q_OBJECT Q_OBJECT

View File

@ -15,18 +15,19 @@ uint64_t netPlayByteSwap(uint64_t);
enum netPlayMsgType enum netPlayMsgType
{ {
NETPLAY_AUTH_REQ, NETPLAY_AUTH_REQ = 0,
NETPLAY_AUTH_RESP, NETPLAY_AUTH_RESP,
NETPLAY_LOAD_ROM_REQ, NETPLAY_LOAD_ROM_REQ = 100,
NETPLAY_UNLOAD_ROM_REQ, NETPLAY_UNLOAD_ROM_REQ,
NETPLAY_SYNC_STATE_REQ, NETPLAY_SYNC_STATE_REQ = 200,
NETPLAY_SYNC_STATE_RESP, NETPLAY_SYNC_STATE_RESP,
NETPLAY_RUN_FRAME_REQ, NETPLAY_RUN_FRAME_REQ = 300,
NETPLAY_CLIENT_STATE, NETPLAY_CLIENT_STATE = 400,
NETPLAY_INFO_MSG, NETPLAY_CLIENT_SYNC_REQ,
NETPLAY_INFO_MSG = 500,
NETPLAY_ERROR_MSG, NETPLAY_ERROR_MSG,
NETPLAY_CHAT_MSG, NETPLAY_CHAT_MSG,
NETPLAY_PING_REQ, NETPLAY_PING_REQ = 1000,
NETPLAY_PING_RESP, NETPLAY_PING_RESP,
}; };
@ -299,8 +300,8 @@ struct netPlayClientState
uint32_t romCrc32; uint32_t romCrc32;
uint8_t ctrlState[4]; uint8_t ctrlState[4];
static constexpr uint32_t PAUSE_FLAG = 0x0001; static constexpr uint32_t PauseFlag = 0x0001;
static constexpr uint32_t DESYNC_FLAG = 0x0002; static constexpr uint32_t DesyncFlag = 0x0002;
netPlayClientState(void) netPlayClientState(void)
: hdr(NETPLAY_CLIENT_STATE, sizeof(netPlayClientState)), flags(0), : hdr(NETPLAY_CLIENT_STATE, sizeof(netPlayClientState)), flags(0),