123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730 |
- // Copyright 2017 Dolphin Emulator Project
- // SPDX-License-Identifier: GPL-2.0-or-later
- #include "DolphinQt/HotkeyScheduler.h"
- #include <algorithm>
- #include <cmath>
- #include <thread>
- #include <fmt/format.h>
- #include <QApplication>
- #include <QCoreApplication>
- #include "AudioCommon/AudioCommon.h"
- #include "Common/Config/Config.h"
- #include "Common/Thread.h"
- #include "Core/AchievementManager.h"
- #include "Core/Config/AchievementSettings.h"
- #include "Core/Config/FreeLookSettings.h"
- #include "Core/Config/GraphicsSettings.h"
- #include "Core/Config/MainSettings.h"
- #include "Core/Config/UISettings.h"
- #include "Core/Core.h"
- #include "Core/FreeLookManager.h"
- #include "Core/Host.h"
- #include "Core/HotkeyManager.h"
- #include "Core/IOS/IOS.h"
- #include "Core/IOS/USB/Bluetooth/BTBase.h"
- #include "Core/IOS/USB/Bluetooth/BTReal.h"
- #include "Core/State.h"
- #include "Core/System.h"
- #include "Core/WiiUtils.h"
- #ifdef HAS_LIBMGBA
- #include "DolphinQt/GBAWidget.h"
- #endif
- #include "DolphinQt/QtUtils/QueueOnObject.h"
- #include "DolphinQt/Settings.h"
- #include "InputCommon/ControlReference/ControlReference.h"
- #include "InputCommon/ControllerInterface/ControllerInterface.h"
- #include "VideoCommon/OnScreenDisplay.h"
- #include "VideoCommon/VertexShaderManager.h"
- #include "VideoCommon/VideoConfig.h"
- constexpr const char* DUBOIS_ALGORITHM_SHADER = "dubois";
- HotkeyScheduler::HotkeyScheduler() : m_stop_requested(false)
- {
- HotkeyManagerEmu::Enable(true);
- }
- HotkeyScheduler::~HotkeyScheduler()
- {
- Stop();
- }
- void HotkeyScheduler::Start()
- {
- m_stop_requested.Set(false);
- m_thread = std::thread(&HotkeyScheduler::Run, this);
- }
- void HotkeyScheduler::Stop()
- {
- m_stop_requested.Set(true);
- if (m_thread.joinable())
- m_thread.join();
- }
- static bool IsHotkey(int id, bool held = false)
- {
- return HotkeyManagerEmu::IsPressed(id, held);
- }
- static void HandleFrameStepHotkeys()
- {
- constexpr int MAX_FRAME_STEP_DELAY = 60;
- constexpr int FRAME_STEP_DELAY = 30;
- static int frame_step_count = 0;
- static int frame_step_delay = 1;
- static int frame_step_delay_count = 0;
- static bool frame_step_hold = false;
- if (IsHotkey(HK_FRAME_ADVANCE_INCREASE_SPEED))
- {
- frame_step_delay = std::max(frame_step_delay - 1, 0);
- return;
- }
- if (IsHotkey(HK_FRAME_ADVANCE_DECREASE_SPEED))
- {
- frame_step_delay = std::min(frame_step_delay + 1, MAX_FRAME_STEP_DELAY);
- return;
- }
- if (IsHotkey(HK_FRAME_ADVANCE_RESET_SPEED))
- {
- frame_step_delay = 1;
- return;
- }
- if (IsHotkey(HK_FRAME_ADVANCE, true))
- {
- if (frame_step_delay_count < frame_step_delay && frame_step_hold)
- frame_step_delay_count++;
- if ((frame_step_count == 0 || frame_step_count == FRAME_STEP_DELAY) && !frame_step_hold)
- {
- if (frame_step_count > 0)
- Settings::Instance().SetIsContinuouslyFrameStepping(true);
- Core::QueueHostJob([](auto& system) { Core::DoFrameStep(system); });
- frame_step_hold = true;
- }
- if (frame_step_count < FRAME_STEP_DELAY)
- {
- frame_step_count++;
- frame_step_hold = false;
- }
- if (frame_step_count == FRAME_STEP_DELAY && frame_step_hold &&
- frame_step_delay_count >= frame_step_delay)
- {
- frame_step_hold = false;
- frame_step_delay_count = 0;
- }
- return;
- }
- else if (frame_step_count > 0)
- {
- // Reset frame advance
- frame_step_count = 0;
- frame_step_hold = false;
- frame_step_delay_count = 0;
- Settings::Instance().SetIsContinuouslyFrameStepping(false);
- emit Settings::Instance().EmulationStateChanged(Core::GetState(Core::System::GetInstance()));
- }
- }
- void HotkeyScheduler::Run()
- {
- Common::SetCurrentThreadName("HotkeyScheduler");
- while (!m_stop_requested.IsSet())
- {
- Common::SleepCurrentThread(5);
- g_controller_interface.SetCurrentInputChannel(ciface::InputChannel::FreeLook);
- g_controller_interface.UpdateInput();
- FreeLook::UpdateInput();
- g_controller_interface.SetCurrentInputChannel(ciface::InputChannel::Host);
- g_controller_interface.UpdateInput();
- if (!HotkeyManagerEmu::IsEnabled())
- continue;
- Core::System& system = Core::System::GetInstance();
- if (Core::GetState(system) != Core::State::Stopping)
- {
- // Obey window focus (config permitting) before checking hotkeys.
- Core::UpdateInputGate(Config::Get(Config::MAIN_FOCUSED_HOTKEYS));
- HotkeyManagerEmu::GetStatus(false);
- // Everything else on the host thread (controller config dialog) should always get input.
- ControlReference::SetInputGate(true);
- HotkeyManagerEmu::GetStatus(true);
- // Open
- if (IsHotkey(HK_OPEN))
- emit Open();
- // Refresh Game List
- if (IsHotkey(HK_REFRESH_LIST))
- emit RefreshGameListHotkey();
- // Recording
- if (IsHotkey(HK_START_RECORDING))
- emit StartRecording();
- // Exit
- if (IsHotkey(HK_EXIT))
- emit ExitHotkey();
- #ifdef USE_RETRO_ACHIEVEMENTS
- if (IsHotkey(HK_OPEN_ACHIEVEMENTS))
- emit OpenAchievements();
- #endif // USE_RETRO_ACHIEVEMENTS
- if (Core::IsUninitialized(system))
- {
- // Only check for Play Recording hotkey when no game is running
- if (IsHotkey(HK_PLAY_RECORDING))
- emit PlayRecording();
- continue;
- }
- // Disc
- if (IsHotkey(HK_EJECT_DISC))
- emit EjectDisc();
- if (IsHotkey(HK_CHANGE_DISC))
- emit ChangeDisc();
- // Fullscreen
- if (IsHotkey(HK_FULLSCREEN))
- {
- emit FullScreenHotkey();
- // Prevent fullscreen from getting toggled too often
- Common::SleepCurrentThread(100);
- }
- // Pause and Unpause
- if (IsHotkey(HK_PLAY_PAUSE))
- emit TogglePauseHotkey();
- // Stop
- if (IsHotkey(HK_STOP))
- emit StopHotkey();
- // Reset
- if (IsHotkey(HK_RESET))
- emit ResetHotkey();
- // Frame advance
- HandleFrameStepHotkeys();
- // Screenshot
- if (IsHotkey(HK_SCREENSHOT))
- emit ScreenShotHotkey();
- // Unlock Cursor
- if (IsHotkey(HK_UNLOCK_CURSOR))
- emit UnlockCursor();
- if (IsHotkey(HK_CENTER_MOUSE, true))
- g_controller_interface.SetMouseCenteringRequested(true);
- auto& settings = Settings::Instance();
- // Toggle Chat
- if (IsHotkey(HK_ACTIVATE_CHAT))
- emit ActivateChat();
- if (IsHotkey(HK_REQUEST_GOLF_CONTROL))
- emit RequestGolfControl();
- if (IsHotkey(HK_EXPORT_RECORDING))
- emit ExportRecording();
- if (IsHotkey(HK_READ_ONLY_MODE))
- emit ToggleReadOnlyMode();
- // Wiimote
- if (auto bt = WiiUtils::GetBluetoothRealDevice())
- bt->UpdateSyncButtonState(IsHotkey(HK_TRIGGER_SYNC_BUTTON, true));
- if (Config::IsDebuggingEnabled())
- {
- CheckDebuggingHotkeys();
- }
- // TODO: HK_MBP_ADD
- if (Core::System::GetInstance().IsWii())
- {
- if (IsHotkey(HK_WIIMOTE1_CONNECT))
- emit ConnectWiiRemote(0);
- if (IsHotkey(HK_WIIMOTE2_CONNECT))
- emit ConnectWiiRemote(1);
- if (IsHotkey(HK_WIIMOTE3_CONNECT))
- emit ConnectWiiRemote(2);
- if (IsHotkey(HK_WIIMOTE4_CONNECT))
- emit ConnectWiiRemote(3);
- if (IsHotkey(HK_BALANCEBOARD_CONNECT))
- emit ConnectWiiRemote(4);
- if (IsHotkey(HK_TOGGLE_SD_CARD))
- Settings::Instance().SetSDCardInserted(!Settings::Instance().IsSDCardInserted());
- if (IsHotkey(HK_TOGGLE_USB_KEYBOARD))
- {
- Settings::Instance().SetUSBKeyboardConnected(
- !Settings::Instance().IsUSBKeyboardConnected());
- }
- }
- if (IsHotkey(HK_PREV_WIIMOTE_PROFILE_1))
- m_profile_cycler.PreviousWiimoteProfile(0);
- else if (IsHotkey(HK_NEXT_WIIMOTE_PROFILE_1))
- m_profile_cycler.NextWiimoteProfile(0);
- if (IsHotkey(HK_PREV_WIIMOTE_PROFILE_2))
- m_profile_cycler.PreviousWiimoteProfile(1);
- else if (IsHotkey(HK_NEXT_WIIMOTE_PROFILE_2))
- m_profile_cycler.NextWiimoteProfile(1);
- if (IsHotkey(HK_PREV_WIIMOTE_PROFILE_3))
- m_profile_cycler.PreviousWiimoteProfile(2);
- else if (IsHotkey(HK_NEXT_WIIMOTE_PROFILE_3))
- m_profile_cycler.NextWiimoteProfile(2);
- if (IsHotkey(HK_PREV_WIIMOTE_PROFILE_4))
- m_profile_cycler.PreviousWiimoteProfile(3);
- else if (IsHotkey(HK_NEXT_WIIMOTE_PROFILE_4))
- m_profile_cycler.NextWiimoteProfile(3);
- if (IsHotkey(HK_PREV_GAME_WIIMOTE_PROFILE_1))
- m_profile_cycler.PreviousWiimoteProfileForGame(0);
- else if (IsHotkey(HK_NEXT_GAME_WIIMOTE_PROFILE_1))
- m_profile_cycler.NextWiimoteProfileForGame(0);
- if (IsHotkey(HK_PREV_GAME_WIIMOTE_PROFILE_2))
- m_profile_cycler.PreviousWiimoteProfileForGame(1);
- else if (IsHotkey(HK_NEXT_GAME_WIIMOTE_PROFILE_2))
- m_profile_cycler.NextWiimoteProfileForGame(1);
- if (IsHotkey(HK_PREV_GAME_WIIMOTE_PROFILE_3))
- m_profile_cycler.PreviousWiimoteProfileForGame(2);
- else if (IsHotkey(HK_NEXT_GAME_WIIMOTE_PROFILE_3))
- m_profile_cycler.NextWiimoteProfileForGame(2);
- if (IsHotkey(HK_PREV_GAME_WIIMOTE_PROFILE_4))
- m_profile_cycler.PreviousWiimoteProfileForGame(3);
- else if (IsHotkey(HK_NEXT_GAME_WIIMOTE_PROFILE_4))
- m_profile_cycler.NextWiimoteProfileForGame(3);
- auto ShowVolume = []() {
- OSD::AddMessage(std::string("Volume: ") +
- (Config::Get(Config::MAIN_AUDIO_MUTED) ?
- "Muted" :
- std::to_string(Config::Get(Config::MAIN_AUDIO_VOLUME)) + "%"));
- };
- // Volume
- if (IsHotkey(HK_VOLUME_DOWN))
- {
- settings.DecreaseVolume(3);
- ShowVolume();
- }
- if (IsHotkey(HK_VOLUME_UP))
- {
- settings.IncreaseVolume(3);
- ShowVolume();
- }
- if (IsHotkey(HK_VOLUME_TOGGLE_MUTE))
- {
- AudioCommon::ToggleMuteVolume(system);
- ShowVolume();
- }
- // Graphics
- const auto efb_scale = Config::Get(Config::GFX_EFB_SCALE);
- const auto ShowEFBScale = [](int new_efb_scale) {
- switch (new_efb_scale)
- {
- case EFB_SCALE_AUTO_INTEGRAL:
- OSD::AddMessage("Internal Resolution: Auto (integral)");
- break;
- case 1:
- OSD::AddMessage("Internal Resolution: Native");
- break;
- default:
- OSD::AddMessage(fmt::format("Internal Resolution: {}x", new_efb_scale));
- break;
- }
- };
- if (IsHotkey(HK_INCREASE_IR))
- {
- Config::SetCurrent(Config::GFX_EFB_SCALE, efb_scale + 1);
- ShowEFBScale(efb_scale + 1);
- }
- if (IsHotkey(HK_DECREASE_IR))
- {
- if (efb_scale > EFB_SCALE_AUTO_INTEGRAL)
- {
- Config::SetCurrent(Config::GFX_EFB_SCALE, efb_scale - 1);
- ShowEFBScale(efb_scale - 1);
- }
- }
- if (IsHotkey(HK_TOGGLE_CROP))
- Config::SetCurrent(Config::GFX_CROP, !Config::Get(Config::GFX_CROP));
- if (IsHotkey(HK_TOGGLE_AR))
- {
- const int aspect_ratio = (static_cast<int>(Config::Get(Config::GFX_ASPECT_RATIO)) + 1) & 3;
- Config::SetCurrent(Config::GFX_ASPECT_RATIO, static_cast<AspectMode>(aspect_ratio));
- switch (static_cast<AspectMode>(aspect_ratio))
- {
- case AspectMode::Stretch:
- OSD::AddMessage("Stretch");
- break;
- case AspectMode::ForceStandard:
- OSD::AddMessage("Force 4:3");
- break;
- case AspectMode::ForceWide:
- OSD::AddMessage("Force 16:9");
- break;
- case AspectMode::Custom:
- OSD::AddMessage("Custom");
- break;
- case AspectMode::CustomStretch:
- OSD::AddMessage("Custom (Stretch)");
- break;
- case AspectMode::Raw:
- OSD::AddMessage("Raw (Square Pixels)");
- break;
- case AspectMode::Auto:
- default:
- OSD::AddMessage("Auto");
- break;
- }
- }
- if (IsHotkey(HK_TOGGLE_SKIP_EFB_ACCESS))
- {
- const bool new_value = !Config::Get(Config::GFX_HACK_EFB_ACCESS_ENABLE);
- Config::SetCurrent(Config::GFX_HACK_EFB_ACCESS_ENABLE, new_value);
- OSD::AddMessage(fmt::format("{} EFB Access from CPU", new_value ? "Skip" : "Don't skip"));
- }
- if (IsHotkey(HK_TOGGLE_EFBCOPIES))
- {
- const bool new_value = !Config::Get(Config::GFX_HACK_SKIP_EFB_COPY_TO_RAM);
- Config::SetCurrent(Config::GFX_HACK_SKIP_EFB_COPY_TO_RAM, new_value);
- OSD::AddMessage(fmt::format("Copy EFB: {}", new_value ? "to Texture" : "to RAM"));
- }
- auto ShowXFBCopies = []() {
- OSD::AddMessage(fmt::format(
- "Copy XFB: {}{}", Config::Get(Config::GFX_HACK_IMMEDIATE_XFB) ? " (Immediate)" : "",
- Config::Get(Config::GFX_HACK_SKIP_XFB_COPY_TO_RAM) ? "to Texture" : "to RAM"));
- };
- if (IsHotkey(HK_TOGGLE_XFBCOPIES))
- {
- Config::SetCurrent(Config::GFX_HACK_SKIP_XFB_COPY_TO_RAM,
- !Config::Get(Config::GFX_HACK_SKIP_XFB_COPY_TO_RAM));
- ShowXFBCopies();
- }
- if (IsHotkey(HK_TOGGLE_IMMEDIATE_XFB))
- {
- Config::SetCurrent(Config::GFX_HACK_IMMEDIATE_XFB,
- !Config::Get(Config::GFX_HACK_IMMEDIATE_XFB));
- ShowXFBCopies();
- }
- if (IsHotkey(HK_TOGGLE_FOG))
- {
- const bool new_value = !Config::Get(Config::GFX_DISABLE_FOG);
- Config::SetCurrent(Config::GFX_DISABLE_FOG, new_value);
- OSD::AddMessage(fmt::format("Fog: {}", new_value ? "Enabled" : "Disabled"));
- }
- if (IsHotkey(HK_TOGGLE_DUMPTEXTURES))
- {
- const bool enable_dumping = !Config::Get(Config::GFX_DUMP_TEXTURES);
- Config::SetCurrent(Config::GFX_DUMP_TEXTURES, enable_dumping);
- OSD::AddMessage(
- fmt::format("Texture Dumping {}",
- enable_dumping ? "enabled. This will reduce performance." : "disabled."),
- OSD::Duration::NORMAL);
- }
- if (IsHotkey(HK_TOGGLE_TEXTURES))
- Config::SetCurrent(Config::GFX_HIRES_TEXTURES, !Config::Get(Config::GFX_HIRES_TEXTURES));
- Core::SetIsThrottlerTempDisabled(IsHotkey(HK_TOGGLE_THROTTLE, true));
- if (IsHotkey(HK_TOGGLE_THROTTLE, true) && !Config::Get(Config::MAIN_AUDIO_MUTED) &&
- Config::Get(Config::MAIN_AUDIO_MUTE_ON_DISABLED_SPEED_LIMIT))
- {
- Config::SetCurrent(Config::MAIN_AUDIO_MUTED, true);
- AudioCommon::UpdateSoundStream(system);
- }
- else if (!IsHotkey(HK_TOGGLE_THROTTLE, true) && Config::Get(Config::MAIN_AUDIO_MUTED) &&
- Config::GetActiveLayerForConfig(Config::MAIN_AUDIO_MUTED) ==
- Config::LayerType::CurrentRun)
- {
- Config::DeleteKey(Config::LayerType::CurrentRun, Config::MAIN_AUDIO_MUTED);
- AudioCommon::UpdateSoundStream(system);
- }
- auto ShowEmulationSpeed = []() {
- const float emulation_speed = Config::Get(Config::MAIN_EMULATION_SPEED);
- if (!AchievementManager::GetInstance().IsHardcoreModeActive() ||
- Config::Get(Config::MAIN_EMULATION_SPEED) >= 1.0f ||
- Config::Get(Config::MAIN_EMULATION_SPEED) <= 0.0f)
- {
- OSD::AddMessage(emulation_speed <= 0 ? "Speed Limit: Unlimited" :
- fmt::format("Speed Limit: {}%",
- std::lround(emulation_speed * 100.f)));
- }
- };
- if (IsHotkey(HK_DECREASE_EMULATION_SPEED))
- {
- auto speed = Config::Get(Config::MAIN_EMULATION_SPEED) - 0.1;
- if (speed > 0)
- {
- speed = (speed >= 0.95 && speed <= 1.05) ? 1.0 : speed;
- Config::SetCurrent(Config::MAIN_EMULATION_SPEED, speed);
- }
- ShowEmulationSpeed();
- }
- if (IsHotkey(HK_INCREASE_EMULATION_SPEED))
- {
- auto speed = Config::Get(Config::MAIN_EMULATION_SPEED) + 0.1;
- speed = (speed >= 0.95 && speed <= 1.05) ? 1.0 : speed;
- Config::SetCurrent(Config::MAIN_EMULATION_SPEED, speed);
- ShowEmulationSpeed();
- }
- // USB Device Emulation
- if (IsHotkey(HK_SKYLANDERS_PORTAL))
- emit SkylandersPortalHotkey();
- if (IsHotkey(HK_INFINITY_BASE))
- emit InfinityBaseHotkey();
- // Slot Saving / Loading
- if (IsHotkey(HK_SAVE_STATE_SLOT_SELECTED))
- emit StateSaveSlotHotkey();
- if (IsHotkey(HK_LOAD_STATE_SLOT_SELECTED))
- emit StateLoadSlotHotkey();
- if (IsHotkey(HK_INCREMENT_SELECTED_STATE_SLOT))
- emit IncrementSelectedStateSlotHotkey();
- if (IsHotkey(HK_DECREMENT_SELECTED_STATE_SLOT))
- emit DecrementSelectedStateSlotHotkey();
- // Stereoscopy
- if (IsHotkey(HK_TOGGLE_STEREO_SBS))
- {
- if (Config::Get(Config::GFX_STEREO_MODE) != StereoMode::SBS)
- {
- // Disable post-processing shader, as stereoscopy itself is currently a shader
- if (Config::Get(Config::GFX_ENHANCE_POST_SHADER) == DUBOIS_ALGORITHM_SHADER)
- Config::SetCurrent(Config::GFX_ENHANCE_POST_SHADER, "");
- Config::SetCurrent(Config::GFX_STEREO_MODE, StereoMode::SBS);
- }
- else
- {
- Config::SetCurrent(Config::GFX_STEREO_MODE, StereoMode::Off);
- }
- }
- if (IsHotkey(HK_TOGGLE_STEREO_TAB))
- {
- if (Config::Get(Config::GFX_STEREO_MODE) != StereoMode::TAB)
- {
- // Disable post-processing shader, as stereoscopy itself is currently a shader
- if (Config::Get(Config::GFX_ENHANCE_POST_SHADER) == DUBOIS_ALGORITHM_SHADER)
- Config::SetCurrent(Config::GFX_ENHANCE_POST_SHADER, "");
- Config::SetCurrent(Config::GFX_STEREO_MODE, StereoMode::TAB);
- }
- else
- {
- Config::SetCurrent(Config::GFX_STEREO_MODE, StereoMode::Off);
- }
- }
- if (IsHotkey(HK_TOGGLE_STEREO_ANAGLYPH))
- {
- if (Config::Get(Config::GFX_STEREO_MODE) != StereoMode::Anaglyph)
- {
- Config::SetCurrent(Config::GFX_STEREO_MODE, StereoMode::Anaglyph);
- Config::SetCurrent(Config::GFX_ENHANCE_POST_SHADER, DUBOIS_ALGORITHM_SHADER);
- }
- else
- {
- Config::SetCurrent(Config::GFX_STEREO_MODE, StereoMode::Off);
- Config::SetCurrent(Config::GFX_ENHANCE_POST_SHADER, "");
- }
- }
- CheckGBAHotkeys();
- }
- const auto stereo_depth = Config::Get(Config::GFX_STEREO_DEPTH);
- if (IsHotkey(HK_DECREASE_DEPTH, true))
- Config::SetCurrent(Config::GFX_STEREO_DEPTH, std::max(stereo_depth - 1, 0));
- if (IsHotkey(HK_INCREASE_DEPTH, true))
- Config::SetCurrent(Config::GFX_STEREO_DEPTH,
- std::min(stereo_depth + 1, Config::GFX_STEREO_DEPTH_MAXIMUM));
- const auto stereo_convergence = Config::Get(Config::GFX_STEREO_CONVERGENCE);
- if (IsHotkey(HK_DECREASE_CONVERGENCE, true))
- Config::SetCurrent(Config::GFX_STEREO_CONVERGENCE, std::max(stereo_convergence - 5, 0));
- if (IsHotkey(HK_INCREASE_CONVERGENCE, true))
- Config::SetCurrent(Config::GFX_STEREO_CONVERGENCE,
- std::min(stereo_convergence + 5, Config::GFX_STEREO_CONVERGENCE_MAXIMUM));
- // Free Look
- if (IsHotkey(HK_FREELOOK_TOGGLE))
- {
- const bool new_value = !Config::Get(Config::FREE_LOOK_ENABLED);
- Config::SetCurrent(Config::FREE_LOOK_ENABLED, new_value);
- const bool hardcore = AchievementManager::GetInstance().IsHardcoreModeActive();
- if (hardcore)
- OSD::AddMessage("Free Look is Disabled in Hardcore Mode");
- else
- OSD::AddMessage(fmt::format("Free Look: {}", new_value ? "Enabled" : "Disabled"));
- }
- // Savestates
- for (u32 i = 0; i < State::NUM_STATES; i++)
- {
- if (IsHotkey(HK_LOAD_STATE_SLOT_1 + i))
- emit StateLoadSlot(i + 1);
- if (IsHotkey(HK_SAVE_STATE_SLOT_1 + i))
- emit StateSaveSlot(i + 1);
- if (IsHotkey(HK_LOAD_LAST_STATE_1 + i))
- emit StateLoadLastSaved(i + 1);
- if (IsHotkey(HK_SELECT_STATE_SLOT_1 + i))
- emit SetStateSlotHotkey(i + 1);
- }
- if (IsHotkey(HK_SAVE_FIRST_STATE))
- emit StateSaveOldest();
- if (IsHotkey(HK_UNDO_LOAD_STATE))
- emit StateLoadUndo();
- if (IsHotkey(HK_UNDO_SAVE_STATE))
- emit StateSaveUndo();
- if (IsHotkey(HK_LOAD_STATE_FILE))
- emit StateLoadFile();
- if (IsHotkey(HK_SAVE_STATE_FILE))
- emit StateSaveFile();
- }
- }
- void HotkeyScheduler::CheckDebuggingHotkeys()
- {
- if (IsHotkey(HK_STEP))
- emit Step();
- if (IsHotkey(HK_STEP_OVER))
- emit StepOver();
- if (IsHotkey(HK_STEP_OUT))
- emit StepOut();
- if (IsHotkey(HK_SKIP))
- emit Skip();
- if (IsHotkey(HK_SHOW_PC))
- emit ShowPC();
- if (IsHotkey(HK_SET_PC))
- emit Skip();
- if (IsHotkey(HK_BP_TOGGLE))
- emit ToggleBreakpoint();
- if (IsHotkey(HK_BP_ADD))
- emit AddBreakpoint();
- }
- void HotkeyScheduler::CheckGBAHotkeys()
- {
- #ifdef HAS_LIBMGBA
- GBAWidget* gba_widget = qobject_cast<GBAWidget*>(QApplication::activeWindow());
- if (!gba_widget)
- return;
- if (IsHotkey(HK_GBA_LOAD))
- QueueOnObject(gba_widget, [gba_widget] { gba_widget->LoadROM(); });
- if (IsHotkey(HK_GBA_UNLOAD))
- QueueOnObject(gba_widget, [gba_widget] { gba_widget->UnloadROM(); });
- if (IsHotkey(HK_GBA_RESET))
- QueueOnObject(gba_widget, [gba_widget] { gba_widget->ResetCore(); });
- if (IsHotkey(HK_GBA_VOLUME_DOWN))
- QueueOnObject(gba_widget, [gba_widget] { gba_widget->VolumeDown(); });
- if (IsHotkey(HK_GBA_VOLUME_UP))
- QueueOnObject(gba_widget, [gba_widget] { gba_widget->VolumeUp(); });
- if (IsHotkey(HK_GBA_TOGGLE_MUTE))
- QueueOnObject(gba_widget, [gba_widget] { gba_widget->ToggleMute(); });
- if (IsHotkey(HK_GBA_1X))
- QueueOnObject(gba_widget, [gba_widget] { gba_widget->Resize(1); });
- if (IsHotkey(HK_GBA_2X))
- QueueOnObject(gba_widget, [gba_widget] { gba_widget->Resize(2); });
- if (IsHotkey(HK_GBA_3X))
- QueueOnObject(gba_widget, [gba_widget] { gba_widget->Resize(3); });
- if (IsHotkey(HK_GBA_4X))
- QueueOnObject(gba_widget, [gba_widget] { gba_widget->Resize(4); });
- #endif
- }
|