citra-qt: Add an "Alternative Speed Limit" with its hotkey (#5281)
* Change "Toggle Speed Limit" to toggle between 100% and a custom value This will change the shortcut for "Toggle Speed Limit" to make it swap between 100% and the value of "Limit Speed Percent" in the config. Old functionality is still there, but renamed to "Unthrottle". * Complete reimplementation of the function * Fix something that didn't get saved correctly * Fix missing indentation * Rewrite to keep only a single QSpinBox * Second rewrite * set Unthrottled to 0 in the Qspinbox * Hotkey for Unthrottle * minor improvements to the design * Apply suggestions from code review Co-authored-by: Ben <bene_thomas@web.de> * Default slider values * clang-format fixes * Prevent the speed slider from changing size ...when an element in its row has variable width. * Change "Game Speed" to "Emulation Speed" * Apply suggestions from code review `game_speed` to` emulation_speed` Co-authored-by: Valentin Vanelslande <vvanelslandedev@gmail.com> * Fix for QSliders * Revert "Prevent the speed slider from changing size" This reverts commit ddaca2004484f1e024f49d2e6dc99ef5e261f64d. * clang-format ...doesn't seem to stick to a choice * Fix 2 for QSliders Co-authored-by: B3n30 <benediktthomas@gmail.com> Co-authored-by: Ben <bene_thomas@web.de> Co-authored-by: Valentin Vanelslande <vvanelslandedev@gmail.com>
This commit is contained in:
		| @@ -123,11 +123,14 @@ void Config::ReadValues() { | |||||||
|     Settings::values.use_shader_jit = sdl2_config->GetBoolean("Renderer", "use_shader_jit", true); |     Settings::values.use_shader_jit = sdl2_config->GetBoolean("Renderer", "use_shader_jit", true); | ||||||
|     Settings::values.resolution_factor = |     Settings::values.resolution_factor = | ||||||
|         static_cast<u16>(sdl2_config->GetInteger("Renderer", "resolution_factor", 1)); |         static_cast<u16>(sdl2_config->GetInteger("Renderer", "resolution_factor", 1)); | ||||||
|     Settings::values.use_frame_limit = sdl2_config->GetBoolean("Renderer", "use_frame_limit", true); |  | ||||||
|     Settings::values.use_disk_shader_cache = |     Settings::values.use_disk_shader_cache = | ||||||
|         sdl2_config->GetBoolean("Renderer", "use_disk_shader_cache", true); |         sdl2_config->GetBoolean("Renderer", "use_disk_shader_cache", true); | ||||||
|     Settings::values.frame_limit = |     Settings::values.frame_limit = | ||||||
|         static_cast<u16>(sdl2_config->GetInteger("Renderer", "frame_limit", 100)); |         static_cast<u16>(sdl2_config->GetInteger("Renderer", "frame_limit", 100)); | ||||||
|  |     Settings::values.use_frame_limit_alternate = | ||||||
|  |         sdl2_config->GetBoolean("Renderer", "use_frame_limit_alternate", false); | ||||||
|  |     Settings::values.frame_limit_alternate = | ||||||
|  |         static_cast<u16>(sdl2_config->GetInteger("Renderer", "frame_limit_alternate", 200)); | ||||||
|     Settings::values.use_vsync_new = |     Settings::values.use_vsync_new = | ||||||
|         static_cast<u16>(sdl2_config->GetInteger("Renderer", "use_vsync_new", 1)); |         static_cast<u16>(sdl2_config->GetInteger("Renderer", "use_vsync_new", 1)); | ||||||
|     Settings::values.texture_filter_name = |     Settings::values.texture_filter_name = | ||||||
|   | |||||||
| @@ -139,14 +139,19 @@ resolution_factor = | |||||||
| # Texture filter name | # Texture filter name | ||||||
| texture_filter_name = | texture_filter_name = | ||||||
|  |  | ||||||
| # Turns on the frame limiter, which will limit frames output to the target game speed | # Limits the speed of the game to run no faster than this value as a percentage of target speed. | ||||||
| # 0: Off, 1: On (default) | # Will not have an effect if unthrottled is enabled. | ||||||
| use_frame_limit = | # 5 - 995: Speed limit as a percentage of target game speed. 0 for unthrottled. 100 (default) | ||||||
|  |  | ||||||
| # Limits the speed of the game to run no faster than this value as a percentage of target speed |  | ||||||
| # 1 - 9999: Speed limit as a percentage of target game speed. 100 (default) |  | ||||||
| frame_limit = | frame_limit = | ||||||
|  |  | ||||||
|  | # Overrides the frame limiter to use frame_limit_alternate instead of frame_limit. | ||||||
|  | # 0: Off (default), 1: On | ||||||
|  | use_frame_limit_alternate = | ||||||
|  |  | ||||||
|  | # Alternate speed limit to be used instead of frame_limit if use_frame_limit_alternate is enabled | ||||||
|  | # 5 - 995: Speed limit as a percentage of target game speed. 0 for unthrottled. 200 (default) | ||||||
|  | frame_limit_alternate = | ||||||
|  |  | ||||||
| # The clear color for the renderer. What shows up on the sides of the bottom screen. | # The clear color for the renderer. What shows up on the sides of the bottom screen. | ||||||
| # Must be in range of 0.0-1.0. Defaults to 0.0 for all. | # Must be in range of 0.0-1.0. Defaults to 0.0 for all. | ||||||
| bg_red = | bg_red = | ||||||
|   | |||||||
| @@ -78,7 +78,7 @@ const std::array<UISettings::Shortcut, 23> default_hotkeys{ | |||||||
|      {QStringLiteral("Toggle Filter Bar"),        QStringLiteral("Main Window"), {QStringLiteral("Ctrl+F"), Qt::WindowShortcut}}, |      {QStringLiteral("Toggle Filter Bar"),        QStringLiteral("Main Window"), {QStringLiteral("Ctrl+F"), Qt::WindowShortcut}}, | ||||||
|      {QStringLiteral("Toggle Frame Advancing"),   QStringLiteral("Main Window"), {QStringLiteral("Ctrl+A"), Qt::ApplicationShortcut}}, |      {QStringLiteral("Toggle Frame Advancing"),   QStringLiteral("Main Window"), {QStringLiteral("Ctrl+A"), Qt::ApplicationShortcut}}, | ||||||
|      {QStringLiteral("Toggle Screen Layout"),     QStringLiteral("Main Window"), {QStringLiteral("F10"), Qt::WindowShortcut}}, |      {QStringLiteral("Toggle Screen Layout"),     QStringLiteral("Main Window"), {QStringLiteral("F10"), Qt::WindowShortcut}}, | ||||||
|      {QStringLiteral("Toggle Speed Limit"),       QStringLiteral("Main Window"), {QStringLiteral("Ctrl+Z"), Qt::ApplicationShortcut}}, |      {QStringLiteral("Toggle Alternate Speed"),   QStringLiteral("Main Window"), {QStringLiteral("Ctrl+Z"), Qt::ApplicationShortcut}}, | ||||||
|      {QStringLiteral("Toggle Status Bar"),        QStringLiteral("Main Window"), {QStringLiteral("Ctrl+S"), Qt::WindowShortcut}}, |      {QStringLiteral("Toggle Status Bar"),        QStringLiteral("Main Window"), {QStringLiteral("Ctrl+S"), Qt::WindowShortcut}}, | ||||||
|      {QStringLiteral("Toggle Texture Dumping"),   QStringLiteral("Main Window"), {QStringLiteral("Ctrl+D"), Qt::ApplicationShortcut}}}}; |      {QStringLiteral("Toggle Texture Dumping"),   QStringLiteral("Main Window"), {QStringLiteral("Ctrl+D"), Qt::ApplicationShortcut}}}}; | ||||||
| // clang-format on | // clang-format on | ||||||
| @@ -483,9 +483,11 @@ void Config::ReadRendererValues() { | |||||||
|     Settings::values.use_vsync_new = ReadSetting(QStringLiteral("use_vsync_new"), true).toBool(); |     Settings::values.use_vsync_new = ReadSetting(QStringLiteral("use_vsync_new"), true).toBool(); | ||||||
|     Settings::values.resolution_factor = |     Settings::values.resolution_factor = | ||||||
|         static_cast<u16>(ReadSetting(QStringLiteral("resolution_factor"), 1).toInt()); |         static_cast<u16>(ReadSetting(QStringLiteral("resolution_factor"), 1).toInt()); | ||||||
|     Settings::values.use_frame_limit = |  | ||||||
|         ReadSetting(QStringLiteral("use_frame_limit"), true).toBool(); |  | ||||||
|     Settings::values.frame_limit = ReadSetting(QStringLiteral("frame_limit"), 100).toInt(); |     Settings::values.frame_limit = ReadSetting(QStringLiteral("frame_limit"), 100).toInt(); | ||||||
|  |     Settings::values.use_frame_limit_alternate = | ||||||
|  |         ReadSetting(QStringLiteral("use_frame_limit_alternate"), false).toBool(); | ||||||
|  |     Settings::values.frame_limit_alternate = | ||||||
|  |         ReadSetting(QStringLiteral("frame_limit_alternate"), 200).toInt(); | ||||||
|  |  | ||||||
|     Settings::values.bg_red = ReadSetting(QStringLiteral("bg_red"), 0.0).toFloat(); |     Settings::values.bg_red = ReadSetting(QStringLiteral("bg_red"), 0.0).toFloat(); | ||||||
|     Settings::values.bg_green = ReadSetting(QStringLiteral("bg_green"), 0.0).toFloat(); |     Settings::values.bg_green = ReadSetting(QStringLiteral("bg_green"), 0.0).toFloat(); | ||||||
| @@ -983,8 +985,11 @@ void Config::SaveRendererValues() { | |||||||
|     WriteSetting(QStringLiteral("use_shader_jit"), Settings::values.use_shader_jit, true); |     WriteSetting(QStringLiteral("use_shader_jit"), Settings::values.use_shader_jit, true); | ||||||
|     WriteSetting(QStringLiteral("use_vsync_new"), Settings::values.use_vsync_new, true); |     WriteSetting(QStringLiteral("use_vsync_new"), Settings::values.use_vsync_new, true); | ||||||
|     WriteSetting(QStringLiteral("resolution_factor"), Settings::values.resolution_factor, 1); |     WriteSetting(QStringLiteral("resolution_factor"), Settings::values.resolution_factor, 1); | ||||||
|     WriteSetting(QStringLiteral("use_frame_limit"), Settings::values.use_frame_limit, true); |  | ||||||
|     WriteSetting(QStringLiteral("frame_limit"), Settings::values.frame_limit, 100); |     WriteSetting(QStringLiteral("frame_limit"), Settings::values.frame_limit, 100); | ||||||
|  |     WriteSetting(QStringLiteral("use_frame_limit_alternate"), | ||||||
|  |                  Settings::values.use_frame_limit_alternate, false); | ||||||
|  |     WriteSetting(QStringLiteral("frame_limit_alternate"), Settings::values.frame_limit_alternate, | ||||||
|  |                  200); | ||||||
|  |  | ||||||
|     // Cast to double because Qt's written float values are not human-readable |     // Cast to double because Qt's written float values are not human-readable | ||||||
|     WriteSetting(QStringLiteral("bg_red"), (double)Settings::values.bg_red, 0.0); |     WriteSetting(QStringLiteral("bg_red"), (double)Settings::values.bg_red, 0.0); | ||||||
|   | |||||||
| @@ -9,17 +9,53 @@ | |||||||
| #include "core/settings.h" | #include "core/settings.h" | ||||||
| #include "ui_configure_general.h" | #include "ui_configure_general.h" | ||||||
|  |  | ||||||
|  | // The QSlider doesn't have an easy way to set a custom step amount, | ||||||
|  | // so we can just convert from the sliders range (0 - 198) to the expected | ||||||
|  | // settings range (5 - 995) with simple math. | ||||||
|  | static constexpr int SliderToSettings(int value) { | ||||||
|  |     return 5 * value + 5; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static constexpr int SettingsToSlider(int value) { | ||||||
|  |     return (value - 5) / 5; | ||||||
|  | } | ||||||
|  |  | ||||||
| ConfigureGeneral::ConfigureGeneral(QWidget* parent) | ConfigureGeneral::ConfigureGeneral(QWidget* parent) | ||||||
|     : QWidget(parent), ui(new Ui::ConfigureGeneral) { |     : QWidget(parent), ui(new Ui::ConfigureGeneral) { | ||||||
|  |  | ||||||
|     ui->setupUi(this); |     ui->setupUi(this); | ||||||
|     SetConfiguration(); |  | ||||||
|  |  | ||||||
|     connect(ui->toggle_frame_limit, &QCheckBox::toggled, ui->frame_limit, &QSpinBox::setEnabled); |     // Set a minimum width for the label to prevent the slider from changing size. | ||||||
|  |     // This scales across DPIs, and is acceptable for uncapitalized strings. | ||||||
|  |     ui->emulation_speed_display_label->setMinimumWidth(tr("unthrottled").size() * 6); | ||||||
|  |  | ||||||
|  |     SetConfiguration(); | ||||||
|  |  | ||||||
|     ui->updateBox->setVisible(UISettings::values.updater_found); |     ui->updateBox->setVisible(UISettings::values.updater_found); | ||||||
|     connect(ui->button_reset_defaults, &QPushButton::clicked, this, |     connect(ui->button_reset_defaults, &QPushButton::clicked, this, | ||||||
|             &ConfigureGeneral::ResetDefaults); |             &ConfigureGeneral::ResetDefaults); | ||||||
|  |  | ||||||
|  |     connect(ui->frame_limit, &QSlider::valueChanged, [&](int value) { | ||||||
|  |         if (value == ui->frame_limit->maximum()) { | ||||||
|  |             ui->emulation_speed_display_label->setText(tr("unthrottled")); | ||||||
|  |         } else { | ||||||
|  |             ui->emulation_speed_display_label->setText( | ||||||
|  |                 QStringLiteral("%1%") | ||||||
|  |                     .arg(SliderToSettings(value)) | ||||||
|  |                     .rightJustified(tr("unthrottled").size())); | ||||||
|  |         } | ||||||
|  |     }); | ||||||
|  |  | ||||||
|  |     connect(ui->frame_limit_alternate, &QSlider::valueChanged, [&](int value) { | ||||||
|  |         if (value == ui->frame_limit_alternate->maximum()) { | ||||||
|  |             ui->emulation_speed_alternate_display_label->setText(tr("unthrottled")); | ||||||
|  |         } else { | ||||||
|  |             ui->emulation_speed_alternate_display_label->setText( | ||||||
|  |                 QStringLiteral("%1%") | ||||||
|  |                     .arg(SliderToSettings(value)) | ||||||
|  |                     .rightJustified(tr("unthrottled").size())); | ||||||
|  |         } | ||||||
|  |     }); | ||||||
| } | } | ||||||
|  |  | ||||||
| ConfigureGeneral::~ConfigureGeneral() = default; | ConfigureGeneral::~ConfigureGeneral() = default; | ||||||
| @@ -35,9 +71,36 @@ void ConfigureGeneral::SetConfiguration() { | |||||||
|     // The first item is "auto-select" with actual value -1, so plus one here will do the trick |     // The first item is "auto-select" with actual value -1, so plus one here will do the trick | ||||||
|     ui->region_combobox->setCurrentIndex(Settings::values.region_value + 1); |     ui->region_combobox->setCurrentIndex(Settings::values.region_value + 1); | ||||||
|  |  | ||||||
|     ui->toggle_frame_limit->setChecked(Settings::values.use_frame_limit); |     if (Settings::values.frame_limit == 0) { | ||||||
|     ui->frame_limit->setEnabled(ui->toggle_frame_limit->isChecked()); |         ui->frame_limit->setValue(ui->frame_limit->maximum()); | ||||||
|     ui->frame_limit->setValue(Settings::values.frame_limit); |     } else { | ||||||
|  |         ui->frame_limit->setValue(SettingsToSlider(Settings::values.frame_limit)); | ||||||
|  |     } | ||||||
|  |     if (ui->frame_limit->value() == ui->frame_limit->maximum()) { | ||||||
|  |         ui->emulation_speed_display_label->setText(tr("unthrottled")); | ||||||
|  |     } else { | ||||||
|  |         ui->emulation_speed_display_label->setText( | ||||||
|  |             QStringLiteral("%1%") | ||||||
|  |                 .arg(SliderToSettings(ui->frame_limit->value())) | ||||||
|  |                 .rightJustified(tr("unthrottled").size())); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     ui->toggle_alternate_speed->setChecked(Settings::values.use_frame_limit_alternate); | ||||||
|  |  | ||||||
|  |     if (Settings::values.frame_limit_alternate == 0) { | ||||||
|  |         ui->frame_limit_alternate->setValue(ui->frame_limit_alternate->maximum()); | ||||||
|  |     } else { | ||||||
|  |         ui->frame_limit_alternate->setValue( | ||||||
|  |             SettingsToSlider(Settings::values.frame_limit_alternate)); | ||||||
|  |     } | ||||||
|  |     if (ui->frame_limit_alternate->value() == ui->frame_limit_alternate->maximum()) { | ||||||
|  |         ui->emulation_speed_alternate_display_label->setText(tr("unthrottled")); | ||||||
|  |     } else { | ||||||
|  |         ui->emulation_speed_alternate_display_label->setText( | ||||||
|  |             QStringLiteral("%1%") | ||||||
|  |                 .arg(SliderToSettings(ui->frame_limit_alternate->value())) | ||||||
|  |                 .rightJustified(tr("unthrottled").size())); | ||||||
|  |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| void ConfigureGeneral::ResetDefaults() { | void ConfigureGeneral::ResetDefaults() { | ||||||
| @@ -63,8 +126,18 @@ void ConfigureGeneral::ApplyConfiguration() { | |||||||
|  |  | ||||||
|     Settings::values.region_value = ui->region_combobox->currentIndex() - 1; |     Settings::values.region_value = ui->region_combobox->currentIndex() - 1; | ||||||
|  |  | ||||||
|     Settings::values.use_frame_limit = ui->toggle_frame_limit->isChecked(); |     if (ui->frame_limit->value() == ui->frame_limit->maximum()) { | ||||||
|     Settings::values.frame_limit = ui->frame_limit->value(); |         Settings::values.frame_limit = 0; | ||||||
|  |     } else { | ||||||
|  |         Settings::values.frame_limit = SliderToSettings(ui->frame_limit->value()); | ||||||
|  |     } | ||||||
|  |     Settings::values.use_frame_limit_alternate = ui->toggle_alternate_speed->isChecked(); | ||||||
|  |     if (ui->frame_limit_alternate->value() == ui->frame_limit_alternate->maximum()) { | ||||||
|  |         Settings::values.frame_limit_alternate = 0; | ||||||
|  |     } else { | ||||||
|  |         Settings::values.frame_limit_alternate = | ||||||
|  |             SliderToSettings(ui->frame_limit_alternate->value()); | ||||||
|  |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| void ConfigureGeneral::RetranslateUI() { | void ConfigureGeneral::RetranslateUI() { | ||||||
|   | |||||||
| @@ -6,8 +6,8 @@ | |||||||
|    <rect> |    <rect> | ||||||
|     <x>0</x> |     <x>0</x> | ||||||
|     <y>0</y> |     <y>0</y> | ||||||
|     <width>345</width> |     <width>408</width> | ||||||
|     <height>358</height> |     <height>396</height> | ||||||
|    </rect> |    </rect> | ||||||
|   </property> |   </property> | ||||||
|   <property name="windowTitle"> |   <property name="windowTitle"> | ||||||
| @@ -75,21 +75,7 @@ | |||||||
|         <string>Emulation</string> |         <string>Emulation</string> | ||||||
|        </property> |        </property> | ||||||
|        <layout class="QGridLayout" name="gridLayout"> |        <layout class="QGridLayout" name="gridLayout"> | ||||||
|         <item row="1" column="0"> |         <item row="0" column="2"> | ||||||
|          <widget class="QCheckBox" name="toggle_frame_limit"> |  | ||||||
|           <property name="text"> |  | ||||||
|            <string>Limit Speed Percent</string> |  | ||||||
|           </property> |  | ||||||
|          </widget> |  | ||||||
|         </item> |  | ||||||
|         <item row="0" column="0"> |  | ||||||
|          <widget class="QLabel" name="label"> |  | ||||||
|           <property name="text"> |  | ||||||
|            <string>Region:</string> |  | ||||||
|           </property> |  | ||||||
|          </widget> |  | ||||||
|         </item> |  | ||||||
|         <item row="0" column="1"> |  | ||||||
|          <widget class="QComboBox" name="region_combobox"> |          <widget class="QComboBox" name="region_combobox"> | ||||||
|           <item> |           <item> | ||||||
|            <property name="text"> |            <property name="text"> | ||||||
| @@ -133,19 +119,94 @@ | |||||||
|           </item> |           </item> | ||||||
|          </widget> |          </widget> | ||||||
|         </item> |         </item> | ||||||
|         <item row="1" column="1"> |         <item row="1" column="0"> | ||||||
|          <widget class="QSpinBox" name="frame_limit"> |          <widget class="QLabel" name="label_emulation_speed"> | ||||||
|           <property name="suffix"> |           <property name="text"> | ||||||
|            <string>%</string> |            <string>Emulation Speed:</string> | ||||||
|           </property> |           </property> | ||||||
|  |          </widget> | ||||||
|  |         </item> | ||||||
|  |         <item row="2" column="0"> | ||||||
|  |          <widget class="QCheckBox" name="toggle_alternate_speed"> | ||||||
|  |           <property name="text"> | ||||||
|  |            <string>Use Alternate Speed:</string> | ||||||
|  |           </property> | ||||||
|  |          </widget> | ||||||
|  |         </item> | ||||||
|  |         <item row="1" column="2"> | ||||||
|  |          <widget class="QSlider" name="frame_limit"> | ||||||
|           <property name="minimum"> |           <property name="minimum"> | ||||||
|            <number>1</number> |            <number>0</number> | ||||||
|           </property> |           </property> | ||||||
|           <property name="maximum"> |           <property name="maximum"> | ||||||
|            <number>9999</number> |            <number>199</number> | ||||||
|  |           </property> | ||||||
|  |           <property name="singleStep"> | ||||||
|  |            <number>5</number> | ||||||
|  |           </property> | ||||||
|  |           <property name="pageStep"> | ||||||
|  |            <number>15</number> | ||||||
|           </property> |           </property> | ||||||
|           <property name="value"> |           <property name="value"> | ||||||
|            <number>100</number> |            <number>19</number> | ||||||
|  |           </property> | ||||||
|  |           <property name="orientation"> | ||||||
|  |            <enum>Qt::Horizontal</enum> | ||||||
|  |           </property> | ||||||
|  |           <property name="tickPosition"> | ||||||
|  |            <enum>QSlider::TicksBelow</enum> | ||||||
|  |           </property> | ||||||
|  |          </widget> | ||||||
|  |         </item> | ||||||
|  |         <item row="1" column="1"> | ||||||
|  |          <widget class="QLabel" name="emulation_speed_display_label"> | ||||||
|  |           <property name="text"> | ||||||
|  |            <string/> | ||||||
|  |           </property> | ||||||
|  |           <property name="alignment"> | ||||||
|  |            <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> | ||||||
|  |           </property> | ||||||
|  |          </widget> | ||||||
|  |         </item> | ||||||
|  |         <item row="0" column="0"> | ||||||
|  |          <widget class="QLabel" name="label"> | ||||||
|  |           <property name="text"> | ||||||
|  |            <string>Region:</string> | ||||||
|  |           </property> | ||||||
|  |          </widget> | ||||||
|  |         </item> | ||||||
|  |         <item row="2" column="2"> | ||||||
|  |          <widget class="QSlider" name="frame_limit_alternate"> | ||||||
|  |           <property name="minimum"> | ||||||
|  |            <number>0</number> | ||||||
|  |           </property> | ||||||
|  |           <property name="maximum"> | ||||||
|  |            <number>199</number> | ||||||
|  |           </property> | ||||||
|  |           <property name="singleStep"> | ||||||
|  |            <number>5</number> | ||||||
|  |           </property> | ||||||
|  |           <property name="pageStep"> | ||||||
|  |            <number>15</number> | ||||||
|  |           </property> | ||||||
|  |           <property name="value"> | ||||||
|  |            <number>39</number> | ||||||
|  |           </property> | ||||||
|  |           <property name="orientation"> | ||||||
|  |            <enum>Qt::Horizontal</enum> | ||||||
|  |           </property> | ||||||
|  |           <property name="tickPosition"> | ||||||
|  |            <enum>QSlider::TicksBelow</enum> | ||||||
|  |           </property> | ||||||
|  |          </widget> | ||||||
|  |         </item> | ||||||
|  |         <item row="2" column="1"> | ||||||
|  |          <widget class="QLabel" name="emulation_speed_alternate_display_label"> | ||||||
|  |           <property name="text"> | ||||||
|  |            <string/> | ||||||
|  |           </property> | ||||||
|  |           <property name="alignment"> | ||||||
|  |            <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> | ||||||
|           </property> |           </property> | ||||||
|          </widget> |          </widget> | ||||||
|         </item> |         </item> | ||||||
|   | |||||||
| @@ -244,6 +244,10 @@ ConfigureSystem::ConfigureSystem(QWidget* parent) : QWidget(parent), ui(new Ui:: | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     // Set a minimum width for the label to prevent the slider from changing size. | ||||||
|  |     // This scales across DPIs. (This value should be enough for "xxx%") | ||||||
|  |     ui->clock_display_label->setMinimumWidth(40); | ||||||
|  |  | ||||||
|     connect(ui->slider_clock_speed, &QSlider::valueChanged, [&](int value) { |     connect(ui->slider_clock_speed, &QSlider::valueChanged, [&](int value) { | ||||||
|         ui->clock_display_label->setText(QStringLiteral("%1%").arg(SliderToSettings(value))); |         ui->clock_display_label->setText(QStringLiteral("%1%").arg(SliderToSettings(value))); | ||||||
|     }); |     }); | ||||||
|   | |||||||
| @@ -491,9 +491,10 @@ void GMainWindow::InitializeHotkeys() { | |||||||
|                     ToggleFullscreen(); |                     ToggleFullscreen(); | ||||||
|                 } |                 } | ||||||
|             }); |             }); | ||||||
|     connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Toggle Speed Limit"), this), |     connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Toggle Alternate Speed"), this), | ||||||
|             &QShortcut::activated, this, [&] { |             &QShortcut::activated, this, [&] { | ||||||
|                 Settings::values.use_frame_limit = !Settings::values.use_frame_limit; |                 Settings::values.use_frame_limit_alternate = | ||||||
|  |                     !Settings::values.use_frame_limit_alternate; | ||||||
|                 UpdateStatusBar(); |                 UpdateStatusBar(); | ||||||
|             }); |             }); | ||||||
|     connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Toggle Texture Dumping"), this), |     connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Toggle Texture Dumping"), this), | ||||||
| @@ -504,17 +505,44 @@ void GMainWindow::InitializeHotkeys() { | |||||||
|     static constexpr u16 SPEED_LIMIT_STEP = 5; |     static constexpr u16 SPEED_LIMIT_STEP = 5; | ||||||
|     connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Increase Speed Limit"), this), |     connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Increase Speed Limit"), this), | ||||||
|             &QShortcut::activated, this, [&] { |             &QShortcut::activated, this, [&] { | ||||||
|                 if (Settings::values.frame_limit < 9999 - SPEED_LIMIT_STEP) { |                 if (Settings::values.use_frame_limit_alternate) { | ||||||
|                     Settings::values.frame_limit += SPEED_LIMIT_STEP; |                     if (Settings::values.frame_limit_alternate == 0) { | ||||||
|                     UpdateStatusBar(); |                         return; | ||||||
|  |                     } | ||||||
|  |                     if (Settings::values.frame_limit_alternate < 995 - SPEED_LIMIT_STEP) { | ||||||
|  |                         Settings::values.frame_limit_alternate += SPEED_LIMIT_STEP; | ||||||
|  |                     } else { | ||||||
|  |                         Settings::values.frame_limit_alternate = 0; | ||||||
|  |                     } | ||||||
|  |                 } else { | ||||||
|  |                     if (Settings::values.frame_limit == 0) { | ||||||
|  |                         return; | ||||||
|  |                     } | ||||||
|  |                     if (Settings::values.frame_limit < 995 - SPEED_LIMIT_STEP) { | ||||||
|  |                         Settings::values.frame_limit += SPEED_LIMIT_STEP; | ||||||
|  |                     } else { | ||||||
|  |                         Settings::values.frame_limit = 0; | ||||||
|  |                     } | ||||||
|                 } |                 } | ||||||
|  |                 UpdateStatusBar(); | ||||||
|             }); |             }); | ||||||
|     connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Decrease Speed Limit"), this), |     connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Decrease Speed Limit"), this), | ||||||
|             &QShortcut::activated, this, [&] { |             &QShortcut::activated, this, [&] { | ||||||
|                 if (Settings::values.frame_limit > SPEED_LIMIT_STEP) { |                 if (Settings::values.use_frame_limit_alternate) { | ||||||
|                     Settings::values.frame_limit -= SPEED_LIMIT_STEP; |                     if (Settings::values.frame_limit_alternate == 0) { | ||||||
|                     UpdateStatusBar(); |                         Settings::values.frame_limit_alternate = 995; | ||||||
|  |                     } else if (Settings::values.frame_limit_alternate > SPEED_LIMIT_STEP) { | ||||||
|  |                         Settings::values.frame_limit_alternate -= SPEED_LIMIT_STEP; | ||||||
|  |                     } | ||||||
|  |                 } else { | ||||||
|  |                     if (Settings::values.frame_limit == 0) { | ||||||
|  |                         Settings::values.frame_limit = 995; | ||||||
|  |                     } else if (Settings::values.frame_limit > SPEED_LIMIT_STEP) { | ||||||
|  |                         Settings::values.frame_limit -= SPEED_LIMIT_STEP; | ||||||
|  |                         UpdateStatusBar(); | ||||||
|  |                     } | ||||||
|                 } |                 } | ||||||
|  |                 UpdateStatusBar(); | ||||||
|             }); |             }); | ||||||
|     connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Toggle Frame Advancing"), this), |     connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Toggle Frame Advancing"), this), | ||||||
|             &QShortcut::activated, ui.action_Enable_Frame_Advancing, &QAction::trigger); |             &QShortcut::activated, ui.action_Enable_Frame_Advancing, &QAction::trigger); | ||||||
| @@ -2019,12 +2047,22 @@ void GMainWindow::UpdateStatusBar() { | |||||||
|  |  | ||||||
|     auto results = Core::System::GetInstance().GetAndResetPerfStats(); |     auto results = Core::System::GetInstance().GetAndResetPerfStats(); | ||||||
|  |  | ||||||
|     if (Settings::values.use_frame_limit) { |     if (Settings::values.use_frame_limit_alternate) { | ||||||
|  |         if (Settings::values.frame_limit_alternate == 0) { | ||||||
|  |             emu_speed_label->setText( | ||||||
|  |                 tr("Speed: %1%").arg(results.emulation_speed * 100.0, 0, 'f', 0)); | ||||||
|  |  | ||||||
|  |         } else { | ||||||
|  |             emu_speed_label->setText(tr("Speed: %1% / %2%") | ||||||
|  |                                          .arg(results.emulation_speed * 100.0, 0, 'f', 0) | ||||||
|  |                                          .arg(Settings::values.frame_limit_alternate)); | ||||||
|  |         } | ||||||
|  |     } else if (Settings::values.frame_limit == 0) { | ||||||
|  |         emu_speed_label->setText(tr("Speed: %1%").arg(results.emulation_speed * 100.0, 0, 'f', 0)); | ||||||
|  |     } else { | ||||||
|         emu_speed_label->setText(tr("Speed: %1% / %2%") |         emu_speed_label->setText(tr("Speed: %1% / %2%") | ||||||
|                                      .arg(results.emulation_speed * 100.0, 0, 'f', 0) |                                      .arg(results.emulation_speed * 100.0, 0, 'f', 0) | ||||||
|                                      .arg(Settings::values.frame_limit)); |                                      .arg(Settings::values.frame_limit)); | ||||||
|     } else { |  | ||||||
|         emu_speed_label->setText(tr("Speed: %1%").arg(results.emulation_speed * 100.0, 0, 'f', 0)); |  | ||||||
|     } |     } | ||||||
|     game_fps_label->setText(tr("Game: %1 FPS").arg(results.game_fps, 0, 'f', 0)); |     game_fps_label->setText(tr("Game: %1 FPS").arg(results.game_fps, 0, 'f', 0)); | ||||||
|     emu_frametime_label->setText(tr("Frame: %1 ms").arg(results.frametime * 1000.0, 0, 'f', 2)); |     emu_frametime_label->setText(tr("Frame: %1 ms").arg(results.frametime * 1000.0, 0, 'f', 2)); | ||||||
|   | |||||||
| @@ -133,13 +133,18 @@ void FrameLimiter::DoFrameLimiting(microseconds current_system_time_us) { | |||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     if (!Settings::values.use_frame_limit) { |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     auto now = Clock::now(); |     auto now = Clock::now(); | ||||||
|     double sleep_scale = Settings::values.frame_limit / 100.0; |     double sleep_scale = Settings::values.frame_limit / 100.0; | ||||||
|  |  | ||||||
|  |     if (Settings::values.use_frame_limit_alternate) { | ||||||
|  |         if (Settings::values.frame_limit_alternate == 0) { | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |         sleep_scale = Settings::values.frame_limit_alternate / 100.0; | ||||||
|  |     } else if (Settings::values.frame_limit == 0) { | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     // Max lag caused by slow frames. Shouldn't be more than the length of a frame at the current |     // Max lag caused by slow frames. Shouldn't be more than the length of a frame at the current | ||||||
|     // speed percent or it will clamp too much and prevent this from properly limiting to that |     // speed percent or it will clamp too much and prevent this from properly limiting to that | ||||||
|     // percent. High values means it'll take longer after a slow frame to recover and start limiting |     // percent. High values means it'll take longer after a slow frame to recover and start limiting | ||||||
|   | |||||||
| @@ -83,8 +83,9 @@ void LogSettings() { | |||||||
|     LogSetting("Renderer_ShadersAccurateMul", Settings::values.shaders_accurate_mul); |     LogSetting("Renderer_ShadersAccurateMul", Settings::values.shaders_accurate_mul); | ||||||
|     LogSetting("Renderer_UseShaderJit", Settings::values.use_shader_jit); |     LogSetting("Renderer_UseShaderJit", Settings::values.use_shader_jit); | ||||||
|     LogSetting("Renderer_UseResolutionFactor", Settings::values.resolution_factor); |     LogSetting("Renderer_UseResolutionFactor", Settings::values.resolution_factor); | ||||||
|     LogSetting("Renderer_UseFrameLimit", Settings::values.use_frame_limit); |  | ||||||
|     LogSetting("Renderer_FrameLimit", Settings::values.frame_limit); |     LogSetting("Renderer_FrameLimit", Settings::values.frame_limit); | ||||||
|  |     LogSetting("Renderer_UseFrameLimitAlternate", Settings::values.use_frame_limit_alternate); | ||||||
|  |     LogSetting("Renderer_FrameLimitAlternate", Settings::values.frame_limit_alternate); | ||||||
|     LogSetting("Renderer_PostProcessingShader", Settings::values.pp_shader_name); |     LogSetting("Renderer_PostProcessingShader", Settings::values.pp_shader_name); | ||||||
|     LogSetting("Renderer_FilterMode", Settings::values.filter_mode); |     LogSetting("Renderer_FilterMode", Settings::values.filter_mode); | ||||||
|     LogSetting("Renderer_TextureFilterName", Settings::values.texture_filter_name); |     LogSetting("Renderer_TextureFilterName", Settings::values.texture_filter_name); | ||||||
|   | |||||||
| @@ -155,8 +155,9 @@ struct Values { | |||||||
|     bool shaders_accurate_mul; |     bool shaders_accurate_mul; | ||||||
|     bool use_shader_jit; |     bool use_shader_jit; | ||||||
|     u16 resolution_factor; |     u16 resolution_factor; | ||||||
|     bool use_frame_limit; |     bool use_frame_limit_alternate; | ||||||
|     u16 frame_limit; |     u16 frame_limit; | ||||||
|  |     u16 frame_limit_alternate; | ||||||
|     std::string texture_filter_name; |     std::string texture_filter_name; | ||||||
|  |  | ||||||
|     LayoutOption layout_option; |     LayoutOption layout_option; | ||||||
|   | |||||||
| @@ -165,9 +165,11 @@ void TelemetrySession::AddInitialInfo(Loader::AppLoader& app_loader) { | |||||||
|     AddField(Telemetry::FieldType::UserConfig, "Core_UseCpuJit", Settings::values.use_cpu_jit); |     AddField(Telemetry::FieldType::UserConfig, "Core_UseCpuJit", Settings::values.use_cpu_jit); | ||||||
|     AddField(Telemetry::FieldType::UserConfig, "Renderer_ResolutionFactor", |     AddField(Telemetry::FieldType::UserConfig, "Renderer_ResolutionFactor", | ||||||
|              Settings::values.resolution_factor); |              Settings::values.resolution_factor); | ||||||
|     AddField(Telemetry::FieldType::UserConfig, "Renderer_UseFrameLimit", |  | ||||||
|              Settings::values.use_frame_limit); |  | ||||||
|     AddField(Telemetry::FieldType::UserConfig, "Renderer_FrameLimit", Settings::values.frame_limit); |     AddField(Telemetry::FieldType::UserConfig, "Renderer_FrameLimit", Settings::values.frame_limit); | ||||||
|  |     AddField(Telemetry::FieldType::UserConfig, "Renderer_UseFrameLimitAlternate", | ||||||
|  |              Settings::values.use_frame_limit_alternate); | ||||||
|  |     AddField(Telemetry::FieldType::UserConfig, "Renderer_FrameLimitAlternate", | ||||||
|  |              Settings::values.frame_limit_alternate); | ||||||
|     AddField(Telemetry::FieldType::UserConfig, "Renderer_UseHwRenderer", |     AddField(Telemetry::FieldType::UserConfig, "Renderer_UseHwRenderer", | ||||||
|              Settings::values.use_hw_renderer); |              Settings::values.use_hw_renderer); | ||||||
|     AddField(Telemetry::FieldType::UserConfig, "Renderer_UseHwShader", |     AddField(Telemetry::FieldType::UserConfig, "Renderer_UseHwShader", | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user