mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 05:40:04 +00:00 
			
		
		
		
	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:
		
							parent
							
								
									6d65319c85
								
							
						
					
					
						commit
						485d64ae73
					
				
					 11 changed files with 259 additions and 61 deletions
				
			
		|  | @ -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 Frame Advancing"),   QStringLiteral("Main Window"), {QStringLiteral("Ctrl+A"), Qt::ApplicationShortcut}}, | ||||
|      {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 Texture Dumping"),   QStringLiteral("Main Window"), {QStringLiteral("Ctrl+D"), Qt::ApplicationShortcut}}}}; | ||||
| // clang-format on
 | ||||
|  | @ -483,9 +483,11 @@ void Config::ReadRendererValues() { | |||
|     Settings::values.use_vsync_new = ReadSetting(QStringLiteral("use_vsync_new"), true).toBool(); | ||||
|     Settings::values.resolution_factor = | ||||
|         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.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_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_vsync_new"), Settings::values.use_vsync_new, true); | ||||
|     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("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
 | ||||
|     WriteSetting(QStringLiteral("bg_red"), (double)Settings::values.bg_red, 0.0); | ||||
|  |  | |||
|  | @ -9,17 +9,53 @@ | |||
| #include "core/settings.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) | ||||
|     : QWidget(parent), ui(new Ui::ConfigureGeneral) { | ||||
| 
 | ||||
|     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); | ||||
|     connect(ui->button_reset_defaults, &QPushButton::clicked, this, | ||||
|             &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; | ||||
|  | @ -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
 | ||||
|     ui->region_combobox->setCurrentIndex(Settings::values.region_value + 1); | ||||
| 
 | ||||
|     ui->toggle_frame_limit->setChecked(Settings::values.use_frame_limit); | ||||
|     ui->frame_limit->setEnabled(ui->toggle_frame_limit->isChecked()); | ||||
|     ui->frame_limit->setValue(Settings::values.frame_limit); | ||||
|     if (Settings::values.frame_limit == 0) { | ||||
|         ui->frame_limit->setValue(ui->frame_limit->maximum()); | ||||
|     } 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() { | ||||
|  | @ -63,8 +126,18 @@ void ConfigureGeneral::ApplyConfiguration() { | |||
| 
 | ||||
|     Settings::values.region_value = ui->region_combobox->currentIndex() - 1; | ||||
| 
 | ||||
|     Settings::values.use_frame_limit = ui->toggle_frame_limit->isChecked(); | ||||
|     Settings::values.frame_limit = ui->frame_limit->value(); | ||||
|     if (ui->frame_limit->value() == ui->frame_limit->maximum()) { | ||||
|         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() { | ||||
|  |  | |||
|  | @ -6,8 +6,8 @@ | |||
|    <rect> | ||||
|     <x>0</x> | ||||
|     <y>0</y> | ||||
|     <width>345</width> | ||||
|     <height>358</height> | ||||
|     <width>408</width> | ||||
|     <height>396</height> | ||||
|    </rect> | ||||
|   </property> | ||||
|   <property name="windowTitle"> | ||||
|  | @ -75,21 +75,7 @@ | |||
|         <string>Emulation</string> | ||||
|        </property> | ||||
|        <layout class="QGridLayout" name="gridLayout"> | ||||
|         <item row="1" column="0"> | ||||
|          <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"> | ||||
|         <item row="0" column="2"> | ||||
|          <widget class="QComboBox" name="region_combobox"> | ||||
|           <item> | ||||
|            <property name="text"> | ||||
|  | @ -133,19 +119,94 @@ | |||
|           </item> | ||||
|          </widget> | ||||
|         </item> | ||||
|         <item row="1" column="1"> | ||||
|          <widget class="QSpinBox" name="frame_limit"> | ||||
|           <property name="suffix"> | ||||
|            <string>%</string> | ||||
|         <item row="1" column="0"> | ||||
|          <widget class="QLabel" name="label_emulation_speed"> | ||||
|           <property name="text"> | ||||
|            <string>Emulation Speed:</string> | ||||
|           </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"> | ||||
|            <number>1</number> | ||||
|            <number>0</number> | ||||
|           </property> | ||||
|           <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 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> | ||||
|          </widget> | ||||
|         </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) { | ||||
|         ui->clock_display_label->setText(QStringLiteral("%1%").arg(SliderToSettings(value))); | ||||
|     }); | ||||
|  |  | |||
|  | @ -491,9 +491,10 @@ void GMainWindow::InitializeHotkeys() { | |||
|                     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, [&] { | ||||
|                 Settings::values.use_frame_limit = !Settings::values.use_frame_limit; | ||||
|                 Settings::values.use_frame_limit_alternate = | ||||
|                     !Settings::values.use_frame_limit_alternate; | ||||
|                 UpdateStatusBar(); | ||||
|             }); | ||||
|     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; | ||||
|     connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Increase Speed Limit"), this), | ||||
|             &QShortcut::activated, this, [&] { | ||||
|                 if (Settings::values.frame_limit < 9999 - SPEED_LIMIT_STEP) { | ||||
|                     Settings::values.frame_limit += SPEED_LIMIT_STEP; | ||||
|                     UpdateStatusBar(); | ||||
|                 if (Settings::values.use_frame_limit_alternate) { | ||||
|                     if (Settings::values.frame_limit_alternate == 0) { | ||||
|                         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), | ||||
|             &QShortcut::activated, this, [&] { | ||||
|                 if (Settings::values.frame_limit > SPEED_LIMIT_STEP) { | ||||
|                     Settings::values.frame_limit -= SPEED_LIMIT_STEP; | ||||
|                     UpdateStatusBar(); | ||||
|                 if (Settings::values.use_frame_limit_alternate) { | ||||
|                     if (Settings::values.frame_limit_alternate == 0) { | ||||
|                         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), | ||||
|             &QShortcut::activated, ui.action_Enable_Frame_Advancing, &QAction::trigger); | ||||
|  | @ -2019,12 +2047,22 @@ void GMainWindow::UpdateStatusBar() { | |||
| 
 | ||||
|     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%") | ||||
|                                      .arg(results.emulation_speed * 100.0, 0, 'f', 0) | ||||
|                                      .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)); | ||||
|     emu_frametime_label->setText(tr("Frame: %1 ms").arg(results.frametime * 1000.0, 0, 'f', 2)); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue