Input: Add FullAxis modifier

This commit is contained in:
TellowKrinkle 2022-09-14 17:06:23 -05:00 committed by tellowkrinkle
parent 02a2e8a7f1
commit a72cecd235
8 changed files with 83 additions and 31 deletions

View File

@ -84,7 +84,7 @@ bool InputBindingDialog::eventFilter(QObject* watched, QEvent* event)
if (dx != 0.0f)
{
InputBindingKey key(InputManager::MakePointerAxisKey(0, InputPointerAxis::WheelX));
key.negative = (dx < 0.0f);
key.modifier = dx < 0.0f ? InputModifier::Negate : InputModifier::None;
m_new_bindings.push_back(key);
}
@ -92,7 +92,7 @@ bool InputBindingDialog::eventFilter(QObject* watched, QEvent* event)
if (dy != 0.0f)
{
InputBindingKey key(InputManager::MakePointerAxisKey(0, InputPointerAxis::WheelY));
key.negative = (dy < 0.0f);
key.modifier = dy < 0.0f ? InputModifier::Negate : InputModifier::None;
m_new_bindings.push_back(key);
}
@ -115,14 +115,14 @@ bool InputBindingDialog::eventFilter(QObject* watched, QEvent* event)
if (std::abs(diff.x()) >= THRESHOLD)
{
InputBindingKey key(InputManager::MakePointerAxisKey(0, InputPointerAxis::X));
key.negative = (diff.x() < 0);
key.modifier = diff.x() < 0 ? InputModifier::Negate : InputModifier::None;
m_new_bindings.push_back(key);
has_one = true;
}
if (std::abs(diff.y()) >= THRESHOLD)
{
InputBindingKey key(InputManager::MakePointerAxisKey(0, InputPointerAxis::Y));
key.negative = (diff.y() < 0);
key.modifier = diff.y() < 0 ? InputModifier::Negate : InputModifier::None;
m_new_bindings.push_back(key);
has_one = true;
}
@ -291,7 +291,7 @@ void InputBindingDialog::inputManagerHookCallback(InputBindingKey key, float val
if (abs_value >= 0.5f)
{
InputBindingKey key_to_add = key;
key_to_add.negative = (value < 0.0f);
key_to_add.modifier = value < 0.0f ? InputModifier::Negate : InputModifier::None;
m_new_bindings.push_back(key_to_add);
}
}

View File

@ -138,7 +138,7 @@ bool InputBindingWidget::eventFilter(QObject* watched, QEvent* event)
if (dx != 0.0f)
{
InputBindingKey key(InputManager::MakePointerAxisKey(0, InputPointerAxis::WheelX));
key.negative = (dx < 0.0f);
key.modifier = dx < 0.0f ? InputModifier::Negate : InputModifier::None;
m_new_bindings.push_back(key);
}
@ -146,7 +146,7 @@ bool InputBindingWidget::eventFilter(QObject* watched, QEvent* event)
if (dy != 0.0f)
{
InputBindingKey key(InputManager::MakePointerAxisKey(0, InputPointerAxis::WheelY));
key.negative = (dy < 0.0f);
key.modifier = dy < 0.0f ? InputModifier::Negate : InputModifier::None;
m_new_bindings.push_back(key);
}
@ -169,14 +169,14 @@ bool InputBindingWidget::eventFilter(QObject* watched, QEvent* event)
if (std::abs(diff.x()) >= THRESHOLD)
{
InputBindingKey key(InputManager::MakePointerAxisKey(0, InputPointerAxis::X));
key.negative = (diff.x() < 0);
key.modifier = diff.x() < 0 ? InputModifier::Negate : InputModifier::None;
m_new_bindings.push_back(key);
has_one = true;
}
if (std::abs(diff.y()) >= THRESHOLD)
{
InputBindingKey key(InputManager::MakePointerAxisKey(0, InputPointerAxis::Y));
key.negative = (diff.y() < 0);
key.modifier = diff.y() < 0 ? InputModifier::Negate : InputModifier::None;
m_new_bindings.push_back(key);
has_one = true;
}
@ -357,7 +357,7 @@ void InputBindingWidget::inputManagerHookCallback(InputBindingKey key, float val
if (abs_value >= 0.5f)
{
InputBindingKey key_to_add = key;
key_to_add.negative = (value < 0.0f);
key_to_add.modifier = value < 0.0f ? InputModifier::Negate : InputModifier::None;
m_new_bindings.push_back(key_to_add);
}
}

View File

@ -1319,7 +1319,7 @@ void FullscreenUI::BeginInputBinding(SettingsInterface* bsi, PAD::ControllerBind
if (abs_value >= 0.5f)
{
InputBindingKey key_to_add = key;
key_to_add.negative = (value < 0.0f);
key_to_add.modifier = (value < 0.0f) ? InputModifier::Negate : InputModifier::None;
s_input_binding_new_bindings.push_back(key_to_add);
}

View File

@ -276,7 +276,7 @@ std::string InputManager::ConvertInputBindingKeyToString(InputBindingKey key)
}
else if (key.source_subtype == InputSubclass::PointerAxis)
{
return fmt::format("Pointer-{}/{}{:c}", u32{key.source_index}, s_pointer_axis_names[key.data], key.negative ? '-' : '+');
return fmt::format("Pointer-{}/{}{:c}", u32{key.source_index}, s_pointer_axis_names[key.data], key.modifier == InputModifier::Negate ? '-' : '+');
}
}
else if (key.source_type < InputSourceType::Count && s_input_sources[static_cast<u32>(key.source_type)])
@ -497,9 +497,9 @@ std::optional<InputBindingKey> InputManager::ParsePointerKey(const std::string_v
const std::string_view dir_part(sub_binding.substr(std::strlen(s_pointer_axis_names[i])));
if (dir_part == "+")
key.negative = false;
key.modifier = InputModifier::None;
else if (dir_part == "-")
key.negative = true;
key.modifier = InputModifier::Negate;
else
return std::nullopt;
@ -677,11 +677,24 @@ bool InputManager::InvokeEvents(InputBindingKey key, float value, GenericInputBi
continue;
const u8 bit = static_cast<u8>(1) << i;
const bool negative = binding->keys[i].negative;
const bool negative = binding->keys[i].modifier == InputModifier::Negate;
const bool new_state = (negative ? (value < 0.0f) : (value > 0.0f));
// 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);
float value_to_pass = 0.0f;
switch (binding->keys[i].modifier)
{
case InputModifier::None:
if (value > 0.0f)
value_to_pass = value;
break;
case InputModifier::Negate:
if (value < 0.0f)
value_to_pass = -value;
break;
case InputModifier::FullAxis:
value_to_pass = value * 0.5f + 0.5f;
break;
}
// axes are fired regardless of a state change, unless they're zero
// (but going from not-zero to zero will still fire, because of the full state)

View File

@ -55,6 +55,13 @@ enum class InputSubclass : u32
ControllerHaptic = 3,
};
enum class InputModifier : u32
{
None = 0,
Negate, ///< Input * -1, gets the negative side of the axis
FullAxis, ///< (Input * 0.5) + 0.5, uses both the negative and positive side of the axis together
};
/// A composite type representing a full input key which is part of an event.
union InputBindingKey
{
@ -63,8 +70,8 @@ union InputBindingKey
InputSourceType source_type : 4;
u32 source_index : 8; ///< controller number
InputSubclass source_subtype : 2; ///< if 1, binding is for an axis and not a button (used for controllers)
u32 negative : 1; ///< if 1, binding is for the negative side of the axis
u32 unused : 17;
InputModifier modifier : 2;
u32 unused : 16;
u32 data;
};
@ -79,7 +86,7 @@ union InputBindingKey
{
InputBindingKey r;
r.bits = bits;
r.negative = false;
r.modifier = InputModifier::None;
return r;
}
};

View File

@ -92,12 +92,21 @@ std::optional<InputBindingKey> InputSource::ParseGenericControllerKey(
key.data = static_cast<u32>(axis_number.value());
if (sub_binding[0] == '+')
key.negative = false;
key.modifier = InputModifier::None;
else if (sub_binding[0] == '-')
key.negative = true;
key.modifier = InputModifier::Negate;
else
return std::nullopt;
}
else if (StringUtil::StartsWith(sub_binding, "FullAxis"))
{
const std::optional<s32> axis_number = StringUtil::FromChars<s32>(sub_binding.substr(8));
if (!axis_number.has_value() || axis_number.value() < 0)
return std::nullopt;
key.source_subtype = InputSubclass::ControllerAxis;
key.data = static_cast<u32>(axis_number.value());
key.modifier = InputModifier::FullAxis;
}
else if (StringUtil::StartsWith(sub_binding, "Button"))
{
const std::optional<s32> button_number = StringUtil::FromChars<s32>(sub_binding.substr(6));
@ -119,8 +128,14 @@ std::string InputSource::ConvertGenericControllerKeyToString(InputBindingKey key
{
if (key.source_subtype == InputSubclass::ControllerAxis)
{
return StringUtil::StdStringFromFormat("%s-%u/%cAxis%u", InputManager::InputSourceToString(key.source_type),
key.source_index, key.negative ? '+' : '-', key.data);
const char* modifier = "";
switch (key.modifier) {
case InputModifier::None: modifier = "+"; break;
case InputModifier::Negate: modifier = "-"; break;
case InputModifier::FullAxis: modifier = "Full"; break;
}
return StringUtil::StdStringFromFormat("%s-%u/%sAxis%u", InputManager::InputSourceToString(key.source_type),
key.source_index, modifier, key.data);
}
else if (key.source_subtype == InputSubclass::ControllerButton)
{

View File

@ -256,7 +256,7 @@ std::optional<InputBindingKey> SDLInputSource::ParseKeyString(
{
key.source_subtype = InputSubclass::ControllerAxis;
key.data = *value;
key.negative = (binding[0] == '-');
key.modifier = (binding[0] == '-') ? InputModifier::Negate : InputModifier::None;
return key;
}
}
@ -267,11 +267,21 @@ std::optional<InputBindingKey> SDLInputSource::ParseKeyString(
// found an axis!
key.source_subtype = InputSubclass::ControllerAxis;
key.data = i;
key.negative = (binding[0] == '-');
key.modifier = (binding[0] == '-') ? InputModifier::Negate : InputModifier::None;
return key;
}
}
}
else if (StringUtil::StartsWith(binding, "FullAxis"))
{
if (auto value = StringUtil::FromChars<u32>(binding.substr(8)))
{
key.source_subtype = InputSubclass::ControllerAxis;
key.data = *value;
key.modifier = InputModifier::FullAxis;
return key;
}
}
else
{
// must be a button
@ -307,11 +317,17 @@ std::string SDLInputSource::ConvertKeyToString(InputBindingKey key)
{
if (key.source_subtype == InputSubclass::ControllerAxis)
{
char modifier = key.negative ? '-' : '+';
const char* modifier = key.modifier == InputModifier::Negate ? "-" : "+";
if (key.data < std::size(s_sdl_axis_names))
ret = StringUtil::StdStringFromFormat("SDL-%u/%c%s", key.source_index, modifier, s_sdl_axis_names[key.data]);
{
ret = StringUtil::StdStringFromFormat("SDL-%u/%s%s", key.source_index, modifier, s_sdl_axis_names[key.data]);
}
else
ret = StringUtil::StdStringFromFormat("SDL-%u/%cAxis%u", key.source_index, modifier, key.data);
{
if (key.modifier == InputModifier::FullAxis)
modifier = "Full";
ret = StringUtil::StdStringFromFormat("SDL-%u/%sAxis%u", key.source_index, modifier, key.data);
}
}
else if (key.source_subtype == InputSubclass::ControllerButton)
{

View File

@ -292,7 +292,7 @@ std::optional<InputBindingKey> XInputSource::ParseKeyString(
// found an axis!
key.source_subtype = InputSubclass::ControllerAxis;
key.data = i;
key.negative = (binding[0] == '-');
key.modifier = binding[0] == '-' ? InputModifier::Negate : InputModifier::None;
return key;
}
}
@ -323,8 +323,9 @@ std::string XInputSource::ConvertKeyToString(InputBindingKey key)
{
if (key.source_subtype == InputSubclass::ControllerAxis && key.data < std::size(s_axis_names))
{
const char modifier = key.modifier == InputModifier::Negate ? '-' : '+';
ret = StringUtil::StdStringFromFormat(
"XInput-%u/%c%s", key.source_index, key.negative ? '-' : '+', s_axis_names[key.data]);
"XInput-%u/%c%s", key.source_index, modifier, s_axis_names[key.data]);
}
else if (key.source_subtype == InputSubclass::ControllerButton && key.data < std::size(s_button_names))
{