From 58aa0150e1d3d391d5fd4e04ab402afb10a60fcc Mon Sep 17 00:00:00 2001 From: iwubcode Date: Sat, 9 May 2020 15:44:45 -0500 Subject: [PATCH] DolphinQt / InputCommon: Support multiple DSU servers --- Source/Core/DolphinQt/CMakeLists.txt | 2 + .../DualShockUDPClientAddServerDialog.cpp | 75 ++++++ .../DualShockUDPClientAddServerDialog.h | 29 +++ .../DualShockUDPClientWidget.cpp | 127 +++++++--- .../DualShockUDPClientWidget.h | 22 +- Source/Core/DolphinQt/DolphinQt.vcxproj | 3 + .../DualShockUDPClient/DualShockUDPClient.cpp | 219 +++++++++++------- .../DualShockUDPClient/DualShockUDPClient.h | 8 +- .../DualShockUDPClient/DualShockUDPProto.h | 4 +- 9 files changed, 359 insertions(+), 130 deletions(-) create mode 100644 Source/Core/DolphinQt/Config/ControllerInterface/DualShockUDPClientAddServerDialog.cpp create mode 100644 Source/Core/DolphinQt/Config/ControllerInterface/DualShockUDPClientAddServerDialog.h diff --git a/Source/Core/DolphinQt/CMakeLists.txt b/Source/Core/DolphinQt/CMakeLists.txt index 3ef723300d..8c95ec3b30 100644 --- a/Source/Core/DolphinQt/CMakeLists.txt +++ b/Source/Core/DolphinQt/CMakeLists.txt @@ -57,6 +57,8 @@ 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 diff --git a/Source/Core/DolphinQt/Config/ControllerInterface/DualShockUDPClientAddServerDialog.cpp b/Source/Core/DolphinQt/Config/ControllerInterface/DualShockUDPClientAddServerDialog.cpp new file mode 100644 index 0000000000..ff510165db --- /dev/null +++ b/Source/Core/DolphinQt/Config/ControllerInterface/DualShockUDPClientAddServerDialog.cpp @@ -0,0 +1,75 @@ +// Copyright 2020 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#include "DolphinQt/Config/ControllerInterface/DualShockUDPClientAddServerDialog.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "Common/Config/Config.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_server_address = + new QLineEdit(QString::fromStdString(ciface::DualShockUDPClient::DEFAULT_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(); +} diff --git a/Source/Core/DolphinQt/Config/ControllerInterface/DualShockUDPClientAddServerDialog.h b/Source/Core/DolphinQt/Config/ControllerInterface/DualShockUDPClientAddServerDialog.h new file mode 100644 index 0000000000..c7b91f45c4 --- /dev/null +++ b/Source/Core/DolphinQt/Config/ControllerInterface/DualShockUDPClientAddServerDialog.h @@ -0,0 +1,29 @@ +// Copyright 2020 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#pragma once + +#include + +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; +}; diff --git a/Source/Core/DolphinQt/Config/ControllerInterface/DualShockUDPClientWidget.cpp b/Source/Core/DolphinQt/Config/ControllerInterface/DualShockUDPClientWidget.cpp index 68e8a75030..eac6cea219 100644 --- a/Source/Core/DolphinQt/Config/ControllerInterface/DualShockUDPClientWidget.cpp +++ b/Source/Core/DolphinQt/Config/ControllerInterface/DualShockUDPClientWidget.cpp @@ -4,14 +4,16 @@ #include "DolphinQt/Config/ControllerInterface/DualShockUDPClientWidget.h" +#include + +#include #include -#include -#include #include -#include -#include +#include +#include #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_server_enabled = new QCheckBox(tr("Enable")); - m_server_enabled->setChecked(Config::Get(ciface::DualShockUDPClient::Settings::SERVER_ENABLED)); + 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_address = new QLineEdit( - QString::fromStdString(Config::Get(ciface::DualShockUDPClient::Settings::SERVER_ADDRESS))); - m_server_address->setEnabled(m_server_enabled->isChecked()); + m_server_list = new QListWidget(); + main_layout->addWidget(m_server_list); - 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()); + m_add_server = new QPushButton(tr("Add...")); + m_add_server->setEnabled(m_servers_enabled->isChecked()); + + m_remove_server = new QPushButton(tr("Remove")); + m_remove_server->setEnabled(m_servers_enabled->isChecked()); + + QHBoxLayout* hlayout = new QHBoxLayout; + hlayout->addStretch(); + hlayout->addWidget(m_add_server); + hlayout->addWidget(m_remove_server); + + main_layout->addItem(hlayout); auto* description = new QLabel(tr("DSU protocol enables the use of input and motion data from compatible " @@ -46,34 +56,75 @@ 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(&QSpinBox::valueChanged), this, - [this] { - Config::SetBaseOrCurrent(ciface::DualShockUDPClient::Settings::SERVER_PORT, - static_cast(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& 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); } diff --git a/Source/Core/DolphinQt/Config/ControllerInterface/DualShockUDPClientWidget.h b/Source/Core/DolphinQt/Config/ControllerInterface/DualShockUDPClientWidget.h index 22e5a88011..e8c5557fbd 100644 --- a/Source/Core/DolphinQt/Config/ControllerInterface/DualShockUDPClientWidget.h +++ b/Source/Core/DolphinQt/Config/ControllerInterface/DualShockUDPClientWidget.h @@ -4,11 +4,12 @@ #pragma once +#include #include class QCheckBox; -class QLineEdit; -class QSpinBox; +class QListWidget; +class QPushButton; class DualShockUDPClientWidget final : public QWidget { @@ -16,11 +17,22 @@ class DualShockUDPClientWidget final : public QWidget 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; }; diff --git a/Source/Core/DolphinQt/DolphinQt.vcxproj b/Source/Core/DolphinQt/DolphinQt.vcxproj index 0fdfc53118..0720ff8e8a 100644 --- a/Source/Core/DolphinQt/DolphinQt.vcxproj +++ b/Source/Core/DolphinQt/DolphinQt.vcxproj @@ -124,6 +124,7 @@ + @@ -212,6 +213,7 @@ + @@ -325,6 +327,7 @@ + diff --git a/Source/Core/InputCommon/ControllerInterface/DualShockUDPClient/DualShockUDPClient.cpp b/Source/Core/InputCommon/ControllerInterface/DualShockUDPClient/DualShockUDPClient.cpp index c398225bfe..837be2c3df 100644 --- a/Source/Core/InputCommon/ControllerInterface/DualShockUDPClient/DualShockUDPClient.cpp +++ b/Source/Core/InputCommon/ControllerInterface/DualShockUDPClient/DualShockUDPClient.cpp @@ -12,6 +12,7 @@ #include #include +#include #include "Common/Config/Config.h" #include "Common/Flag.h" @@ -19,6 +20,7 @@ #include "Common/MathUtil.h" #include "Common/Matrix.h" #include "Common/Random.h" +#include "Common/StringUtil.h" #include "Common/Thread.h" #include "Core/CoreTiming.h" #include "InputCommon/ControllerInterface/ControllerInterface.h" @@ -28,15 +30,10 @@ namespace ciface::DualShockUDPClient { namespace Settings { -constexpr char DEFAULT_SERVER_ADDRESS[] = "127.0.0.1"; -constexpr u16 DEFAULT_SERVER_PORT = 26760; - -const Config::Info SERVER_ENABLED{{Config::System::DualShockUDPClient, "Server", "Enabled"}, - false}; -const Config::Info SERVER_ADDRESS{ - {Config::System::DualShockUDPClient, "Server", "IPAddress"}, DEFAULT_SERVER_ADDRESS}; -const Config::Info SERVER_PORT{{Config::System::DualShockUDPClient, "Server", "Port"}, - DEFAULT_SERVER_PORT}; +const Config::Info SERVERS{{Config::System::DualShockUDPClient, "Server", "Entries"}, + ""}; +const Config::Info SERVERS_ENABLED{{Config::System::DualShockUDPClient, "Server", "Enabled"}, + false}; } // namespace Settings // Clock type used for querying timeframes @@ -130,14 +127,14 @@ private: public: void UpdateInput() override; - Device(Proto::DsModel model, int index); + Device(std::string name, int index, std::string server_address, u16 server_port); std::string GetName() const final override; std::string GetSource() const final override; std::optional GetPreferredId() const final override; private: - const Proto::DsModel m_model; + const std::string m_name; const int m_index; u32 m_client_uid = Common::Random::GenerateValue(); sf::UdpSocket m_socket; @@ -147,6 +144,8 @@ private: bool m_prev_touch_valid = false; int m_touch_x = 0; int m_touch_y = 0; + std::string m_server_address; + u16 m_server_port; }; using MathUtil::GRAVITY_ACCELERATION; @@ -155,16 +154,40 @@ constexpr auto SERVER_LISTPORTS_INTERVAL = std::chrono::seconds{1}; constexpr int TOUCH_X_AXIS_MAX = 1000; constexpr int TOUCH_Y_AXIS_MAX = 500; -static bool s_server_enabled; -static std::string s_server_address; -static u16 s_server_port; +struct Server +{ + Server(std::string description, std::string address, u16 port) + : m_description{std::move(description)}, m_address{std::move(address)}, m_port{port} + { + } + Server(const Server&) = delete; + Server(Server&& other) noexcept + { + m_description = std::move(other.m_description); + m_address = std::move(other.m_address); + m_port = other.m_port; + m_port_info = std::move(other.m_port_info); + } + + Server& operator=(const Server&) = delete; + Server& operator=(Server&&) = delete; + + ~Server() = default; + + std::string m_description; + std::string m_address; + u16 m_port; + std::mutex m_port_info_mutex; + std::array m_port_info; + sf::UdpSocket m_socket; +}; + +static bool s_servers_enabled; +static std::vector s_servers; static u32 s_client_uid; static SteadyClock::time_point s_next_listports; static std::thread s_hotplug_thread; static Common::Flag s_hotplug_thread_running; -static std::mutex s_port_info_mutex; -static std::array s_port_info; -static sf::UdpSocket s_socket; static bool IsSameController(const Proto::MessageType::PortInfo& a, const Proto::MessageType::PortInfo& b) @@ -198,39 +221,48 @@ static void HotplugThreadFunc() { s_next_listports = now + SERVER_LISTPORTS_INTERVAL; - // Request info on the four controller ports - Proto::Message msg(s_client_uid); - auto& list_ports = msg.m_message; - list_ports.pad_request_count = 4; - list_ports.pad_id = {0, 1, 2, 3}; - msg.Finish(); - if (s_socket.send(&list_ports, sizeof list_ports, s_server_address, s_server_port) != - sf::Socket::Status::Done) - ERROR_LOG(SERIALINTERFACE, "DualShockUDPClient HotplugThreadFunc send failed"); + for (auto& server : s_servers) + { + // Request info on the four controller ports + Proto::Message msg(s_client_uid); + auto& list_ports = msg.m_message; + list_ports.pad_request_count = 4; + list_ports.pad_id = {0, 1, 2, 3}; + msg.Finish(); + if (server.m_socket.send(&list_ports, sizeof list_ports, server.m_address, server.m_port) != + sf::Socket::Status::Done) + { + ERROR_LOG(SERIALINTERFACE, "DualShockUDPClient HotplugThreadFunc send failed"); + } + } } - // Receive controller port info - using namespace std::chrono; - using namespace std::chrono_literals; - Proto::Message msg; - const auto timeout = s_next_listports - SteadyClock::now(); - // ReceiveWithTimeout treats a timeout of zero as infinite timeout, which we don't want - const auto timeout_ms = std::max(duration_cast(timeout), 1ms); - std::size_t received_bytes; - sf::IpAddress sender; - u16 port; - if (ReceiveWithTimeout(s_socket, &msg, sizeof(msg), received_bytes, sender, port, - sf::milliseconds(timeout_ms.count())) == sf::Socket::Status::Done) + for (auto& server : s_servers) { - if (auto port_info = msg.CheckAndCastTo()) + // Receive controller port info + using namespace std::chrono; + using namespace std::chrono_literals; + Proto::Message msg; + const auto timeout = s_next_listports - SteadyClock::now(); + // ReceiveWithTimeout treats a timeout of zero as infinite timeout, which we don't want + const auto timeout_ms = std::max(duration_cast(timeout), 1ms); + std::size_t received_bytes; + sf::IpAddress sender; + u16 port; + if (ReceiveWithTimeout(server.m_socket, &msg, sizeof(msg), received_bytes, sender, port, + sf::milliseconds(timeout_ms.count())) == sf::Socket::Status::Done) { - const bool port_changed = !IsSameController(*port_info, s_port_info[port_info->pad_id]); + if (auto port_info = msg.CheckAndCastTo()) { - std::lock_guard lock{s_port_info_mutex}; - s_port_info[port_info->pad_id] = *port_info; + const bool port_changed = + !IsSameController(*port_info, server.m_port_info[port_info->pad_id]); + { + std::lock_guard lock{server.m_port_info_mutex}; + server.m_port_info[port_info->pad_id] = *port_info; + } + if (port_changed) + PopulateDevices(); } - if (port_changed) - PopulateDevices(); } } } @@ -258,7 +290,10 @@ static void StopHotplugThread() return; } - s_socket.unbind(); // interrupt blocking socket + for (auto& server : s_servers) + { + server.m_socket.unbind(); // interrupt blocking socket + } s_hotplug_thread.join(); } @@ -270,29 +305,56 @@ static void Restart() s_client_uid = Common::Random::GenerateValue(); s_next_listports = std::chrono::steady_clock::time_point::min(); - for (size_t port_index = 0; port_index < s_port_info.size(); port_index++) + for (auto& server : s_servers) { - s_port_info[port_index] = {}; - s_port_info[port_index].pad_id = static_cast(port_index); + for (size_t port_index = 0; port_index < server.m_port_info.size(); port_index++) + { + server.m_port_info[port_index] = {}; + server.m_port_info[port_index].pad_id = static_cast(port_index); + } } PopulateDevices(); // remove devices - if (s_server_enabled) + if (s_servers_enabled && !s_servers.empty()) StartHotplugThread(); } static void ConfigChanged() { - bool server_enabled = Config::Get(Settings::SERVER_ENABLED); - std::string server_address = Config::Get(Settings::SERVER_ADDRESS); - u16 server_port = Config::Get(Settings::SERVER_PORT); - if (server_enabled != s_server_enabled || server_address != s_server_address || - server_port != s_server_port) + const bool servers_enabled = Config::Get(Settings::SERVERS_ENABLED); + const std::string servers_setting = Config::Get(Settings::SERVERS); + + std::string new_servers_setting; + for (const auto& server : s_servers) { - s_server_enabled = server_enabled; - s_server_address = server_address; - s_server_port = server_port; + new_servers_setting += + fmt::format("{}:{}:{};", server.m_description, server.m_address, server.m_port); + } + + if (servers_enabled != s_servers_enabled || servers_setting != new_servers_setting) + { + s_servers_enabled = servers_enabled; + s_servers.clear(); + + const auto server_details = SplitString(servers_setting, ';'); + for (const auto& server_detail : server_details) + { + const auto server_info = SplitString(server_detail, ':'); + if (server_info.size() < 3) + continue; + + const std::string description = server_info[0]; + const std::string server_address = server_info[1]; + const auto port = std::stoi(server_info[2]); + if (port >= std::numeric_limits::max()) + { + continue; + } + u16 server_port = static_cast(port); + + s_servers.emplace_back(description, server_address, server_port); + } Restart(); } } @@ -306,18 +368,21 @@ void PopulateDevices() { INFO_LOG(SERIALINTERFACE, "DualShockUDPClient PopulateDevices"); - g_controller_interface.RemoveDevice( - [](const auto* dev) { return dev->GetSource() == "DSUClient"; }); - - std::lock_guard lock{s_port_info_mutex}; - for (size_t port_index = 0; port_index < s_port_info.size(); port_index++) + for (auto& server : s_servers) { - const Proto::MessageType::PortInfo& port_info = s_port_info[port_index]; - if (port_info.pad_state != Proto::DsState::Connected) - continue; + g_controller_interface.RemoveDevice( + [&server](const auto* dev) { return dev->GetName() == server.m_description; }); - g_controller_interface.AddDevice( - std::make_shared(port_info.model, static_cast(port_index))); + std::lock_guard lock{server.m_port_info_mutex}; + for (size_t port_index = 0; port_index < server.m_port_info.size(); port_index++) + { + const Proto::MessageType::PortInfo& port_info = server.m_port_info[port_index]; + if (port_info.pad_state != Proto::DsState::Connected) + continue; + + g_controller_interface.AddDevice(std::make_shared( + server.m_description, static_cast(port_index), server.m_address, server.m_port)); + } } } @@ -326,7 +391,9 @@ void DeInit() StopHotplugThread(); } -Device::Device(Proto::DsModel model, int index) : m_model{model}, m_index{index} +Device::Device(std::string name, int index, std::string server_address, u16 server_port) + : m_name{std::move(name)}, m_index{index}, m_server_address{std::move(server_address)}, + m_server_port{server_port} { m_socket.setBlocking(false); @@ -388,19 +455,7 @@ Device::Device(Proto::DsModel model, int index) : m_model{model}, m_index{index} std::string Device::GetName() const { - switch (m_model) - { - case Proto::DsModel::None: - return "None"; - case Proto::DsModel::DS3: - return "DualShock 3"; - case Proto::DsModel::DS4: - return "DualShock 4"; - case Proto::DsModel::Generic: - return "Generic Gamepad"; - default: - return "Device"; - } + return m_name; } std::string Device::GetSource() const @@ -421,7 +476,7 @@ void Device::UpdateInput() data_req.register_flags = Proto::RegisterFlags::PadID; data_req.pad_id_to_register = m_index; msg.Finish(); - if (m_socket.send(&data_req, sizeof(data_req), s_server_address, s_server_port) != + if (m_socket.send(&data_req, sizeof(data_req), m_server_address, m_server_port) != sf::Socket::Status::Done) ERROR_LOG(SERIALINTERFACE, "DualShockUDPClient UpdateInput send failed"); } diff --git a/Source/Core/InputCommon/ControllerInterface/DualShockUDPClient/DualShockUDPClient.h b/Source/Core/InputCommon/ControllerInterface/DualShockUDPClient/DualShockUDPClient.h index 1b51a2e1b9..e7a9057569 100644 --- a/Source/Core/InputCommon/ControllerInterface/DualShockUDPClient/DualShockUDPClient.h +++ b/Source/Core/InputCommon/ControllerInterface/DualShockUDPClient/DualShockUDPClient.h @@ -8,11 +8,13 @@ namespace ciface::DualShockUDPClient { +constexpr char DEFAULT_SERVER_ADDRESS[] = "127.0.0.1"; +constexpr u16 DEFAULT_SERVER_PORT = 26760; + namespace Settings { -extern const Config::Info SERVER_ENABLED; -extern const Config::Info SERVER_ADDRESS; -extern const Config::Info SERVER_PORT; +extern const Config::Info SERVERS; +extern const Config::Info SERVERS_ENABLED; } // namespace Settings void Init(); diff --git a/Source/Core/InputCommon/ControllerInterface/DualShockUDPClient/DualShockUDPProto.h b/Source/Core/InputCommon/ControllerInterface/DualShockUDPClient/DualShockUDPProto.h index 5e3e9f0dde..97b453a68a 100644 --- a/Source/Core/InputCommon/ControllerInterface/DualShockUDPClient/DualShockUDPProto.h +++ b/Source/Core/InputCommon/ControllerInterface/DualShockUDPClient/DualShockUDPProto.h @@ -45,8 +45,8 @@ enum class DsConnection : u8 enum class DsModel : u8 { None = 0, - DS3 = 1, - DS4 = 2, + PartialGyro = 1, + FullGyro = 2, Generic = 3 };