diff options
| author | fearlessTobi <thm.frey@gmail.com> | 2018-08-21 01:14:06 +0200 | 
|---|---|---|
| committer | fearlessTobi <thm.frey@gmail.com> | 2018-08-21 01:14:06 +0200 | 
| commit | ba8ff096fdc9f7ab101851c4cd06c3244a7d84c3 (patch) | |
| tree | 927b7495e2674a375aca8a4b004907e8af76c638 | |
| parent | 028d90eb79b75292d352cc8d4b96a2df74cd6b6e (diff) | |
Port #3353 from Citra
| -rw-r--r-- | src/core/perf_stats.cpp | 17 | ||||
| -rw-r--r-- | src/core/settings.h | 3 | ||||
| -rw-r--r-- | src/core/telemetry_session.cpp | 5 | ||||
| -rw-r--r-- | src/video_core/renderer_base.cpp | 2 | ||||
| -rw-r--r-- | src/yuzu/configuration/config.cpp | 6 | ||||
| -rw-r--r-- | src/yuzu/configuration/configure_graphics.cpp | 10 | ||||
| -rw-r--r-- | src/yuzu/configuration/configure_graphics.ui | 30 | ||||
| -rw-r--r-- | src/yuzu/main.cpp | 29 | ||||
| -rw-r--r-- | src/yuzu_cmd/config.cpp | 5 | ||||
| -rw-r--r-- | src/yuzu_cmd/default_ini.h | 12 | 
10 files changed, 94 insertions, 25 deletions
| diff --git a/src/core/perf_stats.cpp b/src/core/perf_stats.cpp index 8e09b9b63..c6022c02a 100644 --- a/src/core/perf_stats.cpp +++ b/src/core/perf_stats.cpp @@ -78,20 +78,29 @@ void FrameLimiter::DoFrameLimiting(microseconds current_system_time_us) {      // values increase the time needed to recover and limit framerate again after spikes.      constexpr microseconds MAX_LAG_TIME_US = 25us; -    if (!Settings::values.toggle_framelimit) { +    if (!Settings::values.use_frame_limit) {          return;      }      auto now = Clock::now(); -    frame_limiting_delta_err += current_system_time_us - previous_system_time_us; +    const double sleep_scale = Settings::values.frame_limit / 100.0; + +    // 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 +    // percent. High values means it'll take longer after a slow frame to recover and start +    // limiting +    const microseconds max_lag_time_us = duration_cast<microseconds>( +        std::chrono::duration<double, std::chrono::microseconds::period>(25ms / sleep_scale)); +    frame_limiting_delta_err += duration_cast<microseconds>( +        std::chrono::duration<double, std::chrono::microseconds::period>( +            (current_system_time_us - previous_system_time_us) / sleep_scale));      frame_limiting_delta_err -= duration_cast<microseconds>(now - previous_walltime);      frame_limiting_delta_err = -        std::clamp(frame_limiting_delta_err, -MAX_LAG_TIME_US, MAX_LAG_TIME_US); +        std::clamp(frame_limiting_delta_err, -max_lag_time_us, max_lag_time_us);      if (frame_limiting_delta_err > microseconds::zero()) {          std::this_thread::sleep_for(frame_limiting_delta_err); -          auto now_after_sleep = Clock::now();          frame_limiting_delta_err -= duration_cast<microseconds>(now_after_sleep - now);          now = now_after_sleep; diff --git a/src/core/settings.h b/src/core/settings.h index 73dc3061f..ed6f42471 100644 --- a/src/core/settings.h +++ b/src/core/settings.h @@ -130,7 +130,8 @@ struct Values {      // Renderer      float resolution_factor; -    bool toggle_framelimit; +    bool use_frame_limit; +    u16 frame_limit;      bool use_accurate_framebuffers;      float bg_red; diff --git a/src/core/telemetry_session.cpp b/src/core/telemetry_session.cpp index 69aa7a7be..5bd64f10e 100644 --- a/src/core/telemetry_session.cpp +++ b/src/core/telemetry_session.cpp @@ -161,8 +161,9 @@ TelemetrySession::TelemetrySession() {               Settings::values.use_multi_core);      AddField(Telemetry::FieldType::UserConfig, "Renderer_ResolutionFactor",               Settings::values.resolution_factor); -    AddField(Telemetry::FieldType::UserConfig, "Renderer_ToggleFramelimit", -             Settings::values.toggle_framelimit); +    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_UseAccurateFramebuffers",               Settings::values.use_accurate_framebuffers);      AddField(Telemetry::FieldType::UserConfig, "System_UseDockedMode", diff --git a/src/video_core/renderer_base.cpp b/src/video_core/renderer_base.cpp index afd86a83a..c1abdfbfe 100644 --- a/src/video_core/renderer_base.cpp +++ b/src/video_core/renderer_base.cpp @@ -20,7 +20,7 @@ void RendererBase::RefreshBaseSettings() {      RefreshRasterizerSetting();      UpdateCurrentFramebufferLayout(); -    renderer_settings.use_framelimiter = Settings::values.toggle_framelimit; +    renderer_settings.use_framelimiter = Settings::values.use_frame_limit;  }  void RendererBase::RefreshRasterizerSetting() { diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp index 0bd46dbac..df55c3e3d 100644 --- a/src/yuzu/configuration/config.cpp +++ b/src/yuzu/configuration/config.cpp @@ -83,7 +83,8 @@ void Config::ReadValues() {      qt_config->beginGroup("Renderer");      Settings::values.resolution_factor = qt_config->value("resolution_factor", 1.0).toFloat(); -    Settings::values.toggle_framelimit = qt_config->value("toggle_framelimit", true).toBool(); +    Settings::values.use_frame_limit = qt_config->value("use_frame_limit", true).toBool(); +    Settings::values.frame_limit = qt_config->value("frame_limit", 100).toInt();      Settings::values.use_accurate_framebuffers =          qt_config->value("use_accurate_framebuffers", false).toBool(); @@ -203,7 +204,8 @@ void Config::SaveValues() {      qt_config->beginGroup("Renderer");      qt_config->setValue("resolution_factor", (double)Settings::values.resolution_factor); -    qt_config->setValue("toggle_framelimit", Settings::values.toggle_framelimit); +    qt_config->setValue("use_frame_limit", Settings::values.use_frame_limit); +    qt_config->setValue("frame_limit", Settings::values.frame_limit);      qt_config->setValue("use_accurate_framebuffers", Settings::values.use_accurate_framebuffers);      // Cast to double because Qt's written float values are not human-readable diff --git a/src/yuzu/configuration/configure_graphics.cpp b/src/yuzu/configuration/configure_graphics.cpp index 4afe0f81b..ee1287028 100644 --- a/src/yuzu/configuration/configure_graphics.cpp +++ b/src/yuzu/configuration/configure_graphics.cpp @@ -12,6 +12,10 @@ ConfigureGraphics::ConfigureGraphics(QWidget* parent)      ui->setupUi(this);      this->setConfiguration(); + +    ui->frame_limit->setEnabled(Settings::values.use_frame_limit); +    connect(ui->toggle_frame_limit, &QCheckBox::stateChanged, ui->frame_limit, +            &QSpinBox::setEnabled);  }  ConfigureGraphics::~ConfigureGraphics() = default; @@ -58,13 +62,15 @@ Resolution FromResolutionFactor(float factor) {  void ConfigureGraphics::setConfiguration() {      ui->resolution_factor_combobox->setCurrentIndex(          static_cast<int>(FromResolutionFactor(Settings::values.resolution_factor))); -    ui->toggle_framelimit->setChecked(Settings::values.toggle_framelimit); +    ui->toggle_frame_limit->setChecked(Settings::values.use_frame_limit); +    ui->frame_limit->setValue(Settings::values.frame_limit);      ui->use_accurate_framebuffers->setChecked(Settings::values.use_accurate_framebuffers);  }  void ConfigureGraphics::applyConfiguration() {      Settings::values.resolution_factor =          ToResolutionFactor(static_cast<Resolution>(ui->resolution_factor_combobox->currentIndex())); -    Settings::values.toggle_framelimit = ui->toggle_framelimit->isChecked(); +    Settings::values.use_frame_limit = ui->toggle_frame_limit->isChecked(); +    Settings::values.frame_limit = ui->frame_limit->value();      Settings::values.use_accurate_framebuffers = ui->use_accurate_framebuffers->isChecked();  } diff --git a/src/yuzu/configuration/configure_graphics.ui b/src/yuzu/configuration/configure_graphics.ui index 7d092df03..3bc18c26e 100644 --- a/src/yuzu/configuration/configure_graphics.ui +++ b/src/yuzu/configuration/configure_graphics.ui @@ -23,11 +23,31 @@         </property>         <layout class="QVBoxLayout" name="verticalLayout_2">          <item> -         <widget class="QCheckBox" name="toggle_framelimit"> -          <property name="text"> -           <string>Limit framerate</string> -          </property> -         </widget> +          <layout class="QHBoxLayout" name="horizontalLayout_2"> +            <item> +              <widget class="QCheckBox" name="toggle_frame_limit"> +                <property name="text"> +                  <string>Limit Speed Percent</string> +                </property> +              </widget> +            </item> +            <item> +              <widget class="QSpinBox" name="frame_limit"> +                <property name="suffix"> +                  <string>%</string> +                </property> +                <property name="minimum"> +                  <number>1</number> +                </property> +                <property name="maximum"> +                  <number>9999</number> +                </property> +                <property name="value"> +                  <number>100</number> +                </property> +              </widget> +            </item> +          </layout>          </item>          <item>           <widget class="QCheckBox" name="use_accurate_framebuffers"> diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 11d2331df..41f765f12 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -226,6 +226,10 @@ void GMainWindow::InitializeHotkeys() {                                     Qt::ApplicationShortcut);      hotkey_registry.RegisterHotkey("Main Window", "Toggle Speed Limit", QKeySequence("CTRL+Z"),                                     Qt::ApplicationShortcut); +    hotkey_registry.RegisterHotkey("Main Window", "Increase Speed Limit", QKeySequence("+"), +                                   Qt::ApplicationShortcut); +    hotkey_registry.RegisterHotkey("Main Window", "Decrease Speed Limit", QKeySequence("-"), +                                   Qt::ApplicationShortcut);      hotkey_registry.LoadHotkeys();      connect(hotkey_registry.GetHotkey("Main Window", "Load File", this), &QShortcut::activated, @@ -255,9 +259,24 @@ void GMainWindow::InitializeHotkeys() {              });      connect(hotkey_registry.GetHotkey("Main Window", "Toggle Speed Limit", this),              &QShortcut::activated, this, [&] { -                Settings::values.toggle_framelimit = !Settings::values.toggle_framelimit; +                Settings::values.use_frame_limit = !Settings::values.use_frame_limit;                  UpdateStatusBar();              }); +    constexpr u16 SPEED_LIMIT_STEP = 5; +    connect(hotkey_registry.GetHotkey("Main Window", "Increase Speed Limit", this), +            &QShortcut::activated, this, [&] { +                if (Settings::values.frame_limit < 9999 - SPEED_LIMIT_STEP) { +                    Settings::values.frame_limit += SPEED_LIMIT_STEP; +                    UpdateStatusBar(); +                } +            }); +    connect(hotkey_registry.GetHotkey("Main Window", "Decrease Speed Limit", this), +            &QShortcut::activated, this, [&] { +                if (Settings::values.frame_limit > SPEED_LIMIT_STEP) { +                    Settings::values.frame_limit -= SPEED_LIMIT_STEP; +                    UpdateStatusBar(); +                } +            });  }  void GMainWindow::SetDefaultUIGeometry() { @@ -910,7 +929,13 @@ void GMainWindow::UpdateStatusBar() {      auto results = Core::System::GetInstance().GetAndResetPerfStats(); -    emu_speed_label->setText(tr("Speed: %1%").arg(results.emulation_speed * 100.0, 0, 'f', 0)); +    if (Settings::values.use_frame_limit) { +        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)); diff --git a/src/yuzu_cmd/config.cpp b/src/yuzu_cmd/config.cpp index 9bf26717f..a95580152 100644 --- a/src/yuzu_cmd/config.cpp +++ b/src/yuzu_cmd/config.cpp @@ -96,8 +96,9 @@ void Config::ReadValues() {      // Renderer      Settings::values.resolution_factor =          (float)sdl2_config->GetReal("Renderer", "resolution_factor", 1.0); -    Settings::values.toggle_framelimit = -        sdl2_config->GetBoolean("Renderer", "toggle_framelimit", true); +    Settings::values.use_frame_limit = sdl2_config->GetBoolean("Renderer", "use_frame_limit", true); +    Settings::values.frame_limit = +        static_cast<u16>(sdl2_config->GetInteger("Renderer", "frame_limit", 100));      Settings::values.use_accurate_framebuffers =          sdl2_config->GetBoolean("Renderer", "use_accurate_framebuffers", false); diff --git a/src/yuzu_cmd/default_ini.h b/src/yuzu_cmd/default_ini.h index 9a935a0d5..6ed9e7962 100644 --- a/src/yuzu_cmd/default_ini.h +++ b/src/yuzu_cmd/default_ini.h @@ -102,6 +102,14 @@ resolution_factor =  # 0 (default): Off, 1: On  use_vsync = +# Turns on the frame limiter, which will limit frames output to the target game speed +# 0: Off, 1: On (default) +use_frame_limit = + +# 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 = +  # Whether to use accurate framebuffers  # 0 (default): Off (fast), 1 : On (slow)  use_accurate_framebuffers = @@ -132,10 +140,6 @@ custom_bottom_top =  custom_bottom_right =  custom_bottom_bottom = -# Whether to toggle frame limiter on or off. -# 0: Off, 1 (default): On -toggle_framelimit = -  # Swaps the prominent screen with the other screen.  # For example, if Single Screen is chosen, setting this to 1 will display the bottom screen instead of the top screen.  # 0 (default): Top Screen is prominent, 1: Bottom Screen is prominent | 
