Added framework for a net play host status dialog window.

This commit is contained in:
harry 2024-02-28 07:18:19 -05:00
parent d212b894a7
commit 75e9627aa8
4 changed files with 254 additions and 18 deletions

View File

@ -1695,6 +1695,25 @@ void consoleWin_t::createMainMenu(void)
netPlayMenu->addAction(act);
// NetPlay -> Client Status Dialog
act = new QAction(tr("Host &Status"), this);
//act->setShortcut( QKeySequence(tr("Shift+F7")));
act->setStatusTip(tr("Open Netplay Host Status Dialog"));
connect(act, SIGNAL(triggered()), this, SLOT(openNetPlayStatusWindow(void)) );
netPlayHostStatAct = act;
netPlayMenu->addAction(act);
// NetPlay -> Client Status Dialog
act = new QAction(tr("Client &Status"), this);
//act->setShortcut( QKeySequence(tr("Shift+F7")));
act->setStatusTip(tr("Open Netplay Client Status Dialog"));
connect(act, SIGNAL(triggered()), this, SLOT(openNetPlayStatusWindow(void)) );
netPlayClientStatAct = act;
netPlayMenu->addAction(act);
//netPlayMenu->setEnabled(false);
//-----------------------------------------------------------------------
// Tools
@ -3202,6 +3221,20 @@ void consoleWin_t::openNetPlayJoinWindow(void)
openNetPlayJoinDialog(this);
}
void consoleWin_t::openNetPlayStatusWindow(void)
{
//printf("Open NetPlay Status Window\n");
if (isNetPlayHost())
{
openNetPlayHostStatusDialog(this);
}
else
{
openNetPlayClientStatusDialog(this);
}
}
void consoleWin_t::closeNetPlaySession(void)
{
NetPlayCloseSession();
@ -4766,11 +4799,27 @@ void consoleWin_t::updatePeriodic(void)
stopWavAct->setEnabled( FCEUI_WaveRecordRunning() );
tasEditorAct->setEnabled( FCEU_IsValidUI(FCEUI_TASEDITOR) );
bool netPlayactv = NetPlayActive();
const bool netPlayactv = NetPlayActive();
netPlayHostAct->setEnabled( !netPlayactv );
netPlayJoinAct->setEnabled( !netPlayactv );
netPlayDiscAct->setEnabled( netPlayactv );
if (netPlayactv)
{
const bool isHost = isNetPlayHost();
netPlayHostStatAct->setEnabled(isHost);
netPlayHostStatAct->setVisible(isHost);
netPlayClientStatAct->setEnabled(!isHost);
netPlayClientStatAct->setVisible(!isHost);
}
else
{
netPlayHostStatAct->setEnabled(false);
netPlayHostStatAct->setVisible(false);
netPlayClientStatAct->setEnabled(false);
netPlayClientStatAct->setVisible(false);
}
}
if ( errorMsgValid )

View File

@ -263,6 +263,8 @@ class consoleWin_t : public QMainWindow
QAction *netPlayHostAct;
QAction *netPlayJoinAct;
QAction *netPlayDiscAct;
QAction *netPlayHostStatAct;
QAction *netPlayClientStatAct;
//QAction *aviHudAct;
//QAction *aviMsgAct;
@ -362,6 +364,7 @@ class consoleWin_t : public QMainWindow
void openPaletteEditorWin(void);
void openNetPlayHostWindow(void);
void openNetPlayJoinWindow(void);
void openNetPlayStatusWindow(void);
void closeNetPlaySession(void);
void openAviRiffViewer(void);
void openTimingStatWin(void);

View File

@ -134,6 +134,32 @@ struct NetPlayFrameDataHist_t
};
static NetPlayFrameDataHist_t netPlayFrameData;
//-----------------------------------------------------------------------------
const char* NetPlayPlayerRoleToString(int role)
{
const char* roleString = nullptr;
switch (role)
{
default:
case netPlayerId::NETPLAY_SPECTATOR:
roleString = "Spectator";
break;
case netPlayerId::NETPLAY_PLAYER1:
roleString = "Player 1";
break;
case netPlayerId::NETPLAY_PLAYER2:
roleString = "Player 2";
break;
case netPlayerId::NETPLAY_PLAYER3:
roleString = "Player 3";
break;
case netPlayerId::NETPLAY_PLAYER4:
roleString = "Player 4";
break;
}
return roleString;
}
//-----------------------------------------------------------------------------
//--- NetPlayServer
//-----------------------------------------------------------------------------
NetPlayServer *NetPlayServer::instance = nullptr;
@ -365,6 +391,7 @@ bool NetPlayServer::claimRole(NetPlayClient* client, int _role)
success = true;
roleMask |= mask;
clientPlayer[_role] = client;
client->role = _role;
}
}
return success;
@ -1417,6 +1444,113 @@ void NetPlayJoinDialog::onSocketError(const QString& errorMsg)
client = nullptr;
}
}
//-----------------------------------------------------------------------------
//--- NetPlayJoinDialog
//-----------------------------------------------------------------------------
NetPlayHostStatusDialog* NetPlayHostStatusDialog::instance = nullptr;
//-----------------------------------------------------------------------------
NetPlayHostStatusDialog::NetPlayHostStatusDialog(QWidget *parent)
: QDialog(parent)
{
QVBoxLayout *mainLayout;
QHBoxLayout *hbox;
//QGridLayout *grid;
QPushButton *closeButton;
//QLabel *lbl;
instance = this;
setWindowTitle("NetPlay Status");
mainLayout = new QVBoxLayout();
clientTree = new QTreeWidget();
mainLayout->addWidget( clientTree );
clientTree->setColumnCount(3);
auto* item = new QTreeWidgetItem();
item->setText( 0, QString::fromStdString( "Player" ) );
item->setText( 1, QString::fromStdString( "Role" ) );
item->setText( 2, QString::fromStdString( "State" ) );
item->setTextAlignment( 0, Qt::AlignLeft);
item->setTextAlignment( 1, Qt::AlignLeft);
item->setTextAlignment( 2, Qt::AlignLeft);
//connect( clientTree, SIGNAL(itemClicked(QTreeWidgetItem*, int)),
//this, SLOT(watchClicked( QTreeWidgetItem*, int)) );
clientTree->setHeaderItem( item );
closeButton = new QPushButton( tr("Close") );
closeButton->setIcon(style()->standardIcon(QStyle::SP_DialogCloseButton));
connect(closeButton, SIGNAL(clicked(void)), this, SLOT(closeWindow(void)));
hbox = new QHBoxLayout();
hbox->addStretch(5);
hbox->addWidget( closeButton, 1 );
mainLayout->addLayout( hbox );
setLayout(mainLayout);
loadClientTree();
}
//----------------------------------------------------------------------------
NetPlayHostStatusDialog::~NetPlayHostStatusDialog(void)
{
instance = nullptr;
//printf("Destroy NetPlay Status Window\n");
}
//----------------------------------------------------------------------------
void NetPlayHostStatusDialog::closeEvent(QCloseEvent *event)
{
//printf("NetPlay Host Close Window Event\n");
done(0);
deleteLater();
event->accept();
}
//----------------------------------------------------------------------------
void NetPlayHostStatusDialog::closeWindow(void)
{
//printf("Close Window\n");
done(0);
deleteLater();
}
//----------------------------------------------------------------------------
void NetPlayHostStatusDialog::loadClientTree()
{
auto* server = NetPlayServer::GetInstance();
if (server == nullptr)
{
return;
}
const char *roleString = NetPlayPlayerRoleToString( server->getRole() );
auto* serverTopLvlItem = new NetPlayClientTreeItem();
serverTopLvlItem->server = server;
serverTopLvlItem->setText( 0, tr("Host") );
serverTopLvlItem->setText( 1, tr(roleString) );
clientTree->addTopLevelItem( serverTopLvlItem );
auto& clientList = server->getClientList();
for (auto& client : clientList)
{
roleString = NetPlayPlayerRoleToString( client->role );
auto* clientTopLvlItem = new NetPlayClientTreeItem();
clientTopLvlItem->client = client;
clientTopLvlItem->setText( 0, client->userName );
clientTopLvlItem->setText( 1, tr(roleString) );
clientTree->addTopLevelItem( clientTopLvlItem );
}
}
//----------------------------------------------------------------------------
//---- Global Functions
//----------------------------------------------------------------------------
@ -1515,13 +1649,13 @@ void NetPlayCloseSession(void)
NetPlayServer::Destroy();
}
//----------------------------------------------------------------------------
void openNetPlayHostDialog(QWidget* parent)
template <typename T> void openSingletonDialog(QWidget* parent)
{
NetPlayHostDialog* win = NetPlayHostDialog::GetInstance();
T* win = T::GetInstance();
if (win == nullptr)
{
win = new NetPlayHostDialog(parent);
win = new T(parent);
win->show();
}
@ -1532,21 +1666,24 @@ void openNetPlayHostDialog(QWidget* parent)
}
}
//----------------------------------------------------------------------------
void openNetPlayHostDialog(QWidget* parent)
{
openSingletonDialog<NetPlayHostDialog>(parent);
}
//----------------------------------------------------------------------------
void openNetPlayJoinDialog(QWidget* parent)
{
NetPlayJoinDialog* win = NetPlayJoinDialog::GetInstance();
if (win == nullptr)
{
win = new NetPlayJoinDialog(parent);
win->show();
}
else
{
win->activateWindow();
win->raise();
}
openSingletonDialog<NetPlayJoinDialog>(parent);
}
//----------------------------------------------------------------------------
void openNetPlayHostStatusDialog(QWidget* parent)
{
openSingletonDialog<NetPlayHostStatusDialog>(parent);
}
//----------------------------------------------------------------------------
void openNetPlayClientStatusDialog(QWidget* parent)
{
//openSingletonDialog<NetPlayHostStatusDialog>(parent);
}
//----------------------------------------------------------------------------
//---- Network Byte Swap Utilities

View File

@ -22,6 +22,9 @@
#include <QFrame>
#include <QGroupBox>
#include <QCloseEvent>
#include <QTreeView>
#include <QTreeWidget>
#include <QTreeWidgetItem>
#include <QTcpSocket>
#include <QTcpServer>
@ -73,6 +76,8 @@ class NetPlayServer : public QTcpServer
static int Create(QObject *parent = 0);
static int Destroy();
typedef std::list <NetPlayClient*> ClientList_t;
int closeAllConnections(void);
void update(void);
@ -123,6 +128,7 @@ class NetPlayServer : public QTcpServer
int sendRomLoadReq( NetPlayClient *client );
int sendStateSyncReq( NetPlayClient *client );
void setRole(int _role);
int getRole(void){ return role; }
bool claimRole(NetPlayClient* client, int _role);
uint32_t getMaxLeadFrames(){ return maxLeadFrames; }
@ -130,6 +136,8 @@ class NetPlayServer : public QTcpServer
void serverProcessMessage( NetPlayClient *client, void *msgBuf, size_t msgSize );
ClientList_t& getClientList(){ return clientList; }
QString sessionName;
QString sessionPasswd;
private:
@ -137,7 +145,7 @@ class NetPlayServer : public QTcpServer
void processPendingConnections(void);
std::list <NetPlayClient*> clientList;
ClientList_t clientList;
std::list <NetPlayFrameInput> input;
FCEU::mutex inputMtx;
int role = -1;
@ -330,6 +338,42 @@ public slots:
void onSocketError(const QString& errorMsg);
};
class NetPlayClientTreeItem : public QTreeWidgetItem
{
public:
NetPlayClientTreeItem()
: QTreeWidgetItem()
{
}
NetPlayClient* client = nullptr;
NetPlayServer* server = nullptr;
private:
};
class NetPlayHostStatusDialog : public QDialog
{
Q_OBJECT
public:
NetPlayHostStatusDialog(QWidget *parent = 0);
~NetPlayHostStatusDialog(void);
static NetPlayHostStatusDialog *GetInstance(void){ return instance; };
protected:
void closeEvent(QCloseEvent *event);
void loadClientTree(void);
QTreeWidget *clientTree;
static NetPlayHostStatusDialog* instance;
public slots:
void closeWindow(void);
};
bool NetPlayActive(void);
bool isNetPlayHost(void);
void NetPlayPeriodicUpdate(void);
@ -341,3 +385,6 @@ void NetPlayCloseSession(void);
void NetPlayTraceInstruction(uint8_t *opcode, int size);
void openNetPlayHostDialog(QWidget* parent = nullptr);
void openNetPlayJoinDialog(QWidget* parent = nullptr);
void openNetPlayHostStatusDialog(QWidget* parent = nullptr);
void openNetPlayClientStatusDialog(QWidget* parent = nullptr);
const char* NetPlayPlayerRoleToString(int role);