Skip to content
Permalink
Browse files
Merge pull request #8804 from iwubcode/dsu-improvements
DolphinQt / InputCommon - Support multiple DSU servers
  • Loading branch information
Tilka committed Aug 8, 2020
2 parents 76b955e + 97c9cf3 commit f17b5dd
Show file tree
Hide file tree
Showing 11 changed files with 442 additions and 127 deletions.
@@ -59,10 +59,14 @@ add_executable(dolphin-emu
Config/CheatCodeEditor.h
Config/CheatWarningWidget.cpp
Config/CheatWarningWidget.h
Config/ControllerInterface/DualShockUDPClientAddServerDialog.cpp
Config/ControllerInterface/DualShockUDPClientAddServerDialog.h
Config/ControllerInterface/DualShockUDPClientWidget.cpp
Config/ControllerInterface/DualShockUDPClientWidget.h
Config/ControllerInterface/ControllerInterfaceWindow.cpp
Config/ControllerInterface/ControllerInterfaceWindow.h
Config/ControllerInterface/ServerStringValidator.cpp
Config/ControllerInterface/ServerStringValidator.h
Config/ControllersWindow.cpp
Config/ControllersWindow.h
Config/FilesystemWidget.cpp
@@ -0,0 +1,79 @@
// Copyright 2020 Dolphin Emulator Project
// Licensed under GPLv2+
// Refer to the license.txt file included.

#include "DolphinQt/Config/ControllerInterface/DualShockUDPClientAddServerDialog.h"

#include <fmt/format.h>

#include <QButtonGroup>
#include <QDialog>
#include <QDialogButtonBox>
#include <QGridLayout>
#include <QLabel>
#include <QLineEdit>
#include <QPushButton>
#include <QSpinBox>
#include <QString>
#include <QWidget>

#include "Common/Config/Config.h"
#include "DolphinQt/Config/ControllerInterface/ServerStringValidator.h"
#include "InputCommon/ControllerInterface/DualShockUDPClient/DualShockUDPClient.h"

DualShockUDPClientAddServerDialog::DualShockUDPClientAddServerDialog(QWidget* parent)
: QDialog(parent)
{
CreateWidgets();
setLayout(m_main_layout);
}

void DualShockUDPClientAddServerDialog::CreateWidgets()
{
setWindowTitle(tr("Add New DSU Server"));
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);

m_main_layout = new QGridLayout;

m_description = new QLineEdit();
m_description->setPlaceholderText(tr("BetterJoy, DS4Windows, etc"));
m_description->setValidator(new ServerStringValidator(m_description));

m_server_address =
new QLineEdit(QString::fromStdString(ciface::DualShockUDPClient::DEFAULT_SERVER_ADDRESS));
m_server_address->setValidator(new ServerStringValidator(m_server_address));

m_server_port = new QSpinBox();
m_server_port->setMaximum(65535);
m_server_port->setValue(ciface::DualShockUDPClient::DEFAULT_SERVER_PORT);

m_main_layout->addWidget(new QLabel(tr("Description")), 1, 0);
m_main_layout->addWidget(m_description, 1, 1);
m_main_layout->addWidget(new QLabel(tr("Server IP Address")), 2, 0);
m_main_layout->addWidget(m_server_address, 2, 1);
m_main_layout->addWidget(new QLabel(tr("Server Port")), 3, 0);
m_main_layout->addWidget(m_server_port, 3, 1);

m_buttonbox = new QDialogButtonBox();
auto* add_button = new QPushButton(tr("Add"));
auto* cancel_button = new QPushButton(tr("Cancel"));
m_buttonbox->addButton(add_button, QDialogButtonBox::AcceptRole);
m_buttonbox->addButton(cancel_button, QDialogButtonBox::RejectRole);
connect(add_button, &QPushButton::clicked, this,
&DualShockUDPClientAddServerDialog::OnServerAdded);
connect(cancel_button, &QPushButton::clicked, this, &DualShockUDPClientAddServerDialog::reject);
add_button->setDefault(true);

m_main_layout->addWidget(m_buttonbox, 4, 0, 1, 2);
}

void DualShockUDPClientAddServerDialog::OnServerAdded()
{
const auto& servers_setting = Config::Get(ciface::DualShockUDPClient::Settings::SERVERS);
Config::SetBaseOrCurrent(ciface::DualShockUDPClient::Settings::SERVERS,
servers_setting + fmt::format("{}:{}:{};",
m_description->text().toStdString(),
m_server_address->text().toStdString(),
m_server_port->value()));
accept();
}
@@ -0,0 +1,29 @@
// Copyright 2020 Dolphin Emulator Project
// Licensed under GPLv2+
// Refer to the license.txt file included.

#pragma once

#include <QDialog>

class QDialogButtonBox;
class QGridLayout;
class QLineEdit;
class QSpinBox;

class DualShockUDPClientAddServerDialog final : public QDialog
{
Q_OBJECT
public:
explicit DualShockUDPClientAddServerDialog(QWidget* parent);

private:
void CreateWidgets();
void OnServerAdded();

QDialogButtonBox* m_buttonbox;
QGridLayout* m_main_layout;
QLineEdit* m_description;
QLineEdit* m_server_address;
QSpinBox* m_server_port;
};
@@ -4,14 +4,16 @@

#include "DolphinQt/Config/ControllerInterface/DualShockUDPClientWidget.h"

#include <fmt/format.h>

#include <QBoxLayout>
#include <QCheckBox>
#include <QGridLayout>
#include <QGroupBox>
#include <QLabel>
#include <QLineEdit>
#include <QSpinBox>
#include <QListWidget>
#include <QPushButton>

#include "Common/Config/Config.h"
#include "DolphinQt/Config/ControllerInterface/DualShockUDPClientAddServerDialog.h"
#include "InputCommon/ControllerInterface/DualShockUDPClient/DualShockUDPClient.h"

DualShockUDPClientWidget::DualShockUDPClientWidget()
@@ -22,19 +24,27 @@ DualShockUDPClientWidget::DualShockUDPClientWidget()

void DualShockUDPClientWidget::CreateWidgets()
{
auto* main_layout = new QGridLayout;
auto* main_layout = new QVBoxLayout;

m_servers_enabled = new QCheckBox(tr("Enable"));
m_servers_enabled->setChecked(Config::Get(ciface::DualShockUDPClient::Settings::SERVERS_ENABLED));
main_layout->addWidget(m_servers_enabled, 0, 0);

m_server_list = new QListWidget();
main_layout->addWidget(m_server_list);

m_add_server = new QPushButton(tr("Add..."));
m_add_server->setEnabled(m_servers_enabled->isChecked());

m_server_enabled = new QCheckBox(tr("Enable"));
m_server_enabled->setChecked(Config::Get(ciface::DualShockUDPClient::Settings::SERVER_ENABLED));
m_remove_server = new QPushButton(tr("Remove"));
m_remove_server->setEnabled(m_servers_enabled->isChecked());

m_server_address = new QLineEdit(
QString::fromStdString(Config::Get(ciface::DualShockUDPClient::Settings::SERVER_ADDRESS)));
m_server_address->setEnabled(m_server_enabled->isChecked());
QHBoxLayout* hlayout = new QHBoxLayout;
hlayout->addStretch();
hlayout->addWidget(m_add_server);
hlayout->addWidget(m_remove_server);

m_server_port = new QSpinBox();
m_server_port->setMaximum(65535);
m_server_port->setValue(Config::Get(ciface::DualShockUDPClient::Settings::SERVER_PORT));
m_server_port->setEnabled(m_server_enabled->isChecked());
main_layout->addItem(hlayout);

auto* description =
new QLabel(tr("DSU protocol enables the use of input and motion data from compatible "
@@ -46,34 +56,91 @@ void DualShockUDPClientWidget::CreateWidgets()
description->setWordWrap(true);
description->setTextInteractionFlags(Qt::TextBrowserInteraction);
description->setOpenExternalLinks(true);

main_layout->addWidget(m_server_enabled, 1, 1);
main_layout->addWidget(new QLabel(tr("Server IP Address")), 2, 1);
main_layout->addWidget(m_server_address, 2, 2);
main_layout->addWidget(new QLabel(tr("Server Port")), 3, 1);
main_layout->addWidget(m_server_port, 3, 2);
main_layout->addWidget(description, 4, 1, 1, 2);
main_layout->addWidget(description);

setLayout(main_layout);

RefreshServerList();
}

void DualShockUDPClientWidget::ConnectWidgets()
{
connect(m_server_enabled, &QCheckBox::toggled, this, [this] {
bool checked = m_server_enabled->isChecked();
Config::SetBaseOrCurrent(ciface::DualShockUDPClient::Settings::SERVER_ENABLED, checked);
m_server_address->setEnabled(checked);
m_server_port->setEnabled(checked);
});

connect(m_server_address, &QLineEdit::editingFinished, this, [this] {
Config::SetBaseOrCurrent(ciface::DualShockUDPClient::Settings::SERVER_ADDRESS,
m_server_address->text().toStdString());
});

connect(m_server_port, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), this,
[this] {
Config::SetBaseOrCurrent(ciface::DualShockUDPClient::Settings::SERVER_PORT,
static_cast<u16>(m_server_port->value()));
});
connect(m_servers_enabled, &QCheckBox::clicked, this,
&DualShockUDPClientWidget::OnServersToggled);
connect(m_add_server, &QPushButton::clicked, this, &DualShockUDPClientWidget::OnServerAdded);
connect(m_remove_server, &QPushButton::clicked, this, &DualShockUDPClientWidget::OnServerRemoved);
}

void DualShockUDPClientWidget::RefreshServerList()
{
m_server_list->clear();

const auto server_address_setting =
Config::Get(ciface::DualShockUDPClient::Settings::SERVER_ADDRESS);
const auto server_port_setting = Config::Get(ciface::DualShockUDPClient::Settings::SERVER_PORT);

// Update our servers setting if the user is using old configuration
if (!server_address_setting.empty() && server_port_setting != 0)
{
const auto& servers_setting = Config::Get(ciface::DualShockUDPClient::Settings::SERVERS);
Config::SetBaseOrCurrent(ciface::DualShockUDPClient::Settings::SERVERS,
servers_setting + fmt::format("{}:{}:{};", "DS4",
server_address_setting,
server_port_setting));
Config::SetBase(ciface::DualShockUDPClient::Settings::SERVER_ADDRESS, "");
Config::SetBase(ciface::DualShockUDPClient::Settings::SERVER_PORT, 0);
}

const auto& servers_setting = Config::Get(ciface::DualShockUDPClient::Settings::SERVERS);
const auto server_details = SplitString(servers_setting, ';');
for (const std::string& server_detail : server_details)
{
const auto server_info = SplitString(server_detail, ':');
if (server_info.size() < 3)
continue;

QListWidgetItem* list_item = new QListWidgetItem(QString::fromStdString(
fmt::format("{}:{} - {}", server_info[1], server_info[2], server_info[0])));
m_server_list->addItem(list_item);
}
emit ConfigChanged();
}

void DualShockUDPClientWidget::OnServerAdded()
{
DualShockUDPClientAddServerDialog add_server_dialog(this);
connect(&add_server_dialog, &DualShockUDPClientAddServerDialog::accepted, this,
&DualShockUDPClientWidget::RefreshServerList);
add_server_dialog.exec();
}

void DualShockUDPClientWidget::OnServerRemoved()
{
const int row_to_remove = m_server_list->currentRow();

const auto& servers_setting = Config::Get(ciface::DualShockUDPClient::Settings::SERVERS);
const auto server_details = SplitString(servers_setting, ';');

std::string new_server_setting;
for (int i = 0; i < m_server_list->count(); i++)
{
if (i == row_to_remove)
{
continue;
}

new_server_setting += server_details[i] + ';';
}

Config::SetBaseOrCurrent(ciface::DualShockUDPClient::Settings::SERVERS, new_server_setting);

RefreshServerList();
}

void DualShockUDPClientWidget::OnServersToggled()
{
bool checked = m_servers_enabled->isChecked();
Config::SetBaseOrCurrent(ciface::DualShockUDPClient::Settings::SERVERS_ENABLED, checked);
m_add_server->setEnabled(checked);
m_remove_server->setEnabled(checked);
}
@@ -4,23 +4,35 @@

#pragma once

#include <QStringList>
#include <QWidget>

class QCheckBox;
class QLineEdit;
class QSpinBox;
class QListWidget;
class QPushButton;

class DualShockUDPClientWidget final : public QWidget
{
Q_OBJECT
public:
explicit DualShockUDPClientWidget();

signals:
// Emitted when config has changed so widgets can update to reflect the change.
void ConfigChanged();

private:
void CreateWidgets();
void ConnectWidgets();

QCheckBox* m_server_enabled;
QLineEdit* m_server_address;
QSpinBox* m_server_port;
void RefreshServerList();

void OnServerAdded();
void OnServerRemoved();
void OnServersToggled();

QCheckBox* m_servers_enabled;
QListWidget* m_server_list;
QPushButton* m_add_server;
QPushButton* m_remove_server;
};
@@ -0,0 +1,23 @@
// Copyright 2020 Dolphin Emulator Project
// Licensed under GPLv2+
// Refer to the license.txt file included.

#include "DolphinQt/Config/ControllerInterface/ServerStringValidator.h"

ServerStringValidator::ServerStringValidator(QObject* parent) : QValidator(parent)
{
}

QValidator::State ServerStringValidator::validate(QString& input, int& pos) const
{
if (input.isEmpty())
return Invalid;

if (input.contains(QStringLiteral(":")))
return Invalid;

if (input.contains(QStringLiteral(";")))
return Invalid;

return Acceptable;
}
@@ -0,0 +1,16 @@
// Copyright 2020 Dolphin Emulator Project
// Licensed under GPLv2+
// Refer to the license.txt file included.

#pragma once

#include <QValidator>

class ServerStringValidator : public QValidator
{
Q_OBJECT
public:
explicit ServerStringValidator(QObject* parent);

State validate(QString& input, int& pos) const override;
};

0 comments on commit f17b5dd

Please sign in to comment.