summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
m---------externals/dynarmic0
-rw-r--r--src/yuzu/applets/qt_software_keyboard.cpp2
-rw-r--r--src/yuzu/main.cpp174
-rw-r--r--src/yuzu/main.h9
-rw-r--r--src/yuzu/util/overlay_dialog.cpp2
5 files changed, 155 insertions, 32 deletions
diff --git a/externals/dynarmic b/externals/dynarmic
Subproject befe547d5631024a70d81d2ccee808bbfcb3854 Subproject 165621a872ffb802c7a26ef5900e1e62681f1a8
diff --git a/src/yuzu/applets/qt_software_keyboard.cpp b/src/yuzu/applets/qt_software_keyboard.cpp
index 734b0ea40..4ae49506d 100644
--- a/src/yuzu/applets/qt_software_keyboard.cpp
+++ b/src/yuzu/applets/qt_software_keyboard.cpp
@@ -575,7 +575,7 @@ void QtSoftwareKeyboardDialog::MoveAndResizeWindow(QPoint pos, QSize size) {
575 QDialog::resize(size); 575 QDialog::resize(size);
576 576
577 // High DPI 577 // High DPI
578 const float dpi_scale = qApp->screenAt(pos)->logicalDotsPerInch() / 96.0f; 578 const float dpi_scale = screen()->logicalDotsPerInch() / 96.0f;
579 579
580 RescaleKeyboardElements(size.width(), size.height(), dpi_scale); 580 RescaleKeyboardElements(size.width(), size.height(), dpi_scale);
581} 581}
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index 42b7b64c8..f28268e9b 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -680,8 +680,10 @@ void GMainWindow::SoftwareKeyboardShowNormal() {
680 const auto y = layout.screen.top; 680 const auto y = layout.screen.top;
681 const auto w = layout.screen.GetWidth(); 681 const auto w = layout.screen.GetWidth();
682 const auto h = layout.screen.GetHeight(); 682 const auto h = layout.screen.GetHeight();
683 const auto scale_ratio = devicePixelRatioF();
683 684
684 software_keyboard->ShowNormalKeyboard(render_window->mapToGlobal(QPoint(x, y)), QSize(w, h)); 685 software_keyboard->ShowNormalKeyboard(render_window->mapToGlobal(QPoint(x, y) / scale_ratio),
686 QSize(w, h) / scale_ratio);
685} 687}
686 688
687void GMainWindow::SoftwareKeyboardShowTextCheck( 689void GMainWindow::SoftwareKeyboardShowTextCheck(
@@ -714,9 +716,11 @@ void GMainWindow::SoftwareKeyboardShowInline(
714 (1.0f - appear_parameters.key_top_scale_y)))); 716 (1.0f - appear_parameters.key_top_scale_y))));
715 const auto w = static_cast<int>(layout.screen.GetWidth() * appear_parameters.key_top_scale_x); 717 const auto w = static_cast<int>(layout.screen.GetWidth() * appear_parameters.key_top_scale_x);
716 const auto h = static_cast<int>(layout.screen.GetHeight() * appear_parameters.key_top_scale_y); 718 const auto h = static_cast<int>(layout.screen.GetHeight() * appear_parameters.key_top_scale_y);
719 const auto scale_ratio = devicePixelRatioF();
717 720
718 software_keyboard->ShowInlineKeyboard(std::move(appear_parameters), 721 software_keyboard->ShowInlineKeyboard(std::move(appear_parameters),
719 render_window->mapToGlobal(QPoint(x, y)), QSize(w, h)); 722 render_window->mapToGlobal(QPoint(x, y) / scale_ratio),
723 QSize(w, h) / scale_ratio);
720} 724}
721 725
722void GMainWindow::SoftwareKeyboardHideInline() { 726void GMainWindow::SoftwareKeyboardHideInline() {
@@ -796,10 +800,11 @@ void GMainWindow::WebBrowserOpenWebPage(const std::string& main_url,
796 } 800 }
797 801
798 const auto& layout = render_window->GetFramebufferLayout(); 802 const auto& layout = render_window->GetFramebufferLayout();
799 web_browser_view.resize(layout.screen.GetWidth(), layout.screen.GetHeight()); 803 const auto scale_ratio = devicePixelRatioF();
800 web_browser_view.move(layout.screen.left, layout.screen.top + menuBar()->height()); 804 web_browser_view.resize(layout.screen.GetWidth() / scale_ratio,
801 web_browser_view.setZoomFactor(static_cast<qreal>(layout.screen.GetWidth()) / 805 layout.screen.GetHeight() / scale_ratio);
802 static_cast<qreal>(Layout::ScreenUndocked::Width)); 806 web_browser_view.move(layout.screen.left / scale_ratio,
807 (layout.screen.top / scale_ratio) + menuBar()->height());
803 808
804 web_browser_view.setFocus(); 809 web_browser_view.setFocus();
805 web_browser_view.show(); 810 web_browser_view.show();
@@ -957,6 +962,38 @@ void GMainWindow::InitializeWidgets() {
957 tas_label->setFocusPolicy(Qt::NoFocus); 962 tas_label->setFocusPolicy(Qt::NoFocus);
958 statusBar()->insertPermanentWidget(0, tas_label); 963 statusBar()->insertPermanentWidget(0, tas_label);
959 964
965 volume_popup = new QWidget(this);
966 volume_popup->setWindowFlags(Qt::FramelessWindowHint | Qt::NoDropShadowWindowHint | Qt::Popup);
967 volume_popup->setLayout(new QVBoxLayout());
968 volume_popup->setMinimumWidth(200);
969
970 volume_slider = new QSlider(Qt::Horizontal);
971 volume_slider->setObjectName(QStringLiteral("volume_slider"));
972 volume_slider->setMaximum(200);
973 volume_slider->setPageStep(5);
974 connect(volume_slider, &QSlider::valueChanged, this, [this](int percentage) {
975 Settings::values.audio_muted = false;
976 const auto volume = static_cast<u8>(percentage);
977 Settings::values.volume.SetValue(volume);
978 UpdateVolumeUI();
979 });
980 volume_popup->layout()->addWidget(volume_slider);
981
982 volume_button = new QPushButton();
983 volume_button->setObjectName(QStringLiteral("TogglableStatusBarButton"));
984 volume_button->setFocusPolicy(Qt::NoFocus);
985 volume_button->setCheckable(true);
986 UpdateVolumeUI();
987 connect(volume_button, &QPushButton::clicked, this, [&] {
988 UpdateVolumeUI();
989 volume_popup->setVisible(!volume_popup->isVisible());
990 QRect rect = volume_button->geometry();
991 QPoint bottomLeft = statusBar()->mapToGlobal(rect.topLeft());
992 bottomLeft.setY(bottomLeft.y() - volume_popup->geometry().height());
993 volume_popup->setGeometry(QRect(bottomLeft, QSize(rect.width(), rect.height())));
994 });
995 statusBar()->insertPermanentWidget(0, volume_button);
996
960 // setup AA button 997 // setup AA button
961 aa_status_button = new QPushButton(); 998 aa_status_button = new QPushButton();
962 aa_status_button->setObjectName(QStringLiteral("TogglableStatusBarButton")); 999 aa_status_button->setObjectName(QStringLiteral("TogglableStatusBarButton"));
@@ -1119,30 +1156,9 @@ void GMainWindow::InitializeHotkeys() {
1119 &GMainWindow::OnToggleAdaptingFilter); 1156 &GMainWindow::OnToggleAdaptingFilter);
1120 connect_shortcut(QStringLiteral("Change Docked Mode"), &GMainWindow::OnToggleDockedMode); 1157 connect_shortcut(QStringLiteral("Change Docked Mode"), &GMainWindow::OnToggleDockedMode);
1121 connect_shortcut(QStringLiteral("Change GPU Accuracy"), &GMainWindow::OnToggleGpuAccuracy); 1158 connect_shortcut(QStringLiteral("Change GPU Accuracy"), &GMainWindow::OnToggleGpuAccuracy);
1122 connect_shortcut(QStringLiteral("Audio Mute/Unmute"), 1159 connect_shortcut(QStringLiteral("Audio Mute/Unmute"), &GMainWindow::OnMute);
1123 [] { Settings::values.audio_muted = !Settings::values.audio_muted; }); 1160 connect_shortcut(QStringLiteral("Audio Volume Down"), &GMainWindow::OnDecreaseVolume);
1124 connect_shortcut(QStringLiteral("Audio Volume Down"), [] { 1161 connect_shortcut(QStringLiteral("Audio Volume Up"), &GMainWindow::OnIncreaseVolume);
1125 const auto current_volume = static_cast<s32>(Settings::values.volume.GetValue());
1126 int step = 5;
1127 if (current_volume <= 30) {
1128 step = 2;
1129 }
1130 if (current_volume <= 6) {
1131 step = 1;
1132 }
1133 Settings::values.volume.SetValue(std::max(current_volume - step, 0));
1134 });
1135 connect_shortcut(QStringLiteral("Audio Volume Up"), [] {
1136 const auto current_volume = static_cast<s32>(Settings::values.volume.GetValue());
1137 int step = 5;
1138 if (current_volume < 30) {
1139 step = 2;
1140 }
1141 if (current_volume < 6) {
1142 step = 1;
1143 }
1144 Settings::values.volume.SetValue(current_volume + step);
1145 });
1146 connect_shortcut(QStringLiteral("Toggle Framerate Limit"), [] { 1162 connect_shortcut(QStringLiteral("Toggle Framerate Limit"), [] {
1147 Settings::values.use_speed_limit.SetValue(!Settings::values.use_speed_limit.GetValue()); 1163 Settings::values.use_speed_limit.SetValue(!Settings::values.use_speed_limit.GetValue());
1148 }); 1164 });
@@ -3456,6 +3472,39 @@ void GMainWindow::OnToggleGpuAccuracy() {
3456 UpdateGPUAccuracyButton(); 3472 UpdateGPUAccuracyButton();
3457} 3473}
3458 3474
3475void GMainWindow::OnMute() {
3476 Settings::values.audio_muted = !Settings::values.audio_muted;
3477 UpdateVolumeUI();
3478}
3479
3480void GMainWindow::OnDecreaseVolume() {
3481 Settings::values.audio_muted = false;
3482 const auto current_volume = static_cast<s32>(Settings::values.volume.GetValue());
3483 int step = 5;
3484 if (current_volume <= 30) {
3485 step = 2;
3486 }
3487 if (current_volume <= 6) {
3488 step = 1;
3489 }
3490 Settings::values.volume.SetValue(std::max(current_volume - step, 0));
3491 UpdateVolumeUI();
3492}
3493
3494void GMainWindow::OnIncreaseVolume() {
3495 Settings::values.audio_muted = false;
3496 const auto current_volume = static_cast<s32>(Settings::values.volume.GetValue());
3497 int step = 5;
3498 if (current_volume < 30) {
3499 step = 2;
3500 }
3501 if (current_volume < 6) {
3502 step = 1;
3503 }
3504 Settings::values.volume.SetValue(current_volume + step);
3505 UpdateVolumeUI();
3506}
3507
3459void GMainWindow::OnToggleAdaptingFilter() { 3508void GMainWindow::OnToggleAdaptingFilter() {
3460 auto filter = Settings::values.scaling_filter.GetValue(); 3509 auto filter = Settings::values.scaling_filter.GetValue();
3461 if (filter == Settings::ScalingFilter::LastFilter) { 3510 if (filter == Settings::ScalingFilter::LastFilter) {
@@ -3914,6 +3963,18 @@ void GMainWindow::UpdateAAText() {
3914 } 3963 }
3915} 3964}
3916 3965
3966void GMainWindow::UpdateVolumeUI() {
3967 const auto volume_value = static_cast<int>(Settings::values.volume.GetValue());
3968 volume_slider->setValue(volume_value);
3969 if (Settings::values.audio_muted) {
3970 volume_button->setChecked(false);
3971 volume_button->setText(tr("VOLUME: MUTE"));
3972 } else {
3973 volume_button->setChecked(true);
3974 volume_button->setText(tr("VOLUME: %1%", "Volume percentage (e.g. 50%)").arg(volume_value));
3975 }
3976}
3977
3917void GMainWindow::UpdateStatusButtons() { 3978void GMainWindow::UpdateStatusButtons() {
3918 renderer_status_button->setChecked(Settings::values.renderer_backend.GetValue() == 3979 renderer_status_button->setChecked(Settings::values.renderer_backend.GetValue() ==
3919 Settings::RendererBackend::Vulkan); 3980 Settings::RendererBackend::Vulkan);
@@ -3922,6 +3983,7 @@ void GMainWindow::UpdateStatusButtons() {
3922 UpdateDockedButton(); 3983 UpdateDockedButton();
3923 UpdateFilterText(); 3984 UpdateFilterText();
3924 UpdateAAText(); 3985 UpdateAAText();
3986 UpdateVolumeUI();
3925} 3987}
3926 3988
3927void GMainWindow::UpdateUISettings() { 3989void GMainWindow::UpdateUISettings() {
@@ -4391,6 +4453,55 @@ void GMainWindow::changeEvent(QEvent* event) {
4391#undef main 4453#undef main
4392#endif 4454#endif
4393 4455
4456static void SetHighDPIAttributes() {
4457#ifdef _WIN32
4458 // For Windows, we want to avoid scaling artifacts on fractional scaling ratios.
4459 // This is done by setting the optimal scaling policy for the primary screen.
4460
4461 // Create a temporary QApplication.
4462 int temp_argc = 0;
4463 char** temp_argv = nullptr;
4464 QApplication temp{temp_argc, temp_argv};
4465
4466 // Get the current screen geometry.
4467 const QScreen* primary_screen = QGuiApplication::primaryScreen();
4468 if (primary_screen == nullptr) {
4469 return;
4470 }
4471
4472 const QRect screen_rect = primary_screen->geometry();
4473 const int real_width = screen_rect.width();
4474 const int real_height = screen_rect.height();
4475 const float real_ratio = primary_screen->logicalDotsPerInch() / 96.0f;
4476
4477 // Recommended minimum width and height for proper window fit.
4478 // Any screen with a lower resolution than this will still have a scale of 1.
4479 constexpr float minimum_width = 1350.0f;
4480 constexpr float minimum_height = 900.0f;
4481
4482 const float width_ratio = std::max(1.0f, real_width / minimum_width);
4483 const float height_ratio = std::max(1.0f, real_height / minimum_height);
4484
4485 // Get the lower of the 2 ratios and truncate, this is the maximum integer scale.
4486 const float max_ratio = std::trunc(std::min(width_ratio, height_ratio));
4487
4488 if (max_ratio > real_ratio) {
4489 QApplication::setHighDpiScaleFactorRoundingPolicy(
4490 Qt::HighDpiScaleFactorRoundingPolicy::Round);
4491 } else {
4492 QApplication::setHighDpiScaleFactorRoundingPolicy(
4493 Qt::HighDpiScaleFactorRoundingPolicy::Floor);
4494 }
4495#else
4496 // Other OSes should be better than Windows at fractional scaling.
4497 QApplication::setHighDpiScaleFactorRoundingPolicy(
4498 Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
4499#endif
4500
4501 QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
4502 QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
4503}
4504
4394int main(int argc, char* argv[]) { 4505int main(int argc, char* argv[]) {
4395 std::unique_ptr<Config> config = std::make_unique<Config>(); 4506 std::unique_ptr<Config> config = std::make_unique<Config>();
4396 bool has_broken_vulkan = false; 4507 bool has_broken_vulkan = false;
@@ -4446,6 +4557,8 @@ int main(int argc, char* argv[]) {
4446 } 4557 }
4447#endif 4558#endif
4448 4559
4560 SetHighDPIAttributes();
4561
4449#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) 4562#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
4450 // Disables the "?" button on all dialogs. Disabled by default on Qt6. 4563 // Disables the "?" button on all dialogs. Disabled by default on Qt6.
4451 QCoreApplication::setAttribute(Qt::AA_DisableWindowContextHelpButton); 4564 QCoreApplication::setAttribute(Qt::AA_DisableWindowContextHelpButton);
@@ -4453,6 +4566,7 @@ int main(int argc, char* argv[]) {
4453 4566
4454 // Enables the core to make the qt created contexts current on std::threads 4567 // Enables the core to make the qt created contexts current on std::threads
4455 QCoreApplication::setAttribute(Qt::AA_DontCheckOpenGLContextThreadAffinity); 4568 QCoreApplication::setAttribute(Qt::AA_DontCheckOpenGLContextThreadAffinity);
4569
4456 QApplication app(argc, argv); 4570 QApplication app(argc, argv);
4457 4571
4458#ifdef _WIN32 4572#ifdef _WIN32
diff --git a/src/yuzu/main.h b/src/yuzu/main.h
index 0f61abc7a..a23b373a5 100644
--- a/src/yuzu/main.h
+++ b/src/yuzu/main.h
@@ -37,6 +37,8 @@ class QLabel;
37class MultiplayerState; 37class MultiplayerState;
38class QPushButton; 38class QPushButton;
39class QProgressDialog; 39class QProgressDialog;
40class QSlider;
41class QHBoxLayout;
40class WaitTreeWidget; 42class WaitTreeWidget;
41enum class GameListOpenTarget; 43enum class GameListOpenTarget;
42enum class GameListRemoveTarget; 44enum class GameListRemoveTarget;
@@ -312,6 +314,9 @@ private slots:
312 void OnMenuRecentFile(); 314 void OnMenuRecentFile();
313 void OnConfigure(); 315 void OnConfigure();
314 void OnConfigureTas(); 316 void OnConfigureTas();
317 void OnDecreaseVolume();
318 void OnIncreaseVolume();
319 void OnMute();
315 void OnTasStartStop(); 320 void OnTasStartStop();
316 void OnTasRecord(); 321 void OnTasRecord();
317 void OnTasReset(); 322 void OnTasReset();
@@ -364,6 +369,7 @@ private:
364 void UpdateAPIText(); 369 void UpdateAPIText();
365 void UpdateFilterText(); 370 void UpdateFilterText();
366 void UpdateAAText(); 371 void UpdateAAText();
372 void UpdateVolumeUI();
367 void UpdateStatusBar(); 373 void UpdateStatusBar();
368 void UpdateGPUAccuracyButton(); 374 void UpdateGPUAccuracyButton();
369 void UpdateStatusButtons(); 375 void UpdateStatusButtons();
@@ -412,6 +418,9 @@ private:
412 QPushButton* dock_status_button = nullptr; 418 QPushButton* dock_status_button = nullptr;
413 QPushButton* filter_status_button = nullptr; 419 QPushButton* filter_status_button = nullptr;
414 QPushButton* aa_status_button = nullptr; 420 QPushButton* aa_status_button = nullptr;
421 QPushButton* volume_button = nullptr;
422 QWidget* volume_popup = nullptr;
423 QSlider* volume_slider = nullptr;
415 QTimer status_bar_update_timer; 424 QTimer status_bar_update_timer;
416 425
417 std::unique_ptr<Config> config; 426 std::unique_ptr<Config> config;
diff --git a/src/yuzu/util/overlay_dialog.cpp b/src/yuzu/util/overlay_dialog.cpp
index 796f5bf41..ee35a3e15 100644
--- a/src/yuzu/util/overlay_dialog.cpp
+++ b/src/yuzu/util/overlay_dialog.cpp
@@ -163,7 +163,7 @@ void OverlayDialog::MoveAndResizeWindow() {
163 const auto height = static_cast<float>(parentWidget()->height()); 163 const auto height = static_cast<float>(parentWidget()->height());
164 164
165 // High DPI 165 // High DPI
166 const float dpi_scale = parentWidget()->windowHandle()->screen()->logicalDotsPerInch() / 96.0f; 166 const float dpi_scale = screen()->logicalDotsPerInch() / 96.0f;
167 167
168 const auto title_text_font_size = BASE_TITLE_FONT_SIZE * (height / BASE_HEIGHT) / dpi_scale; 168 const auto title_text_font_size = BASE_TITLE_FONT_SIZE * (height / BASE_HEIGHT) / dpi_scale;
169 const auto body_text_font_size = 169 const auto body_text_font_size =