diff --git a/src/lime_qt/configuration/config.cpp b/src/lime_qt/configuration/config.cpp index 4fb5f494d..4138c9c63 100644 --- a/src/lime_qt/configuration/config.cpp +++ b/src/lime_qt/configuration/config.cpp @@ -54,7 +54,7 @@ const std::array, Settings::NativeAnalog::NumAnalogs> Config: // This must be in alphabetical order according to action name as it must have the same order as // UISetting::values.shortcuts, which is alphabetically ordered. // clang-format off -const std::array Config::default_hotkeys {{ +const std::array Config::default_hotkeys {{ {QStringLiteral("Advance Frame"), QStringLiteral("Main Window"), {QStringLiteral(""), Qt::ApplicationShortcut}}, {QStringLiteral("Audio Mute/Unmute"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+M"), Qt::WindowShortcut}}, {QStringLiteral("Audio Volume Down"), QStringLiteral("Main Window"), {QStringLiteral(""), Qt::WindowShortcut}}, @@ -83,6 +83,7 @@ const std::array Config::default_hotkeys {{ {QStringLiteral("Stop Emulation"), QStringLiteral("Main Window"), {QStringLiteral("F5"), Qt::WindowShortcut}}, {QStringLiteral("Swap Screens"), QStringLiteral("Main Window"), {QStringLiteral("F9"), Qt::WindowShortcut}}, {QStringLiteral("Toggle 3D"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+3"), Qt::ApplicationShortcut}}, + {QStringLiteral("Toggle Custom Emulation Speed"), QStringLiteral("Main Window"), {QStringLiteral("+"), Qt::ApplicationShortcut}}, {QStringLiteral("Toggle Custom Textures"), QStringLiteral("Main Window"), {QStringLiteral("F7"), Qt::ApplicationShortcut}}, {QStringLiteral("Toggle Filter Bar"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+F"), Qt::WindowShortcut}}, {QStringLiteral("Toggle Frame Advancing"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+A"), Qt::ApplicationShortcut}}, diff --git a/src/lime_qt/configuration/config.h b/src/lime_qt/configuration/config.h index 5bb8ef3d9..d40ca2b4f 100644 --- a/src/lime_qt/configuration/config.h +++ b/src/lime_qt/configuration/config.h @@ -26,7 +26,7 @@ public: static const std::array default_buttons; static const std::array, Settings::NativeAnalog::NumAnalogs> default_analogs; - static const std::array default_hotkeys; + static const std::array default_hotkeys; private: void Initialize(const std::string& config_name); diff --git a/src/lime_qt/main.cpp b/src/lime_qt/main.cpp index 2e77c8157..50e441e24 100644 --- a/src/lime_qt/main.cpp +++ b/src/lime_qt/main.cpp @@ -670,32 +670,18 @@ void GMainWindow::InitializeHotkeys() { [&] { Settings::values.dump_textures = !Settings::values.dump_textures; }); connect_shortcut(QStringLiteral("Toggle Custom Textures"), [&] { Settings::values.custom_textures = !Settings::values.custom_textures; }); - // We use "static" here in order to avoid capturing by lambda due to a MSVC bug, which makes - // the variable hold a garbage value after this function exits - static constexpr u16 SPEED_LIMIT_STEP = 5; + + connect_shortcut(QStringLiteral("Toggle Custom Emulation Speed"), &GMainWindow::ToggleEmulationSpeed); + connect_shortcut(QStringLiteral("Increase Speed Limit"), [&] { - if (Settings::values.frame_limit.GetValue() == 0) { - return; - } - if (Settings::values.frame_limit.GetValue() < 995 - SPEED_LIMIT_STEP) { - Settings::values.frame_limit.SetValue(Settings::values.frame_limit.GetValue() + - SPEED_LIMIT_STEP); - } else { - Settings::values.frame_limit = 0; - } - UpdateStatusBar(); + AdjustSpeedLimit(true); }); + connect_shortcut(QStringLiteral("Decrease Speed Limit"), [&] { - if (Settings::values.frame_limit.GetValue() == 0) { - Settings::values.frame_limit = 995; - } else if (Settings::values.frame_limit.GetValue() > SPEED_LIMIT_STEP) { - Settings::values.frame_limit.SetValue(Settings::values.frame_limit.GetValue() - - SPEED_LIMIT_STEP); - UpdateStatusBar(); - } - UpdateStatusBar(); + AdjustSpeedLimit(false); }); + connect_shortcut(QStringLiteral("Audio Mute/Unmute"), &GMainWindow::OnMute); connect_shortcut(QStringLiteral("Audio Volume Down"), &GMainWindow::OnDecreaseVolume); connect_shortcut(QStringLiteral("Audio Volume Up"), &GMainWindow::OnIncreaseVolume); @@ -2463,6 +2449,56 @@ void GMainWindow::ChangeScreenLayout() { UpdateSecondaryWindowVisibility(); } +void GMainWindow::ToggleEmulationSpeed() { + static bool key_pressed = false; // Prevent spam on hold + static int initial_frame_limit = Settings::values.frame_limit.GetValue(); // Store original frame limit + + if (!key_pressed) { + key_pressed = true; + turbo_mode_active = !turbo_mode_active; + + if (turbo_mode_active) { + initial_frame_limit = Settings::values.frame_limit.GetValue(); + Settings::values.frame_limit.SetValue(UISettings::values.turbo_speed_slider.GetValue()); + } else { + Settings::values.frame_limit.SetValue(initial_frame_limit); + } + + UpdateStatusBar(); + QTimer::singleShot(200, [] { key_pressed = false; }); + } +} + +void GMainWindow::AdjustSpeedLimit(bool increase) { + const int SPEED_LIMIT_STEP = 5; + + if (turbo_mode_active) { + int turbo_speed = UISettings::values.turbo_speed_slider.GetValue(); + if (increase) { + if (turbo_speed < 995) { + UISettings::values.turbo_speed_slider.SetValue(turbo_speed + SPEED_LIMIT_STEP); + } + } else { + if (turbo_speed > SPEED_LIMIT_STEP) { + UISettings::values.turbo_speed_slider.SetValue(turbo_speed - SPEED_LIMIT_STEP); + } + } + Settings::values.frame_limit.SetValue(UISettings::values.turbo_speed_slider.GetValue()); + } else { + int current_frame_limit = Settings::values.frame_limit.GetValue(); + if (increase) { + if (current_frame_limit < 995) { + Settings::values.frame_limit.SetValue(current_frame_limit + SPEED_LIMIT_STEP); + } + } else { + if (current_frame_limit > SPEED_LIMIT_STEP) { + Settings::values.frame_limit.SetValue(current_frame_limit - SPEED_LIMIT_STEP); + } + } + } + UpdateStatusBar(); +} + void GMainWindow::ToggleScreenLayout() { const Settings::LayoutOption new_layout = []() { switch (Settings::values.layout_option.GetValue()) { diff --git a/src/lime_qt/main.h b/src/lime_qt/main.h index 7e3c821ce..e60e2bc72 100644 --- a/src/lime_qt/main.h +++ b/src/lime_qt/main.h @@ -260,6 +260,8 @@ private slots: void ToggleFullscreen(); void ToggleSecondaryFullscreen(); void ChangeScreenLayout(); + void ToggleEmulationSpeed(); + void AdjustSpeedLimit(bool increase); void UpdateSecondaryWindowVisibility(); void ToggleScreenLayout(); void OnSwapScreens(); @@ -347,6 +349,9 @@ private: MultiplayerState* multiplayer_state = nullptr; std::unique_ptr config; + // Hotkeys + bool turbo_mode_active = false; + // Whether emulation is currently running in Lime3DS. bool emulation_running = false; std::unique_ptr emu_thread; diff --git a/src/lime_qt/uisettings.h b/src/lime_qt/uisettings.h index 1c5fb9657..53c3cf803 100644 --- a/src/lime_qt/uisettings.h +++ b/src/lime_qt/uisettings.h @@ -76,7 +76,7 @@ struct Values { Settings::Setting show_filter_bar{true, "showFilterBar"}; Settings::Setting show_status_bar{true, "showStatusBar"}; - Settings::Setting turbo_speed_slider{69, "turboSpeedSlider"}; + Settings::Setting turbo_speed_slider{100, "turboSpeedSlider"}; Settings::Setting confirm_before_closing{true, "confirmClose"}; Settings::Setting save_state_warning{true, "saveStateWarning"}; Settings::Setting first_start{true, "firstStart"};