Merge pull request #2987 from HeatXD/input_delay_option

Netplay/UI: add input delay option to netplay dialogs
This commit is contained in:
Connor McLaughlin 2023-07-24 19:31:44 +10:00 committed by GitHub
commit 36fde6214c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 62 additions and 38 deletions

View File

@ -2060,7 +2060,7 @@ void Netplay::SetInputs(Netplay::Input inputs[2])
} }
} }
bool Netplay::CreateSession(std::string nickname, s32 port, s32 max_players, std::string password) bool Netplay::CreateSession(std::string nickname, s32 port, s32 max_players, std::string password, int inputdelay)
{ {
s_local_session_password = std::move(password); s_local_session_password = std::move(password);
@ -2068,10 +2068,7 @@ bool Netplay::CreateSession(std::string nickname, s32 port, s32 max_players, std
// to have the same data, and we don't want to trash their local memcards. We should therefore load // to have the same data, and we don't want to trash their local memcards. We should therefore load
// the memory cards for this game (based on game/global settings), and copy that to the temp card. // the memory cards for this game (based on game/global settings), and copy that to the temp card.
// TODO: input delay. GGPO Should support changing it on the fly. if (!Netplay::Start(true, std::move(nickname), std::string(), port, inputdelay))
const s32 input_delay = 1;
if (!Netplay::Start(true, std::move(nickname), std::string(), port, input_delay))
{ {
CloseSession(); CloseSession();
return false; return false;
@ -2086,15 +2083,12 @@ bool Netplay::CreateSession(std::string nickname, s32 port, s32 max_players, std
} }
bool Netplay::JoinSession(std::string nickname, const std::string& hostname, s32 port, std::string password, bool Netplay::JoinSession(std::string nickname, const std::string& hostname, s32 port, std::string password,
bool spectating) bool spectating, int inputdelay)
{ {
s_local_session_password = std::move(password); s_local_session_password = std::move(password);
s_local_spectating = spectating; s_local_spectating = spectating;
// TODO: input delay. GGPO Should support changing it on the fly. if (!Netplay::Start(false, std::move(nickname), hostname, port, inputdelay))
const s32 input_delay = 1;
if (!Netplay::Start(false, std::move(nickname), hostname, port, input_delay))
{ {
CloseSession(); CloseSession();
return false; return false;

View File

@ -31,8 +31,8 @@ enum : u8
NUM_ENET_CHANNELS, NUM_ENET_CHANNELS,
}; };
bool CreateSession(std::string nickname, s32 port, s32 max_players, std::string password); bool CreateSession(std::string nickname, s32 port, s32 max_players, std::string password, int inputdelay);
bool JoinSession(std::string nickname, const std::string& hostname, s32 port, std::string password, bool spectating); bool JoinSession(std::string nickname, const std::string& hostname, s32 port, std::string password, bool spectating, int inputdelay);
bool IsActive(); bool IsActive();

View File

@ -10,7 +10,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>496</width> <width>496</width>
<height>235</height> <height>267</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@ -92,14 +92,14 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="0"> <item row="3" column="0">
<widget class="QLabel" name="label_5"> <widget class="QLabel" name="label_5">
<property name="text"> <property name="text">
<string>Port:</string> <string>Port:</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="1"> <item row="3" column="1">
<widget class="QSpinBox" name="port"> <widget class="QSpinBox" name="port">
<property name="minimum"> <property name="minimum">
<number>1</number> <number>1</number>
@ -129,14 +129,14 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="3" column="0"> <item row="4" column="0">
<widget class="QLabel" name="label_7"> <widget class="QLabel" name="label_7">
<property name="text"> <property name="text">
<string>Password:</string> <string>Password:</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="3" column="1"> <item row="4" column="1">
<widget class="QLineEdit" name="password"> <widget class="QLineEdit" name="password">
<property name="maxLength"> <property name="maxLength">
<number>128</number> <number>128</number>
@ -146,6 +146,16 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="0">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Input Delay:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QSpinBox" name="inputDelay"/>
</item>
</layout> </layout>
</item> </item>
<item> <item>

View File

@ -10,7 +10,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>480</width> <width>480</width>
<height>226</height> <height>254</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@ -92,14 +92,14 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="0"> <item row="3" column="0">
<widget class="QLabel" name="label_5"> <widget class="QLabel" name="label_5">
<property name="text"> <property name="text">
<string>Port:</string> <string>Port:</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="1"> <item row="3" column="1">
<widget class="QSpinBox" name="port"> <widget class="QSpinBox" name="port">
<property name="minimum"> <property name="minimum">
<number>1</number> <number>1</number>
@ -112,28 +112,28 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="0"> <item row="2" column="0">
<widget class="QLabel" name="label_6"> <widget class="QLabel" name="label_6">
<property name="text"> <property name="text">
<string>Hostname:</string> <string>Hostname:</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="1"> <item row="2" column="1">
<widget class="QLineEdit" name="hostname"> <widget class="QLineEdit" name="hostname">
<property name="text"> <property name="text">
<string>localhost</string> <string>localhost</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="3" column="0"> <item row="4" column="0">
<widget class="QLabel" name="label_7"> <widget class="QLabel" name="label_7">
<property name="text"> <property name="text">
<string>Password:</string> <string>Password:</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="3" column="1"> <item row="4" column="1">
<widget class="QLineEdit" name="password"> <widget class="QLineEdit" name="password">
<property name="maxLength"> <property name="maxLength">
<number>128</number> <number>128</number>
@ -143,6 +143,16 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="0">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Input Delay:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QSpinBox" name="inputDelay"/>
</item>
</layout> </layout>
</item> </item>
<item> <item>

View File

@ -14,6 +14,7 @@ CreateNetplaySessionDialog::CreateNetplaySessionDialog(QWidget* parent) : QDialo
connect(m_ui.maxPlayers, &QSpinBox::valueChanged, this, &CreateNetplaySessionDialog::updateState); connect(m_ui.maxPlayers, &QSpinBox::valueChanged, this, &CreateNetplaySessionDialog::updateState);
connect(m_ui.port, &QSpinBox::valueChanged, this, &CreateNetplaySessionDialog::updateState); connect(m_ui.port, &QSpinBox::valueChanged, this, &CreateNetplaySessionDialog::updateState);
connect(m_ui.inputDelay, &QSpinBox::valueChanged, this, &CreateNetplaySessionDialog::updateState);
connect(m_ui.nickname, &QLineEdit::textChanged, this, &CreateNetplaySessionDialog::updateState); connect(m_ui.nickname, &QLineEdit::textChanged, this, &CreateNetplaySessionDialog::updateState);
connect(m_ui.password, &QLineEdit::textChanged, this, &CreateNetplaySessionDialog::updateState); connect(m_ui.password, &QLineEdit::textChanged, this, &CreateNetplaySessionDialog::updateState);
@ -34,19 +35,22 @@ void CreateNetplaySessionDialog::accept()
const int players = m_ui.maxPlayers->value(); const int players = m_ui.maxPlayers->value();
const int port = m_ui.port->value(); const int port = m_ui.port->value();
const int inputdelay = m_ui.inputDelay->value();
const QString& nickname = m_ui.nickname->text(); const QString& nickname = m_ui.nickname->text();
const QString& password = m_ui.password->text(); const QString& password = m_ui.password->text();
QDialog::accept(); QDialog::accept();
g_emu_thread->createNetplaySession(nickname.trimmed(), port, players, password); g_emu_thread->createNetplaySession(nickname.trimmed(), port, players, password, inputdelay);
} }
bool CreateNetplaySessionDialog::validate() bool CreateNetplaySessionDialog::validate()
{ {
const int players = m_ui.maxPlayers->value(); const int players = m_ui.maxPlayers->value();
const int port = m_ui.port->value(); const int port = m_ui.port->value();
const int inputdelay = m_ui.inputDelay->value();
const QString& nickname = m_ui.nickname->text(); const QString& nickname = m_ui.nickname->text();
return (!nickname.isEmpty() && players >= 2 && players <= Netplay::MAX_PLAYERS && port > 0 && port <= 65535); return (!nickname.isEmpty() && players >= 2 && players <= Netplay::MAX_PLAYERS && port > 0 && port <= 65535 &&
inputdelay >= 0 && inputdelay <= 10);
} }
void CreateNetplaySessionDialog::updateState() void CreateNetplaySessionDialog::updateState()
@ -59,6 +63,7 @@ JoinNetplaySessionDialog::JoinNetplaySessionDialog(QWidget* parent)
m_ui.setupUi(this); m_ui.setupUi(this);
connect(m_ui.port, &QSpinBox::valueChanged, this, &JoinNetplaySessionDialog::updateState); connect(m_ui.port, &QSpinBox::valueChanged, this, &JoinNetplaySessionDialog::updateState);
connect(m_ui.inputDelay, &QSpinBox::valueChanged, this, &JoinNetplaySessionDialog::updateState);
connect(m_ui.nickname, &QLineEdit::textChanged, this, &JoinNetplaySessionDialog::updateState); connect(m_ui.nickname, &QLineEdit::textChanged, this, &JoinNetplaySessionDialog::updateState);
connect(m_ui.password, &QLineEdit::textChanged, this, &JoinNetplaySessionDialog::updateState); connect(m_ui.password, &QLineEdit::textChanged, this, &JoinNetplaySessionDialog::updateState);
connect(m_ui.hostname, &QLineEdit::textChanged, this, &JoinNetplaySessionDialog::updateState); connect(m_ui.hostname, &QLineEdit::textChanged, this, &JoinNetplaySessionDialog::updateState);
@ -79,21 +84,23 @@ void JoinNetplaySessionDialog::accept()
return; return;
const int port = m_ui.port->value(); const int port = m_ui.port->value();
const int inputdelay = m_ui.inputDelay->value();
const QString& nickname = m_ui.nickname->text(); const QString& nickname = m_ui.nickname->text();
const QString& hostname = m_ui.hostname->text(); const QString& hostname = m_ui.hostname->text();
const QString& password = m_ui.password->text(); const QString& password = m_ui.password->text();
const bool spectating = m_ui.spectating->isChecked(); const bool spectating = m_ui.spectating->isChecked();
QDialog::accept(); QDialog::accept();
g_emu_thread->joinNetplaySession(nickname.trimmed(), hostname.trimmed(), port, password, spectating); g_emu_thread->joinNetplaySession(nickname.trimmed(), hostname.trimmed(), port, password, spectating, inputdelay);
} }
bool JoinNetplaySessionDialog::validate() bool JoinNetplaySessionDialog::validate()
{ {
const int port = m_ui.port->value(); const int port = m_ui.port->value();
const int inputdelay = m_ui.inputDelay->value();
const QString& nickname = m_ui.nickname->text(); const QString& nickname = m_ui.nickname->text();
const QString& hostname = m_ui.hostname->text(); const QString& hostname = m_ui.hostname->text();
return (!nickname.isEmpty() && !hostname.isEmpty() && port > 0 && port <= 65535); return (!nickname.isEmpty() && !hostname.isEmpty() && port > 0 && port <= 65535 && inputdelay >= 0 && inputdelay <= 10);
} }
void JoinNetplaySessionDialog::updateState() void JoinNetplaySessionDialog::updateState()

View File

@ -1071,12 +1071,13 @@ void EmuThread::reloadPostProcessingShaders()
System::ReloadPostProcessingShaders(); System::ReloadPostProcessingShaders();
} }
void EmuThread::createNetplaySession(const QString& nickname, qint32 port, qint32 max_players, const QString& password) void EmuThread::createNetplaySession(const QString& nickname, qint32 port, qint32 max_players, const QString& password, int inputdelay)
{ {
if (!isOnThread()) if (!isOnThread())
{ {
QMetaObject::invokeMethod(this, "createNetplaySession", Qt::QueuedConnection, Q_ARG(const QString&, nickname), QMetaObject::invokeMethod(this, "createNetplaySession", Qt::QueuedConnection, Q_ARG(const QString&, nickname),
Q_ARG(qint32, port), Q_ARG(qint32, max_players), Q_ARG(const QString&, password)); Q_ARG(qint32, port), Q_ARG(qint32, max_players), Q_ARG(const QString&, password),
Q_ARG(int, inputdelay));
return; return;
} }
@ -1084,7 +1085,7 @@ void EmuThread::createNetplaySession(const QString& nickname, qint32 port, qint3
if (!System::IsValid()) if (!System::IsValid())
return; return;
if (!Netplay::CreateSession(nickname.toStdString(), port, max_players, password.toStdString())) if (!Netplay::CreateSession(nickname.toStdString(), port, max_players, password.toStdString(), inputdelay))
{ {
errorReported(tr("Netplay Error"), tr("Failed to create netplay session. The log may contain more information.")); errorReported(tr("Netplay Error"), tr("Failed to create netplay session. The log may contain more information."));
return; return;
@ -1092,17 +1093,18 @@ void EmuThread::createNetplaySession(const QString& nickname, qint32 port, qint3
} }
void EmuThread::joinNetplaySession(const QString& nickname, const QString& hostname, qint32 port, void EmuThread::joinNetplaySession(const QString& nickname, const QString& hostname, qint32 port,
const QString& password, bool spectating) const QString& password, bool spectating, int inputdelay)
{ {
if (!isOnThread()) if (!isOnThread())
{ {
QMetaObject::invokeMethod(this, "joinNetplaySession", Qt::QueuedConnection, Q_ARG(const QString&, nickname), QMetaObject::invokeMethod(this, "joinNetplaySession", Qt::QueuedConnection, Q_ARG(const QString&, nickname),
Q_ARG(const QString&, hostname), Q_ARG(qint32, port), Q_ARG(const QString&, password), Q_ARG(const QString&, hostname), Q_ARG(qint32, port), Q_ARG(const QString&, password),
Q_ARG(bool, spectating)); Q_ARG(bool, spectating), Q_ARG(int, inputdelay));
return; return;
} }
if (!Netplay::JoinSession(nickname.toStdString(), hostname.toStdString(), port, password.toStdString(), spectating)) if (!Netplay::JoinSession(nickname.toStdString(), hostname.toStdString(), port, password.toStdString(), spectating,
inputdelay))
{ {
errorReported(tr("Netplay Error"), tr("Failed to join netplay session. The log may contain more information.")); errorReported(tr("Netplay Error"), tr("Failed to join netplay session. The log may contain more information."));
return; return;
@ -2243,11 +2245,11 @@ int main(int argc, char* argv[])
params->override_fast_boot = true; params->override_fast_boot = true;
params->fast_forward_to_first_frame = true; params->fast_forward_to_first_frame = true;
g_emu_thread->bootSystem(std::move(params)); g_emu_thread->bootSystem(std::move(params));
g_emu_thread->createNetplaySession(nickname, port, 2, QString()); g_emu_thread->createNetplaySession(nickname, port, 2, QString(), 0);
} }
else else
{ {
g_emu_thread->joinNetplaySession(nickname, remote, port, QString(), false); g_emu_thread->joinNetplaySession(nickname, remote, port, QString(), false, 0);
} }
}); });
} }

View File

@ -187,9 +187,10 @@ public Q_SLOTS:
void setCheatEnabled(quint32 index, bool enabled); void setCheatEnabled(quint32 index, bool enabled);
void applyCheat(quint32 index); void applyCheat(quint32 index);
void reloadPostProcessingShaders(); void reloadPostProcessingShaders();
void createNetplaySession(const QString& nickname, qint32 port, qint32 max_players, const QString& password); void createNetplaySession(const QString& nickname, qint32 port, qint32 max_players, const QString& password,
int inputdelay);
void joinNetplaySession(const QString& nickname, const QString& hostname, qint32 port, const QString& password, void joinNetplaySession(const QString& nickname, const QString& hostname, qint32 port, const QString& password,
bool spectating); bool spectating, int inputdelay);
private Q_SLOTS: private Q_SLOTS:
void stopInThread(); void stopInThread();