diff options
Diffstat (limited to 'src/yuzu')
| -rw-r--r-- | src/yuzu/applets/profile_select.cpp | 2 | ||||
| -rw-r--r-- | src/yuzu/bootmanager.cpp | 78 | ||||
| -rw-r--r-- | src/yuzu/bootmanager.h | 8 | ||||
| -rw-r--r-- | src/yuzu/configuration/config.cpp | 15 | ||||
| -rw-r--r-- | src/yuzu/configuration/configure_dialog.cpp | 22 | ||||
| -rw-r--r-- | src/yuzu/configuration/configure_input_player.cpp | 10 | ||||
| -rw-r--r-- | src/yuzu/configuration/configure_motion_touch.cpp | 63 | ||||
| -rw-r--r-- | src/yuzu/configuration/configure_motion_touch.ui | 16 | ||||
| -rw-r--r-- | src/yuzu/configuration/configure_profile_manager.cpp | 6 | ||||
| -rw-r--r-- | src/yuzu/configuration/configure_service.cpp | 2 | ||||
| -rw-r--r-- | src/yuzu/configuration/configure_touchscreen_advanced.cpp | 3 | ||||
| -rw-r--r-- | src/yuzu/configuration/configure_touchscreen_advanced.ui | 29 | ||||
| -rw-r--r-- | src/yuzu/debugger/wait_tree.cpp | 128 | ||||
| -rw-r--r-- | src/yuzu/debugger/wait_tree.h | 17 | ||||
| -rw-r--r-- | src/yuzu/game_list.cpp | 60 | ||||
| -rw-r--r-- | src/yuzu/game_list_p.h | 2 |
16 files changed, 223 insertions, 238 deletions
diff --git a/src/yuzu/applets/profile_select.cpp b/src/yuzu/applets/profile_select.cpp index 4bf2bfd40..0a4c48b3d 100644 --- a/src/yuzu/applets/profile_select.cpp +++ b/src/yuzu/applets/profile_select.cpp @@ -93,7 +93,7 @@ QtProfileSelectionDialog::QtProfileSelectionDialog(QWidget* parent) const auto& profiles = profile_manager->GetAllUsers(); for (const auto& user : profiles) { - Service::Account::ProfileBase profile; + Service::Account::ProfileBase profile{}; if (!profile_manager->GetProfileBase(user, profile)) continue; diff --git a/src/yuzu/bootmanager.cpp b/src/yuzu/bootmanager.cpp index 85ee2577d..4528eb196 100644 --- a/src/yuzu/bootmanager.cpp +++ b/src/yuzu/bootmanager.cpp @@ -290,8 +290,8 @@ GRenderWindow::GRenderWindow(GMainWindow* parent, EmuThread* emu_thread_, QString::fromUtf8(Common::g_scm_branch), QString::fromUtf8(Common::g_scm_desc))); setAttribute(Qt::WA_AcceptTouchEvents); - auto layout = new QHBoxLayout(this); - layout->setMargin(0); + auto* layout = new QHBoxLayout(this); + layout->setContentsMargins(0, 0, 0, 0); setLayout(layout); input_subsystem->Initialize(); @@ -394,7 +394,7 @@ void GRenderWindow::mousePressEvent(QMouseEvent* event) { input_subsystem->GetMouse()->PressButton(x, y, event->button()); if (event->button() == Qt::LeftButton) { - this->TouchPressed(x, y); + this->TouchPressed(x, y, 0); } emit MouseActivity(); @@ -409,7 +409,7 @@ 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); + this->TouchMoved(x, y, 0); emit MouseActivity(); } @@ -423,36 +423,72 @@ void GRenderWindow::mouseReleaseEvent(QMouseEvent* event) { input_subsystem->GetMouse()->ReleaseButton(event->button()); if (event->button() == Qt::LeftButton) { - this->TouchReleased(); + this->TouchReleased(0); } } void GRenderWindow::TouchBeginEvent(const QTouchEvent* event) { - // TouchBegin always has exactly one touch point, so take the .first() - const auto [x, y] = ScaleTouch(event->touchPoints().first().pos()); - this->TouchPressed(x, y); + QList<QTouchEvent::TouchPoint> touch_points = event->touchPoints(); + for (const auto& touch_point : touch_points) { + if (!TouchUpdate(touch_point)) { + TouchStart(touch_point); + } + } } void GRenderWindow::TouchUpdateEvent(const QTouchEvent* event) { - QPointF pos; - int active_points = 0; - - // average all active touch points - for (const auto& tp : event->touchPoints()) { - if (tp.state() & (Qt::TouchPointPressed | Qt::TouchPointMoved | Qt::TouchPointStationary)) { - active_points++; - pos += tp.pos(); + QList<QTouchEvent::TouchPoint> touch_points = event->touchPoints(); + for (const auto& touch_point : touch_points) { + if (!TouchUpdate(touch_point)) { + TouchStart(touch_point); } } + // Release all inactive points + for (std::size_t id = 0; id < touch_ids.size(); ++id) { + if (!TouchExist(touch_ids[id], touch_points)) { + touch_ids[id] = 0; + this->TouchReleased(id + 1); + } + } +} - pos /= active_points; +void GRenderWindow::TouchEndEvent() { + for (std::size_t id = 0; id < touch_ids.size(); ++id) { + if (touch_ids[id] != 0) { + touch_ids[id] = 0; + this->TouchReleased(id + 1); + } + } +} - const auto [x, y] = ScaleTouch(pos); - this->TouchMoved(x, y); +bool GRenderWindow::TouchStart(const QTouchEvent::TouchPoint& touch_point) { + for (std::size_t id = 0; id < touch_ids.size(); ++id) { + if (touch_ids[id] == 0) { + touch_ids[id] = touch_point.id() + 1; + const auto [x, y] = ScaleTouch(touch_point.pos()); + this->TouchPressed(x, y, id + 1); + return true; + } + } + return false; } -void GRenderWindow::TouchEndEvent() { - this->TouchReleased(); +bool GRenderWindow::TouchUpdate(const QTouchEvent::TouchPoint& touch_point) { + for (std::size_t id = 0; id < touch_ids.size(); ++id) { + if (touch_ids[id] == static_cast<std::size_t>(touch_point.id() + 1)) { + const auto [x, y] = ScaleTouch(touch_point.pos()); + this->TouchMoved(x, y, id + 1); + return true; + } + } + return false; +} + +bool GRenderWindow::TouchExist(std::size_t id, + const QList<QTouchEvent::TouchPoint>& touch_points) const { + return std::any_of(touch_points.begin(), touch_points.end(), [id](const auto& point) { + return id == static_cast<std::size_t>(point.id() + 1); + }); } bool GRenderWindow::event(QEvent* event) { diff --git a/src/yuzu/bootmanager.h b/src/yuzu/bootmanager.h index 339095509..b5ec7de07 100644 --- a/src/yuzu/bootmanager.h +++ b/src/yuzu/bootmanager.h @@ -11,6 +11,7 @@ #include <QImage> #include <QThread> +#include <QTouchEvent> #include <QWidget> #include <QWindow> @@ -21,7 +22,6 @@ class GRenderWindow; class GMainWindow; class QKeyEvent; -class QTouchEvent; class QStringList; namespace InputCommon { @@ -191,6 +191,10 @@ private: void TouchUpdateEvent(const QTouchEvent* event); void TouchEndEvent(); + bool TouchStart(const QTouchEvent::TouchPoint& touch_point); + bool TouchUpdate(const QTouchEvent::TouchPoint& touch_point); + bool TouchExist(std::size_t id, const QList<QTouchEvent::TouchPoint>& touch_points) const; + void OnMinimalClientAreaChangeRequest(std::pair<u32, u32> minimal_size) override; bool InitializeOpenGL(); @@ -215,6 +219,8 @@ private: bool first_frame = false; + std::array<std::size_t, 16> touch_ids{}; + protected: void showEvent(QShowEvent* event) override; bool eventFilter(QObject* object, QEvent* event) override; diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp index cda448718..8d85a1986 100644 --- a/src/yuzu/configuration/config.cpp +++ b/src/yuzu/configuration/config.cpp @@ -464,13 +464,7 @@ void Config::ReadMouseValues() { void Config::ReadTouchscreenValues() { Settings::values.touchscreen.enabled = ReadSetting(QStringLiteral("touchscreen_enabled"), true).toBool(); - Settings::values.touchscreen.device = - ReadSetting(QStringLiteral("touchscreen_device"), QStringLiteral("engine:emu_window")) - .toString() - .toStdString(); - Settings::values.touchscreen.finger = - ReadSetting(QStringLiteral("touchscreen_finger"), 0).toUInt(); Settings::values.touchscreen.rotation_angle = ReadSetting(QStringLiteral("touchscreen_angle"), 0).toUInt(); Settings::values.touchscreen.diameter_x = @@ -563,7 +557,8 @@ void Config::ReadMotionTouchValues() { .toString() .toStdString(); Settings::values.touch_device = - ReadSetting(QStringLiteral("touch_device"), QStringLiteral("engine:emu_window")) + ReadSetting(QStringLiteral("touch_device"), + QStringLiteral("min_x:100,min_y:50,max_x:1800,max_y:850")) .toString() .toStdString(); Settings::values.use_touch_from_button = @@ -1005,7 +1000,8 @@ void Config::SavePlayerValue(std::size_t player_index) { static_cast<u8>(Settings::ControllerType::ProController)); if (!player_prefix.isEmpty()) { - WriteSetting(QStringLiteral("%1connected").arg(player_prefix), player.connected, false); + WriteSetting(QStringLiteral("%1connected").arg(player_prefix), player.connected, + player_index == 0); WriteSetting(QStringLiteral("%1vibration_enabled").arg(player_prefix), player.vibration_enabled, true); WriteSetting(QStringLiteral("%1vibration_strength").arg(player_prefix), @@ -1087,10 +1083,7 @@ void Config::SaveTouchscreenValues() { const auto& touchscreen = Settings::values.touchscreen; WriteSetting(QStringLiteral("touchscreen_enabled"), touchscreen.enabled, true); - WriteSetting(QStringLiteral("touchscreen_device"), QString::fromStdString(touchscreen.device), - QStringLiteral("engine:emu_window")); - WriteSetting(QStringLiteral("touchscreen_finger"), touchscreen.finger, 0); WriteSetting(QStringLiteral("touchscreen_angle"), touchscreen.rotation_angle, 0); WriteSetting(QStringLiteral("touchscreen_diameter_x"), touchscreen.diameter_x, 15); WriteSetting(QStringLiteral("touchscreen_diameter_y"), touchscreen.diameter_y, 15); diff --git a/src/yuzu/configuration/configure_dialog.cpp b/src/yuzu/configuration/configure_dialog.cpp index b33f8437a..d6b17a28d 100644 --- a/src/yuzu/configuration/configure_dialog.cpp +++ b/src/yuzu/configuration/configure_dialog.cpp @@ -117,31 +117,13 @@ void ConfigureDialog::UpdateVisibleTabs() { return; } - const std::map<QWidget*, QString> widgets = { - {ui->generalTab, tr("General")}, - {ui->systemTab, tr("System")}, - {ui->profileManagerTab, tr("Profiles")}, - {ui->inputTab, tr("Controls")}, - {ui->hotkeysTab, tr("Hotkeys")}, - {ui->cpuTab, tr("CPU")}, - {ui->cpuDebugTab, tr("Debug")}, - {ui->graphicsTab, tr("Graphics")}, - {ui->graphicsAdvancedTab, tr("Advanced")}, - {ui->audioTab, tr("Audio")}, - {ui->debugTab, tr("Debug")}, - {ui->webTab, tr("Web")}, - {ui->uiTab, tr("UI")}, - {ui->filesystemTab, tr("Filesystem")}, - {ui->serviceTab, tr("Services")}, - }; - [[maybe_unused]] const QSignalBlocker blocker(ui->tabWidget); ui->tabWidget->clear(); - const QList<QWidget*> tabs = qvariant_cast<QList<QWidget*>>(items[0]->data(Qt::UserRole)); + const auto tabs = qvariant_cast<QList<QWidget*>>(items[0]->data(Qt::UserRole)); - for (const auto tab : tabs) { + for (auto* const tab : tabs) { ui->tabWidget->addTab(tab, tab->accessibleName()); } } diff --git a/src/yuzu/configuration/configure_input_player.cpp b/src/yuzu/configuration/configure_input_player.cpp index 46ea026e4..13f0351d4 100644 --- a/src/yuzu/configuration/configure_input_player.cpp +++ b/src/yuzu/configuration/configure_input_player.cpp @@ -575,6 +575,16 @@ void ConfigureInputPlayer::ApplyConfiguration() { std::transform(motions_param.begin(), motions_param.end(), motions.begin(), [](const Common::ParamPackage& param) { return param.Serialize(); }); + + // Apply configuration for handheld + if (player_index == 0) { + auto& handheld = Settings::values.players.GetValue()[HANDHELD_INDEX]; + if (player.controller_type == Settings::ControllerType::Handheld) { + handheld = player; + } + handheld.connected = ui->groupConnectedController->isChecked() && + player.controller_type == Settings::ControllerType::Handheld; + } } void ConfigureInputPlayer::TryConnectSelectedController() { diff --git a/src/yuzu/configuration/configure_motion_touch.cpp b/src/yuzu/configuration/configure_motion_touch.cpp index eb8eacbf9..1f2b792e4 100644 --- a/src/yuzu/configuration/configure_motion_touch.cpp +++ b/src/yuzu/configuration/configure_motion_touch.cpp @@ -4,12 +4,15 @@ #include <array> #include <sstream> + #include <QCloseEvent> #include <QLabel> #include <QMessageBox> #include <QPushButton> +#include <QRegularExpression> #include <QStringListModel> #include <QVBoxLayout> + #include "common/logging/log.h" #include "core/settings.h" #include "input_common/main.h" @@ -78,19 +81,11 @@ void CalibrationConfigurationDialog::UpdateButtonText(const QString& text) { cancel_button->setText(text); } -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")}, -}}; - ConfigureMotionTouch::ConfigureMotionTouch(QWidget* parent, InputCommon::InputSubsystem* input_subsystem_) : QDialog(parent), input_subsystem{input_subsystem_}, ui(std::make_unique<Ui::ConfigureMotionTouch>()) { ui->setupUi(this); - for (const auto& [provider, name] : TouchProviders) { - ui->touch_provider->addItem(tr(name), QString::fromUtf8(provider)); - } ui->udp_learn_more->setOpenExternalLinks(true); ui->udp_learn_more->setText( @@ -109,11 +104,7 @@ ConfigureMotionTouch::~ConfigureMotionTouch() = default; void ConfigureMotionTouch::SetConfiguration() { const Common::ParamPackage motion_param(Settings::values.motion_device); const Common::ParamPackage touch_param(Settings::values.touch_device); - const std::string motion_engine = motion_param.Get("engine", "motion_emu"); - const std::string touch_engine = touch_param.Get("engine", "emu_window"); - ui->touch_provider->setCurrentIndex( - ui->touch_provider->findData(QString::fromStdString(touch_engine))); ui->touch_from_button_checkbox->setChecked(Settings::values.use_touch_from_button); touch_from_button_maps = Settings::values.touch_from_button_maps; for (const auto& touch_map : touch_from_button_maps) { @@ -146,30 +137,21 @@ void ConfigureMotionTouch::SetConfiguration() { } void ConfigureMotionTouch::UpdateUiDisplay() { - const QString touch_engine = ui->touch_provider->currentData().toString(); const QString cemuhook_udp = QStringLiteral("cemuhookudp"); ui->motion_sensitivity_label->setVisible(true); ui->motion_sensitivity->setVisible(true); - if (touch_engine == cemuhook_udp) { - ui->touch_calibration->setVisible(true); - ui->touch_calibration_config->setVisible(true); - ui->touch_calibration_label->setVisible(true); - ui->touch_calibration->setText( - QStringLiteral("(%1, %2) - (%3, %4)").arg(min_x).arg(min_y).arg(max_x).arg(max_y)); - } else { - ui->touch_calibration->setVisible(false); - ui->touch_calibration_config->setVisible(false); - ui->touch_calibration_label->setVisible(false); - } + ui->touch_calibration->setVisible(true); + ui->touch_calibration_config->setVisible(true); + ui->touch_calibration_label->setVisible(true); + ui->touch_calibration->setText( + QStringLiteral("(%1, %2) - (%3, %4)").arg(min_x).arg(min_y).arg(max_x).arg(max_y)); ui->udp_config_group_box->setVisible(true); } void ConfigureMotionTouch::ConnectEvents() { - 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); @@ -185,14 +167,15 @@ void ConfigureMotionTouch::ConnectEvents() { } void ConfigureMotionTouch::OnUDPAddServer() { - QRegExp re(tr(R"re(^(?:(?: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]?)$)re")); // a valid ip address + // Validator for IP address + const QRegularExpression re(QStringLiteral( + R"re(^(?:(?: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]?)$)re")); bool ok; - QString port_text = ui->udp_port->text(); - QString server_text = ui->udp_server->text(); + const QString port_text = ui->udp_port->text(); + const 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(); + const int port_number = port_text.toInt(&ok, 10); + const int row = udp_server_list_model->rowCount(); if (!ok) { QMessageBox::warning(this, tr("yuzu"), tr("Port number has invalid characters")); @@ -202,7 +185,7 @@ void ConfigureMotionTouch::OnUDPAddServer() { QMessageBox::warning(this, tr("yuzu"), tr("Port has to be in range 0 and 65353")); return; } - if (!re.exactMatch(server_text)) { + if (!re.match(server_text).hasMatch()) { QMessageBox::warning(this, tr("yuzu"), tr("IP address is not valid")); return; } @@ -324,17 +307,11 @@ void ConfigureMotionTouch::ApplyConfiguration() { return; } - std::string touch_engine = ui->touch_provider->currentData().toString().toStdString(); - Common::ParamPackage touch_param{}; - touch_param.Set("engine", std::move(touch_engine)); - - if (touch_engine == "cemuhookudp") { - touch_param.Set("min_x", min_x); - touch_param.Set("min_y", min_y); - touch_param.Set("max_x", max_x); - touch_param.Set("max_y", max_y); - } + touch_param.Set("min_x", min_x); + touch_param.Set("min_y", min_y); + touch_param.Set("max_x", max_x); + touch_param.Set("max_y", max_y); Settings::values.touch_device = touch_param.Serialize(); Settings::values.use_touch_from_button = ui->touch_from_button_checkbox->isChecked(); diff --git a/src/yuzu/configuration/configure_motion_touch.ui b/src/yuzu/configuration/configure_motion_touch.ui index ebca835ac..1e35ea946 100644 --- a/src/yuzu/configuration/configure_motion_touch.ui +++ b/src/yuzu/configuration/configure_motion_touch.ui @@ -68,23 +68,9 @@ <item> <layout class="QHBoxLayout"> <item> - <widget class="QLabel" name="touch_provider_label"> - <property name="text"> - <string>Touch Provider:</string> - </property> - </widget> - </item> - <item> - <widget class="QComboBox" name="touch_provider"/> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout"> - <item> <widget class="QLabel" name="touch_calibration_label"> <property name="text"> - <string>Calibration:</string> + <string>UDP Calibration:</string> </property> </widget> </item> diff --git a/src/yuzu/configuration/configure_profile_manager.cpp b/src/yuzu/configuration/configure_profile_manager.cpp index 13d9a4757..d102a43af 100644 --- a/src/yuzu/configuration/configure_profile_manager.cpp +++ b/src/yuzu/configuration/configure_profile_manager.cpp @@ -40,7 +40,7 @@ QString GetImagePath(Common::UUID uuid) { } QString GetAccountUsername(const Service::Account::ProfileManager& manager, Common::UUID uuid) { - Service::Account::ProfileBase profile; + Service::Account::ProfileBase profile{}; if (!manager.GetProfileBase(uuid, profile)) { return {}; } @@ -147,7 +147,7 @@ void ConfigureProfileManager::SetConfiguration() { void ConfigureProfileManager::PopulateUserList() { const auto& profiles = profile_manager->GetAllUsers(); for (const auto& user : profiles) { - Service::Account::ProfileBase profile; + Service::Account::ProfileBase profile{}; if (!profile_manager->GetProfileBase(user, profile)) continue; @@ -212,7 +212,7 @@ void ConfigureProfileManager::RenameUser() { const auto uuid = profile_manager->GetUser(user); ASSERT(uuid); - Service::Account::ProfileBase profile; + Service::Account::ProfileBase profile{}; if (!profile_manager->GetProfileBase(*uuid, profile)) return; diff --git a/src/yuzu/configuration/configure_service.cpp b/src/yuzu/configuration/configure_service.cpp index 0de7a4f0b..b580cfff2 100644 --- a/src/yuzu/configuration/configure_service.cpp +++ b/src/yuzu/configuration/configure_service.cpp @@ -9,6 +9,7 @@ #include "ui_configure_service.h" #include "yuzu/configuration/configure_service.h" +#ifdef YUZU_ENABLE_BOXCAT namespace { QString FormatEventStatusString(const Service::BCAT::EventStatus& status) { QString out; @@ -32,6 +33,7 @@ QString FormatEventStatusString(const Service::BCAT::EventStatus& status) { return out; } } // Anonymous namespace +#endif ConfigureService::ConfigureService(QWidget* parent) : QWidget(parent), ui(std::make_unique<Ui::ConfigureService>()) { diff --git a/src/yuzu/configuration/configure_touchscreen_advanced.cpp b/src/yuzu/configuration/configure_touchscreen_advanced.cpp index 7d7cc00b7..29c86c7bc 100644 --- a/src/yuzu/configuration/configure_touchscreen_advanced.cpp +++ b/src/yuzu/configuration/configure_touchscreen_advanced.cpp @@ -33,21 +33,18 @@ void ConfigureTouchscreenAdvanced::RetranslateUI() { } void ConfigureTouchscreenAdvanced::ApplyConfiguration() { - Settings::values.touchscreen.finger = ui->finger_box->value(); Settings::values.touchscreen.diameter_x = ui->diameter_x_box->value(); Settings::values.touchscreen.diameter_y = ui->diameter_y_box->value(); Settings::values.touchscreen.rotation_angle = ui->angle_box->value(); } void ConfigureTouchscreenAdvanced::LoadConfiguration() { - ui->finger_box->setValue(Settings::values.touchscreen.finger); ui->diameter_x_box->setValue(Settings::values.touchscreen.diameter_x); ui->diameter_y_box->setValue(Settings::values.touchscreen.diameter_y); ui->angle_box->setValue(Settings::values.touchscreen.rotation_angle); } void ConfigureTouchscreenAdvanced::RestoreDefaults() { - ui->finger_box->setValue(0); ui->diameter_x_box->setValue(15); ui->diameter_y_box->setValue(15); ui->angle_box->setValue(0); diff --git a/src/yuzu/configuration/configure_touchscreen_advanced.ui b/src/yuzu/configuration/configure_touchscreen_advanced.ui index 30ceccddb..88e7cf050 100644 --- a/src/yuzu/configuration/configure_touchscreen_advanced.ui +++ b/src/yuzu/configuration/configure_touchscreen_advanced.ui @@ -65,20 +65,13 @@ </property> </spacer> </item> - <item row="2" column="1"> + <item row="1" column="1"> <widget class="QLabel" name="label_4"> <property name="text"> <string>Touch Diameter Y</string> </property> </widget> </item> - <item row="0" column="1"> - <widget class="QLabel" name="label"> - <property name="text"> - <string>Finger</string> - </property> - </widget> - </item> <item row="0" column="3"> <spacer name="horizontalSpacer_2"> <property name="orientation"> @@ -92,37 +85,27 @@ </property> </spacer> </item> - <item row="1" column="1"> + <item row="0" column="1"> <widget class="QLabel" name="label_3"> <property name="text"> <string>Touch Diameter X</string> </property> </widget> </item> - <item row="0" column="2"> - <widget class="QSpinBox" name="finger_box"> - <property name="minimumSize"> - <size> - <width>80</width> - <height>0</height> - </size> - </property> - </widget> - </item> - <item row="3" column="1"> + <item row="2" column="1"> <widget class="QLabel" name="label_5"> <property name="text"> <string>Rotational Angle</string> </property> </widget> </item> - <item row="1" column="2"> + <item row="0" column="2"> <widget class="QSpinBox" name="diameter_x_box"/> </item> - <item row="2" column="2"> + <item row="1" column="2"> <widget class="QSpinBox" name="diameter_y_box"/> </item> - <item row="3" column="2"> + <item row="2" column="2"> <widget class="QSpinBox" name="angle_box"/> </item> </layout> diff --git a/src/yuzu/debugger/wait_tree.cpp b/src/yuzu/debugger/wait_tree.cpp index 0925c10b4..a93b5d3c2 100644 --- a/src/yuzu/debugger/wait_tree.cpp +++ b/src/yuzu/debugger/wait_tree.cpp @@ -14,10 +14,10 @@ #include "core/core.h" #include "core/hle/kernel/handle_table.h" #include "core/hle/kernel/k_scheduler.h" -#include "core/hle/kernel/mutex.h" +#include "core/hle/kernel/k_synchronization_object.h" #include "core/hle/kernel/process.h" #include "core/hle/kernel/readable_event.h" -#include "core/hle/kernel/synchronization_object.h" +#include "core/hle/kernel/svc_common.h" #include "core/hle/kernel/thread.h" #include "core/memory.h" @@ -116,7 +116,7 @@ QString WaitTreeText::GetText() const { WaitTreeMutexInfo::WaitTreeMutexInfo(VAddr mutex_address, const Kernel::HandleTable& handle_table) : mutex_address(mutex_address) { mutex_value = Core::System::GetInstance().Memory().Read32(mutex_address); - owner_handle = static_cast<Kernel::Handle>(mutex_value & Kernel::Mutex::MutexOwnerMask); + owner_handle = static_cast<Kernel::Handle>(mutex_value & Kernel::Svc::HandleWaitMask); owner = handle_table.Get<Kernel::Thread>(owner_handle); } @@ -127,7 +127,7 @@ QString WaitTreeMutexInfo::GetText() const { } std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeMutexInfo::GetChildren() const { - const bool has_waiters = (mutex_value & Kernel::Mutex::MutexHasWaitersFlag) != 0; + const bool has_waiters = (mutex_value & Kernel::Svc::HandleWaitMask) != 0; std::vector<std::unique_ptr<WaitTreeItem>> list; list.push_back(std::make_unique<WaitTreeText>(tr("has waiters: %1").arg(has_waiters))); @@ -169,7 +169,8 @@ std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeCallstack::GetChildren() cons return list; } -WaitTreeSynchronizationObject::WaitTreeSynchronizationObject(const Kernel::SynchronizationObject& o) +WaitTreeSynchronizationObject::WaitTreeSynchronizationObject( + const Kernel::KSynchronizationObject& o) : object(o) {} WaitTreeSynchronizationObject::~WaitTreeSynchronizationObject() = default; @@ -188,7 +189,7 @@ QString WaitTreeSynchronizationObject::GetText() const { } std::unique_ptr<WaitTreeSynchronizationObject> WaitTreeSynchronizationObject::make( - const Kernel::SynchronizationObject& object) { + const Kernel::KSynchronizationObject& object) { switch (object.GetHandleType()) { case Kernel::HandleType::ReadableEvent: return std::make_unique<WaitTreeEvent>(static_cast<const Kernel::ReadableEvent&>(object)); @@ -202,7 +203,7 @@ std::unique_ptr<WaitTreeSynchronizationObject> WaitTreeSynchronizationObject::ma std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeSynchronizationObject::GetChildren() const { std::vector<std::unique_ptr<WaitTreeItem>> list; - const auto& threads = object.GetWaitingThreads(); + const auto& threads = object.GetWaitingThreadsForDebugging(); if (threads.empty()) { list.push_back(std::make_unique<WaitTreeText>(tr("waited by no thread"))); } else { @@ -211,8 +212,8 @@ std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeSynchronizationObject::GetChi return list; } -WaitTreeObjectList::WaitTreeObjectList( - const std::vector<std::shared_ptr<Kernel::SynchronizationObject>>& list, bool w_all) +WaitTreeObjectList::WaitTreeObjectList(const std::vector<Kernel::KSynchronizationObject*>& list, + bool w_all) : object_list(list), wait_all(w_all) {} WaitTreeObjectList::~WaitTreeObjectList() = default; @@ -237,8 +238,8 @@ WaitTreeThread::~WaitTreeThread() = default; QString WaitTreeThread::GetText() const { const auto& thread = static_cast<const Kernel::Thread&>(object); QString status; - switch (thread.GetStatus()) { - case Kernel::ThreadStatus::Ready: + switch (thread.GetState()) { + case Kernel::ThreadState::Runnable: if (!thread.IsPaused()) { if (thread.WasRunning()) { status = tr("running"); @@ -249,35 +250,39 @@ QString WaitTreeThread::GetText() const { status = tr("paused"); } break; - case Kernel::ThreadStatus::Paused: - status = tr("paused"); - break; - case Kernel::ThreadStatus::WaitHLEEvent: - status = tr("waiting for HLE return"); - break; - case Kernel::ThreadStatus::WaitSleep: - status = tr("sleeping"); - break; - case Kernel::ThreadStatus::WaitIPC: - status = tr("waiting for IPC reply"); - break; - case Kernel::ThreadStatus::WaitSynch: - status = tr("waiting for objects"); - break; - case Kernel::ThreadStatus::WaitMutex: - status = tr("waiting for mutex"); - break; - case Kernel::ThreadStatus::WaitCondVar: - status = tr("waiting for condition variable"); + case Kernel::ThreadState::Waiting: + switch (thread.GetWaitReasonForDebugging()) { + case Kernel::ThreadWaitReasonForDebugging::Sleep: + status = tr("sleeping"); + break; + case Kernel::ThreadWaitReasonForDebugging::IPC: + status = tr("waiting for IPC reply"); + break; + case Kernel::ThreadWaitReasonForDebugging::Synchronization: + status = tr("waiting for objects"); + break; + case Kernel::ThreadWaitReasonForDebugging::ConditionVar: + status = tr("waiting for condition variable"); + break; + case Kernel::ThreadWaitReasonForDebugging::Arbitration: + status = tr("waiting for address arbiter"); + break; + case Kernel::ThreadWaitReasonForDebugging::Suspended: + status = tr("waiting for suspend resume"); + break; + default: + status = tr("waiting"); + break; + } break; - case Kernel::ThreadStatus::WaitArb: - status = tr("waiting for address arbiter"); + case Kernel::ThreadState::Initialized: + status = tr("initialized"); break; - case Kernel::ThreadStatus::Dormant: - status = tr("dormant"); + case Kernel::ThreadState::Terminated: + status = tr("terminated"); break; - case Kernel::ThreadStatus::Dead: - status = tr("dead"); + default: + status = tr("unknown"); break; } @@ -293,8 +298,8 @@ QColor WaitTreeThread::GetColor() const { const std::size_t color_index = IsDarkTheme() ? 1 : 0; const auto& thread = static_cast<const Kernel::Thread&>(object); - switch (thread.GetStatus()) { - case Kernel::ThreadStatus::Ready: + switch (thread.GetState()) { + case Kernel::ThreadState::Runnable: if (!thread.IsPaused()) { if (thread.WasRunning()) { return QColor(WaitTreeColors[0][color_index]); @@ -304,21 +309,24 @@ QColor WaitTreeThread::GetColor() const { } else { return QColor(WaitTreeColors[2][color_index]); } - case Kernel::ThreadStatus::Paused: - return QColor(WaitTreeColors[3][color_index]); - case Kernel::ThreadStatus::WaitHLEEvent: - case Kernel::ThreadStatus::WaitIPC: - return QColor(WaitTreeColors[4][color_index]); - case Kernel::ThreadStatus::WaitSleep: - return QColor(WaitTreeColors[5][color_index]); - case Kernel::ThreadStatus::WaitSynch: - case Kernel::ThreadStatus::WaitMutex: - case Kernel::ThreadStatus::WaitCondVar: - case Kernel::ThreadStatus::WaitArb: - return QColor(WaitTreeColors[6][color_index]); - case Kernel::ThreadStatus::Dormant: + case Kernel::ThreadState::Waiting: + switch (thread.GetWaitReasonForDebugging()) { + case Kernel::ThreadWaitReasonForDebugging::IPC: + return QColor(WaitTreeColors[4][color_index]); + case Kernel::ThreadWaitReasonForDebugging::Sleep: + return QColor(WaitTreeColors[5][color_index]); + case Kernel::ThreadWaitReasonForDebugging::Synchronization: + case Kernel::ThreadWaitReasonForDebugging::ConditionVar: + case Kernel::ThreadWaitReasonForDebugging::Arbitration: + case Kernel::ThreadWaitReasonForDebugging::Suspended: + return QColor(WaitTreeColors[6][color_index]); + break; + default: + return QColor(WaitTreeColors[3][color_index]); + } + case Kernel::ThreadState::Initialized: return QColor(WaitTreeColors[7][color_index]); - case Kernel::ThreadStatus::Dead: + case Kernel::ThreadState::Terminated: return QColor(WaitTreeColors[8][color_index]); default: return WaitTreeItem::GetColor(); @@ -354,11 +362,11 @@ std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeThread::GetChildren() const { list.push_back(std::make_unique<WaitTreeText>(tr("thread id = %1").arg(thread.GetThreadID()))); list.push_back(std::make_unique<WaitTreeText>(tr("priority = %1(current) / %2(normal)") .arg(thread.GetPriority()) - .arg(thread.GetNominalPriority()))); + .arg(thread.GetBasePriority()))); list.push_back(std::make_unique<WaitTreeText>( tr("last running ticks = %1").arg(thread.GetLastScheduledTick()))); - const VAddr mutex_wait_address = thread.GetMutexWaitAddress(); + const VAddr mutex_wait_address = thread.GetMutexWaitAddressForDebugging(); if (mutex_wait_address != 0) { const auto& handle_table = thread.GetOwnerProcess()->GetHandleTable(); list.push_back(std::make_unique<WaitTreeMutexInfo>(mutex_wait_address, handle_table)); @@ -366,9 +374,11 @@ std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeThread::GetChildren() const { list.push_back(std::make_unique<WaitTreeText>(tr("not waiting for mutex"))); } - if (thread.GetStatus() == Kernel::ThreadStatus::WaitSynch) { - list.push_back(std::make_unique<WaitTreeObjectList>(thread.GetSynchronizationObjects(), - thread.IsWaitingSync())); + if (thread.GetState() == Kernel::ThreadState::Waiting && + thread.GetWaitReasonForDebugging() == + Kernel::ThreadWaitReasonForDebugging::Synchronization) { + list.push_back(std::make_unique<WaitTreeObjectList>(thread.GetWaitObjectsForDebugging(), + thread.IsCancellable())); } list.push_back(std::make_unique<WaitTreeCallstack>(thread)); @@ -380,7 +390,7 @@ WaitTreeEvent::WaitTreeEvent(const Kernel::ReadableEvent& object) : WaitTreeSynchronizationObject(object) {} WaitTreeEvent::~WaitTreeEvent() = default; -WaitTreeThreadList::WaitTreeThreadList(const std::vector<std::shared_ptr<Kernel::Thread>>& list) +WaitTreeThreadList::WaitTreeThreadList(const std::vector<Kernel::Thread*>& list) : thread_list(list) {} WaitTreeThreadList::~WaitTreeThreadList() = default; diff --git a/src/yuzu/debugger/wait_tree.h b/src/yuzu/debugger/wait_tree.h index 8e3bc4b24..cf96911ea 100644 --- a/src/yuzu/debugger/wait_tree.h +++ b/src/yuzu/debugger/wait_tree.h @@ -18,8 +18,8 @@ class EmuThread; namespace Kernel { class HandleTable; +class KSynchronizationObject; class ReadableEvent; -class SynchronizationObject; class Thread; } // namespace Kernel @@ -102,30 +102,29 @@ private: class WaitTreeSynchronizationObject : public WaitTreeExpandableItem { Q_OBJECT public: - explicit WaitTreeSynchronizationObject(const Kernel::SynchronizationObject& object); + explicit WaitTreeSynchronizationObject(const Kernel::KSynchronizationObject& object); ~WaitTreeSynchronizationObject() override; static std::unique_ptr<WaitTreeSynchronizationObject> make( - const Kernel::SynchronizationObject& object); + const Kernel::KSynchronizationObject& object); QString GetText() const override; std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const override; protected: - const Kernel::SynchronizationObject& object; + const Kernel::KSynchronizationObject& object; }; class WaitTreeObjectList : public WaitTreeExpandableItem { Q_OBJECT public: - WaitTreeObjectList(const std::vector<std::shared_ptr<Kernel::SynchronizationObject>>& list, - bool wait_all); + WaitTreeObjectList(const std::vector<Kernel::KSynchronizationObject*>& list, bool wait_all); ~WaitTreeObjectList() override; QString GetText() const override; std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const override; private: - const std::vector<std::shared_ptr<Kernel::SynchronizationObject>>& object_list; + const std::vector<Kernel::KSynchronizationObject*>& object_list; bool wait_all; }; @@ -150,14 +149,14 @@ public: class WaitTreeThreadList : public WaitTreeExpandableItem { Q_OBJECT public: - explicit WaitTreeThreadList(const std::vector<std::shared_ptr<Kernel::Thread>>& list); + explicit WaitTreeThreadList(const std::vector<Kernel::Thread*>& list); ~WaitTreeThreadList() override; QString GetText() const override; std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const override; private: - const std::vector<std::shared_ptr<Kernel::Thread>>& thread_list; + const std::vector<Kernel::Thread*>& thread_list; }; class WaitTreeModel : public QAbstractItemModel { diff --git a/src/yuzu/game_list.cpp b/src/yuzu/game_list.cpp index 70d865112..9afd5b45f 100644 --- a/src/yuzu/game_list.cpp +++ b/src/yuzu/game_list.cpp @@ -119,7 +119,7 @@ void GameListSearchField::setFocus() { GameListSearchField::GameListSearchField(GameList* parent) : QWidget{parent} { auto* const key_release_eater = new KeyReleaseEater(parent, this); layout_filter = new QHBoxLayout; - layout_filter->setMargin(8); + layout_filter->setContentsMargins(8, 8, 8, 8); label_filter = new QLabel; label_filter->setText(tr("Filter:")); edit_filter = new QLineEdit; @@ -173,8 +173,8 @@ void GameList::OnItemExpanded(const QModelIndex& item) { return; } - auto* game_dir = item.data(GameListDir::GameDirRole).value<UISettings::GameDir*>(); - game_dir->expanded = tree_view->isExpanded(item); + UISettings::values.game_dirs[item.data(GameListDir::GameDirRole).toInt()].expanded = + tree_view->isExpanded(item); } // Event in order to filter the gamelist after editing the searchfield @@ -262,9 +262,9 @@ void GameList::OnUpdateThemedIcons() { Qt::DecorationRole); break; case GameListItemType::CustomDir: { - const UISettings::GameDir* game_dir = - child->data(GameListDir::GameDirRole).value<UISettings::GameDir*>(); - const QString icon_name = QFileInfo::exists(game_dir->path) + const UISettings::GameDir& game_dir = + UISettings::values.game_dirs[child->data(GameListDir::GameDirRole).toInt()]; + const QString icon_name = QFileInfo::exists(game_dir.path) ? QStringLiteral("folder") : QStringLiteral("bad_folder"); child->setData( @@ -366,7 +366,7 @@ void GameList::AddDirEntry(GameListDir* entry_items) { item_model->invisibleRootItem()->appendRow(entry_items); tree_view->setExpanded( entry_items->index(), - entry_items->data(GameListDir::GameDirRole).value<UISettings::GameDir*>()->expanded); + UISettings::values.game_dirs[entry_items->data(GameListDir::GameDirRole).toInt()].expanded); } void GameList::AddEntry(const QList<QStandardItem*>& entry_items, GameListDir* parent) { @@ -549,7 +549,7 @@ void GameList::AddGamePopup(QMenu& context_menu, u64 program_id, const std::stri void GameList::AddCustomDirPopup(QMenu& context_menu, QModelIndex selected) { UISettings::GameDir& game_dir = - *selected.data(GameListDir::GameDirRole).value<UISettings::GameDir*>(); + UISettings::values.game_dirs[selected.data(GameListDir::GameDirRole).toInt()]; QAction* deep_scan = context_menu.addAction(tr("Scan Subfolders")); QAction* delete_dir = context_menu.addAction(tr("Remove Game Directory")); @@ -568,8 +568,7 @@ void GameList::AddCustomDirPopup(QMenu& context_menu, QModelIndex selected) { } void GameList::AddPermDirPopup(QMenu& context_menu, QModelIndex selected) { - UISettings::GameDir& game_dir = - *selected.data(GameListDir::GameDirRole).value<UISettings::GameDir*>(); + const int game_dir_index = selected.data(GameListDir::GameDirRole).toInt(); QAction* move_up = context_menu.addAction(tr("\u25B2 Move Up")); QAction* move_down = context_menu.addAction(tr("\u25bc Move Down")); @@ -580,34 +579,39 @@ void GameList::AddPermDirPopup(QMenu& context_menu, QModelIndex selected) { move_up->setEnabled(row > 0); move_down->setEnabled(row < item_model->rowCount() - 2); - connect(move_up, &QAction::triggered, [this, selected, row, &game_dir] { - // find the indices of the items in settings and swap them - std::swap(UISettings::values.game_dirs[UISettings::values.game_dirs.indexOf(game_dir)], - UISettings::values.game_dirs[UISettings::values.game_dirs.indexOf( - *selected.sibling(row - 1, 0) - .data(GameListDir::GameDirRole) - .value<UISettings::GameDir*>())]); + connect(move_up, &QAction::triggered, [this, selected, row, game_dir_index] { + const int other_index = selected.sibling(row - 1, 0).data(GameListDir::GameDirRole).toInt(); + // swap the items in the settings + std::swap(UISettings::values.game_dirs[game_dir_index], + UISettings::values.game_dirs[other_index]); + // swap the indexes held by the QVariants + item_model->setData(selected, QVariant(other_index), GameListDir::GameDirRole); + item_model->setData(selected.sibling(row - 1, 0), QVariant(game_dir_index), + GameListDir::GameDirRole); // move the treeview items QList<QStandardItem*> item = item_model->takeRow(row); item_model->invisibleRootItem()->insertRow(row - 1, item); - tree_view->setExpanded(selected, game_dir.expanded); + tree_view->setExpanded(selected, UISettings::values.game_dirs[game_dir_index].expanded); }); - connect(move_down, &QAction::triggered, [this, selected, row, &game_dir] { - // find the indices of the items in settings and swap them - std::swap(UISettings::values.game_dirs[UISettings::values.game_dirs.indexOf(game_dir)], - UISettings::values.game_dirs[UISettings::values.game_dirs.indexOf( - *selected.sibling(row + 1, 0) - .data(GameListDir::GameDirRole) - .value<UISettings::GameDir*>())]); + connect(move_down, &QAction::triggered, [this, selected, row, game_dir_index] { + const int other_index = selected.sibling(row + 1, 0).data(GameListDir::GameDirRole).toInt(); + // swap the items in the settings + std::swap(UISettings::values.game_dirs[game_dir_index], + UISettings::values.game_dirs[other_index]); + // swap the indexes held by the QVariants + item_model->setData(selected, QVariant(other_index), GameListDir::GameDirRole); + item_model->setData(selected.sibling(row + 1, 0), QVariant(game_dir_index), + GameListDir::GameDirRole); // move the treeview items const QList<QStandardItem*> item = item_model->takeRow(row); item_model->invisibleRootItem()->insertRow(row + 1, item); - tree_view->setExpanded(selected, game_dir.expanded); + tree_view->setExpanded(selected, UISettings::values.game_dirs[game_dir_index].expanded); }); - connect(open_directory_location, &QAction::triggered, - [this, game_dir] { emit OpenDirectory(game_dir.path); }); + connect(open_directory_location, &QAction::triggered, [this, game_dir_index] { + emit OpenDirectory(UISettings::values.game_dirs[game_dir_index].path); + }); } void GameList::LoadCompatibilityList() { diff --git a/src/yuzu/game_list_p.h b/src/yuzu/game_list_p.h index df935022d..f25445f18 100644 --- a/src/yuzu/game_list_p.h +++ b/src/yuzu/game_list_p.h @@ -230,7 +230,7 @@ public: setData(type(), TypeRole); UISettings::GameDir* game_dir = &directory; - setData(QVariant::fromValue(game_dir), GameDirRole); + setData(QVariant(UISettings::values.game_dirs.indexOf(directory)), GameDirRole); const int icon_size = std::min(static_cast<int>(UISettings::values.icon_size), 64); switch (dir_type) { |
