summaryrefslogtreecommitdiff
path: root/src/yuzu
diff options
context:
space:
mode:
Diffstat (limited to 'src/yuzu')
-rw-r--r--src/yuzu/bootmanager.cpp56
-rw-r--r--src/yuzu/bootmanager.h6
-rw-r--r--src/yuzu/configuration/configure_debug.cpp3
-rw-r--r--src/yuzu/configuration/configure_debug.ui86
-rw-r--r--src/yuzu/main.cpp83
-rw-r--r--src/yuzu/main.h5
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>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;When checked, disables reording of mapped memory uploads which allows to associate uploads with specific draws. May reduce performance in some cases.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</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;
};