input_source.cpp (5240B)
1 // SPDX-FileCopyrightText: 2019-2022 Connor McLaughlin <stenzek@gmail.com> 2 // SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0) 3 4 #include "input_source.h" 5 #include "common/string_util.h" 6 7 InputSource::InputSource() = default; 8 9 InputSource::~InputSource() = default; 10 11 void InputSource::UpdateMotorState(InputBindingKey large_key, InputBindingKey small_key, float large_intensity, 12 float small_intensity) 13 { 14 if (large_key.bits != 0) 15 UpdateMotorState(large_key, large_intensity); 16 if (small_key.bits != 0) 17 UpdateMotorState(small_key, small_intensity); 18 } 19 20 InputBindingKey InputSource::MakeGenericControllerAxisKey(InputSourceType clazz, u32 controller_index, s32 axis_index) 21 { 22 InputBindingKey key = {}; 23 key.source_type = clazz; 24 key.source_index = controller_index; 25 key.source_subtype = InputSubclass::ControllerAxis; 26 key.data = static_cast<u32>(axis_index); 27 return key; 28 } 29 30 InputBindingKey InputSource::MakeGenericControllerButtonKey(InputSourceType clazz, u32 controller_index, 31 s32 button_index) 32 { 33 InputBindingKey key = {}; 34 key.source_type = clazz; 35 key.source_index = controller_index; 36 key.source_subtype = InputSubclass::ControllerButton; 37 key.data = static_cast<u32>(button_index); 38 return key; 39 } 40 41 InputBindingKey InputSource::MakeGenericControllerHatKey(InputSourceType clazz, u32 controller_index, s32 hat_index, 42 u8 hat_direction, u32 num_directions) 43 { 44 InputBindingKey key = {}; 45 key.source_type = clazz; 46 key.source_index = controller_index; 47 key.source_subtype = InputSubclass::ControllerHat; 48 key.data = static_cast<u32>(hat_index) * num_directions + hat_direction; 49 return key; 50 } 51 52 InputBindingKey InputSource::MakeGenericControllerMotorKey(InputSourceType clazz, u32 controller_index, s32 motor_index) 53 { 54 InputBindingKey key = {}; 55 key.source_type = clazz; 56 key.source_index = controller_index; 57 key.source_subtype = InputSubclass::ControllerMotor; 58 key.data = static_cast<u32>(motor_index); 59 return key; 60 } 61 62 std::optional<InputBindingKey> InputSource::ParseGenericControllerKey(InputSourceType clazz, 63 std::string_view source, 64 std::string_view sub_binding) 65 { 66 // try to find the number, this function doesn't care about whether it's xinput or sdl or whatever 67 std::string_view::size_type pos = 0; 68 while (pos < source.size()) 69 { 70 if (source[pos] >= '0' && source[pos] <= '9') 71 break; 72 pos++; 73 } 74 if (pos == source.size()) 75 return std::nullopt; 76 77 const std::optional<s32> source_index = StringUtil::FromChars<s32>(source.substr(pos)); 78 if (!source_index.has_value() || source_index.value() < 0) 79 return std::nullopt; 80 81 InputBindingKey key = {}; 82 key.source_type = clazz; 83 key.source_index = source_index.value(); 84 85 if (sub_binding.starts_with("+Axis") || sub_binding.starts_with("-Axis")) 86 { 87 const std::optional<s32> axis_number = StringUtil::FromChars<s32>(sub_binding.substr(5)); 88 if (!axis_number.has_value() || axis_number.value() < 0) 89 return std::nullopt; 90 91 key.source_subtype = InputSubclass::ControllerAxis; 92 key.data = static_cast<u32>(axis_number.value()); 93 94 if (sub_binding[0] == '+') 95 key.modifier = InputModifier::None; 96 else if (sub_binding[0] == '-') 97 key.modifier = InputModifier::Negate; 98 else 99 return std::nullopt; 100 } 101 else if (sub_binding.starts_with("FullAxis")) 102 { 103 const std::optional<s32> axis_number = StringUtil::FromChars<s32>(sub_binding.substr(8)); 104 if (!axis_number.has_value() || axis_number.value() < 0) 105 return std::nullopt; 106 key.source_subtype = InputSubclass::ControllerAxis; 107 key.data = static_cast<u32>(axis_number.value()); 108 key.modifier = InputModifier::FullAxis; 109 } 110 else if (sub_binding.starts_with("Button")) 111 { 112 const std::optional<s32> button_number = StringUtil::FromChars<s32>(sub_binding.substr(6)); 113 if (!button_number.has_value() || button_number.value() < 0) 114 return std::nullopt; 115 116 key.source_subtype = InputSubclass::ControllerButton; 117 key.data = static_cast<u32>(button_number.value()); 118 } 119 else 120 { 121 return std::nullopt; 122 } 123 124 return key; 125 } 126 127 std::string InputSource::ConvertGenericControllerKeyToString(InputBindingKey key) 128 { 129 if (key.source_subtype == InputSubclass::ControllerAxis) 130 { 131 const char* modifier = ""; 132 switch (key.modifier) 133 { 134 case InputModifier::None: 135 modifier = "+"; 136 break; 137 case InputModifier::Negate: 138 modifier = "-"; 139 break; 140 case InputModifier::FullAxis: 141 modifier = "Full"; 142 break; 143 } 144 return fmt::format("{}-{}/{}Axis{}", InputManager::InputSourceToString(key.source_type), 145 static_cast<u32>(key.source_index), modifier, key.data); 146 } 147 else if (key.source_subtype == InputSubclass::ControllerButton) 148 { 149 return fmt::format("{}{}/Button{}", InputManager::InputSourceToString(key.source_type), 150 static_cast<u32>(key.source_index), key.data); 151 } 152 else 153 { 154 return {}; 155 } 156 }