mirror of https://github.com/PCSX2/pcsx2.git
PAD: Add macro buttons
This commit is contained in:
parent
e5248db844
commit
9504671919
|
@ -583,6 +583,18 @@ void InputManager::AddPadBindings(SettingsInterface& si, u32 pad_index, const ch
|
|||
}
|
||||
}
|
||||
|
||||
for (u32 macro_button_index = 0; macro_button_index < PAD::NUM_MACRO_BUTTONS_PER_CONTROLLER; macro_button_index++)
|
||||
{
|
||||
const std::vector<std::string> bindings(si.GetStringList(section.c_str(),
|
||||
StringUtil::StdStringFromFormat("Macro%u", macro_button_index + 1).c_str()));
|
||||
if (!bindings.empty())
|
||||
{
|
||||
AddBindings(bindings, InputButtonEventHandler{[pad_index, macro_button_index](bool state) {
|
||||
PAD::SetMacroButtonState(pad_index, macro_button_index, state);
|
||||
}});
|
||||
}
|
||||
}
|
||||
|
||||
const PAD::VibrationCapabilities vibcaps = PAD::GetControllerVibrationCapabilities(type);
|
||||
if (vibcaps != PAD::VibrationCapabilities::NoVibration)
|
||||
{
|
||||
|
|
|
@ -31,6 +31,25 @@ const u32 build = 0; // increase that with each version
|
|||
|
||||
KeyStatus g_key_status;
|
||||
|
||||
namespace PAD
|
||||
{
|
||||
struct MacroButton
|
||||
{
|
||||
std::vector<u32> buttons; ///< Buttons to activate.
|
||||
u32 toggle_frequency; ///< Interval at which the buttons will be toggled, if not 0.
|
||||
u32 toggle_counter; ///< When this counter reaches zero, buttons will be toggled.
|
||||
bool toggle_state; ///< Current state for turbo.
|
||||
bool trigger_state; ///< Whether the macro button is active.
|
||||
};
|
||||
|
||||
static const char* GetDefaultPadType(u32 pad);
|
||||
static void LoadMacroButtonConfig(const SettingsInterface& si, u32 pad, const std::string_view& type, const std::string& section);
|
||||
static void ApplyMacroButton(u32 pad, const MacroButton& mb);
|
||||
static void UpdateMacroButtons();
|
||||
|
||||
static std::array<std::array<MacroButton, NUM_MACRO_BUTTONS_PER_CONTROLLER>, GAMEPAD_NUMBER> s_macro_buttons;
|
||||
} // namespace PAD
|
||||
|
||||
s32 PADinit()
|
||||
{
|
||||
Pad::reset_all();
|
||||
|
@ -161,11 +180,13 @@ u8 PADpoll(u8 value)
|
|||
|
||||
void PAD::LoadConfig(const SettingsInterface& si)
|
||||
{
|
||||
// This is where we would load controller types, if onepad supported them.
|
||||
PAD::s_macro_buttons = {};
|
||||
|
||||
// This is where we would load controller types, if onepad supported them.
|
||||
for (u32 i = 0; i < GAMEPAD_NUMBER; i++)
|
||||
{
|
||||
const std::string section(StringUtil::StdStringFromFormat("Pad%u", i + 1u));
|
||||
const std::string type(si.GetStringValue(section.c_str(), "Type", GetDefaultPadType(i)));
|
||||
const float axis_scale = si.GetFloatValue(section.c_str(), "AxisScale", 1.0f);
|
||||
const float large_motor_scale = si.GetFloatValue(section.c_str(), "LargeMotorScale", 1.0f);
|
||||
const float small_motor_scale = si.GetFloatValue(section.c_str(), "SmallMotorScale", 1.0f);
|
||||
|
@ -173,9 +194,16 @@ void PAD::LoadConfig(const SettingsInterface& si)
|
|||
g_key_status.SetAxisScale(i, axis_scale);
|
||||
g_key_status.SetVibrationScale(i, 0, large_motor_scale);
|
||||
g_key_status.SetVibrationScale(i, 1, small_motor_scale);
|
||||
|
||||
LoadMacroButtonConfig(si, i, type, section);
|
||||
}
|
||||
}
|
||||
|
||||
const char* PAD::GetDefaultPadType(u32 pad)
|
||||
{
|
||||
return (pad == 0) ? "DualShock2" : "None";
|
||||
}
|
||||
|
||||
void PAD::SetDefaultConfig(SettingsInterface& si)
|
||||
{
|
||||
si.ClearSection("InputSources");
|
||||
|
@ -191,7 +219,7 @@ void PAD::SetDefaultConfig(SettingsInterface& si)
|
|||
si.SetBoolValue("InputSources", "XInput", false);
|
||||
|
||||
// PCSX2 Controller Settings - Controller 1 / Controller 2 / ...
|
||||
si.SetStringValue("Pad1", "Type", "DualShock2");
|
||||
si.SetStringValue("Pad1", "Type", GetDefaultPadType(0));
|
||||
si.SetStringValue("Pad1", "Up", "Keyboard/Up");
|
||||
si.SetStringValue("Pad1", "Right", "Keyboard/Right");
|
||||
si.SetStringValue("Pad1", "Down", "Keyboard/Down");
|
||||
|
@ -227,12 +255,12 @@ void PAD::SetDefaultConfig(SettingsInterface& si)
|
|||
si.SetStringValue("Hotkeys", "CycleAspectRatio", "Keyboard/F6");
|
||||
si.SetStringValue("Hotkeys", "CycleMipmapMode", "Keyboard/Insert");
|
||||
si.SetStringValue("Hotkeys", "CycleInterlaceMode", "Keyboard/F5");
|
||||
// si.SetStringValue("Hotkeys", "DecreaseUpscaleMultiplier", "Keyboard"); TBD
|
||||
// si.SetStringValue("Hotkeys", "IncreaseUpscaleMultiplier", "Keyboard"); TBD
|
||||
// si.SetStringValue("Hotkeys", "DecreaseUpscaleMultiplier", "Keyboard"); TBD
|
||||
// si.SetStringValue("Hotkeys", "IncreaseUpscaleMultiplier", "Keyboard"); TBD
|
||||
si.SetStringValue("Hotkeys", "ToggleSoftwareRendering", "Keyboard/F9");
|
||||
si.SetStringValue("Hotkeys", "ZoomIn", "Keyboard/Control & Keyboard/Plus");
|
||||
si.SetStringValue("Hotkeys", "ZoomOut", "Keyboard/Control & Keyboard/Minus");
|
||||
// Missing hotkey for resetting zoom back to 100 with Keyboard/Control & Keyboard/Asterisk
|
||||
// Missing hotkey for resetting zoom back to 100 with Keyboard/Control & Keyboard/Asterisk
|
||||
|
||||
// PCSX2 Controller Settings - Hotkeys - Save States
|
||||
si.SetStringValue("Hotkeys", "LoadStateFromSlot", "Keyboard/F3");
|
||||
|
@ -241,8 +269,8 @@ void PAD::SetDefaultConfig(SettingsInterface& si)
|
|||
si.SetStringValue("Hotkeys", "PreviousSaveStateSlot", "Keyboard/Shift & Keyboard/F2");
|
||||
|
||||
// PCSX2 Controller Settings - Hotkeys - System
|
||||
// si.SetStringValue("Hotkeys", "DecreaseSpeed", "Keyboard"); TBD
|
||||
// si.SetStringValue("Hotkeys", "IncreaseSpeed", "Keyboard"); TBD
|
||||
// si.SetStringValue("Hotkeys", "DecreaseSpeed", "Keyboard"); TBD
|
||||
// si.SetStringValue("Hotkeys", "IncreaseSpeed", "Keyboard"); TBD
|
||||
si.SetStringValue("Hotkeys", "ToggleFrameLimit", "Keyboard/F4");
|
||||
si.SetStringValue("Hotkeys", "TogglePause", "Keyboard/Space");
|
||||
si.SetStringValue("Hotkeys", "ToggleSlowMotion", "Keyboard/Shift & Keyboard/Backtab");
|
||||
|
@ -253,6 +281,7 @@ void PAD::SetDefaultConfig(SettingsInterface& si)
|
|||
void PAD::Update()
|
||||
{
|
||||
Pad::rumble_all();
|
||||
UpdateMacroButtons();
|
||||
}
|
||||
|
||||
std::vector<std::string> PAD::GetControllerTypeNames()
|
||||
|
@ -313,3 +342,88 @@ void PAD::SetControllerState(u32 controller, u32 bind, float value)
|
|||
|
||||
g_key_status.Set(controller, bind, value);
|
||||
}
|
||||
|
||||
void PAD::LoadMacroButtonConfig(const SettingsInterface& si, u32 pad, const std::string_view& type, const std::string& section)
|
||||
{
|
||||
// lazily initialized
|
||||
std::vector<std::string> binds;
|
||||
|
||||
for (u32 i = 0; i < NUM_MACRO_BUTTONS_PER_CONTROLLER; i++)
|
||||
{
|
||||
std::string binds_string;
|
||||
if (!si.GetStringValue(section.c_str(), StringUtil::StdStringFromFormat("Macro%uBinds", i + 1).c_str(), &binds_string))
|
||||
continue;
|
||||
|
||||
const u32 frequency = si.GetUIntValue(section.c_str(), StringUtil::StdStringFromFormat("Macro%uFrequency", i + 1).c_str(), 0u);
|
||||
if (binds.empty())
|
||||
binds = GetControllerBinds(type);
|
||||
|
||||
// convert binds
|
||||
std::vector<u32> bind_indices;
|
||||
std::vector<std::string_view> buttons_split(StringUtil::SplitString(binds_string, '&', true));
|
||||
if (buttons_split.empty())
|
||||
continue;
|
||||
for (const std::string_view& button : buttons_split)
|
||||
{
|
||||
auto it = std::find(binds.begin(), binds.end(), button);
|
||||
if (it == binds.end())
|
||||
{
|
||||
Console.Error("Invalid bind '%.*s' in macro button %u for pad %u", static_cast<int>(button.size()), button.data(), pad, i);
|
||||
continue;
|
||||
}
|
||||
|
||||
bind_indices.push_back(static_cast<u32>(std::distance(binds.begin(), it)));
|
||||
}
|
||||
if (bind_indices.empty())
|
||||
continue;
|
||||
|
||||
s_macro_buttons[pad][i].buttons = std::move(bind_indices);
|
||||
s_macro_buttons[pad][i].toggle_frequency = frequency;
|
||||
}
|
||||
}
|
||||
|
||||
void PAD::SetMacroButtonState(u32 pad, u32 index, bool state)
|
||||
{
|
||||
if (pad >= GAMEPAD_NUMBER || index >= NUM_MACRO_BUTTONS_PER_CONTROLLER)
|
||||
return;
|
||||
|
||||
MacroButton& mb = s_macro_buttons[pad][index];
|
||||
if (mb.buttons.empty() || mb.trigger_state == state)
|
||||
return;
|
||||
|
||||
mb.toggle_counter = mb.toggle_frequency;
|
||||
mb.trigger_state = state;
|
||||
if (mb.toggle_state != state)
|
||||
{
|
||||
mb.toggle_state = state;
|
||||
ApplyMacroButton(pad, mb);
|
||||
}
|
||||
}
|
||||
|
||||
void PAD::ApplyMacroButton(u32 pad, const MacroButton& mb)
|
||||
{
|
||||
const float value = mb.toggle_state ? 1.0f : 0.0f;
|
||||
for (const u32 btn : mb.buttons)
|
||||
g_key_status.Set(pad, btn, value);
|
||||
}
|
||||
|
||||
void PAD::UpdateMacroButtons()
|
||||
{
|
||||
for (u32 pad = 0; pad < GAMEPAD_NUMBER; pad++)
|
||||
{
|
||||
for (u32 index = 0; index < NUM_MACRO_BUTTONS_PER_CONTROLLER; index++)
|
||||
{
|
||||
MacroButton& mb = s_macro_buttons[pad][index];
|
||||
if (!mb.trigger_state || mb.toggle_frequency == 0)
|
||||
continue;
|
||||
|
||||
mb.toggle_counter--;
|
||||
if (mb.toggle_counter > 0)
|
||||
continue;
|
||||
|
||||
mb.toggle_counter = mb.toggle_frequency;
|
||||
mb.toggle_state = !mb.toggle_state;
|
||||
ApplyMacroButton(pad, mb);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,6 +43,9 @@ namespace PAD
|
|||
Count
|
||||
};
|
||||
|
||||
/// Number of macro buttons per controller.
|
||||
static constexpr u32 NUM_MACRO_BUTTONS_PER_CONTROLLER = 4;
|
||||
|
||||
/// Reloads configuration.
|
||||
void LoadConfig(const SettingsInterface& si);
|
||||
|
||||
|
@ -63,4 +66,7 @@ namespace PAD
|
|||
|
||||
/// Sets the specified bind on a controller to the specified pressure (normalized to 0..1).
|
||||
void SetControllerState(u32 controller, u32 bind, float value);
|
||||
|
||||
/// Sets the state of the specified macro button.
|
||||
void SetMacroButtonState(u32 pad, u32 index, bool state);
|
||||
} // namespace PAD
|
||||
|
|
Loading…
Reference in New Issue