diff options
Diffstat (limited to 'src/yuzu')
-rw-r--r-- | src/yuzu/bootmanager.cpp | 56 | ||||
-rw-r--r-- | src/yuzu/bootmanager.h | 6 | ||||
-rw-r--r-- | src/yuzu/configuration/configure_debug.cpp | 3 | ||||
-rw-r--r-- | src/yuzu/configuration/configure_debug.ui | 86 | ||||
-rw-r--r-- | src/yuzu/main.cpp | 83 | ||||
-rw-r--r-- | src/yuzu/main.h | 5 |
6 files changed, 150 insertions, 89 deletions
diff --git a/src/yuzu/bootmanager.cpp b/src/yuzu/bootmanager.cpp index 2afa72140..ed5750155 100644 --- a/src/yuzu/bootmanager.cpp +++ b/src/yuzu/bootmanager.cpp @@ -30,7 +30,6 @@ #include <QSize> #include <QStringLiteral> #include <QSurfaceFormat> -#include <QTimer> #include <QWindow> #include <QtCore/qobjectdefs.h> @@ -66,6 +65,8 @@ class QObject; class QPaintEngine; class QSurface; +constexpr int default_mouse_constrain_timeout = 10; + EmuThread::EmuThread(Core::System& system) : m_system{system} {} EmuThread::~EmuThread() = default; @@ -304,6 +305,9 @@ GRenderWindow::GRenderWindow(GMainWindow* parent, EmuThread* emu_thread_, Qt::QueuedConnection); connect(this, &GRenderWindow::ExitSignal, parent, &GMainWindow::OnExit, Qt::QueuedConnection); connect(this, &GRenderWindow::TasPlaybackStateChanged, parent, &GMainWindow::OnTasStateChanged); + + mouse_constrain_timer.setInterval(default_mouse_constrain_timeout); + connect(&mouse_constrain_timer, &QTimer::timeout, this, &GRenderWindow::ConstrainMouse); } void GRenderWindow::ExecuteProgram(std::size_t program_index) { @@ -393,6 +397,22 @@ void GRenderWindow::closeEvent(QCloseEvent* event) { QWidget::closeEvent(event); } +void GRenderWindow::leaveEvent(QEvent* event) { + if (Settings::values.mouse_panning) { + const QRect& rect = QWidget::geometry(); + QPoint position = QCursor::pos(); + + qint32 x = qBound(rect.left(), position.x(), rect.right()); + qint32 y = qBound(rect.top(), position.y(), rect.bottom()); + // Only start the timer if the mouse has left the window bound. + // The leave event is also triggered when the window looses focus. + if (x != position.x() || y != position.y()) { + mouse_constrain_timer.start(); + } + event->accept(); + } +} + int GRenderWindow::QtKeyToSwitchKey(Qt::Key qt_key) { static constexpr std::array<std::pair<Qt::Key, Settings::NativeKeyboard::Keys>, 106> key_map = { std::pair<Qt::Key, Settings::NativeKeyboard::Keys>{Qt::Key_A, Settings::NativeKeyboard::A}, @@ -658,10 +678,19 @@ void GRenderWindow::mouseMoveEvent(QMouseEvent* event) { input_subsystem->GetMouse()->TouchMove(touch_x, touch_y); input_subsystem->GetMouse()->Move(pos.x(), pos.y(), center_x, center_y); + // Center mouse for mouse panning if (Settings::values.mouse_panning && !Settings::values.mouse_enabled) { QCursor::setPos(mapToGlobal(QPoint{center_x, center_y})); } + // Constrain mouse for mouse emulation with mouse panning + if (Settings::values.mouse_panning && Settings::values.mouse_enabled) { + const auto [clamped_mouse_x, clamped_mouse_y] = ClipToTouchScreen(x, y); + QCursor::setPos(mapToGlobal( + QPoint{static_cast<int>(clamped_mouse_x), static_cast<int>(clamped_mouse_y)})); + } + + mouse_constrain_timer.stop(); emit MouseActivity(); } @@ -675,6 +704,31 @@ void GRenderWindow::mouseReleaseEvent(QMouseEvent* event) { input_subsystem->GetMouse()->ReleaseButton(button); } +void GRenderWindow::ConstrainMouse() { + if (emu_thread == nullptr || !Settings::values.mouse_panning) { + mouse_constrain_timer.stop(); + return; + } + if (!this->isActiveWindow()) { + mouse_constrain_timer.stop(); + return; + } + + if (Settings::values.mouse_enabled) { + const auto pos = mapFromGlobal(QCursor::pos()); + const int new_pos_x = std::clamp(pos.x(), 0, width()); + const int new_pos_y = std::clamp(pos.y(), 0, height()); + + QCursor::setPos(mapToGlobal(QPoint{new_pos_x, new_pos_y})); + return; + } + + const int center_x = width() / 2; + const int center_y = height() / 2; + + QCursor::setPos(mapToGlobal(QPoint{center_x, center_y})); +} + void GRenderWindow::wheelEvent(QWheelEvent* event) { const int x = event->angleDelta().x(); const int y = event->angleDelta().y(); diff --git a/src/yuzu/bootmanager.h b/src/yuzu/bootmanager.h index 87b23df12..60edd464c 100644 --- a/src/yuzu/bootmanager.h +++ b/src/yuzu/bootmanager.h @@ -17,6 +17,7 @@ #include <QString> #include <QStringList> #include <QThread> +#include <QTimer> #include <QWidget> #include <qglobal.h> #include <qnamespace.h> @@ -38,7 +39,6 @@ class QMouseEvent; class QObject; class QResizeEvent; class QShowEvent; -class QTimer; class QTouchEvent; class QWheelEvent; @@ -166,6 +166,7 @@ public: std::pair<u32, u32> ScaleTouch(const QPointF& pos) const; void closeEvent(QCloseEvent* event) override; + void leaveEvent(QEvent* event) override; void resizeEvent(QResizeEvent* event) override; @@ -229,6 +230,7 @@ private: void TouchBeginEvent(const QTouchEvent* event); void TouchUpdateEvent(const QTouchEvent* event); void TouchEndEvent(); + void ConstrainMouse(); void RequestCameraCapture(); void OnCameraCapture(int requestId, const QImage& img); @@ -268,6 +270,8 @@ private: std::unique_ptr<QTimer> camera_timer; #endif + QTimer mouse_constrain_timer; + Core::System& system; protected: diff --git a/src/yuzu/configuration/configure_debug.cpp b/src/yuzu/configuration/configure_debug.cpp index ef421c754..1010038b7 100644 --- a/src/yuzu/configuration/configure_debug.cpp +++ b/src/yuzu/configuration/configure_debug.cpp @@ -51,6 +51,8 @@ void ConfigureDebug::SetConfiguration() { ui->enable_all_controllers->setChecked(Settings::values.enable_all_controllers.GetValue()); ui->enable_renderdoc_hotkey->setEnabled(runtime_lock); ui->enable_renderdoc_hotkey->setChecked(Settings::values.enable_renderdoc_hotkey.GetValue()); + ui->disable_buffer_reorder->setEnabled(runtime_lock); + ui->disable_buffer_reorder->setChecked(Settings::values.disable_buffer_reorder.GetValue()); ui->enable_graphics_debugging->setEnabled(runtime_lock); ui->enable_graphics_debugging->setChecked(Settings::values.renderer_debug.GetValue()); ui->enable_shader_feedback->setEnabled(runtime_lock); @@ -96,6 +98,7 @@ void ConfigureDebug::ApplyConfiguration() { Settings::values.enable_all_controllers = ui->enable_all_controllers->isChecked(); Settings::values.renderer_debug = ui->enable_graphics_debugging->isChecked(); Settings::values.enable_renderdoc_hotkey = ui->enable_renderdoc_hotkey->isChecked(); + Settings::values.disable_buffer_reorder = ui->disable_buffer_reorder->isChecked(); Settings::values.renderer_shader_feedback = ui->enable_shader_feedback->isChecked(); Settings::values.cpu_debug_mode = ui->enable_cpu_debugging->isChecked(); Settings::values.enable_nsight_aftermath = ui->enable_nsight_aftermath->isChecked(); diff --git a/src/yuzu/configuration/configure_debug.ui b/src/yuzu/configuration/configure_debug.ui index 76fe98924..22b51f39c 100644 --- a/src/yuzu/configuration/configure_debug.ui +++ b/src/yuzu/configuration/configure_debug.ui @@ -271,19 +271,6 @@ </widget> </item> <item row="8" column="0"> - <widget class="QCheckBox" name="disable_macro_hle"> - <property name="enabled"> - <bool>true</bool> - </property> - <property name="toolTip"> - <string>When checked, it disables the macro HLE functions. Enabling this makes games run slower</string> - </property> - <property name="text"> - <string>Disable Macro HLE</string> - </property> - </widget> - </item> - <item row="7" column="0"> <widget class="QCheckBox" name="dump_macros"> <property name="enabled"> <bool>true</bool> @@ -306,17 +293,27 @@ </property> </widget> </item> - <item row="2" column="0"> - <widget class="QCheckBox" name="enable_shader_feedback"> + <item row="6" column="0"> + <widget class="QCheckBox" name="dump_shaders"> + <property name="enabled"> + <bool>true</bool> + </property> <property name="toolTip"> - <string>When checked, yuzu will log statistics about the compiled pipeline cache</string> + <string>When checked, it will dump all the original assembler shaders from the disk shader cache or game as found</string> </property> <property name="text"> - <string>Enable Shader Feedback</string> + <string>Dump Game Shaders</string> </property> </widget> </item> - <item row="6" column="0"> + <item row="1" column="0"> + <widget class="QCheckBox" name="enable_renderdoc_hotkey"> + <property name="text"> + <string>Enable Renderdoc Hotkey</string> + </property> + </widget> + </item> + <item row="7" column="0"> <widget class="QCheckBox" name="disable_macro_jit"> <property name="enabled"> <bool>true</bool> @@ -330,20 +327,17 @@ </widget> </item> <item row="9" column="0"> - <spacer name="verticalSpacer_5"> - <property name="orientation"> - <enum>Qt::Vertical</enum> + <widget class="QCheckBox" name="disable_macro_hle"> + <property name="enabled"> + <bool>true</bool> </property> - <property name="sizeType"> - <enum>QSizePolicy::Preferred</enum> + <property name="toolTip"> + <string>When checked, it disables the macro HLE functions. Enabling this makes games run slower</string> </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>0</height> - </size> + <property name="text"> + <string>Disable Macro HLE</string> </property> - </spacer> + </widget> </item> <item row="0" column="0"> <widget class="QCheckBox" name="enable_graphics_debugging"> @@ -358,23 +352,39 @@ </property> </widget> </item> - <item row="5" column="0"> - <widget class="QCheckBox" name="dump_shaders"> - <property name="enabled"> - <bool>true</bool> + <item row="10" column="0"> + <spacer name="verticalSpacer_5"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Preferred</enum> </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>0</height> + </size> + </property> + </spacer> + </item> + <item row="2" column="0"> + <widget class="QCheckBox" name="enable_shader_feedback"> <property name="toolTip"> - <string>When checked, it will dump all the original assembler shaders from the disk shader cache or game as found</string> + <string>When checked, yuzu will log statistics about the compiled pipeline cache</string> </property> <property name="text"> - <string>Dump Game Shaders</string> + <string>Enable Shader Feedback</string> </property> </widget> </item> - <item row="1" column="0"> - <widget class="QCheckBox" name="enable_renderdoc_hotkey"> + <item row="5" column="0"> + <widget class="QCheckBox" name="disable_buffer_reorder"> + <property name="toolTip"> + <string><html><head/><body><p>When checked, disables reording of mapped memory uploads which allows to associate uploads with specific draws. May reduce performance in some cases.</p></body></html></string> + </property> <property name="text"> - <string>Enable Renderdoc Hotkey</string> + <string>Disable Buffer Reorder</string> </property> </widget> </item> diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 6ef518b6a..10c788290 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -48,6 +48,7 @@ #include "core/hle/service/am/applet_ae.h" #include "core/hle/service/am/applet_oe.h" #include "core/hle/service/am/applets/applets.h" +#include "core/hle/service/set/set_sys.h" #include "yuzu/multiplayer/state.h" #include "yuzu/util/controller_navigation.h" @@ -187,7 +188,6 @@ __declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1; #endif constexpr int default_mouse_hide_timeout = 2500; -constexpr int default_mouse_center_timeout = 10; constexpr int default_input_update_timeout = 1; constexpr size_t CopyBufferSize = 1_MiB; @@ -438,9 +438,6 @@ GMainWindow::GMainWindow(std::unique_ptr<QtConfig> config_, bool has_broken_vulk connect(&mouse_hide_timer, &QTimer::timeout, this, &GMainWindow::HideMouseCursor); connect(ui->menubar, &QMenuBar::hovered, this, &GMainWindow::ShowMouseCursor); - mouse_center_timer.setInterval(default_mouse_center_timeout); - connect(&mouse_center_timer, &QTimer::timeout, this, &GMainWindow::CenterMouseCursor); - update_input_timer.setInterval(default_input_update_timeout); connect(&update_input_timer, &QTimer::timeout, this, &GMainWindow::UpdateInputDrivers); update_input_timer.start(); @@ -1050,7 +1047,12 @@ void GMainWindow::InitializeWidgets() { statusBar()->addPermanentWidget(label); } - // TODO (flTobi): Add the widget when multiplayer is fully implemented + firmware_label = new QLabel(); + firmware_label->setObjectName(QStringLiteral("FirmwareLabel")); + firmware_label->setVisible(false); + firmware_label->setFocusPolicy(Qt::NoFocus); + statusBar()->addPermanentWidget(firmware_label); + statusBar()->addPermanentWidget(multiplayer_state->GetStatusText(), 0); statusBar()->addPermanentWidget(multiplayer_state->GetStatusIcon(), 0); @@ -1372,14 +1374,6 @@ void GMainWindow::InitializeHotkeys() { } }); connect_shortcut(QStringLiteral("Toggle Mouse Panning"), [&] { - if (Settings::values.mouse_enabled) { - Settings::values.mouse_panning = false; - QMessageBox::warning( - this, tr("Emulated mouse is enabled"), - tr("Real mouse input and mouse panning are incompatible. Please disable the " - "emulated mouse in input advanced settings to allow mouse panning.")); - return; - } Settings::values.mouse_panning = !Settings::values.mouse_panning; if (Settings::values.mouse_panning) { render_window->installEventFilter(render_window); @@ -2171,6 +2165,10 @@ void GMainWindow::OnEmulationStopped() { emu_frametime_label->setVisible(false); renderer_status_button->setEnabled(!UISettings::values.has_broken_vulkan); + if (!firmware_label->text().isEmpty()) { + firmware_label->setVisible(true); + } + current_game_path.clear(); // When closing the game, destroy the GLWindow to clear the context after the game is closed @@ -4613,6 +4611,7 @@ void GMainWindow::UpdateStatusBar() { emu_speed_label->setVisible(!Settings::values.use_multi_core.GetValue()); game_fps_label->setVisible(true); emu_frametime_label->setVisible(true); + firmware_label->setVisible(false); } void GMainWindow::UpdateGPUAccuracyButton() { @@ -4722,26 +4721,10 @@ void GMainWindow::ShowMouseCursor() { } } -void GMainWindow::CenterMouseCursor() { - if (emu_thread == nullptr || !Settings::values.mouse_panning) { - mouse_center_timer.stop(); - return; - } - if (!this->isActiveWindow()) { - mouse_center_timer.stop(); - return; - } - const int center_x = render_window->width() / 2; - const int center_y = render_window->height() / 2; - - QCursor::setPos(mapToGlobal(QPoint{center_x, center_y})); -} - void GMainWindow::OnMouseActivity() { if (!Settings::values.mouse_panning) { ShowMouseCursor(); } - mouse_center_timer.stop(); } void GMainWindow::OnReinitializeKeys(ReinitializeKeyBehavior behavior) { @@ -4832,6 +4815,8 @@ void GMainWindow::OnReinitializeKeys(ReinitializeKeyBehavior behavior) { "games.")); } + SetFirmwareVersion(); + if (behavior == ReinitializeKeyBehavior::Warning) { game_list->PopulateAsync(UISettings::values.game_dirs); } @@ -4859,7 +4844,7 @@ bool GMainWindow::CheckSystemArchiveDecryption() { } bool GMainWindow::CheckFirmwarePresence() { - constexpr u64 MiiEditId = 0x0100000000001009ull; + constexpr u64 MiiEditId = static_cast<u64>(Service::AM::Applets::AppletProgramId::MiiEdit); auto bis_system = system->GetFileSystemController().GetSystemNANDContents(); if (!bis_system) { @@ -4874,6 +4859,28 @@ bool GMainWindow::CheckFirmwarePresence() { return true; } +void GMainWindow::SetFirmwareVersion() { + Service::Set::FirmwareVersionFormat firmware_data{}; + const auto result = Service::Set::GetFirmwareVersionImpl( + firmware_data, *system, Service::Set::GetFirmwareVersionType::Version2); + + if (result.IsError() || !CheckFirmwarePresence()) { + LOG_INFO(Frontend, "Installed firmware: No firmware available"); + firmware_label->setVisible(false); + return; + } + + firmware_label->setVisible(true); + + const std::string display_version(firmware_data.display_version.data()); + const std::string display_title(firmware_data.display_title.data()); + + LOG_INFO(Frontend, "Installed firmware: {}", display_title); + + firmware_label->setText(QString::fromStdString(display_version)); + firmware_label->setToolTip(QString::fromStdString(display_title)); +} + bool GMainWindow::SelectRomFSDumpTarget(const FileSys::ContentProvider& installed, u64 program_id, u64* selected_title_id, u8* selected_content_record_type) { using ContentInfo = std::tuple<u64, FileSys::TitleType, FileSys::ContentRecordType>; @@ -5018,22 +5025,6 @@ void GMainWindow::dragMoveEvent(QDragMoveEvent* event) { AcceptDropEvent(event); } -void GMainWindow::leaveEvent(QEvent* event) { - if (Settings::values.mouse_panning) { - const QRect& rect = geometry(); - QPoint position = QCursor::pos(); - - qint32 x = qBound(rect.left(), position.x(), rect.right()); - qint32 y = qBound(rect.top(), position.y(), rect.bottom()); - // Only start the timer if the mouse has left the window bound. - // The leave event is also triggered when the window looses focus. - if (x != position.x() || y != position.y()) { - mouse_center_timer.start(); - } - event->accept(); - } -} - bool GMainWindow::ConfirmChangeGame() { if (emu_thread == nullptr) return true; diff --git a/src/yuzu/main.h b/src/yuzu/main.h index 2e13e1834..530e445f9 100644 --- a/src/yuzu/main.h +++ b/src/yuzu/main.h @@ -452,13 +452,13 @@ private: void UpdateInputDrivers(); void HideMouseCursor(); void ShowMouseCursor(); - void CenterMouseCursor(); void OpenURL(const QUrl& url); void LoadTranslation(); void OpenPerGameConfiguration(u64 title_id, const std::string& file_name); bool CheckDarkMode(); bool CheckSystemArchiveDecryption(); bool CheckFirmwarePresence(); + void SetFirmwareVersion(); void ConfigureFilesystemProvider(const std::string& filepath); /** * Open (or not) the right confirm dialog based on current setting and game exit lock @@ -513,6 +513,7 @@ private: QLabel* game_fps_label = nullptr; QLabel* emu_frametime_label = nullptr; QLabel* tas_label = nullptr; + QLabel* firmware_label = nullptr; QPushButton* gpu_accuracy_button = nullptr; QPushButton* renderer_status_button = nullptr; QPushButton* dock_status_button = nullptr; @@ -534,7 +535,6 @@ private: bool auto_paused = false; bool auto_muted = false; QTimer mouse_hide_timer; - QTimer mouse_center_timer; QTimer update_input_timer; QString startup_icon_theme; @@ -591,5 +591,4 @@ protected: void dropEvent(QDropEvent* event) override; void dragEnterEvent(QDragEnterEvent* event) override; void dragMoveEvent(QDragMoveEvent* event) override; - void leaveEvent(QEvent* event) override; }; |