diff options
Diffstat (limited to 'src/yuzu')
| -rw-r--r-- | src/yuzu/bootmanager.cpp | 28 | ||||
| -rw-r--r-- | src/yuzu/bootmanager.h | 2 | ||||
| -rw-r--r-- | src/yuzu/configuration/config.cpp | 23 | ||||
| -rw-r--r-- | src/yuzu/configuration/configure_dialog.cpp | 3 | ||||
| -rw-r--r-- | src/yuzu/configuration/configure_input_player.cpp | 87 | ||||
| -rw-r--r-- | src/yuzu/configuration/configure_motion_touch.cpp | 134 | ||||
| -rw-r--r-- | src/yuzu/configuration/configure_motion_touch.h | 5 | ||||
| -rw-r--r-- | src/yuzu/configuration/configure_motion_touch.ui | 269 | ||||
| -rw-r--r-- | src/yuzu/configuration/configure_per_game.cpp | 2 | ||||
| -rw-r--r-- | src/yuzu/configuration/configure_profile_manager.cpp | 2 | ||||
| -rw-r--r-- | src/yuzu/configuration/configure_system.cpp | 12 | ||||
| -rw-r--r-- | src/yuzu/configuration/configure_ui.cpp | 3 | ||||
| -rw-r--r-- | src/yuzu/main.cpp | 42 | 
13 files changed, 393 insertions, 219 deletions
| diff --git a/src/yuzu/bootmanager.cpp b/src/yuzu/bootmanager.cpp index f0338cf7a..489104d5f 100644 --- a/src/yuzu/bootmanager.cpp +++ b/src/yuzu/bootmanager.cpp @@ -35,7 +35,7 @@  #include "core/settings.h"  #include "input_common/keyboard.h"  #include "input_common/main.h" -#include "input_common/motion_emu.h" +#include "input_common/mouse/mouse_input.h"  #include "video_core/renderer_base.h"  #include "video_core/video_core.h"  #include "yuzu/bootmanager.h" @@ -314,7 +314,7 @@ GRenderWindow::~GRenderWindow() {      input_subsystem->Shutdown();  } -void GRenderWindow::PollEvents() { +void GRenderWindow::OnFrameDisplayed() {      if (!first_frame) {          first_frame = true;          emit FirstFrameDisplayed(); @@ -388,23 +388,19 @@ void GRenderWindow::keyReleaseEvent(QKeyEvent* event) {  }  void GRenderWindow::mousePressEvent(QMouseEvent* event) { -    if (!Settings::values.touchscreen.enabled) { -        input_subsystem->GetKeyboard()->PressKey(event->button()); -        return; -    } -      // Touch input is handled in TouchBeginEvent      if (event->source() == Qt::MouseEventSynthesizedBySystem) {          return;      }      auto pos = event->pos(); +    const auto [x, y] = ScaleTouch(pos); +    input_subsystem->GetMouse()->PressButton(x, y, event->button()); +      if (event->button() == Qt::LeftButton) { -        const auto [x, y] = ScaleTouch(pos);          this->TouchPressed(x, y); -    } else if (event->button() == Qt::RightButton) { -        input_subsystem->GetMotionEmu()->BeginTilt(pos.x(), pos.y());      } +      QWidget::mousePressEvent(event);  } @@ -416,26 +412,22 @@ void GRenderWindow::mouseMoveEvent(QMouseEvent* event) {      auto pos = event->pos();      const auto [x, y] = ScaleTouch(pos); +    input_subsystem->GetMouse()->MouseMove(x, y);      this->TouchMoved(x, y); -    input_subsystem->GetMotionEmu()->Tilt(pos.x(), pos.y()); +      QWidget::mouseMoveEvent(event);  }  void GRenderWindow::mouseReleaseEvent(QMouseEvent* event) { -    if (!Settings::values.touchscreen.enabled) { -        input_subsystem->GetKeyboard()->ReleaseKey(event->button()); -        return; -    } -      // Touch input is handled in TouchEndEvent      if (event->source() == Qt::MouseEventSynthesizedBySystem) {          return;      } +    input_subsystem->GetMouse()->ReleaseButton(event->button()); +      if (event->button() == Qt::LeftButton) {          this->TouchReleased(); -    } else if (event->button() == Qt::RightButton) { -        input_subsystem->GetMotionEmu()->EndTilt();      }  } diff --git a/src/yuzu/bootmanager.h b/src/yuzu/bootmanager.h index 503b4f89e..a6d788d40 100644 --- a/src/yuzu/bootmanager.h +++ b/src/yuzu/bootmanager.h @@ -131,7 +131,7 @@ public:      ~GRenderWindow() override;      // EmuWindow implementation. -    void PollEvents() override; +    void OnFrameDisplayed() override;      bool IsShown() const override;      std::unique_ptr<Core::Frontend::GraphicsContext> CreateSharedContext() const override; diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp index 3c423a271..fcc38b3af 100644 --- a/src/yuzu/configuration/config.cpp +++ b/src/yuzu/configuration/config.cpp @@ -7,6 +7,7 @@  #include <QSettings>  #include "common/common_paths.h"  #include "common/file_util.h" +#include "core/core.h"  #include "core/hle/service/acc/profile_manager.h"  #include "core/hle/service/hid/controllers/npad.h"  #include "input_common/main.h" @@ -568,16 +569,11 @@ void Config::ReadMotionTouchValues() {          ReadSetting(QStringLiteral("touch_from_button_map"), 0).toInt();      Settings::values.touch_from_button_map_index =          std::clamp(Settings::values.touch_from_button_map_index, 0, num_touch_from_button_maps - 1); -    Settings::values.udp_input_address = -        ReadSetting(QStringLiteral("udp_input_address"), -                    QString::fromUtf8(InputCommon::CemuhookUDP::DEFAULT_ADDR)) +    Settings::values.udp_input_servers = +        ReadSetting(QStringLiteral("udp_input_servers"), +                    QString::fromUtf8(InputCommon::CemuhookUDP::DEFAULT_SRV))              .toString()              .toStdString(); -    Settings::values.udp_input_port = static_cast<u16>( -        ReadSetting(QStringLiteral("udp_input_port"), InputCommon::CemuhookUDP::DEFAULT_PORT) -            .toInt()); -    Settings::values.udp_pad_index = -        static_cast<u8>(ReadSetting(QStringLiteral("udp_pad_index"), 0).toUInt());  }  void Config::ReadCoreValues() { @@ -1108,12 +1104,9 @@ void Config::SaveMotionTouchValues() {                   false);      WriteSetting(QStringLiteral("touch_from_button_map"),                   Settings::values.touch_from_button_map_index, 0); -    WriteSetting(QStringLiteral("udp_input_address"), -                 QString::fromStdString(Settings::values.udp_input_address), -                 QString::fromUtf8(InputCommon::CemuhookUDP::DEFAULT_ADDR)); -    WriteSetting(QStringLiteral("udp_input_port"), Settings::values.udp_input_port, -                 InputCommon::CemuhookUDP::DEFAULT_PORT); -    WriteSetting(QStringLiteral("udp_pad_index"), Settings::values.udp_pad_index, 0); +    WriteSetting(QStringLiteral("udp_input_servers"), +                 QString::fromStdString(Settings::values.udp_input_servers), +                 QString::fromUtf8(InputCommon::CemuhookUDP::DEFAULT_SRV));      qt_config->beginWriteArray(QStringLiteral("touch_from_button_maps"));      for (std::size_t p = 0; p < Settings::values.touch_from_button_maps.size(); ++p) { @@ -1598,7 +1591,7 @@ void Config::Reload() {      Settings::Sanitize();      // To apply default value changes      SaveValues(); -    Settings::Apply(); +    Settings::Apply(Core::System::GetInstance());  }  void Config::Save() { diff --git a/src/yuzu/configuration/configure_dialog.cpp b/src/yuzu/configuration/configure_dialog.cpp index 5041e0bf8..b33f8437a 100644 --- a/src/yuzu/configuration/configure_dialog.cpp +++ b/src/yuzu/configuration/configure_dialog.cpp @@ -5,6 +5,7 @@  #include <QHash>  #include <QListWidgetItem>  #include <QSignalBlocker> +#include "core/core.h"  #include "core/settings.h"  #include "ui_configure.h"  #include "yuzu/configuration/config.h" @@ -54,7 +55,7 @@ void ConfigureDialog::ApplyConfiguration() {      ui->debugTab->ApplyConfiguration();      ui->webTab->ApplyConfiguration();      ui->serviceTab->ApplyConfiguration(); -    Settings::Apply(); +    Settings::Apply(Core::System::GetInstance());      Settings::LogSettings();  } diff --git a/src/yuzu/configuration/configure_input_player.cpp b/src/yuzu/configuration/configure_input_player.cpp index 918bfb56b..f9915fb7a 100644 --- a/src/yuzu/configuration/configure_input_player.cpp +++ b/src/yuzu/configuration/configure_input_player.cpp @@ -19,6 +19,7 @@  #include "core/hle/service/sm/sm.h"  #include "input_common/gcadapter/gc_poller.h"  #include "input_common/main.h" +#include "input_common/mouse/mouse_poller.h"  #include "input_common/udp/udp.h"  #include "ui_configure_input_player.h"  #include "yuzu/configuration/config.h" @@ -152,6 +153,14 @@ QString ButtonToText(const Common::ParamPackage& param) {          return {};      } +    if (param.Get("engine", "") == "mouse") { +        if (param.Has("button")) { +            const QString button_str = QString::number(int(param.Get("button", 0))); +            return QObject::tr("Click %1").arg(button_str); +        } +        return GetKeyName(param.Get("code", 0)); +    } +      return QObject::tr("[unknown]");  } @@ -203,6 +212,26 @@ QString AnalogToText(const Common::ParamPackage& param, const std::string& dir)          return {};      } + +    if (param.Get("engine", "") == "mouse") { +        if (dir == "modifier") { +            return QObject::tr("[unused]"); +        } + +        if (dir == "left" || dir == "right") { +            const QString axis_x_str = QString::fromStdString(param.Get("axis_x", "")); + +            return QObject::tr("Mouse %1").arg(axis_x_str); +        } + +        if (dir == "up" || dir == "down") { +            const QString axis_y_str = QString::fromStdString(param.Get("axis_y", "")); + +            return QObject::tr("Mouse %1").arg(axis_y_str); +        } + +        return {}; +    }      return QObject::tr("[unknown]");  }  } // namespace @@ -484,6 +513,34 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i                  return;              }          } +        if (input_subsystem->GetMouseButtons()->IsPolling()) { +            params = input_subsystem->GetMouseButtons()->GetNextInput(); +            if (params.Has("engine") && IsInputAcceptable(params)) { +                SetPollingResult(params, false); +                return; +            } +        } +        if (input_subsystem->GetMouseAnalogs()->IsPolling()) { +            params = input_subsystem->GetMouseAnalogs()->GetNextInput(); +            if (params.Has("engine") && IsInputAcceptable(params)) { +                SetPollingResult(params, false); +                return; +            } +        } +        if (input_subsystem->GetMouseMotions()->IsPolling()) { +            params = input_subsystem->GetMouseMotions()->GetNextInput(); +            if (params.Has("engine") && IsInputAcceptable(params)) { +                SetPollingResult(params, false); +                return; +            } +        } +        if (input_subsystem->GetMouseTouch()->IsPolling()) { +            params = input_subsystem->GetMouseTouch()->GetNextInput(); +            if (params.Has("engine") && IsInputAcceptable(params)) { +                SetPollingResult(params, false); +                return; +            } +        }          for (auto& poller : device_pollers) {              params = poller->GetNextInput();              if (params.Has("engine") && IsInputAcceptable(params)) { @@ -761,8 +818,9 @@ void ConfigureInputPlayer::UpdateUI() {          int slider_value;          auto& param = analogs_param[analog_id]; -        const bool is_controller = -            param.Get("engine", "") == "sdl" || param.Get("engine", "") == "gcpad"; +        const bool is_controller = param.Get("engine", "") == "sdl" || +                                   param.Get("engine", "") == "gcpad" || +                                   param.Get("engine", "") == "mouse";          if (is_controller) {              if (!param.Has("deadzone")) { @@ -1078,6 +1136,16 @@ void ConfigureInputPlayer::HandleClick(          input_subsystem->GetUDPMotions()->BeginConfiguration();      } +    if (type == InputCommon::Polling::DeviceType::Button) { +        input_subsystem->GetMouseButtons()->BeginConfiguration(); +    } else if (type == InputCommon::Polling::DeviceType::AnalogPreferred) { +        input_subsystem->GetMouseAnalogs()->BeginConfiguration(); +    } else if (type == InputCommon::Polling::DeviceType::Motion) { +        input_subsystem->GetMouseMotions()->BeginConfiguration(); +    } else { +        input_subsystem->GetMouseTouch()->BeginConfiguration(); +    } +      timeout_timer->start(2500); // Cancel after 2.5 seconds      poll_timer->start(50);      // Check for new inputs every 50ms  } @@ -1097,6 +1165,11 @@ void ConfigureInputPlayer::SetPollingResult(const Common::ParamPackage& params,      input_subsystem->GetUDPMotions()->EndConfiguration(); +    input_subsystem->GetMouseButtons()->EndConfiguration(); +    input_subsystem->GetMouseAnalogs()->EndConfiguration(); +    input_subsystem->GetMouseMotions()->EndConfiguration(); +    input_subsystem->GetMouseTouch()->EndConfiguration(); +      if (!abort) {          (*input_setter)(params);      } @@ -1128,15 +1201,7 @@ void ConfigureInputPlayer::mousePressEvent(QMouseEvent* event) {          return;      } -    if (want_keyboard_mouse) { -        SetPollingResult(Common::ParamPackage{InputCommon::GenerateKeyboardParam(event->button())}, -                         false); -    } else { -        // We don't want any mouse buttons, so don't stop polling -        return; -    } - -    SetPollingResult({}, true); +    input_subsystem->GetMouse()->PressButton(0, 0, event->button());  }  void ConfigureInputPlayer::keyPressEvent(QKeyEvent* event) { diff --git a/src/yuzu/configuration/configure_motion_touch.cpp b/src/yuzu/configuration/configure_motion_touch.cpp index 170574d9b..2afac591a 100644 --- a/src/yuzu/configuration/configure_motion_touch.cpp +++ b/src/yuzu/configuration/configure_motion_touch.cpp @@ -3,10 +3,12 @@  // Refer to the license.txt file included.  #include <array> +#include <sstream>  #include <QCloseEvent>  #include <QLabel>  #include <QMessageBox>  #include <QPushButton> +#include <QStringListModel>  #include <QVBoxLayout>  #include "common/logging/log.h"  #include "core/settings.h" @@ -74,11 +76,6 @@ void CalibrationConfigurationDialog::UpdateButtonText(const QString& text) {      cancel_button->setText(text);  } -constexpr std::array<std::pair<const char*, const char*>, 2> MotionProviders = {{ -    {"motion_emu", QT_TRANSLATE_NOOP("ConfigureMotionTouch", "Mouse (Right Click)")}, -    {"cemuhookudp", QT_TRANSLATE_NOOP("ConfigureMotionTouch", "CemuhookUDP")}, -}}; -  constexpr std::array<std::pair<const char*, const char*>, 2> TouchProviders = {{      {"emu_window", QT_TRANSLATE_NOOP("ConfigureMotionTouch", "Emulator Window")},      {"cemuhookudp", QT_TRANSLATE_NOOP("ConfigureMotionTouch", "CemuhookUDP")}, @@ -89,9 +86,6 @@ ConfigureMotionTouch::ConfigureMotionTouch(QWidget* parent,      : QDialog(parent), input_subsystem{input_subsystem_},        ui(std::make_unique<Ui::ConfigureMotionTouch>()) {      ui->setupUi(this); -    for (const auto& [provider, name] : MotionProviders) { -        ui->motion_provider->addItem(tr(name), QString::fromUtf8(provider)); -    }      for (const auto& [provider, name] : TouchProviders) {          ui->touch_provider->addItem(tr(name), QString::fromUtf8(provider));      } @@ -116,8 +110,6 @@ void ConfigureMotionTouch::SetConfiguration() {      const std::string motion_engine = motion_param.Get("engine", "motion_emu");      const std::string touch_engine = touch_param.Get("engine", "emu_window"); -    ui->motion_provider->setCurrentIndex( -        ui->motion_provider->findData(QString::fromStdString(motion_engine)));      ui->touch_provider->setCurrentIndex(          ui->touch_provider->findData(QString::fromStdString(touch_engine)));      ui->touch_from_button_checkbox->setChecked(Settings::values.use_touch_from_button); @@ -133,23 +125,30 @@ void ConfigureMotionTouch::SetConfiguration() {      max_x = touch_param.Get("max_x", 1800);      max_y = touch_param.Get("max_y", 850); -    ui->udp_server->setText(QString::fromStdString(Settings::values.udp_input_address)); -    ui->udp_port->setText(QString::number(Settings::values.udp_input_port)); -    ui->udp_pad_index->setCurrentIndex(Settings::values.udp_pad_index); +    ui->udp_server->setText(QString::fromStdString("127.0.0.1")); +    ui->udp_port->setText(QString::number(26760)); + +    udp_server_list_model = new QStringListModel(this); +    udp_server_list_model->setStringList({}); +    ui->udp_server_list->setModel(udp_server_list_model); + +    std::stringstream ss(Settings::values.udp_input_servers); +    std::string token; + +    while (std::getline(ss, token, ',')) { +        const int row = udp_server_list_model->rowCount(); +        udp_server_list_model->insertRows(row, 1); +        const QModelIndex index = udp_server_list_model->index(row); +        udp_server_list_model->setData(index, QString::fromStdString(token)); +    }  }  void ConfigureMotionTouch::UpdateUiDisplay() { -    const QString motion_engine = ui->motion_provider->currentData().toString();      const QString touch_engine = ui->touch_provider->currentData().toString();      const QString cemuhook_udp = QStringLiteral("cemuhookudp"); -    if (motion_engine == QStringLiteral("motion_emu")) { -        ui->motion_sensitivity_label->setVisible(true); -        ui->motion_sensitivity->setVisible(true); -    } else { -        ui->motion_sensitivity_label->setVisible(false); -        ui->motion_sensitivity->setVisible(false); -    } +    ui->motion_sensitivity_label->setVisible(true); +    ui->motion_sensitivity->setVisible(true);      if (touch_engine == cemuhook_udp) {          ui->touch_calibration->setVisible(true); @@ -163,19 +162,15 @@ void ConfigureMotionTouch::UpdateUiDisplay() {          ui->touch_calibration_label->setVisible(false);      } -    if (motion_engine == cemuhook_udp || touch_engine == cemuhook_udp) { -        ui->udp_config_group_box->setVisible(true); -    } else { -        ui->udp_config_group_box->setVisible(false); -    } +    ui->udp_config_group_box->setVisible(true);  }  void ConfigureMotionTouch::ConnectEvents() { -    connect(ui->motion_provider, qOverload<int>(&QComboBox::currentIndexChanged), this, -            [this](int index) { UpdateUiDisplay(); });      connect(ui->touch_provider, qOverload<int>(&QComboBox::currentIndexChanged), this,              [this](int index) { UpdateUiDisplay(); });      connect(ui->udp_test, &QPushButton::clicked, this, &ConfigureMotionTouch::OnCemuhookUDPTest); +    connect(ui->udp_add, &QPushButton::clicked, this, &ConfigureMotionTouch::OnUDPAddServer); +    connect(ui->udp_remove, &QPushButton::clicked, this, &ConfigureMotionTouch::OnUDPDeleteServer);      connect(ui->touch_calibration_config, &QPushButton::clicked, this,              &ConfigureMotionTouch::OnConfigureTouchCalibration);      connect(ui->touch_from_button_config_btn, &QPushButton::clicked, this, @@ -187,13 +182,58 @@ void ConfigureMotionTouch::ConnectEvents() {      });  } +void ConfigureMotionTouch::OnUDPAddServer() { +    QRegExp re(tr("^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[" +                  "0-9][0-9]?)$")); // a valid ip address +    bool ok; +    QString port_text = ui->udp_port->text(); +    QString server_text = ui->udp_server->text(); +    const QString server_string = tr("%1:%2").arg(server_text, port_text); +    int port_number = port_text.toInt(&ok, 10); +    int row = udp_server_list_model->rowCount(); + +    if (!ok) { +        QMessageBox::warning(this, tr("yuzu"), tr("Port number has invalid characters")); +        return; +    } +    if (port_number < 0 || port_number > 65353) { +        QMessageBox::warning(this, tr("yuzu"), tr("Port has to be in range 0 and 65353")); +        return; +    } +    if (!re.exactMatch(server_text)) { +        QMessageBox::warning(this, tr("yuzu"), tr("IP address is not valid")); +        return; +    } +    // Search for duplicates +    for (const auto& item : udp_server_list_model->stringList()) { +        if (item == server_string) { +            QMessageBox::warning(this, tr("yuzu"), tr("This UDP server already exists")); +            return; +        } +    } +    // Limit server count to 8 +    if (row == 8) { +        QMessageBox::warning(this, tr("yuzu"), tr("Unable to add more than 8 servers")); +        return; +    } + +    udp_server_list_model->insertRows(row, 1); +    QModelIndex index = udp_server_list_model->index(row); +    udp_server_list_model->setData(index, server_string); +    ui->udp_server_list->setCurrentIndex(index); +} + +void ConfigureMotionTouch::OnUDPDeleteServer() { +    udp_server_list_model->removeRows(ui->udp_server_list->currentIndex().row(), 1); +} +  void ConfigureMotionTouch::OnCemuhookUDPTest() {      ui->udp_test->setEnabled(false);      ui->udp_test->setText(tr("Testing"));      udp_test_in_progress = true;      InputCommon::CemuhookUDP::TestCommunication( -        ui->udp_server->text().toStdString(), static_cast<u16>(ui->udp_port->text().toInt()), -        static_cast<u32>(ui->udp_pad_index->currentIndex()), 24872, +        ui->udp_server->text().toStdString(), static_cast<u16>(ui->udp_port->text().toInt()), 0, +        24872,          [this] {              LOG_INFO(Frontend, "UDP input test success");              QMetaObject::invokeMethod(this, "ShowUDPTestResult", Q_ARG(bool, true)); @@ -207,9 +247,9 @@ void ConfigureMotionTouch::OnCemuhookUDPTest() {  void ConfigureMotionTouch::OnConfigureTouchCalibration() {      ui->touch_calibration_config->setEnabled(false);      ui->touch_calibration_config->setText(tr("Configuring")); -    CalibrationConfigurationDialog dialog( -        this, ui->udp_server->text().toStdString(), static_cast<u16>(ui->udp_port->text().toUInt()), -        static_cast<u8>(ui->udp_pad_index->currentIndex()), 24872); +    CalibrationConfigurationDialog dialog(this, ui->udp_server->text().toStdString(), +                                          static_cast<u16>(ui->udp_port->text().toUInt()), 0, +                                          24872);      dialog.exec();      if (dialog.completed) {          min_x = dialog.min_x; @@ -269,7 +309,7 @@ void ConfigureMotionTouch::OnConfigureTouchFromButton() {  bool ConfigureMotionTouch::CanCloseDialog() {      if (udp_test_in_progress) { -        QMessageBox::warning(this, tr("Citra"), +        QMessageBox::warning(this, tr("yuzu"),                               tr("UDP Test or calibration configuration is in progress.<br>Please "                                  "wait for them to finish."));          return false; @@ -282,17 +322,11 @@ void ConfigureMotionTouch::ApplyConfiguration() {          return;      } -    std::string motion_engine = ui->motion_provider->currentData().toString().toStdString();      std::string touch_engine = ui->touch_provider->currentData().toString().toStdString(); -    Common::ParamPackage motion_param{}, touch_param{}; -    motion_param.Set("engine", std::move(motion_engine)); +    Common::ParamPackage touch_param{};      touch_param.Set("engine", std::move(touch_engine)); -    if (motion_engine == "motion_emu") { -        motion_param.Set("sensitivity", static_cast<float>(ui->motion_sensitivity->value())); -    } -      if (touch_engine == "cemuhookudp") {          touch_param.Set("min_x", min_x);          touch_param.Set("min_y", min_y); @@ -300,15 +334,25 @@ void ConfigureMotionTouch::ApplyConfiguration() {          touch_param.Set("max_y", max_y);      } -    Settings::values.motion_device = motion_param.Serialize();      Settings::values.touch_device = touch_param.Serialize();      Settings::values.use_touch_from_button = ui->touch_from_button_checkbox->isChecked();      Settings::values.touch_from_button_map_index = ui->touch_from_button_map->currentIndex();      Settings::values.touch_from_button_maps = touch_from_button_maps; -    Settings::values.udp_input_address = ui->udp_server->text().toStdString(); -    Settings::values.udp_input_port = static_cast<u16>(ui->udp_port->text().toInt()); -    Settings::values.udp_pad_index = static_cast<u8>(ui->udp_pad_index->currentIndex()); +    Settings::values.udp_input_servers = GetUDPServerString();      input_subsystem->ReloadInputDevices();      accept();  } + +std::string ConfigureMotionTouch::GetUDPServerString() const { +    QString input_servers; + +    for (const auto& item : udp_server_list_model->stringList()) { +        input_servers += item; +        input_servers += QLatin1Char{','}; +    } + +    // Remove last comma +    input_servers.chop(1); +    return input_servers.toStdString(); +} diff --git a/src/yuzu/configuration/configure_motion_touch.h b/src/yuzu/configuration/configure_motion_touch.h index 3d4b5d659..15d61e8ba 100644 --- a/src/yuzu/configuration/configure_motion_touch.h +++ b/src/yuzu/configuration/configure_motion_touch.h @@ -10,6 +10,7 @@  class QLabel;  class QPushButton; +class QStringListModel;  class QVBoxLayout;  namespace InputCommon { @@ -62,6 +63,8 @@ public slots:      void ApplyConfiguration();  private slots: +    void OnUDPAddServer(); +    void OnUDPDeleteServer();      void OnCemuhookUDPTest();      void OnConfigureTouchCalibration();      void OnConfigureTouchFromButton(); @@ -73,10 +76,12 @@ private:      void UpdateUiDisplay();      void ConnectEvents();      bool CanCloseDialog(); +    std::string GetUDPServerString() const;      InputCommon::InputSubsystem* input_subsystem;      std::unique_ptr<Ui::ConfigureMotionTouch> ui; +    QStringListModel* udp_server_list_model;      // Coordinate system of the CemuhookUDP touch provider      int min_x{}; diff --git a/src/yuzu/configuration/configure_motion_touch.ui b/src/yuzu/configuration/configure_motion_touch.ui index 5b78c5a4b..ebca835ac 100644 --- a/src/yuzu/configuration/configure_motion_touch.ui +++ b/src/yuzu/configuration/configure_motion_touch.ui @@ -2,41 +2,30 @@  <ui version="4.0">   <class>ConfigureMotionTouch</class>   <widget class="QDialog" name="ConfigureMotionTouch"> -  <property name="windowTitle"> -   <string>Configure Motion / Touch</string> -  </property>    <property name="geometry">     <rect>      <x>0</x>      <y>0</y>      <width>500</width> -    <height>450</height> +    <height>482</height>     </rect>    </property> +  <property name="windowTitle"> +   <string>Configure Motion / Touch</string> +  </property> +  <property name="styleSheet"> +   <string notr="true"/> +  </property>    <layout class="QVBoxLayout">     <item>      <widget class="QGroupBox" name="motion_group_box">       <property name="title"> -      <string>Motion</string> +      <string>Mouse Motion</string>       </property>       <layout class="QVBoxLayout">        <item>         <layout class="QHBoxLayout">          <item> -         <widget class="QLabel" name="motion_provider_label"> -          <property name="text"> -           <string>Motion Provider:</string> -          </property> -         </widget> -        </item> -        <item> -         <widget class="QComboBox" name="motion_provider"/> -        </item> -       </layout> -      </item> -      <item> -       <layout class="QHBoxLayout"> -        <item>           <widget class="QLabel" name="motion_sensitivity_label">            <property name="text">             <string>Sensitivity:</string> @@ -180,103 +169,171 @@         </widget>        </item>        <item> -       <layout class="QHBoxLayout"> +       <layout class="QHBoxLayout" name="horizontalLayout">          <item> -         <widget class="QLabel" name="udp_server_label"> -          <property name="text"> -           <string>Server:</string> -          </property> -         </widget> +         <widget class="QListView" name="udp_server_list"/>          </item>          <item> -         <widget class="QLineEdit" name="udp_server"> -          <property name="sizePolicy"> -           <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> -            <horstretch>0</horstretch> -            <verstretch>0</verstretch> -           </sizepolicy> +         <layout class="QVBoxLayout" name="verticalLayout"> +          <property name="leftMargin"> +           <number>0</number>            </property> -         </widget> -        </item> -       </layout> -      </item> -      <item> -       <layout class="QHBoxLayout"> -        <item> -         <widget class="QLabel" name="udp_port_label"> -          <property name="text"> -           <string>Port:</string> +          <property name="topMargin"> +           <number>0</number>            </property> -         </widget> -        </item> -        <item> -         <widget class="QLineEdit" name="udp_port"> -          <property name="sizePolicy"> -           <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> -            <horstretch>0</horstretch> -            <verstretch>0</verstretch> -           </sizepolicy> +          <property name="rightMargin"> +           <number>0</number>            </property> -         </widget> -        </item> -       </layout> -      </item> -      <item> -       <layout class="QHBoxLayout"> -        <item> -         <widget class="QLabel" name="udp_pad_index_label"> -          <property name="text"> -           <string>Pad:</string> +          <property name="bottomMargin"> +           <number>0</number>            </property> -         </widget> -        </item> -        <item> -         <widget class="QComboBox" name="udp_pad_index">            <item> -           <property name="text"> -            <string>Pad 1</string> -           </property> +           <layout class="QHBoxLayout"> +            <property name="leftMargin"> +             <number>3</number> +            </property> +            <property name="topMargin"> +             <number>3</number> +            </property> +            <property name="rightMargin"> +             <number>0</number> +            </property> +            <item> +             <widget class="QLabel" name="udp_server_label"> +              <property name="text"> +               <string>Server:</string> +              </property> +             </widget> +            </item> +            <item> +             <widget class="QLineEdit" name="udp_server"> +              <property name="sizePolicy"> +               <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> +                <horstretch>0</horstretch> +                <verstretch>0</verstretch> +               </sizepolicy> +              </property> +             </widget> +            </item> +           </layout>            </item>            <item> -           <property name="text"> -            <string>Pad 2</string> -           </property> +           <layout class="QHBoxLayout"> +            <property name="leftMargin"> +             <number>3</number> +            </property> +            <property name="rightMargin"> +             <number>0</number> +            </property> +            <item> +             <widget class="QLabel" name="udp_port_label"> +              <property name="text"> +               <string>Port:</string> +              </property> +             </widget> +            </item> +            <item> +             <widget class="QLineEdit" name="udp_port"> +              <property name="sizePolicy"> +               <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> +                <horstretch>0</horstretch> +                <verstretch>0</verstretch> +               </sizepolicy> +              </property> +             </widget> +            </item> +           </layout>            </item>            <item> -           <property name="text"> -            <string>Pad 3</string> -           </property> +           <layout class="QHBoxLayout"> +            <property name="leftMargin"> +             <number>3</number> +            </property> +            <property name="rightMargin"> +             <number>0</number> +            </property> +            <item> +             <widget class="QLabel" name="udp_learn_more"> +              <property name="text"> +               <string>Learn More</string> +              </property> +             </widget> +            </item> +            <item> +             <widget class="QPushButton" name="udp_test"> +              <property name="sizePolicy"> +               <sizepolicy hsizetype="Maximum" vsizetype="Fixed"> +                <horstretch>0</horstretch> +                <verstretch>0</verstretch> +               </sizepolicy> +              </property> +              <property name="text"> +               <string>Test</string> +              </property> +             </widget> +            </item> +            <item> +             <widget class="QPushButton" name="udp_add"> +              <property name="sizePolicy"> +               <sizepolicy hsizetype="Maximum" vsizetype="Fixed"> +                <horstretch>0</horstretch> +                <verstretch>0</verstretch> +               </sizepolicy> +              </property> +              <property name="text"> +               <string>Add Server</string> +              </property> +             </widget> +            </item> +           </layout>            </item>            <item> -           <property name="text"> -            <string>Pad 4</string> -           </property> +           <spacer name="verticalSpacer_3"> +            <property name="orientation"> +             <enum>Qt::Vertical</enum> +            </property> +            <property name="sizeHint" stdset="0"> +             <size> +              <width>20</width> +              <height>40</height> +             </size> +            </property> +           </spacer>            </item> -         </widget> -        </item> -       </layout> -      </item> -      <item> -       <layout class="QHBoxLayout"> -        <item> -         <widget class="QLabel" name="udp_learn_more"> -          <property name="text"> -           <string>Learn More</string> -          </property> -         </widget> -        </item> -        <item> -         <widget class="QPushButton" name="udp_test"> -          <property name="sizePolicy"> -           <sizepolicy hsizetype="Maximum" vsizetype="Fixed"> -            <horstretch>0</horstretch> -            <verstretch>0</verstretch> -           </sizepolicy> -          </property> -          <property name="text"> -           <string>Test</string> -          </property> -         </widget> +          <item> +           <layout class="QHBoxLayout" name="horizontalLayout_2"> +            <property name="topMargin"> +             <number>0</number> +            </property> +            <item> +             <widget class="QPushButton" name="udp_remove"> +              <property name="sizePolicy"> +               <sizepolicy hsizetype="Maximum" vsizetype="Fixed"> +                <horstretch>0</horstretch> +                <verstretch>0</verstretch> +               </sizepolicy> +              </property> +              <property name="text"> +               <string>Remove Server</string> +              </property> +             </widget> +            </item> +            <item> +             <spacer name="horizontalSpacer_2"> +              <property name="orientation"> +               <enum>Qt::Horizontal</enum> +              </property> +              <property name="sizeHint" stdset="0"> +               <size> +                <width>40</width> +                <height>20</height> +               </size> +              </property> +             </spacer> +            </item> +           </layout> +          </item> +         </layout>          </item>         </layout>        </item> @@ -312,6 +369,16 @@     <signal>accepted()</signal>     <receiver>ConfigureMotionTouch</receiver>     <slot>ApplyConfiguration()</slot> +   <hints> +    <hint type="sourcelabel"> +     <x>20</x> +     <y>20</y> +    </hint> +    <hint type="destinationlabel"> +     <x>20</x> +     <y>20</y> +    </hint> +   </hints>    </connection>   </connections>  </ui> diff --git a/src/yuzu/configuration/configure_per_game.cpp b/src/yuzu/configuration/configure_per_game.cpp index 8eac3bd9d..f598513df 100644 --- a/src/yuzu/configuration/configure_per_game.cpp +++ b/src/yuzu/configuration/configure_per_game.cpp @@ -57,7 +57,7 @@ void ConfigurePerGame::ApplyConfiguration() {      ui->graphicsAdvancedTab->ApplyConfiguration();      ui->audioTab->ApplyConfiguration(); -    Settings::Apply(); +    Settings::Apply(Core::System::GetInstance());      Settings::LogSettings();      game_config->Save(); diff --git a/src/yuzu/configuration/configure_profile_manager.cpp b/src/yuzu/configuration/configure_profile_manager.cpp index 6334c4c50..13d9a4757 100644 --- a/src/yuzu/configuration/configure_profile_manager.cpp +++ b/src/yuzu/configuration/configure_profile_manager.cpp @@ -180,7 +180,7 @@ void ConfigureProfileManager::ApplyConfiguration() {          return;      } -    Settings::Apply(); +    Settings::Apply(Core::System::GetInstance());  }  void ConfigureProfileManager::SelectUser(const QModelIndex& index) { diff --git a/src/yuzu/configuration/configure_system.cpp b/src/yuzu/configuration/configure_system.cpp index 59a58d92c..6cf2032da 100644 --- a/src/yuzu/configuration/configure_system.cpp +++ b/src/yuzu/configuration/configure_system.cpp @@ -105,16 +105,18 @@ void ConfigureSystem::SetConfiguration() {  void ConfigureSystem::ReadSystemSettings() {}  void ConfigureSystem::ApplyConfiguration() { -    // Allow setting custom RTC even if system is powered on, to allow in-game time to be fast -    // forwared +    auto& system = Core::System::GetInstance(); + +    // Allow setting custom RTC even if system is powered on, +    // to allow in-game time to be fast forwarded      if (Settings::values.custom_rtc.UsingGlobal()) {          if (ui->custom_rtc_checkbox->isChecked()) {              Settings::values.custom_rtc.SetValue(                  std::chrono::seconds(ui->custom_rtc_edit->dateTime().toSecsSinceEpoch())); -            if (Core::System::GetInstance().IsPoweredOn()) { +            if (system.IsPoweredOn()) {                  const s64 posix_time{Settings::values.custom_rtc.GetValue()->count() +                                       Service::Time::TimeManager::GetExternalTimeZoneOffset()}; -                Core::System::GetInstance().GetTimeManager().UpdateLocalSystemClockTime(posix_time); +                system.GetTimeManager().UpdateLocalSystemClockTime(posix_time);              }          } else {              Settings::values.custom_rtc.SetValue(std::nullopt); @@ -197,7 +199,7 @@ void ConfigureSystem::ApplyConfiguration() {          }      } -    Settings::Apply(); +    Settings::Apply(system);  }  void ConfigureSystem::RefreshConsoleID() { diff --git a/src/yuzu/configuration/configure_ui.cpp b/src/yuzu/configuration/configure_ui.cpp index dbe3f78c8..aed876008 100644 --- a/src/yuzu/configuration/configure_ui.cpp +++ b/src/yuzu/configuration/configure_ui.cpp @@ -9,6 +9,7 @@  #include <QDirIterator>  #include "common/common_types.h"  #include "common/file_util.h" +#include "core/core.h"  #include "core/settings.h"  #include "ui_configure_ui.h"  #include "yuzu/configuration/configure_ui.h" @@ -84,7 +85,7 @@ void ConfigureUi::ApplyConfiguration() {      UISettings::values.enable_screenshot_save_as = ui->enable_screenshot_save_as->isChecked();      Common::FS::GetUserPath(Common::FS::UserPath::ScreenshotsDir,                              ui->screenshot_path_edit->text().toStdString()); -    Settings::Apply(); +    Settings::Apply(Core::System::GetInstance());  }  void ConfigureUi::RequestGameListUpdate() { diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 805619ccf..26f5e42ed 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -172,7 +172,7 @@ void GMainWindow::ShowTelemetryCallout() {             "<br/><br/>Would you like to share your usage data with us?");      if (QMessageBox::question(this, tr("Telemetry"), telemetry_message) != QMessageBox::Yes) {          Settings::values.enable_telemetry = false; -        Settings::Apply(); +        Settings::Apply(Core::System::GetInstance());      }  } @@ -302,7 +302,7 @@ void GMainWindow::ControllerSelectorReconfigureControllers(      emit ControllerSelectorReconfigureFinished();      // Don't forget to apply settings. -    Settings::Apply(); +    Settings::Apply(Core::System::GetInstance());      config->Save();      UpdateStatusButtons(); @@ -477,11 +477,13 @@ void GMainWindow::WebBrowserOpenPage(std::string_view filename, std::string_view  #else  void GMainWindow::WebBrowserOpenPage(std::string_view filename, std::string_view additional_args) { +#ifndef __linux__      QMessageBox::warning(          this, tr("Web Applet"),          tr("This version of yuzu was built without QtWebEngine support, meaning that yuzu cannot "             "properly display the game manual or web page requested."),          QMessageBox::Ok, QMessageBox::Ok); +#endif      LOG_INFO(Frontend,               "(STUBBED) called - Missing QtWebEngine dependency needed to open website page at " @@ -571,11 +573,11 @@ void GMainWindow::InitializeWidgets() {          if (emulation_running) {              return;          } -        bool is_async = !Settings::values.use_asynchronous_gpu_emulation.GetValue() || -                        Settings::values.use_multi_core.GetValue(); +        const bool is_async = !Settings::values.use_asynchronous_gpu_emulation.GetValue() || +                              Settings::values.use_multi_core.GetValue();          Settings::values.use_asynchronous_gpu_emulation.SetValue(is_async);          async_status_button->setChecked(Settings::values.use_asynchronous_gpu_emulation.GetValue()); -        Settings::Apply(); +        Settings::Apply(Core::System::GetInstance());      });      async_status_button->setText(tr("ASYNC"));      async_status_button->setCheckable(true); @@ -590,12 +592,12 @@ void GMainWindow::InitializeWidgets() {              return;          }          Settings::values.use_multi_core.SetValue(!Settings::values.use_multi_core.GetValue()); -        bool is_async = Settings::values.use_asynchronous_gpu_emulation.GetValue() || -                        Settings::values.use_multi_core.GetValue(); +        const bool is_async = Settings::values.use_asynchronous_gpu_emulation.GetValue() || +                              Settings::values.use_multi_core.GetValue();          Settings::values.use_asynchronous_gpu_emulation.SetValue(is_async);          async_status_button->setChecked(Settings::values.use_asynchronous_gpu_emulation.GetValue());          multicore_status_button->setChecked(Settings::values.use_multi_core.GetValue()); -        Settings::Apply(); +        Settings::Apply(Core::System::GetInstance());      });      multicore_status_button->setText(tr("MULTICORE"));      multicore_status_button->setCheckable(true); @@ -630,7 +632,7 @@ void GMainWindow::InitializeWidgets() {              Settings::values.renderer_backend.SetValue(Settings::RendererBackend::OpenGL);          } -        Settings::Apply(); +        Settings::Apply(Core::System::GetInstance());      });  #endif // HAS_VULKAN      statusBar()->insertPermanentWidget(0, renderer_status_button); @@ -1342,12 +1344,12 @@ void GMainWindow::OnGameListOpenFolder(u64 program_id, GameListOpenTarget target              const auto user_id = manager.GetUser(static_cast<std::size_t>(index));              ASSERT(user_id);              path = nand_dir + FileSys::SaveDataFactory::GetFullPath( -                                  FileSys::SaveDataSpaceId::NandUser, +                                  system, FileSys::SaveDataSpaceId::NandUser,                                    FileSys::SaveDataType::SaveData, program_id, user_id->uuid, 0);          } else {              // Device save data              path = nand_dir + FileSys::SaveDataFactory::GetFullPath( -                                  FileSys::SaveDataSpaceId::NandUser, +                                  system, FileSys::SaveDataSpaceId::NandUser,                                    FileSys::SaveDataType::SaveData, program_id, {}, 0);          } @@ -2130,14 +2132,14 @@ void GMainWindow::OnPauseGame() {  }  void GMainWindow::OnStopGame() { -    Core::System& system{Core::System::GetInstance()}; +    auto& system{Core::System::GetInstance()};      if (system.GetExitLock() && !ConfirmForceLockedExit()) {          return;      }      ShutdownGame(); -    Settings::RestoreGlobalState(); +    Settings::RestoreGlobalState(system.IsPoweredOn());      UpdateStatusButtons();  } @@ -2312,10 +2314,11 @@ void GMainWindow::OnConfigurePerGame() {  void GMainWindow::OpenPerGameConfiguration(u64 title_id, const std::string& file_name) {      const auto v_file = Core::GetGameFileFromPath(vfs, file_name); +    const auto& system = Core::System::GetInstance();      ConfigurePerGame dialog(this, title_id);      dialog.LoadFromFile(v_file); -    auto result = dialog.exec(); +    const auto result = dialog.exec();      if (result == QDialog::Accepted) {          dialog.ApplyConfiguration(); @@ -2325,13 +2328,14 @@ void GMainWindow::OpenPerGameConfiguration(u64 title_id, const std::string& file          }          // Do not cause the global config to write local settings into the config file -        Settings::RestoreGlobalState(); +        const bool is_powered_on = system.IsPoweredOn(); +        Settings::RestoreGlobalState(is_powered_on); -        if (!Core::System::GetInstance().IsPoweredOn()) { +        if (!is_powered_on) {              config->Save();          }      } else { -        Settings::RestoreGlobalState(); +        Settings::RestoreGlobalState(system.IsPoweredOn());      }  } @@ -2602,7 +2606,7 @@ void GMainWindow::OnCoreError(Core::System::ResultStatus result, std::string det          if (emu_thread) {              ShutdownGame(); -            Settings::RestoreGlobalState(); +            Settings::RestoreGlobalState(Core::System::GetInstance().IsPoweredOn());              UpdateStatusButtons();          }      } else { @@ -2774,7 +2778,7 @@ void GMainWindow::closeEvent(QCloseEvent* event) {      if (emu_thread != nullptr) {          ShutdownGame(); -        Settings::RestoreGlobalState(); +        Settings::RestoreGlobalState(Core::System::GetInstance().IsPoweredOn());          UpdateStatusButtons();      } | 
