mirror of https://github.com/PCSX2/pcsx2.git
InputManager: Fix chord bindings when activating in reverse
This commit is contained in:
parent
b20e5a1e01
commit
14181ec70d
|
@ -952,7 +952,7 @@ SysMtgsThread& GetMTGS()
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
|
|
||||||
BEGIN_HOTKEY_LIST(g_host_hotkeys)
|
BEGIN_HOTKEY_LIST(g_host_hotkeys)
|
||||||
DEFINE_HOTKEY("ShutdownVM", "System", "Shut Down Virtual Machine", [](bool pressed) {
|
DEFINE_HOTKEY("ShutdownVM", "System", "Shut Down Virtual Machine", [](s32 pressed) {
|
||||||
if (!pressed)
|
if (!pressed)
|
||||||
{
|
{
|
||||||
// run it on the host thread, that way we get the confirm prompt (if enabled)
|
// run it on the host thread, that way we get the confirm prompt (if enabled)
|
||||||
|
@ -960,16 +960,16 @@ DEFINE_HOTKEY("ShutdownVM", "System", "Shut Down Virtual Machine", [](bool press
|
||||||
Q_ARG(bool, true), Q_ARG(bool, true), Q_ARG(bool, true));
|
Q_ARG(bool, true), Q_ARG(bool, true), Q_ARG(bool, true));
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
DEFINE_HOTKEY("TogglePause", "System", "Toggle Pause", [](bool pressed) {
|
DEFINE_HOTKEY("TogglePause", "System", "Toggle Pause", [](s32 pressed) {
|
||||||
if (!pressed)
|
if (!pressed)
|
||||||
g_emu_thread->setVMPaused(VMManager::GetState() != VMState::Paused);
|
g_emu_thread->setVMPaused(VMManager::GetState() != VMState::Paused);
|
||||||
})
|
})
|
||||||
DEFINE_HOTKEY("ToggleFullscreen", "General", "Toggle Fullscreen", [](bool pressed) {
|
DEFINE_HOTKEY("ToggleFullscreen", "General", "Toggle Fullscreen", [](s32 pressed) {
|
||||||
if (!pressed)
|
if (!pressed)
|
||||||
g_emu_thread->toggleFullscreen();
|
g_emu_thread->toggleFullscreen();
|
||||||
})
|
})
|
||||||
// Input Recording Hot Keys
|
// Input Recording Hot Keys
|
||||||
DEFINE_HOTKEY("InputRecToggleMode", "Input Recording", "Toggle Recording Mode", [](bool pressed) {
|
DEFINE_HOTKEY("InputRecToggleMode", "Input Recording", "Toggle Recording Mode", [](s32 pressed) {
|
||||||
if (!pressed) // ?? - not pressed so it is on key up?
|
if (!pressed) // ?? - not pressed so it is on key up?
|
||||||
{
|
{
|
||||||
g_InputRecordingControls.RecordModeToggle();
|
g_InputRecordingControls.RecordModeToggle();
|
||||||
|
|
|
@ -622,51 +622,20 @@ bool InputManager::IsAxisHandler(const InputEventHandler& handler)
|
||||||
|
|
||||||
bool InputManager::InvokeEvents(InputBindingKey key, float value, GenericInputBinding generic_key)
|
bool InputManager::InvokeEvents(InputBindingKey key, float value, GenericInputBinding generic_key)
|
||||||
{
|
{
|
||||||
if (PreprocessEvent(key, value, generic_key))
|
if (DoEventHook(key, value))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
// If imgui ate the event, don't fire our handlers.
|
||||||
|
const bool skip_button_handlers = PreprocessEvent(key, value, generic_key);
|
||||||
|
|
||||||
// find all the bindings associated with this key
|
// find all the bindings associated with this key
|
||||||
const InputBindingKey masked_key = key.MaskDirection();
|
const InputBindingKey masked_key = key.MaskDirection();
|
||||||
const auto range = s_binding_map.equal_range(masked_key);
|
const auto range = s_binding_map.equal_range(masked_key);
|
||||||
if (range.first == s_binding_map.end())
|
if (range.first == s_binding_map.end())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Workaround for modifier keys. Basically, if we bind say, F1 and Shift+F1, and press shift
|
|
||||||
// and then F1, we'll fire bindings for both F1 and Shift+F1, when we really only want to fire
|
|
||||||
// the binding for Shift+F1. So, let's search through the binding list, and see if there's a
|
|
||||||
// "longer" binding (more keys), and if so, only activate that and not the shorter binding(s).
|
|
||||||
const InputBinding* longest_hotkey_binding = nullptr;
|
|
||||||
for (auto it = range.first; it != range.second; ++it)
|
|
||||||
{
|
|
||||||
InputBinding* binding = it->second.get();
|
|
||||||
if (IsAxisHandler(binding->handler))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// find the key which matches us
|
|
||||||
for (u32 i = 0; i < binding->num_keys; i++)
|
|
||||||
{
|
|
||||||
if (binding->keys[i].MaskDirection() != masked_key)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
const u8 bit = static_cast<u8>(1) << i;
|
|
||||||
const bool negative = binding->keys[i].negative;
|
|
||||||
const bool new_state = (negative ? (value < 0.0f) : (value > 0.0f));
|
|
||||||
const u8 new_mask = (new_state ? (binding->current_mask | bit) : (binding->current_mask & ~bit));
|
|
||||||
const bool prev_full_state = (binding->current_mask == binding->full_mask);
|
|
||||||
const bool new_full_state = (new_mask == binding->full_mask);
|
|
||||||
|
|
||||||
// If we're activating this chord, block activation of other bindings with fewer keys.
|
|
||||||
if (prev_full_state || new_full_state)
|
|
||||||
{
|
|
||||||
if (!longest_hotkey_binding || longest_hotkey_binding->num_keys < binding->num_keys)
|
|
||||||
longest_hotkey_binding = binding;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now we can actually fire/activate bindings.
|
// Now we can actually fire/activate bindings.
|
||||||
|
u32 min_num_keys = 0;
|
||||||
for (auto it = range.first; it != range.second; ++it)
|
for (auto it = range.first; it != range.second; ++it)
|
||||||
{
|
{
|
||||||
InputBinding* binding = it->second.get();
|
InputBinding* binding = it->second.get();
|
||||||
|
@ -681,20 +650,6 @@ bool InputManager::InvokeEvents(InputBindingKey key, float value, GenericInputBi
|
||||||
const bool negative = binding->keys[i].negative;
|
const bool negative = binding->keys[i].negative;
|
||||||
const bool new_state = (negative ? (value < 0.0f) : (value > 0.0f));
|
const bool new_state = (negative ? (value < 0.0f) : (value > 0.0f));
|
||||||
|
|
||||||
// Don't register the key press when we're part of a longer chord. That way,
|
|
||||||
// the state won't change, and it won't get the released event either.
|
|
||||||
if (longest_hotkey_binding && new_state && !IsAxisHandler(binding->handler) &&
|
|
||||||
binding->num_keys != longest_hotkey_binding->num_keys)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// update state based on whether the whole chord was activated
|
|
||||||
const u8 new_mask = (new_state ? (binding->current_mask | bit) : (binding->current_mask & ~bit));
|
|
||||||
const bool prev_full_state = (binding->current_mask == binding->full_mask);
|
|
||||||
const bool new_full_state = (new_mask == binding->full_mask);
|
|
||||||
binding->current_mask = new_mask;
|
|
||||||
|
|
||||||
// invert if we're negative, since the handler expects 0..1
|
// invert if we're negative, since the handler expects 0..1
|
||||||
const float value_to_pass = (negative ? ((value < 0.0f) ? -value : 0.0f) : (value > 0.0f) ? value : 0.0f);
|
const float value_to_pass = (negative ? ((value < 0.0f) ? -value : 0.0f) : (value > 0.0f) ? value : 0.0f);
|
||||||
|
|
||||||
|
@ -704,13 +659,60 @@ bool InputManager::InvokeEvents(InputBindingKey key, float value, GenericInputBi
|
||||||
// and 0 on release (when the full state changes).
|
// and 0 on release (when the full state changes).
|
||||||
if (IsAxisHandler(binding->handler))
|
if (IsAxisHandler(binding->handler))
|
||||||
{
|
{
|
||||||
if (prev_full_state != new_full_state || value_to_pass >= 0.0f)
|
if (value_to_pass >= 0.0f)
|
||||||
std::get<InputAxisEventHandler>(binding->handler)(value_to_pass);
|
std::get<InputAxisEventHandler>(binding->handler)(value_to_pass);
|
||||||
}
|
}
|
||||||
else
|
else if (binding->num_keys >= min_num_keys)
|
||||||
{
|
{
|
||||||
if (prev_full_state != new_full_state)
|
// update state based on whether the whole chord was activated
|
||||||
std::get<InputButtonEventHandler>(binding->handler)(value_to_pass > 0.0f);
|
const u8 new_mask = (new_state ? (binding->current_mask | bit) : (binding->current_mask & ~bit));
|
||||||
|
const bool prev_full_state = (binding->current_mask == binding->full_mask);
|
||||||
|
const bool new_full_state = (new_mask == binding->full_mask);
|
||||||
|
binding->current_mask = new_mask;
|
||||||
|
|
||||||
|
// Workaround for multi-key bindings that share the same keys.
|
||||||
|
if (binding->num_keys > 1 && new_full_state && prev_full_state != new_full_state &&
|
||||||
|
range.first != range.second)
|
||||||
|
{
|
||||||
|
// Because the binding map isn't ordered, we could iterate in the order of Shift+F1 and then
|
||||||
|
// F1, which would mean that F1 wouldn't get cancelled and still activate. So, to handle this
|
||||||
|
// case, we skip activating any future bindings with a fewer number of keys.
|
||||||
|
min_num_keys = std::max<u32>(min_num_keys, binding->num_keys);
|
||||||
|
|
||||||
|
// Basically, if we bind say, F1 and Shift+F1, and press shift and then F1, we'll fire bindings
|
||||||
|
// for both F1 and Shift+F1, when we really only want to fire the binding for Shift+F1. So,
|
||||||
|
// when we activate a multi-key chord (key press), we go through the binding map for all the
|
||||||
|
// other keys in the chord, and cancel them if they have a shorter chord. If they're longer,
|
||||||
|
// they could still activate and take precedence over us, so we leave them alone.
|
||||||
|
for (u32 i = 0; i < binding->num_keys; i++)
|
||||||
|
{
|
||||||
|
const auto range = s_binding_map.equal_range(binding->keys[i].MaskDirection());
|
||||||
|
for (auto it = range.first; it != range.second; ++it)
|
||||||
|
{
|
||||||
|
InputBinding* other_binding = it->second.get();
|
||||||
|
if (other_binding == binding || IsAxisHandler(other_binding->handler) ||
|
||||||
|
other_binding->num_keys >= binding->num_keys)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We only need to cancel the binding if it was fully active before. Which in the above
|
||||||
|
// case of Shift+F1 / F1, it will be.
|
||||||
|
if (other_binding->current_mask == other_binding->full_mask)
|
||||||
|
std::get<InputButtonEventHandler>(other_binding->handler)(-1);
|
||||||
|
|
||||||
|
// Zero out the current bits so that we don't release this binding, if the other part
|
||||||
|
// of the chord releases first.
|
||||||
|
other_binding->current_mask = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (prev_full_state != new_full_state && binding->num_keys >= min_num_keys)
|
||||||
|
{
|
||||||
|
const s32 pressed = skip_button_handlers ? -1 : static_cast<s32>(value_to_pass > 0.0f);
|
||||||
|
std::get<InputButtonEventHandler>(binding->handler)(pressed);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// bail out, since we shouldn't have the same key twice in the chord
|
// bail out, since we shouldn't have the same key twice in the chord
|
||||||
|
@ -723,9 +725,6 @@ bool InputManager::InvokeEvents(InputBindingKey key, float value, GenericInputBi
|
||||||
|
|
||||||
bool InputManager::PreprocessEvent(InputBindingKey key, float value, GenericInputBinding generic_key)
|
bool InputManager::PreprocessEvent(InputBindingKey key, float value, GenericInputBinding generic_key)
|
||||||
{
|
{
|
||||||
if (DoEventHook(key, value))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
// does imgui want the event?
|
// does imgui want the event?
|
||||||
if (key.source_type == InputSourceType::Keyboard)
|
if (key.source_type == InputSourceType::Keyboard)
|
||||||
{
|
{
|
||||||
|
@ -739,7 +738,7 @@ bool InputManager::PreprocessEvent(InputBindingKey key, float value, GenericInpu
|
||||||
}
|
}
|
||||||
else if (generic_key != GenericInputBinding::Unknown)
|
else if (generic_key != GenericInputBinding::Unknown)
|
||||||
{
|
{
|
||||||
if (ImGuiManager::ProcessGenericInputEvent(generic_key, value))
|
if (ImGuiManager::ProcessGenericInputEvent(generic_key, value) && value != 0.0f)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -90,7 +90,7 @@ struct InputBindingKeyHash
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Callback type for a binary event. Usually used for hotkeys.
|
/// Callback type for a binary event. Usually used for hotkeys.
|
||||||
using InputButtonEventHandler = std::function<void(bool value)>;
|
using InputButtonEventHandler = std::function<void(s32 value)>;
|
||||||
|
|
||||||
/// Callback types for a normalized event. Usually used for pads.
|
/// Callback types for a normalized event. Usually used for pads.
|
||||||
using InputAxisEventHandler = std::function<void(float value)>;
|
using InputAxisEventHandler = std::function<void(float value)>;
|
||||||
|
@ -110,12 +110,15 @@ struct InputInterceptHook
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Hotkeys are actions (e.g. toggle frame limit) which can be bound to keys or chords.
|
/// Hotkeys are actions (e.g. toggle frame limit) which can be bound to keys or chords.
|
||||||
|
/// The handler is called with an integer representing the key state, where 0 means that
|
||||||
|
/// one or more keys were released, 1 means all the keys were pressed, and -1 means that
|
||||||
|
/// the hotkey was cancelled due to a chord with more keys being activated.
|
||||||
struct HotkeyInfo
|
struct HotkeyInfo
|
||||||
{
|
{
|
||||||
const char* name;
|
const char* name;
|
||||||
const char* category;
|
const char* category;
|
||||||
const char* display_name;
|
const char* display_name;
|
||||||
void (*handler)(bool pressed);
|
void (*handler)(s32 pressed);
|
||||||
};
|
};
|
||||||
#define DECLARE_HOTKEY_LIST(name) extern const HotkeyInfo name[]
|
#define DECLARE_HOTKEY_LIST(name) extern const HotkeyInfo name[]
|
||||||
#define BEGIN_HOTKEY_LIST(name) const HotkeyInfo name[] = {
|
#define BEGIN_HOTKEY_LIST(name) const HotkeyInfo name[] = {
|
||||||
|
|
|
@ -1623,7 +1623,7 @@ static void HotkeyAdjustZoom(double delta)
|
||||||
}
|
}
|
||||||
|
|
||||||
BEGIN_HOTKEY_LIST(g_gs_hotkeys)
|
BEGIN_HOTKEY_LIST(g_gs_hotkeys)
|
||||||
{"Screenshot", "Graphics", "Save Screenshot", [](bool pressed) {
|
{"Screenshot", "Graphics", "Save Screenshot", [](s32 pressed) {
|
||||||
if (!pressed)
|
if (!pressed)
|
||||||
{
|
{
|
||||||
GetMTGS().RunOnGSThread([]() {
|
GetMTGS().RunOnGSThread([]() {
|
||||||
|
@ -1631,7 +1631,7 @@ BEGIN_HOTKEY_LIST(g_gs_hotkeys)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}},
|
}},
|
||||||
{"GSDumpSingleFrame", "Graphics", "Save Single Frame GS Dump", [](bool pressed) {
|
{"GSDumpSingleFrame", "Graphics", "Save Single Frame GS Dump", [](s32 pressed) {
|
||||||
if (!pressed)
|
if (!pressed)
|
||||||
{
|
{
|
||||||
GetMTGS().RunOnGSThread([]() {
|
GetMTGS().RunOnGSThread([]() {
|
||||||
|
@ -1639,27 +1639,27 @@ BEGIN_HOTKEY_LIST(g_gs_hotkeys)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}},
|
}},
|
||||||
{"GSDumpMultiFrame", "Graphics", "Save Multi Frame GS Dump", [](bool pressed) {
|
{"GSDumpMultiFrame", "Graphics", "Save Multi Frame GS Dump", [](s32 pressed) {
|
||||||
GetMTGS().RunOnGSThread([pressed]() {
|
GetMTGS().RunOnGSThread([pressed]() {
|
||||||
if (pressed)
|
if (pressed > 0)
|
||||||
GSQueueSnapshot(std::string(), std::numeric_limits<u32>::max());
|
GSQueueSnapshot(std::string(), std::numeric_limits<u32>::max());
|
||||||
else
|
else
|
||||||
GSStopGSDump();
|
GSStopGSDump();
|
||||||
});
|
});
|
||||||
}},
|
}},
|
||||||
{"ToggleSoftwareRendering", "Graphics", "Toggle Software Rendering", [](bool pressed) {
|
{"ToggleSoftwareRendering", "Graphics", "Toggle Software Rendering", [](s32 pressed) {
|
||||||
if (!pressed)
|
if (!pressed)
|
||||||
GetMTGS().ToggleSoftwareRendering();
|
GetMTGS().ToggleSoftwareRendering();
|
||||||
}},
|
}},
|
||||||
{"IncreaseUpscaleMultiplier", "Graphics", "Increase Upscale Multiplier", [](bool pressed) {
|
{"IncreaseUpscaleMultiplier", "Graphics", "Increase Upscale Multiplier", [](s32 pressed) {
|
||||||
if (!pressed)
|
if (!pressed)
|
||||||
HotkeyAdjustUpscaleMultiplier(1);
|
HotkeyAdjustUpscaleMultiplier(1);
|
||||||
}},
|
}},
|
||||||
{"DecreaseUpscaleMultiplier", "Graphics", "Decrease Upscale Multiplier", [](bool pressed) {
|
{"DecreaseUpscaleMultiplier", "Graphics", "Decrease Upscale Multiplier", [](s32 pressed) {
|
||||||
if (!pressed)
|
if (!pressed)
|
||||||
HotkeyAdjustUpscaleMultiplier(-1);
|
HotkeyAdjustUpscaleMultiplier(-1);
|
||||||
}},
|
}},
|
||||||
{"CycleAspectRatio", "Graphics", "Cycle Aspect Ratio", [](bool pressed) {
|
{"CycleAspectRatio", "Graphics", "Cycle Aspect Ratio", [](s32 pressed) {
|
||||||
if (pressed)
|
if (pressed)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -1667,7 +1667,7 @@ BEGIN_HOTKEY_LIST(g_gs_hotkeys)
|
||||||
EmuConfig.CurrentAspectRatio = static_cast<AspectRatioType>((static_cast<int>(EmuConfig.CurrentAspectRatio) + 1) % static_cast<int>(AspectRatioType::MaxCount));
|
EmuConfig.CurrentAspectRatio = static_cast<AspectRatioType>((static_cast<int>(EmuConfig.CurrentAspectRatio) + 1) % static_cast<int>(AspectRatioType::MaxCount));
|
||||||
Host::AddKeyedFormattedOSDMessage("CycleAspectRatio", 10.0f, "Aspect ratio set to '%s'.", Pcsx2Config::GSOptions::AspectRatioNames[static_cast<int>(EmuConfig.CurrentAspectRatio)]);
|
Host::AddKeyedFormattedOSDMessage("CycleAspectRatio", 10.0f, "Aspect ratio set to '%s'.", Pcsx2Config::GSOptions::AspectRatioNames[static_cast<int>(EmuConfig.CurrentAspectRatio)]);
|
||||||
}},
|
}},
|
||||||
{"CycleMipmapMode", "Graphics", "Cycle Hardware Mipmapping", [](bool pressed) {
|
{"CycleMipmapMode", "Graphics", "Cycle Hardware Mipmapping", [](s32 pressed) {
|
||||||
if (pressed)
|
if (pressed)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -1684,7 +1684,7 @@ BEGIN_HOTKEY_LIST(g_gs_hotkeys)
|
||||||
g_gs_renderer->PurgePool();
|
g_gs_renderer->PurgePool();
|
||||||
});
|
});
|
||||||
}},
|
}},
|
||||||
{"CycleInterlaceMode", "Graphics", "Cycle Deinterlace Mode", [](bool pressed) {
|
{"CycleInterlaceMode", "Graphics", "Cycle Deinterlace Mode", [](s32 pressed) {
|
||||||
if (pressed)
|
if (pressed)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -1705,15 +1705,15 @@ BEGIN_HOTKEY_LIST(g_gs_hotkeys)
|
||||||
|
|
||||||
GetMTGS().RunOnGSThread([new_mode]() { GSConfig.InterlaceMode = new_mode; });
|
GetMTGS().RunOnGSThread([new_mode]() { GSConfig.InterlaceMode = new_mode; });
|
||||||
}},
|
}},
|
||||||
{"ZoomIn", "Graphics", "Zoom In", [](bool pressed) {
|
{"ZoomIn", "Graphics", "Zoom In", [](s32 pressed) {
|
||||||
if (!pressed)
|
if (!pressed)
|
||||||
HotkeyAdjustZoom(1.0);
|
HotkeyAdjustZoom(1.0);
|
||||||
}},
|
}},
|
||||||
{"ZoomOut", "Graphics", "Zoom Out", [](bool pressed) {
|
{"ZoomOut", "Graphics", "Zoom Out", [](s32 pressed) {
|
||||||
if (!pressed)
|
if (!pressed)
|
||||||
HotkeyAdjustZoom(-1.0);
|
HotkeyAdjustZoom(-1.0);
|
||||||
}},
|
}},
|
||||||
{"ToggleTextureDumping", "Graphics", "Toggle Texture Dumping", [](bool pressed) {
|
{"ToggleTextureDumping", "Graphics", "Toggle Texture Dumping", [](s32 pressed) {
|
||||||
if (!pressed)
|
if (!pressed)
|
||||||
{
|
{
|
||||||
EmuConfig.GS.DumpReplaceableTextures = !EmuConfig.GS.DumpReplaceableTextures;
|
EmuConfig.GS.DumpReplaceableTextures = !EmuConfig.GS.DumpReplaceableTextures;
|
||||||
|
@ -1721,7 +1721,7 @@ BEGIN_HOTKEY_LIST(g_gs_hotkeys)
|
||||||
GetMTGS().ApplySettings();
|
GetMTGS().ApplySettings();
|
||||||
}
|
}
|
||||||
}},
|
}},
|
||||||
{"ToggleTextureReplacements", "Graphics", "Toggle Texture Replacements", [](bool pressed) {
|
{"ToggleTextureReplacements", "Graphics", "Toggle Texture Replacements", [](s32 pressed) {
|
||||||
if (!pressed)
|
if (!pressed)
|
||||||
{
|
{
|
||||||
EmuConfig.GS.LoadTextureReplacements = !EmuConfig.GS.LoadTextureReplacements;
|
EmuConfig.GS.LoadTextureReplacements = !EmuConfig.GS.LoadTextureReplacements;
|
||||||
|
@ -1729,7 +1729,7 @@ BEGIN_HOTKEY_LIST(g_gs_hotkeys)
|
||||||
GetMTGS().ApplySettings();
|
GetMTGS().ApplySettings();
|
||||||
}
|
}
|
||||||
}},
|
}},
|
||||||
{"ReloadTextureReplacements", "Graphics", "Reload Texture Replacements", [](bool pressed) {
|
{"ReloadTextureReplacements", "Graphics", "Reload Texture Replacements", [](s32 pressed) {
|
||||||
if (!pressed)
|
if (!pressed)
|
||||||
{
|
{
|
||||||
if (!EmuConfig.GS.LoadTextureReplacements)
|
if (!EmuConfig.GS.LoadTextureReplacements)
|
||||||
|
|
|
@ -1713,7 +1713,7 @@ static void HotkeySaveStateSlot(s32 slot)
|
||||||
}
|
}
|
||||||
|
|
||||||
BEGIN_HOTKEY_LIST(g_vm_manager_hotkeys)
|
BEGIN_HOTKEY_LIST(g_vm_manager_hotkeys)
|
||||||
DEFINE_HOTKEY("ToggleFrameLimit", "System", "Toggle Frame Limit", [](bool pressed) {
|
DEFINE_HOTKEY("ToggleFrameLimit", "System", "Toggle Frame Limit", [](s32 pressed) {
|
||||||
if (!pressed)
|
if (!pressed)
|
||||||
{
|
{
|
||||||
VMManager::SetLimiterMode((EmuConfig.LimiterMode != LimiterModeType::Unlimited) ?
|
VMManager::SetLimiterMode((EmuConfig.LimiterMode != LimiterModeType::Unlimited) ?
|
||||||
|
@ -1721,7 +1721,7 @@ DEFINE_HOTKEY("ToggleFrameLimit", "System", "Toggle Frame Limit", [](bool presse
|
||||||
LimiterModeType::Nominal);
|
LimiterModeType::Nominal);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
DEFINE_HOTKEY("ToggleTurbo", "System", "Toggle Turbo", [](bool pressed) {
|
DEFINE_HOTKEY("ToggleTurbo", "System", "Toggle Turbo", [](s32 pressed) {
|
||||||
if (!pressed)
|
if (!pressed)
|
||||||
{
|
{
|
||||||
VMManager::SetLimiterMode((EmuConfig.LimiterMode != LimiterModeType::Turbo) ?
|
VMManager::SetLimiterMode((EmuConfig.LimiterMode != LimiterModeType::Turbo) ?
|
||||||
|
@ -1729,21 +1729,21 @@ DEFINE_HOTKEY("ToggleTurbo", "System", "Toggle Turbo", [](bool pressed) {
|
||||||
LimiterModeType::Nominal);
|
LimiterModeType::Nominal);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
DEFINE_HOTKEY("HoldTurbo", "System", "Turbo (Hold)", [](bool pressed) {
|
DEFINE_HOTKEY("HoldTurbo", "System", "Turbo (Hold)", [](s32 pressed) {
|
||||||
if (pressed && !s_limiter_mode_prior_to_hold_interaction.has_value())
|
if (pressed > 0 && !s_limiter_mode_prior_to_hold_interaction.has_value())
|
||||||
{
|
{
|
||||||
s_limiter_mode_prior_to_hold_interaction = VMManager::GetLimiterMode();
|
s_limiter_mode_prior_to_hold_interaction = VMManager::GetLimiterMode();
|
||||||
VMManager::SetLimiterMode((s_limiter_mode_prior_to_hold_interaction.value() != LimiterModeType::Turbo) ?
|
VMManager::SetLimiterMode((s_limiter_mode_prior_to_hold_interaction.value() != LimiterModeType::Turbo) ?
|
||||||
LimiterModeType::Turbo :
|
LimiterModeType::Turbo :
|
||||||
LimiterModeType::Nominal);
|
LimiterModeType::Nominal);
|
||||||
}
|
}
|
||||||
else if (!pressed && s_limiter_mode_prior_to_hold_interaction.has_value())
|
else if (pressed >= 0 && s_limiter_mode_prior_to_hold_interaction.has_value())
|
||||||
{
|
{
|
||||||
VMManager::SetLimiterMode(s_limiter_mode_prior_to_hold_interaction.value());
|
VMManager::SetLimiterMode(s_limiter_mode_prior_to_hold_interaction.value());
|
||||||
s_limiter_mode_prior_to_hold_interaction.reset();
|
s_limiter_mode_prior_to_hold_interaction.reset();
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
DEFINE_HOTKEY("ToggleSlowMotion", "System", "Toggle Slow Motion", [](bool pressed) {
|
DEFINE_HOTKEY("ToggleSlowMotion", "System", "Toggle Slow Motion", [](s32 pressed) {
|
||||||
if (!pressed)
|
if (!pressed)
|
||||||
{
|
{
|
||||||
VMManager::SetLimiterMode((EmuConfig.LimiterMode != LimiterModeType::Slomo) ?
|
VMManager::SetLimiterMode((EmuConfig.LimiterMode != LimiterModeType::Slomo) ?
|
||||||
|
@ -1751,42 +1751,42 @@ DEFINE_HOTKEY("ToggleSlowMotion", "System", "Toggle Slow Motion", [](bool presse
|
||||||
LimiterModeType::Nominal);
|
LimiterModeType::Nominal);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
DEFINE_HOTKEY("IncreaseSpeed", "System", "Increase Target Speed", [](bool pressed) {
|
DEFINE_HOTKEY("IncreaseSpeed", "System", "Increase Target Speed", [](s32 pressed) {
|
||||||
if (!pressed)
|
if (!pressed)
|
||||||
HotkeyAdjustTargetSpeed(0.1);
|
HotkeyAdjustTargetSpeed(0.1);
|
||||||
})
|
})
|
||||||
DEFINE_HOTKEY("DecreaseSpeed", "System", "Decrease Target Speed", [](bool pressed) {
|
DEFINE_HOTKEY("DecreaseSpeed", "System", "Decrease Target Speed", [](s32 pressed) {
|
||||||
if (!pressed)
|
if (!pressed)
|
||||||
HotkeyAdjustTargetSpeed(-0.1);
|
HotkeyAdjustTargetSpeed(-0.1);
|
||||||
})
|
})
|
||||||
DEFINE_HOTKEY("ResetVM", "System", "Reset Virtual Machine", [](bool pressed) {
|
DEFINE_HOTKEY("ResetVM", "System", "Reset Virtual Machine", [](s32 pressed) {
|
||||||
if (!pressed && VMManager::HasValidVM())
|
if (!pressed && VMManager::HasValidVM())
|
||||||
VMManager::Reset();
|
VMManager::Reset();
|
||||||
})
|
})
|
||||||
DEFINE_HOTKEY("FrameAdvance", "System", "Frame Advance", [](bool pressed) {
|
DEFINE_HOTKEY("FrameAdvance", "System", "Frame Advance", [](s32 pressed) {
|
||||||
if (!pressed)
|
if (!pressed)
|
||||||
VMManager::FrameAdvance(1);
|
VMManager::FrameAdvance(1);
|
||||||
})
|
})
|
||||||
|
|
||||||
DEFINE_HOTKEY("PreviousSaveStateSlot", "Save States", "Select Previous Save Slot", [](bool pressed) {
|
DEFINE_HOTKEY("PreviousSaveStateSlot", "Save States", "Select Previous Save Slot", [](s32 pressed) {
|
||||||
if (!pressed)
|
if (!pressed)
|
||||||
HotkeyCycleSaveSlot(-1);
|
HotkeyCycleSaveSlot(-1);
|
||||||
})
|
})
|
||||||
DEFINE_HOTKEY("NextSaveStateSlot", "Save States", "Select Next Save Slot", [](bool pressed) {
|
DEFINE_HOTKEY("NextSaveStateSlot", "Save States", "Select Next Save Slot", [](s32 pressed) {
|
||||||
if (!pressed)
|
if (!pressed)
|
||||||
HotkeyCycleSaveSlot(1);
|
HotkeyCycleSaveSlot(1);
|
||||||
})
|
})
|
||||||
DEFINE_HOTKEY("SaveStateToSlot", "Save States", "Save State To Selected Slot", [](bool pressed) {
|
DEFINE_HOTKEY("SaveStateToSlot", "Save States", "Save State To Selected Slot", [](s32 pressed) {
|
||||||
if (!pressed)
|
if (!pressed)
|
||||||
VMManager::SaveStateToSlot(s_current_save_slot);
|
VMManager::SaveStateToSlot(s_current_save_slot);
|
||||||
})
|
})
|
||||||
DEFINE_HOTKEY("LoadStateFromSlot", "Save States", "Load State From Selected Slot", [](bool pressed) {
|
DEFINE_HOTKEY("LoadStateFromSlot", "Save States", "Load State From Selected Slot", [](s32 pressed) {
|
||||||
if (!pressed)
|
if (!pressed)
|
||||||
HotkeyLoadStateSlot(s_current_save_slot);
|
HotkeyLoadStateSlot(s_current_save_slot);
|
||||||
})
|
})
|
||||||
|
|
||||||
#define DEFINE_HOTKEY_SAVESTATE_X(slotnum, slotnumstr) DEFINE_HOTKEY("SaveStateToSlot" #slotnum, \
|
#define DEFINE_HOTKEY_SAVESTATE_X(slotnum, slotnumstr) DEFINE_HOTKEY("SaveStateToSlot" #slotnum, \
|
||||||
"Save States", "Save State To Slot " #slotnumstr, [](bool pressed) { if (!pressed) HotkeySaveStateSlot(slotnum); })
|
"Save States", "Save State To Slot " #slotnumstr, [](s32 pressed) { if (!pressed) HotkeySaveStateSlot(slotnum); })
|
||||||
DEFINE_HOTKEY_SAVESTATE_X(1, 01)
|
DEFINE_HOTKEY_SAVESTATE_X(1, 01)
|
||||||
DEFINE_HOTKEY_SAVESTATE_X(2, 02)
|
DEFINE_HOTKEY_SAVESTATE_X(2, 02)
|
||||||
DEFINE_HOTKEY_SAVESTATE_X(3, 03)
|
DEFINE_HOTKEY_SAVESTATE_X(3, 03)
|
||||||
|
@ -1798,7 +1798,7 @@ DEFINE_HOTKEY_SAVESTATE_X(8, 08)
|
||||||
DEFINE_HOTKEY_SAVESTATE_X(9, 09)
|
DEFINE_HOTKEY_SAVESTATE_X(9, 09)
|
||||||
DEFINE_HOTKEY_SAVESTATE_X(10, 10)
|
DEFINE_HOTKEY_SAVESTATE_X(10, 10)
|
||||||
#define DEFINE_HOTKEY_LOADSTATE_X(slotnum, slotnumstr) DEFINE_HOTKEY("LoadStateFromSlot" #slotnum, \
|
#define DEFINE_HOTKEY_LOADSTATE_X(slotnum, slotnumstr) DEFINE_HOTKEY("LoadStateFromSlot" #slotnum, \
|
||||||
"Save States", "Load State From Slot " #slotnumstr, [](bool pressed) { \
|
"Save States", "Load State From Slot " #slotnumstr, [](s32 pressed) { \
|
||||||
if (!pressed) \
|
if (!pressed) \
|
||||||
HotkeyLoadStateSlot(slotnum); \
|
HotkeyLoadStateSlot(slotnum); \
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in New Issue