diff options
Diffstat (limited to 'src/yuzu')
25 files changed, 581 insertions, 126 deletions
diff --git a/src/yuzu/CMakeLists.txt b/src/yuzu/CMakeLists.txt index 733c296e4..fe98e3605 100644 --- a/src/yuzu/CMakeLists.txt +++ b/src/yuzu/CMakeLists.txt @@ -98,6 +98,9 @@ add_executable(yuzu configuration/configure_input_profile_dialog.cpp configuration/configure_input_profile_dialog.h configuration/configure_input_profile_dialog.ui + configuration/configure_mouse_panning.cpp + configuration/configure_mouse_panning.h + configuration/configure_mouse_panning.ui configuration/configure_motion_touch.cpp configuration/configure_motion_touch.h configuration/configure_motion_touch.ui diff --git a/src/yuzu/bootmanager.cpp b/src/yuzu/bootmanager.cpp index cc6b6a25a..bdd1497b5 100644 --- a/src/yuzu/bootmanager.cpp +++ b/src/yuzu/bootmanager.cpp @@ -105,14 +105,12 @@ void EmuThread::run() { std::unique_lock lk{m_should_run_mutex}; if (m_should_run) { m_system.Run(); - m_is_running.store(true); - m_is_running.notify_all(); + m_stopped.Reset(); Common::CondvarWait(m_should_run_cv, lk, stop_token, [&] { return !m_should_run; }); } else { m_system.Pause(); - m_is_running.store(false); - m_is_running.notify_all(); + m_stopped.Set(); EmulationPaused(lk); Common::CondvarWait(m_should_run_cv, lk, stop_token, [&] { return m_should_run; }); diff --git a/src/yuzu/bootmanager.h b/src/yuzu/bootmanager.h index b7b9d4141..87b23df12 100644 --- a/src/yuzu/bootmanager.h +++ b/src/yuzu/bootmanager.h @@ -3,7 +3,6 @@ #pragma once -#include <atomic> #include <condition_variable> #include <cstddef> #include <memory> @@ -88,7 +87,7 @@ public: // Wait until paused, if pausing. if (!should_run) { - m_is_running.wait(true); + m_stopped.Wait(); } } @@ -97,7 +96,7 @@ public: * @return True if the emulation thread is running, otherwise false */ bool IsRunning() const { - return m_is_running.load() || m_should_run; + return m_should_run; } /** @@ -118,7 +117,7 @@ private: std::stop_source m_stop_source; std::mutex m_should_run_mutex; std::condition_variable_any m_should_run_cv; - std::atomic<bool> m_is_running{false}; + Common::Event m_stopped; bool m_should_run{true}; signals: diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp index bac9dff90..29467d380 100644 --- a/src/yuzu/configuration/config.cpp +++ b/src/yuzu/configuration/config.cpp @@ -351,6 +351,10 @@ void Config::ReadPlayerValue(std::size_t player_index) { player_motions = default_param; } } + + if (player_index == 0) { + ReadMousePanningValues(); + } } void Config::ReadDebugValues() { @@ -471,6 +475,7 @@ void Config::ReadControlValues() { ReadKeyboardValues(); ReadMouseValues(); ReadTouchscreenValues(); + ReadMousePanningValues(); ReadMotionTouchValues(); ReadHidbusValues(); ReadIrCameraValues(); @@ -481,8 +486,6 @@ void Config::ReadControlValues() { Settings::values.enable_raw_input = false; #endif ReadBasicSetting(Settings::values.emulate_analog_keyboard); - Settings::values.mouse_panning = false; - ReadBasicSetting(Settings::values.mouse_panning_sensitivity); ReadBasicSetting(Settings::values.enable_joycon_driver); ReadBasicSetting(Settings::values.enable_procon_driver); ReadBasicSetting(Settings::values.random_amiibo_id); @@ -496,6 +499,16 @@ void Config::ReadControlValues() { qt_config->endGroup(); } +void Config::ReadMousePanningValues() { + ReadBasicSetting(Settings::values.mouse_panning); + ReadBasicSetting(Settings::values.mouse_panning_x_sensitivity); + ReadBasicSetting(Settings::values.mouse_panning_y_sensitivity); + ReadBasicSetting(Settings::values.mouse_panning_deadzone_x_counterweight); + ReadBasicSetting(Settings::values.mouse_panning_deadzone_y_counterweight); + ReadBasicSetting(Settings::values.mouse_panning_decay_strength); + ReadBasicSetting(Settings::values.mouse_panning_min_decay); +} + void Config::ReadMotionTouchValues() { int num_touch_from_button_maps = qt_config->beginReadArray(QStringLiteral("touch_from_button_maps")); @@ -761,6 +774,7 @@ void Config::ReadRendererValues() { ReadGlobalSetting(Settings::values.use_vulkan_driver_pipeline_cache); ReadGlobalSetting(Settings::values.enable_compute_pipelines); ReadGlobalSetting(Settings::values.use_video_framerate); + ReadGlobalSetting(Settings::values.barrier_feedback_loops); ReadGlobalSetting(Settings::values.bg_red); ReadGlobalSetting(Settings::values.bg_green); ReadGlobalSetting(Settings::values.bg_blue); @@ -890,6 +904,7 @@ void Config::ReadUIValues() { ReadBasicSetting(UISettings::values.pause_when_in_background); ReadBasicSetting(UISettings::values.mute_when_in_background); ReadBasicSetting(UISettings::values.hide_mouse); + ReadBasicSetting(UISettings::values.controller_applet_disabled); ReadBasicSetting(UISettings::values.disable_web_applet); qt_config->endGroup(); @@ -1063,6 +1078,10 @@ void Config::SavePlayerValue(std::size_t player_index) { QString::fromStdString(player.motions[i]), QString::fromStdString(default_param)); } + + if (player_index == 0) { + SaveMousePanningValues(); + } } void Config::SaveDebugValues() { @@ -1099,6 +1118,16 @@ void Config::SaveTouchscreenValues() { WriteSetting(QStringLiteral("touchscreen_diameter_y"), touchscreen.diameter_y, 15); } +void Config::SaveMousePanningValues() { + // Don't overwrite values.mouse_panning + WriteBasicSetting(Settings::values.mouse_panning_x_sensitivity); + WriteBasicSetting(Settings::values.mouse_panning_y_sensitivity); + WriteBasicSetting(Settings::values.mouse_panning_deadzone_x_counterweight); + WriteBasicSetting(Settings::values.mouse_panning_deadzone_y_counterweight); + WriteBasicSetting(Settings::values.mouse_panning_decay_strength); + WriteBasicSetting(Settings::values.mouse_panning_min_decay); +} + void Config::SaveMotionTouchValues() { WriteBasicSetting(Settings::values.touch_device); WriteBasicSetting(Settings::values.touch_from_button_map_index); @@ -1185,6 +1214,7 @@ void Config::SaveControlValues() { SaveDebugValues(); SaveMouseValues(); SaveTouchscreenValues(); + SaveMousePanningValues(); SaveMotionTouchValues(); SaveHidbusValues(); SaveIrCameraValues(); @@ -1199,7 +1229,6 @@ void Config::SaveControlValues() { WriteBasicSetting(Settings::values.random_amiibo_id); WriteBasicSetting(Settings::values.keyboard_enabled); WriteBasicSetting(Settings::values.emulate_analog_keyboard); - WriteBasicSetting(Settings::values.mouse_panning_sensitivity); WriteBasicSetting(Settings::values.controller_navigation); WriteBasicSetting(Settings::values.tas_enable); @@ -1417,6 +1446,7 @@ void Config::SaveRendererValues() { WriteGlobalSetting(Settings::values.use_vulkan_driver_pipeline_cache); WriteGlobalSetting(Settings::values.enable_compute_pipelines); WriteGlobalSetting(Settings::values.use_video_framerate); + WriteGlobalSetting(Settings::values.barrier_feedback_loops); WriteGlobalSetting(Settings::values.bg_red); WriteGlobalSetting(Settings::values.bg_green); WriteGlobalSetting(Settings::values.bg_blue); @@ -1522,6 +1552,7 @@ void Config::SaveUIValues() { WriteBasicSetting(UISettings::values.pause_when_in_background); WriteBasicSetting(UISettings::values.mute_when_in_background); WriteBasicSetting(UISettings::values.hide_mouse); + WriteBasicSetting(UISettings::values.controller_applet_disabled); WriteBasicSetting(UISettings::values.disable_web_applet); qt_config->endGroup(); diff --git a/src/yuzu/configuration/config.h b/src/yuzu/configuration/config.h index 0fd4baf6b..1211389d2 100644 --- a/src/yuzu/configuration/config.h +++ b/src/yuzu/configuration/config.h @@ -74,6 +74,7 @@ private: void ReadKeyboardValues(); void ReadMouseValues(); void ReadTouchscreenValues(); + void ReadMousePanningValues(); void ReadMotionTouchValues(); void ReadHidbusValues(); void ReadIrCameraValues(); @@ -104,6 +105,7 @@ private: void SaveDebugValues(); void SaveMouseValues(); void SaveTouchscreenValues(); + void SaveMousePanningValues(); void SaveMotionTouchValues(); void SaveHidbusValues(); void SaveIrCameraValues(); diff --git a/src/yuzu/configuration/configure_general.cpp b/src/yuzu/configuration/configure_general.cpp index 26258d744..2f55159f5 100644 --- a/src/yuzu/configuration/configure_general.cpp +++ b/src/yuzu/configuration/configure_general.cpp @@ -40,6 +40,9 @@ void ConfigureGeneral::SetConfiguration() { ui->toggle_user_on_boot->setChecked(UISettings::values.select_user_on_boot.GetValue()); ui->toggle_background_pause->setChecked(UISettings::values.pause_when_in_background.GetValue()); ui->toggle_hide_mouse->setChecked(UISettings::values.hide_mouse.GetValue()); + ui->toggle_controller_applet_disabled->setEnabled(runtime_lock); + ui->toggle_controller_applet_disabled->setChecked( + UISettings::values.controller_applet_disabled.GetValue()); ui->toggle_speed_limit->setChecked(Settings::values.use_speed_limit.GetValue()); ui->speed_limit->setValue(Settings::values.speed_limit.GetValue()); @@ -82,6 +85,8 @@ void ConfigureGeneral::ApplyConfiguration() { UISettings::values.select_user_on_boot = ui->toggle_user_on_boot->isChecked(); UISettings::values.pause_when_in_background = ui->toggle_background_pause->isChecked(); UISettings::values.hide_mouse = ui->toggle_hide_mouse->isChecked(); + UISettings::values.controller_applet_disabled = + ui->toggle_controller_applet_disabled->isChecked(); // Guard if during game and set to game-specific value if (Settings::values.use_speed_limit.UsingGlobal()) { @@ -128,6 +133,7 @@ void ConfigureGeneral::SetupPerGameUI() { ui->toggle_user_on_boot->setVisible(false); ui->toggle_background_pause->setVisible(false); ui->toggle_hide_mouse->setVisible(false); + ui->toggle_controller_applet_disabled->setVisible(false); ui->button_reset_defaults->setVisible(false); diff --git a/src/yuzu/configuration/configure_general.ui b/src/yuzu/configuration/configure_general.ui index 986a1625b..fe757d011 100644 --- a/src/yuzu/configuration/configure_general.ui +++ b/src/yuzu/configuration/configure_general.ui @@ -89,6 +89,13 @@ </property> </widget> </item> + <item> + <widget class="QCheckBox" name="toggle_controller_applet_disabled"> + <property name="text"> + <string>Disable controller applet</string> + </property> + </widget> + </item> </layout> </item> </layout> diff --git a/src/yuzu/configuration/configure_graphics.cpp b/src/yuzu/configuration/configure_graphics.cpp index 78b487494..a4965524a 100644 --- a/src/yuzu/configuration/configure_graphics.cpp +++ b/src/yuzu/configuration/configure_graphics.cpp @@ -508,7 +508,7 @@ void ConfigureGraphics::RetrieveVulkanDevices() { vulkan_devices.push_back(QString::fromStdString(record.name)); device_present_modes.push_back(record.vsync_support); - if (record.is_intel_proprietary) { + if (record.has_broken_compute) { expose_compute_option(); } } diff --git a/src/yuzu/configuration/configure_graphics_advanced.cpp b/src/yuzu/configuration/configure_graphics_advanced.cpp index 0463ac8b9..c0a044767 100644 --- a/src/yuzu/configuration/configure_graphics_advanced.cpp +++ b/src/yuzu/configuration/configure_graphics_advanced.cpp @@ -43,6 +43,8 @@ void ConfigureGraphicsAdvanced::SetConfiguration() { ui->enable_compute_pipelines_checkbox->setChecked( Settings::values.enable_compute_pipelines.GetValue()); ui->use_video_framerate_checkbox->setChecked(Settings::values.use_video_framerate.GetValue()); + ui->barrier_feedback_loops_checkbox->setChecked( + Settings::values.barrier_feedback_loops.GetValue()); if (Settings::IsConfiguringGlobal()) { ui->gpu_accuracy->setCurrentIndex( @@ -94,6 +96,9 @@ void ConfigureGraphicsAdvanced::ApplyConfiguration() { enable_compute_pipelines); ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_video_framerate, ui->use_video_framerate_checkbox, use_video_framerate); + ConfigurationShared::ApplyPerGameSetting(&Settings::values.barrier_feedback_loops, + ui->barrier_feedback_loops_checkbox, + barrier_feedback_loops); } void ConfigureGraphicsAdvanced::changeEvent(QEvent* event) { @@ -130,6 +135,8 @@ void ConfigureGraphicsAdvanced::SetupPerGameUI() { Settings::values.enable_compute_pipelines.UsingGlobal()); ui->use_video_framerate_checkbox->setEnabled( Settings::values.use_video_framerate.UsingGlobal()); + ui->barrier_feedback_loops_checkbox->setEnabled( + Settings::values.barrier_feedback_loops.UsingGlobal()); return; } @@ -157,6 +164,9 @@ void ConfigureGraphicsAdvanced::SetupPerGameUI() { ConfigurationShared::SetColoredTristate(ui->use_video_framerate_checkbox, Settings::values.use_video_framerate, use_video_framerate); + ConfigurationShared::SetColoredTristate(ui->barrier_feedback_loops_checkbox, + Settings::values.barrier_feedback_loops, + barrier_feedback_loops); ConfigurationShared::SetColoredComboBox( ui->gpu_accuracy, ui->label_gpu_accuracy, static_cast<int>(Settings::values.gpu_accuracy.GetValue(true))); diff --git a/src/yuzu/configuration/configure_graphics_advanced.h b/src/yuzu/configuration/configure_graphics_advanced.h index a4dc8ceb0..369a7c83e 100644 --- a/src/yuzu/configuration/configure_graphics_advanced.h +++ b/src/yuzu/configuration/configure_graphics_advanced.h @@ -48,6 +48,7 @@ private: ConfigurationShared::CheckState use_vulkan_driver_pipeline_cache; ConfigurationShared::CheckState enable_compute_pipelines; ConfigurationShared::CheckState use_video_framerate; + ConfigurationShared::CheckState barrier_feedback_loops; const Core::System& system; }; diff --git a/src/yuzu/configuration/configure_graphics_advanced.ui b/src/yuzu/configuration/configure_graphics_advanced.ui index e7f0ef6be..d527a6f38 100644 --- a/src/yuzu/configuration/configure_graphics_advanced.ui +++ b/src/yuzu/configuration/configure_graphics_advanced.ui @@ -202,6 +202,16 @@ Compute pipelines are always enabled on all other drivers.</string> </widget> </item> <item> + <widget class="QCheckBox" name="barrier_feedback_loops_checkbox"> + <property name="toolTip"> + <string>Improves rendering of transparency effects in specific games.</string> + </property> + <property name="text"> + <string>Barrier feedback loops</string> + </property> + </widget> + </item> + <item> <widget class="QWidget" name="af_layout" native="true"> <layout class="QHBoxLayout" name="horizontalLayout_1"> <property name="leftMargin"> diff --git a/src/yuzu/configuration/configure_input_advanced.cpp b/src/yuzu/configuration/configure_input_advanced.cpp index f13156434..3cfd5d439 100644 --- a/src/yuzu/configuration/configure_input_advanced.cpp +++ b/src/yuzu/configuration/configure_input_advanced.cpp @@ -129,9 +129,6 @@ void ConfigureInputAdvanced::ApplyConfiguration() { Settings::values.mouse_enabled = ui->mouse_enabled->isChecked(); Settings::values.keyboard_enabled = ui->keyboard_enabled->isChecked(); Settings::values.emulate_analog_keyboard = ui->emulate_analog_keyboard->isChecked(); - Settings::values.mouse_panning = ui->mouse_panning->isChecked(); - Settings::values.mouse_panning_sensitivity = - static_cast<float>(ui->mouse_panning_sensitivity->value()); Settings::values.touchscreen.enabled = ui->touchscreen_enabled->isChecked(); Settings::values.enable_raw_input = ui->enable_raw_input->isChecked(); Settings::values.enable_udp_controller = ui->enable_udp_controller->isChecked(); @@ -167,8 +164,6 @@ void ConfigureInputAdvanced::LoadConfiguration() { ui->mouse_enabled->setChecked(Settings::values.mouse_enabled.GetValue()); ui->keyboard_enabled->setChecked(Settings::values.keyboard_enabled.GetValue()); ui->emulate_analog_keyboard->setChecked(Settings::values.emulate_analog_keyboard.GetValue()); - ui->mouse_panning->setChecked(Settings::values.mouse_panning.GetValue()); - ui->mouse_panning_sensitivity->setValue(Settings::values.mouse_panning_sensitivity.GetValue()); ui->touchscreen_enabled->setChecked(Settings::values.touchscreen.enabled); ui->enable_raw_input->setChecked(Settings::values.enable_raw_input.GetValue()); ui->enable_udp_controller->setChecked(Settings::values.enable_udp_controller.GetValue()); @@ -197,8 +192,6 @@ void ConfigureInputAdvanced::RetranslateUI() { void ConfigureInputAdvanced::UpdateUIEnabled() { ui->debug_configure->setEnabled(ui->debug_enabled->isChecked()); ui->touchscreen_advanced->setEnabled(ui->touchscreen_enabled->isChecked()); - ui->mouse_panning->setEnabled(!ui->mouse_enabled->isChecked()); - ui->mouse_panning_sensitivity->setEnabled(!ui->mouse_enabled->isChecked()); ui->ring_controller_configure->setEnabled(ui->enable_ring_controller->isChecked()); #if QT_VERSION > QT_VERSION_CHECK(6, 0, 0) || !defined(YUZU_USE_QT_MULTIMEDIA) ui->enable_ir_sensor->setEnabled(false); diff --git a/src/yuzu/configuration/configure_input_advanced.ui b/src/yuzu/configuration/configure_input_advanced.ui index 2e8b13660..2994d0ab4 100644 --- a/src/yuzu/configuration/configure_input_advanced.ui +++ b/src/yuzu/configuration/configure_input_advanced.ui @@ -2744,48 +2744,13 @@ </widget> </item> <item row="8" column="0"> - <widget class="QCheckBox" name="mouse_panning"> - <property name="minimumSize"> - <size> - <width>0</width> - <height>23</height> - </size> - </property> - <property name="text"> - <string>Enable mouse panning</string> - </property> - </widget> - </item> - <item row="8" column="2"> - <widget class="QSpinBox" name="mouse_panning_sensitivity"> - <property name="toolTip"> - <string>Mouse sensitivity</string> - </property> - <property name="alignment"> - <set>Qt::AlignCenter</set> - </property> - <property name="suffix"> - <string>%</string> - </property> - <property name="minimum"> - <number>1</number> - </property> - <property name="maximum"> - <number>100</number> - </property> - <property name="value"> - <number>100</number> - </property> - </widget> - </item> - <item row="9" column="0"> <widget class="QLabel" name="motion_touch"> <property name="text"> <string>Motion / Touch</string> </property> </widget> </item> - <item row="9" column="2"> + <item row="8" column="2"> <widget class="QPushButton" name="buttonMotionTouch"> <property name="text"> <string>Configure</string> diff --git a/src/yuzu/configuration/configure_input_player.cpp b/src/yuzu/configuration/configure_input_player.cpp index 2c2e7e47b..576f5b571 100644 --- a/src/yuzu/configuration/configure_input_player.cpp +++ b/src/yuzu/configuration/configure_input_player.cpp @@ -23,6 +23,7 @@ #include "yuzu/configuration/config.h" #include "yuzu/configuration/configure_input_player.h" #include "yuzu/configuration/configure_input_player_widget.h" +#include "yuzu/configuration/configure_mouse_panning.h" #include "yuzu/configuration/input_profiles.h" #include "yuzu/util/limitable_input_dialog.h" @@ -711,6 +712,21 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i }); } + if (player_index_ == 0) { + connect(ui->mousePanningButton, &QPushButton::clicked, [this, input_subsystem_] { + const auto right_stick_param = + emulated_controller->GetStickParam(Settings::NativeAnalog::RStick); + ConfigureMousePanning dialog(this, input_subsystem_, + right_stick_param.Get("deadzone", 0.0f), + right_stick_param.Get("range", 1.0f)); + if (dialog.exec() == QDialog::Accepted) { + dialog.ApplyConfiguration(); + } + }); + } else { + ui->mousePanningWidget->hide(); + } + // Player Connected checkbox connect(ui->groupConnectedController, &QGroupBox::toggled, [this](bool checked) { emit Connected(checked); }); diff --git a/src/yuzu/configuration/configure_input_player.ui b/src/yuzu/configuration/configure_input_player.ui index a9567c6ee..43f6c7b50 100644 --- a/src/yuzu/configuration/configure_input_player.ui +++ b/src/yuzu/configuration/configure_input_player.ui @@ -3048,6 +3048,102 @@ </item> </layout> </item> + <item> + <widget class="QWidget" name="mousePanningWidget" native="true"> + <layout class="QHBoxLayout" name="mousePanningHorizontalLayout"> + <property name="spacing"> + <number>0</number> + </property> + <property name="leftMargin"> + <number>0</number> + </property> + <property name="topMargin"> + <number>0</number> + </property> + <property name="rightMargin"> + <number>0</number> + </property> + <property name="bottomMargin"> + <number>3</number> + </property> + <item> + <spacer name="mousePanningHorizontalSpacerLeft"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QGroupBox" name="mousePanningGroup"> + <property name="title"> + <string>Mouse panning</string> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + <layout class="QVBoxLayout" name="mousePanningVerticalLayout"> + <property name="spacing"> + <number>3</number> + </property> + <property name="leftMargin"> + <number>3</number> + </property> + <property name="topMargin"> + <number>3</number> + </property> + <property name="rightMargin"> + <number>3</number> + </property> + <property name="bottomMargin"> + <number>3</number> + </property> + <item> + <widget class="QPushButton" name="mousePanningButton"> + <property name="minimumSize"> + <size> + <width>68</width> + <height>0</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>68</width> + <height>16777215</height> + </size> + </property> + <property name="styleSheet"> + <string notr="true">min-width: 68px;</string> + </property> + <property name="text"> + <string>Configure</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <spacer name="mousePanningHorizontalSpacerRight"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + </item> </layout> </widget> </item> diff --git a/src/yuzu/configuration/configure_mouse_panning.cpp b/src/yuzu/configuration/configure_mouse_panning.cpp new file mode 100644 index 000000000..f183d2740 --- /dev/null +++ b/src/yuzu/configuration/configure_mouse_panning.cpp @@ -0,0 +1,79 @@ +// SPDX-FileCopyrightText: 2023 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include <QCloseEvent> + +#include "common/settings.h" +#include "ui_configure_mouse_panning.h" +#include "yuzu/configuration/configure_mouse_panning.h" + +ConfigureMousePanning::ConfigureMousePanning(QWidget* parent, + InputCommon::InputSubsystem* input_subsystem_, + float right_stick_deadzone, float right_stick_range) + : QDialog(parent), input_subsystem{input_subsystem_}, + ui(std::make_unique<Ui::ConfigureMousePanning>()) { + ui->setupUi(this); + SetConfiguration(right_stick_deadzone, right_stick_range); + ConnectEvents(); +} + +ConfigureMousePanning::~ConfigureMousePanning() = default; + +void ConfigureMousePanning::closeEvent(QCloseEvent* event) { + event->accept(); +} + +void ConfigureMousePanning::SetConfiguration(float right_stick_deadzone, float right_stick_range) { + ui->enable->setChecked(Settings::values.mouse_panning.GetValue()); + ui->x_sensitivity->setValue(Settings::values.mouse_panning_x_sensitivity.GetValue()); + ui->y_sensitivity->setValue(Settings::values.mouse_panning_y_sensitivity.GetValue()); + ui->deadzone_x_counterweight->setValue( + Settings::values.mouse_panning_deadzone_x_counterweight.GetValue()); + ui->deadzone_y_counterweight->setValue( + Settings::values.mouse_panning_deadzone_y_counterweight.GetValue()); + ui->decay_strength->setValue(Settings::values.mouse_panning_decay_strength.GetValue()); + ui->min_decay->setValue(Settings::values.mouse_panning_min_decay.GetValue()); + + if (right_stick_deadzone > 0.0f || right_stick_range != 1.0f) { + ui->warning_label->setText(QString::fromStdString( + "Mouse panning works better with a deadzone of 0% and a range of 100%.\n" + "Current values are " + + std::to_string(static_cast<int>(right_stick_deadzone * 100.0f)) + "% and " + + std::to_string(static_cast<int>(right_stick_range * 100.0f)) + "% respectively.")); + } else { + ui->warning_label->hide(); + } +} + +void ConfigureMousePanning::SetDefaultConfiguration() { + ui->x_sensitivity->setValue(Settings::values.mouse_panning_x_sensitivity.GetDefault()); + ui->y_sensitivity->setValue(Settings::values.mouse_panning_y_sensitivity.GetDefault()); + ui->deadzone_x_counterweight->setValue( + Settings::values.mouse_panning_deadzone_x_counterweight.GetDefault()); + ui->deadzone_y_counterweight->setValue( + Settings::values.mouse_panning_deadzone_y_counterweight.GetDefault()); + ui->decay_strength->setValue(Settings::values.mouse_panning_decay_strength.GetDefault()); + ui->min_decay->setValue(Settings::values.mouse_panning_min_decay.GetDefault()); +} + +void ConfigureMousePanning::ConnectEvents() { + connect(ui->default_button, &QPushButton::clicked, this, + &ConfigureMousePanning::SetDefaultConfiguration); + connect(ui->button_box, &QDialogButtonBox::accepted, this, + &ConfigureMousePanning::ApplyConfiguration); + connect(ui->button_box, &QDialogButtonBox::rejected, this, [this] { reject(); }); +} + +void ConfigureMousePanning::ApplyConfiguration() { + Settings::values.mouse_panning = ui->enable->isChecked(); + Settings::values.mouse_panning_x_sensitivity = static_cast<float>(ui->x_sensitivity->value()); + Settings::values.mouse_panning_y_sensitivity = static_cast<float>(ui->y_sensitivity->value()); + Settings::values.mouse_panning_deadzone_x_counterweight = + static_cast<float>(ui->deadzone_x_counterweight->value()); + Settings::values.mouse_panning_deadzone_y_counterweight = + static_cast<float>(ui->deadzone_y_counterweight->value()); + Settings::values.mouse_panning_decay_strength = static_cast<float>(ui->decay_strength->value()); + Settings::values.mouse_panning_min_decay = static_cast<float>(ui->min_decay->value()); + + accept(); +} diff --git a/src/yuzu/configuration/configure_mouse_panning.h b/src/yuzu/configuration/configure_mouse_panning.h new file mode 100644 index 000000000..08c6e1f62 --- /dev/null +++ b/src/yuzu/configuration/configure_mouse_panning.h @@ -0,0 +1,35 @@ +// SPDX-FileCopyrightText: 2023 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include <memory> +#include <QDialog> + +namespace InputCommon { +class InputSubsystem; +} + +namespace Ui { +class ConfigureMousePanning; +} + +class ConfigureMousePanning : public QDialog { + Q_OBJECT +public: + explicit ConfigureMousePanning(QWidget* parent, InputCommon::InputSubsystem* input_subsystem_, + float right_stick_deadzone, float right_stick_range); + ~ConfigureMousePanning() override; + +public slots: + void ApplyConfiguration(); + +private: + void closeEvent(QCloseEvent* event) override; + void SetConfiguration(float right_stick_deadzone, float right_stick_range); + void SetDefaultConfiguration(); + void ConnectEvents(); + + InputCommon::InputSubsystem* input_subsystem; + std::unique_ptr<Ui::ConfigureMousePanning> ui; +}; diff --git a/src/yuzu/configuration/configure_mouse_panning.ui b/src/yuzu/configuration/configure_mouse_panning.ui new file mode 100644 index 000000000..75795b727 --- /dev/null +++ b/src/yuzu/configuration/configure_mouse_panning.ui @@ -0,0 +1,238 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>ConfigureMousePanning</class> + <widget class="QDialog" name="configure_mouse_panning"> + <property name="windowTitle"> + <string>Configure mouse panning</string> + </property> + <layout class="QVBoxLayout"> + <item> + <widget class="QCheckBox" name="enable"> + <property name="text"> + <string>Enable</string> + </property> + <property name="toolTip"> + <string>Can be toggled via a hotkey</string> + </property> + </widget> + </item> + <item> + <layout class="QHBoxLayout"> + <item> + <widget class="QGroupBox" name="sensitivity_box"> + <property name="title"> + <string>Sensitivity</string> + </property> + <layout class="QGridLayout"> + <item row="0" column="0"> + <widget class="QLabel" name="x_sensitivity_label"> + <property name="text"> + <string>Horizontal</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QSpinBox" name="x_sensitivity"> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + <property name="suffix"> + <string>%</string> + </property> + <property name="minimum"> + <number>1</number> + </property> + <property name="maximum"> + <number>100</number> + </property> + <property name="value"> + <number>50</number> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="y_sensitivity_label"> + <property name="text"> + <string>Vertical</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QSpinBox" name="y_sensitivity"> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + <property name="suffix"> + <string>%</string> + </property> + <property name="minimum"> + <number>1</number> + </property> + <property name="maximum"> + <number>100</number> + </property> + <property name="value"> + <number>50</number> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QGroupBox" name="deadzone_counterweight_box"> + <property name="title"> + <string>Deadzone counterweight</string> + </property> + <property name="toolTip"> + <string>Counteracts a game's built-in deadzone</string> + </property> + <layout class="QGridLayout"> + <item row="0" column="0"> + <widget class="QLabel" name="deadzone_x_counterweight_label"> + <property name="text"> + <string>Horizontal</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QSpinBox" name="deadzone_x_counterweight"> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + <property name="suffix"> + <string>%</string> + </property> + <property name="minimum"> + <number>0</number> + </property> + <property name="maximum"> + <number>100</number> + </property> + <property name="value"> + <number>0</number> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="deadzone_y_counterweight_label"> + <property name="text"> + <string>Vertical</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QSpinBox" name="deadzone_y_counterweight"> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + <property name="suffix"> + <string>%</string> + </property> + <property name="minimum"> + <number>0</number> + </property> + <property name="maximum"> + <number>100</number> + </property> + <property name="value"> + <number>0</number> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QGroupBox" name="decay_box"> + <property name="title"> + <string>Stick decay</string> + </property> + <layout class="QGridLayout"> + <item row="0" column="0"> + <widget class="QLabel" name="decay_strength_label"> + <property name="text"> + <string>Strength</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QSpinBox" name="decay_strength"> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + <property name="suffix"> + <string>%</string> + </property> + <property name="minimum"> + <number>0</number> + </property> + <property name="maximum"> + <number>100</number> + </property> + <property name="value"> + <number>22</number> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="min_decay_label"> + <property name="text"> + <string>Minimum</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QSpinBox" name="min_decay"> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + <property name="suffix"> + <string>%</string> + </property> + <property name="minimum"> + <number>0</number> + </property> + <property name="maximum"> + <number>100</number> + </property> + <property name="value"> + <number>5</number> + </property> + </widget> + </item> + </layout> + </widget> + </item> + </layout> + </item> + <item> + <widget class="QLabel" name="warning_label"> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item> + <layout class="QHBoxLayout"> + <item> + <widget class="QPushButton" name="default_button"> + <property name="text"> + <string>Default</string> + </property> + </widget> + </item> + <item> + <widget class="QDialogButtonBox" name="button_box"> + <property name="standardButtons"> + <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + <resources/> + <connections/> +</ui> diff --git a/src/yuzu/configuration/configure_ringcon.cpp b/src/yuzu/configuration/configure_ringcon.cpp index 71afbc423..f83705544 100644 --- a/src/yuzu/configuration/configure_ringcon.cpp +++ b/src/yuzu/configuration/configure_ringcon.cpp @@ -305,6 +305,9 @@ void ConfigureRingController::EnableRingController() { QMessageBox::warning(this, dialog_title, tr("The current mapped device doesn't have a ring attached")); break; + case Common::Input::DriverResult::InvalidHandle: + QMessageBox::warning(this, dialog_title, tr("The current mapped device is not connected")); + break; default: QMessageBox::warning(this, dialog_title, tr("Unexpected driver result %1").arg(static_cast<int>(result))); diff --git a/src/yuzu/configuration/configure_ringcon.ui b/src/yuzu/configuration/configure_ringcon.ui index 514dff372..38ecccc3d 100644 --- a/src/yuzu/configuration/configure_ringcon.ui +++ b/src/yuzu/configuration/configure_ringcon.ui @@ -23,7 +23,7 @@ </size> </property> <property name="text"> - <string>If you want to use this controller configure player 1 as right controller and player 2 as dual joycon before starting the game to allow this controller to be detected properly.</string> + <string>To use Ring-Con, configure player 1 as right Joy-Con (both physical and emulated), and player 2 as left Joy-Con (left physical and dual emulated) before starting the game.</string> </property> <property name="wordWrap"> <bool>true</bool> diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 8768a7c3c..e8418b302 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -447,6 +447,14 @@ GMainWindow::GMainWindow(std::unique_ptr<Config> config_, bool has_broken_vulkan #if defined(HAVE_SDL2) && !defined(_WIN32) SDL_InitSubSystem(SDL_INIT_VIDEO); + + // Set a screensaver inhibition reason string. Currently passed to DBus by SDL and visible to + // the user through their desktop environment. + //: TRANSLATORS: This string is shown to the user to explain why yuzu needs to prevent the + //: computer from sleeping + QByteArray wakelock_reason = tr("Running a game").toLatin1(); + SDL_SetHint(SDL_HINT_SCREENSAVER_INHIBIT_ACTIVITY_NAME, wakelock_reason.data()); + // SDL disables the screen saver by default, and setting the hint // SDL_HINT_VIDEO_ALLOW_SCREENSAVER doesn't seem to work, so we just enable the screen saver // for now. @@ -1623,45 +1631,6 @@ void GMainWindow::OnPrepareForSleep(bool prepare_sleep) { } #ifdef __unix__ -static std::optional<QDBusObjectPath> HoldWakeLockLinux(u32 window_id = 0) { - if (!QDBusConnection::sessionBus().isConnected()) { - return {}; - } - // reference: https://flatpak.github.io/xdg-desktop-portal/#gdbus-org.freedesktop.portal.Inhibit - QDBusInterface xdp(QString::fromLatin1("org.freedesktop.portal.Desktop"), - QString::fromLatin1("/org/freedesktop/portal/desktop"), - QString::fromLatin1("org.freedesktop.portal.Inhibit")); - if (!xdp.isValid()) { - LOG_WARNING(Frontend, "Couldn't connect to XDP D-Bus endpoint"); - return {}; - } - QVariantMap options = {}; - //: TRANSLATORS: This string is shown to the user to explain why yuzu needs to prevent the - //: computer from sleeping - options.insert(QString::fromLatin1("reason"), - QCoreApplication::translate("GMainWindow", "yuzu is running a game")); - // 0x4: Suspend lock; 0x8: Idle lock - QDBusReply<QDBusObjectPath> reply = - xdp.call(QString::fromLatin1("Inhibit"), - QString::fromLatin1("x11:") + QString::number(window_id, 16), 12U, options); - - if (reply.isValid()) { - return reply.value(); - } - LOG_WARNING(Frontend, "Couldn't read Inhibit reply from XDP: {}", - reply.error().message().toStdString()); - return {}; -} - -static void ReleaseWakeLockLinux(QDBusObjectPath lock) { - if (!QDBusConnection::sessionBus().isConnected()) { - return; - } - QDBusInterface unlocker(QString::fromLatin1("org.freedesktop.portal.Desktop"), lock.path(), - QString::fromLatin1("org.freedesktop.portal.Request")); - unlocker.call(QString::fromLatin1("Close")); -} - std::array<int, 3> GMainWindow::sig_interrupt_fds{0, 0, 0}; void GMainWindow::SetupSigInterrupts() { @@ -1714,12 +1683,6 @@ void GMainWindow::PreventOSSleep() { SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED | ES_DISPLAY_REQUIRED); #elif defined(HAVE_SDL2) SDL_DisableScreenSaver(); -#ifdef __unix__ - auto reply = HoldWakeLockLinux(winId()); - if (reply) { - wake_lock = std::move(reply.value()); - } -#endif #endif } @@ -1728,11 +1691,6 @@ void GMainWindow::AllowOSSleep() { SetThreadExecutionState(ES_CONTINUOUS); #elif defined(HAVE_SDL2) SDL_EnableScreenSaver(); -#ifdef __unix__ - if (!wake_lock.path().isEmpty()) { - ReleaseWakeLockLinux(wake_lock); - } -#endif #endif } @@ -1749,15 +1707,17 @@ bool GMainWindow::LoadROM(const QString& filename, u64 program_id, std::size_t p system->SetFilesystem(vfs); system->SetAppletFrontendSet({ - std::make_unique<QtAmiiboSettings>(*this), // Amiibo Settings - std::make_unique<QtControllerSelector>(*this), // Controller Selector - std::make_unique<QtErrorDisplay>(*this), // Error Display - nullptr, // Mii Editor - nullptr, // Parental Controls - nullptr, // Photo Viewer - std::make_unique<QtProfileSelector>(*this), // Profile Selector - std::make_unique<QtSoftwareKeyboard>(*this), // Software Keyboard - std::make_unique<QtWebBrowser>(*this), // Web Browser + std::make_unique<QtAmiiboSettings>(*this), // Amiibo Settings + (UISettings::values.controller_applet_disabled.GetValue() == true) + ? nullptr + : std::make_unique<QtControllerSelector>(*this), // Controller Selector + std::make_unique<QtErrorDisplay>(*this), // Error Display + nullptr, // Mii Editor + nullptr, // Parental Controls + nullptr, // Photo Viewer + std::make_unique<QtProfileSelector>(*this), // Profile Selector + std::make_unique<QtSoftwareKeyboard>(*this), // Software Keyboard + std::make_unique<QtWebBrowser>(*this), // Web Browser }); const Core::SystemResultStatus result{ @@ -3840,7 +3800,7 @@ void GMainWindow::OnLoadAmiibo() { auto* virtual_amiibo = input_subsystem->GetVirtualAmiibo(); // Remove amiibo if one is connected - if (virtual_amiibo->GetCurrentState() == InputCommon::VirtualAmiibo::State::AmiiboIsOpen) { + if (virtual_amiibo->GetCurrentState() == InputCommon::VirtualAmiibo::State::TagNearby) { virtual_amiibo->CloseAmiibo(); QMessageBox::warning(this, tr("Amiibo"), tr("The current amiibo has been removed")); return; @@ -3868,7 +3828,7 @@ void GMainWindow::LoadAmiibo(const QString& filename) { auto* virtual_amiibo = input_subsystem->GetVirtualAmiibo(); const QString title = tr("Error loading Amiibo data"); // Remove amiibo if one is connected - if (virtual_amiibo->GetCurrentState() == InputCommon::VirtualAmiibo::State::AmiiboIsOpen) { + if (virtual_amiibo->GetCurrentState() == InputCommon::VirtualAmiibo::State::TagNearby) { virtual_amiibo->CloseAmiibo(); QMessageBox::warning(this, tr("Amiibo"), tr("The current amiibo has been removed")); return; diff --git a/src/yuzu/main.h b/src/yuzu/main.h index e0e775d87..2cfb96257 100644 --- a/src/yuzu/main.h +++ b/src/yuzu/main.h @@ -504,8 +504,6 @@ private: #ifdef __unix__ QSocketNotifier* sig_interrupt_notifier; static std::array<int, 3> sig_interrupt_fds; - - QDBusObjectPath wake_lock{}; #endif protected: diff --git a/src/yuzu/uisettings.h b/src/yuzu/uisettings.h index db43b7033..20a517d34 100644 --- a/src/yuzu/uisettings.h +++ b/src/yuzu/uisettings.h @@ -77,6 +77,8 @@ struct Values { Settings::Setting<bool> pause_when_in_background{false, "pauseWhenInBackground"}; Settings::Setting<bool> mute_when_in_background{false, "muteWhenInBackground"}; Settings::Setting<bool> hide_mouse{true, "hideInactiveMouse"}; + Settings::Setting<bool> controller_applet_disabled{false, "disableControllerApplet"}; + // Set when Vulkan is known to crash the application bool has_broken_vulkan = false; diff --git a/src/yuzu/vk_device_info.cpp b/src/yuzu/vk_device_info.cpp index 9bd1ec686..7c26a3dc7 100644 --- a/src/yuzu/vk_device_info.cpp +++ b/src/yuzu/vk_device_info.cpp @@ -5,10 +5,12 @@ #include <vector> #include "common/dynamic_library.h" #include "common/logging/log.h" +#include "video_core/vulkan_common/vulkan_device.h" #include "video_core/vulkan_common/vulkan_instance.h" #include "video_core/vulkan_common/vulkan_library.h" #include "video_core/vulkan_common/vulkan_surface.h" #include "video_core/vulkan_common/vulkan_wrapper.h" +#include "vulkan/vulkan_core.h" #include "yuzu/qt_common.h" #include "yuzu/vk_device_info.h" @@ -16,8 +18,8 @@ class QWindow; namespace VkDeviceInfo { Record::Record(std::string_view name_, const std::vector<VkPresentModeKHR>& vsync_modes_, - bool is_intel_proprietary_) - : name{name_}, vsync_support{vsync_modes_}, is_intel_proprietary{is_intel_proprietary_} {} + bool has_broken_compute_) + : name{name_}, vsync_support{vsync_modes_}, has_broken_compute{has_broken_compute_} {} Record::~Record() = default; @@ -48,9 +50,10 @@ void PopulateRecords(std::vector<Record>& records, QWindow* window) try { properties.pNext = &driver_properties; dld.vkGetPhysicalDeviceProperties2(physical_device, &properties); - records.push_back(VkDeviceInfo::Record(name, present_modes, - driver_properties.driverID == - VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS)); + bool has_broken_compute{Vulkan::Device::CheckBrokenCompute( + driver_properties.driverID, properties.properties.driverVersion)}; + + records.push_back(VkDeviceInfo::Record(name, present_modes, has_broken_compute)); } } catch (const Vulkan::vk::Exception& exception) { LOG_ERROR(Frontend, "Failed to enumerate devices with error: {}", exception.what()); diff --git a/src/yuzu/vk_device_info.h b/src/yuzu/vk_device_info.h index 5a6c64416..bda8262f4 100644 --- a/src/yuzu/vk_device_info.h +++ b/src/yuzu/vk_device_info.h @@ -24,12 +24,12 @@ namespace VkDeviceInfo { class Record { public: explicit Record(std::string_view name, const std::vector<VkPresentModeKHR>& vsync_modes, - bool is_intel_proprietary); + bool has_broken_compute); ~Record(); const std::string name; const std::vector<VkPresentModeKHR> vsync_support; - const bool is_intel_proprietary; + const bool has_broken_compute; }; void PopulateRecords(std::vector<Record>& records, QWindow* window); |