input_manager.cpp (68614B)
1 // SPDX-FileCopyrightText: 2019-2024 Connor McLaughlin <stenzek@gmail.com> 2 // SPDX-License-Identifier: (GPL-3.0 OR PolyForm-Strict-1.0.0) 3 4 #include "input_manager.h" 5 #include "common/assert.h" 6 #include "common/file_system.h" 7 #include "common/log.h" 8 #include "common/path.h" 9 #include "common/string_util.h" 10 #include "common/timer.h" 11 #include "core/controller.h" 12 #include "core/host.h" 13 #include "core/system.h" 14 #include "imgui_manager.h" 15 #include "input_source.h" 16 17 #include "IconsPromptFont.h" 18 19 #include "fmt/core.h" 20 21 #include <algorithm> 22 #include <array> 23 #include <atomic> 24 #include <memory> 25 #include <mutex> 26 #include <sstream> 27 #include <unordered_map> 28 #include <variant> 29 #include <vector> 30 31 Log_SetChannel(InputManager); 32 33 namespace { 34 35 // ------------------------------------------------------------------------ 36 // Constants 37 // ------------------------------------------------------------------------ 38 39 enum : u32 40 { 41 MAX_KEYS_PER_BINDING = 4, 42 MAX_MOTORS_PER_PAD = 2, 43 FIRST_EXTERNAL_INPUT_SOURCE = static_cast<u32>(InputSourceType::Pointer) + 1u, 44 LAST_EXTERNAL_INPUT_SOURCE = static_cast<u32>(InputSourceType::Count), 45 }; 46 47 // ------------------------------------------------------------------------ 48 // Binding Type 49 // ------------------------------------------------------------------------ 50 // This class tracks both the keys which make it up (for chords), as well 51 // as the state of all buttons. For button callbacks, it's fired when 52 // all keys go active, and for axis callbacks, when all are active and 53 // the value changes. 54 55 struct InputBinding 56 { 57 InputBindingKey keys[MAX_KEYS_PER_BINDING] = {}; 58 InputEventHandler handler; 59 u8 num_keys = 0; 60 u8 full_mask = 0; 61 u8 current_mask = 0; 62 }; 63 64 struct PadVibrationBinding 65 { 66 struct Motor 67 { 68 InputBindingKey binding; 69 u64 last_update_time; 70 InputSource* source; 71 float last_intensity; 72 }; 73 74 u32 pad_index = 0; 75 Motor motors[MAX_MOTORS_PER_PAD] = {}; 76 77 /// Returns true if the two motors are bound to the same host motor. 78 ALWAYS_INLINE bool AreMotorsCombined() const { return motors[0].binding == motors[1].binding; } 79 80 /// Returns the intensity when both motors are combined. 81 ALWAYS_INLINE float GetCombinedIntensity() const 82 { 83 return std::max(motors[0].last_intensity, motors[1].last_intensity); 84 } 85 }; 86 87 struct MacroButton 88 { 89 std::vector<u32> buttons; ///< Buttons to activate. 90 u16 toggle_frequency; ///< Interval at which the buttons will be toggled, if not 0. 91 u16 toggle_counter; ///< When this counter reaches zero, buttons will be toggled. 92 bool toggle_state; ///< Current state for turbo. 93 bool trigger_state; ///< Whether the macro button is active. 94 bool trigger_toggle; ///< Whether the macro is trigged by holding or press. 95 }; 96 97 } // namespace 98 99 // ------------------------------------------------------------------------ 100 // Forward Declarations (for static qualifier) 101 // ------------------------------------------------------------------------ 102 namespace InputManager { 103 static std::optional<InputBindingKey> ParseHostKeyboardKey(std::string_view source, std::string_view sub_binding); 104 static std::optional<InputBindingKey> ParsePointerKey(std::string_view source, std::string_view sub_binding); 105 static std::optional<InputBindingKey> ParseSensorKey(std::string_view source, std::string_view sub_binding); 106 107 static std::vector<std::string_view> SplitChord(std::string_view binding); 108 static bool SplitBinding(std::string_view binding, std::string_view* source, std::string_view* sub_binding); 109 static void PrettifyInputBindingPart(std::string_view binding, SmallString& ret, bool& changed); 110 static void AddBindings(const std::vector<std::string>& bindings, const InputEventHandler& handler); 111 static void UpdatePointerCount(); 112 113 static bool IsAxisHandler(const InputEventHandler& handler); 114 static float ApplySingleBindingScale(float sensitivity, float deadzone, float value); 115 116 static void AddHotkeyBindings(SettingsInterface& si); 117 static void AddPadBindings(SettingsInterface& si, const std::string& section, u32 pad, 118 const Controller::ControllerInfo* cinfo); 119 static void UpdateContinuedVibration(); 120 static void GenerateRelativeMouseEvents(); 121 122 static bool DoEventHook(InputBindingKey key, float value); 123 static bool PreprocessEvent(InputBindingKey key, float value, GenericInputBinding generic_key); 124 static bool ProcessEvent(InputBindingKey key, float value, bool skip_button_handlers); 125 126 static void LoadMacroButtonConfig(SettingsInterface& si, const std::string& section, u32 pad, 127 const Controller::ControllerInfo* cinfo); 128 static void ApplyMacroButton(u32 pad, const MacroButton& mb); 129 static void UpdateMacroButtons(); 130 131 static void UpdateInputSourceState(SettingsInterface& si, std::unique_lock<std::mutex>& settings_lock, 132 InputSourceType type, std::unique_ptr<InputSource> (*factory_function)()); 133 } // namespace InputManager 134 135 // ------------------------------------------------------------------------ 136 // Local Variables 137 // ------------------------------------------------------------------------ 138 139 // This is a multimap containing any binds related to the specified key. 140 using BindingMap = std::unordered_multimap<InputBindingKey, std::shared_ptr<InputBinding>, InputBindingKeyHash>; 141 using VibrationBindingArray = std::vector<PadVibrationBinding>; 142 static BindingMap s_binding_map; 143 static VibrationBindingArray s_pad_vibration_array; 144 static std::mutex s_binding_map_write_lock; 145 146 // Hooks/intercepting (for setting bindings) 147 static std::mutex m_event_intercept_mutex; 148 static InputInterceptHook::Callback m_event_intercept_callback; 149 150 // Input sources. Keyboard/mouse don't exist here. 151 static std::array<std::unique_ptr<InputSource>, static_cast<u32>(InputSourceType::Count)> s_input_sources; 152 153 // Macro buttons. 154 static std::array<std::array<MacroButton, InputManager::NUM_MACRO_BUTTONS_PER_CONTROLLER>, 155 NUM_CONTROLLER_AND_CARD_PORTS> 156 s_macro_buttons; 157 158 // ------------------------------------------------------------------------ 159 // Hotkeys 160 // ------------------------------------------------------------------------ 161 162 static const HotkeyInfo* const s_hotkey_list[] = {g_common_hotkeys, g_host_hotkeys}; 163 164 // ------------------------------------------------------------------------ 165 // Tracking host mouse movement and turning into relative events 166 // 4 axes: pointer left/right, wheel vertical/horizontal. Last/Next/Normalized. 167 // ------------------------------------------------------------------------ 168 static constexpr const std::array<const char*, static_cast<u8>(InputPointerAxis::Count)> s_pointer_axis_names = { 169 {"X", "Y", "WheelX", "WheelY"}}; 170 static constexpr const std::array<const char*, 3> s_pointer_button_names = { 171 {"LeftButton", "RightButton", "MiddleButton"}}; 172 static constexpr const std::array<const char*, 3> s_sensor_accelerometer_names = {{"Turn", "Tilt", "Rotate"}}; 173 174 struct PointerAxisState 175 { 176 std::atomic<s32> delta; 177 float last_value; 178 }; 179 static std::array<std::array<float, static_cast<u8>(InputPointerAxis::Count)>, InputManager::MAX_POINTER_DEVICES> 180 s_host_pointer_positions; 181 static std::array<std::array<PointerAxisState, static_cast<u8>(InputPointerAxis::Count)>, 182 InputManager::MAX_POINTER_DEVICES> 183 s_pointer_state; 184 static u32 s_pointer_count = 0; 185 static std::array<float, static_cast<u8>(InputPointerAxis::Count)> s_pointer_axis_scale; 186 187 using PointerMoveCallback = std::function<void(InputBindingKey key, float value)>; 188 static std::vector<std::pair<u32, PointerMoveCallback>> s_pointer_move_callbacks; 189 190 // Window size, used for clamping the mouse position in raw input modes. 191 static std::array<float, 2> s_window_size = {}; 192 static bool s_relative_mouse_mode = false; 193 static bool s_relative_mouse_mode_active = false; 194 static bool s_hide_host_mouse_cursor = false; 195 static bool s_hide_host_mouse_cusor_active = false; 196 197 // ------------------------------------------------------------------------ 198 // Binding Parsing 199 // ------------------------------------------------------------------------ 200 201 std::vector<std::string_view> InputManager::SplitChord(std::string_view binding) 202 { 203 std::vector<std::string_view> parts; 204 205 // under an if for RVO 206 if (!binding.empty()) 207 { 208 std::string_view::size_type last = 0; 209 std::string_view::size_type next; 210 while ((next = binding.find('&', last)) != std::string_view::npos) 211 { 212 if (last != next) 213 { 214 std::string_view part(StringUtil::StripWhitespace(binding.substr(last, next - last))); 215 if (!part.empty()) 216 parts.push_back(std::move(part)); 217 } 218 last = next + 1; 219 } 220 if (last < (binding.size() - 1)) 221 { 222 std::string_view part(StringUtil::StripWhitespace(binding.substr(last))); 223 if (!part.empty()) 224 parts.push_back(std::move(part)); 225 } 226 } 227 228 return parts; 229 } 230 231 bool InputManager::SplitBinding(std::string_view binding, std::string_view* source, std::string_view* sub_binding) 232 { 233 const std::string_view::size_type slash_pos = binding.find('/'); 234 if (slash_pos == std::string_view::npos) 235 { 236 WARNING_LOG("Malformed binding: '{}'", binding); 237 return false; 238 } 239 240 *source = std::string_view(binding).substr(0, slash_pos); 241 *sub_binding = std::string_view(binding).substr(slash_pos + 1); 242 return true; 243 } 244 245 std::optional<InputBindingKey> InputManager::ParseInputBindingKey(std::string_view binding) 246 { 247 std::string_view source, sub_binding; 248 if (!SplitBinding(binding, &source, &sub_binding)) 249 return std::nullopt; 250 251 // lameee, string matching 252 if (source.starts_with("Keyboard")) 253 { 254 return ParseHostKeyboardKey(source, sub_binding); 255 } 256 else if (source.starts_with("Pointer")) 257 { 258 return ParsePointerKey(source, sub_binding); 259 } 260 else if (source.starts_with("Sensor")) 261 { 262 return ParseSensorKey(source, sub_binding); 263 } 264 else 265 { 266 for (u32 i = FIRST_EXTERNAL_INPUT_SOURCE; i < LAST_EXTERNAL_INPUT_SOURCE; i++) 267 { 268 if (s_input_sources[i]) 269 { 270 std::optional<InputBindingKey> key = s_input_sources[i]->ParseKeyString(source, sub_binding); 271 if (key.has_value()) 272 return key; 273 } 274 } 275 } 276 277 return std::nullopt; 278 } 279 280 bool InputManager::ParseBindingAndGetSource(std::string_view binding, InputBindingKey* key, InputSource** source) 281 { 282 std::string_view source_string, sub_binding; 283 if (!SplitBinding(binding, &source_string, &sub_binding)) 284 return false; 285 286 for (u32 i = FIRST_EXTERNAL_INPUT_SOURCE; i < LAST_EXTERNAL_INPUT_SOURCE; i++) 287 { 288 if (s_input_sources[i]) 289 { 290 std::optional<InputBindingKey> parsed_key = s_input_sources[i]->ParseKeyString(source_string, sub_binding); 291 if (parsed_key.has_value()) 292 { 293 *key = parsed_key.value(); 294 *source = s_input_sources[i].get(); 295 return true; 296 } 297 } 298 } 299 300 return false; 301 } 302 303 std::string InputManager::ConvertInputBindingKeyToString(InputBindingInfo::Type binding_type, InputBindingKey key) 304 { 305 if (binding_type == InputBindingInfo::Type::Pointer) 306 { 307 // pointer and device bindings don't have a data part 308 if (key.source_type == InputSourceType::Pointer) 309 { 310 return GetPointerDeviceName(key.source_index); 311 } 312 else if (key.source_type < InputSourceType::Count && s_input_sources[static_cast<u32>(key.source_type)]) 313 { 314 // This assumes that it always follows the Type/Binding form. 315 std::string keystr(s_input_sources[static_cast<u32>(key.source_type)]->ConvertKeyToString(key)); 316 std::string::size_type pos = keystr.find('/'); 317 if (pos != std::string::npos) 318 keystr.erase(pos); 319 return keystr; 320 } 321 } 322 else 323 { 324 if (key.source_type == InputSourceType::Keyboard) 325 { 326 const std::optional<std::string> str(ConvertHostKeyboardCodeToString(key.data)); 327 if (str.has_value() && !str->empty()) 328 return fmt::format("Keyboard/{}", str->c_str()); 329 } 330 else if (key.source_type == InputSourceType::Pointer) 331 { 332 if (key.source_subtype == InputSubclass::PointerButton) 333 { 334 if (key.data < s_pointer_button_names.size()) 335 return fmt::format("Pointer-{}/{}", u32{key.source_index}, s_pointer_button_names[key.data]); 336 else 337 return fmt::format("Pointer-{}/Button{}", u32{key.source_index}, key.data); 338 } 339 else if (key.source_subtype == InputSubclass::PointerAxis) 340 { 341 return fmt::format("Pointer-{}/{}{:c}", u32{key.source_index}, s_pointer_axis_names[key.data], 342 key.modifier == InputModifier::Negate ? '-' : '+'); 343 } 344 } 345 else if (key.source_type < InputSourceType::Count && s_input_sources[static_cast<u32>(key.source_type)]) 346 { 347 return std::string(s_input_sources[static_cast<u32>(key.source_type)]->ConvertKeyToString(key)); 348 } 349 } 350 351 return {}; 352 } 353 354 std::string InputManager::ConvertInputBindingKeysToString(InputBindingInfo::Type binding_type, 355 const InputBindingKey* keys, size_t num_keys) 356 { 357 // can't have a chord of devices/pointers 358 if (binding_type == InputBindingInfo::Type::Pointer) 359 { 360 // so only take the first 361 if (num_keys > 0) 362 return ConvertInputBindingKeyToString(binding_type, keys[0]); 363 } 364 365 std::stringstream ss; 366 for (size_t i = 0; i < num_keys; i++) 367 { 368 const std::string keystr(ConvertInputBindingKeyToString(binding_type, keys[i])); 369 if (keystr.empty()) 370 return std::string(); 371 372 if (i > 0) 373 ss << " & "; 374 375 ss << keystr; 376 } 377 378 return ss.str(); 379 } 380 381 bool InputManager::PrettifyInputBinding(SmallStringBase& binding) 382 { 383 if (binding.empty()) 384 return false; 385 386 const std::string_view binding_view = binding.view(); 387 388 SmallString ret; 389 bool changed = false; 390 391 std::string_view::size_type last = 0; 392 std::string_view::size_type next; 393 while ((next = binding_view.find('&', last)) != std::string_view::npos) 394 { 395 if (last != next) 396 { 397 const std::string_view part = StringUtil::StripWhitespace(binding_view.substr(last, next - last)); 398 if (!part.empty()) 399 { 400 if (!ret.empty()) 401 ret.append(" + "); 402 PrettifyInputBindingPart(part, ret, changed); 403 } 404 } 405 last = next + 1; 406 } 407 if (last < (binding_view.size() - 1)) 408 { 409 const std::string_view part = StringUtil::StripWhitespace(binding_view.substr(last)); 410 if (!part.empty()) 411 { 412 if (!ret.empty()) 413 ret.append(" + "); 414 PrettifyInputBindingPart(part, ret, changed); 415 } 416 } 417 418 if (changed) 419 binding = ret; 420 421 return changed; 422 } 423 424 void InputManager::PrettifyInputBindingPart(const std::string_view binding, SmallString& ret, bool& changed) 425 { 426 std::string_view source, sub_binding; 427 if (!SplitBinding(binding, &source, &sub_binding)) 428 return; 429 430 // lameee, string matching 431 if (source.starts_with("Keyboard")) 432 { 433 std::optional<InputBindingKey> key = ParseHostKeyboardKey(source, sub_binding); 434 const char* icon = key.has_value() ? ConvertHostKeyboardCodeToIcon(key->data) : nullptr; 435 if (icon) 436 { 437 ret.append(icon); 438 changed = true; 439 return; 440 } 441 } 442 else if (source.starts_with("Pointer")) 443 { 444 const std::optional<InputBindingKey> key = ParsePointerKey(source, sub_binding); 445 if (key.has_value()) 446 { 447 if (key->source_subtype == InputSubclass::PointerButton) 448 { 449 static constexpr const char* button_icons[] = { 450 ICON_PF_MOUSE_BUTTON_1, ICON_PF_MOUSE_BUTTON_2, ICON_PF_MOUSE_BUTTON_3, 451 ICON_PF_MOUSE_BUTTON_4, ICON_PF_MOUSE_BUTTON_5, 452 }; 453 if (key->data < std::size(button_icons)) 454 { 455 ret.append(button_icons[key->data]); 456 changed = true; 457 return; 458 } 459 } 460 } 461 } 462 else if (source.starts_with("Sensor")) 463 { 464 } 465 else 466 { 467 for (u32 i = FIRST_EXTERNAL_INPUT_SOURCE; i < LAST_EXTERNAL_INPUT_SOURCE; i++) 468 { 469 if (s_input_sources[i]) 470 { 471 std::optional<InputBindingKey> key = s_input_sources[i]->ParseKeyString(source, sub_binding); 472 if (key.has_value()) 473 { 474 const TinyString icon = s_input_sources[i]->ConvertKeyToIcon(key.value()); 475 if (!icon.empty()) 476 { 477 ret.append(icon); 478 changed = true; 479 return; 480 } 481 482 break; 483 } 484 } 485 } 486 } 487 488 ret.append(binding); 489 } 490 491 void InputManager::AddBindings(const std::vector<std::string>& bindings, const InputEventHandler& handler) 492 { 493 for (const std::string& binding : bindings) 494 AddBinding(binding, handler); 495 } 496 497 void InputManager::AddBinding(std::string_view binding, const InputEventHandler& handler) 498 { 499 std::shared_ptr<InputBinding> ibinding; 500 const std::vector<std::string_view> chord_bindings(SplitChord(binding)); 501 502 for (const std::string_view& chord_binding : chord_bindings) 503 { 504 std::optional<InputBindingKey> key = ParseInputBindingKey(chord_binding); 505 if (!key.has_value()) 506 { 507 ERROR_LOG("Invalid binding: '{}'", binding); 508 ibinding.reset(); 509 break; 510 } 511 512 if (!ibinding) 513 { 514 ibinding = std::make_shared<InputBinding>(); 515 ibinding->handler = handler; 516 } 517 518 if (ibinding->num_keys == MAX_KEYS_PER_BINDING) 519 { 520 ERROR_LOG("Too many chord parts, max is {} ({})", static_cast<unsigned>(MAX_KEYS_PER_BINDING), binding.size()); 521 ibinding.reset(); 522 break; 523 } 524 525 ibinding->keys[ibinding->num_keys] = key.value(); 526 ibinding->full_mask |= (static_cast<u8>(1) << ibinding->num_keys); 527 ibinding->num_keys++; 528 } 529 530 if (!ibinding) 531 return; 532 533 // plop it in the input map for all the keys 534 for (u32 i = 0; i < ibinding->num_keys; i++) 535 s_binding_map.emplace(ibinding->keys[i].MaskDirection(), ibinding); 536 } 537 538 void InputManager::AddVibrationBinding(u32 pad_index, const InputBindingKey* motor_0_binding, 539 InputSource* motor_0_source, const InputBindingKey* motor_1_binding, 540 InputSource* motor_1_source) 541 { 542 PadVibrationBinding vib; 543 vib.pad_index = pad_index; 544 if (motor_0_binding) 545 { 546 vib.motors[0].binding = *motor_0_binding; 547 vib.motors[0].source = motor_0_source; 548 } 549 if (motor_1_binding) 550 { 551 vib.motors[1].binding = *motor_1_binding; 552 vib.motors[1].source = motor_1_source; 553 } 554 s_pad_vibration_array.push_back(std::move(vib)); 555 } 556 557 // ------------------------------------------------------------------------ 558 // Key Decoders 559 // ------------------------------------------------------------------------ 560 561 InputBindingKey InputManager::MakeHostKeyboardKey(u32 key_code) 562 { 563 InputBindingKey key = {}; 564 key.source_type = InputSourceType::Keyboard; 565 key.data = key_code; 566 return key; 567 } 568 569 InputBindingKey InputManager::MakePointerButtonKey(u32 index, u32 button_index) 570 { 571 InputBindingKey key = {}; 572 key.source_index = index; 573 key.source_type = InputSourceType::Pointer; 574 key.source_subtype = InputSubclass::PointerButton; 575 key.data = button_index; 576 return key; 577 } 578 579 InputBindingKey InputManager::MakePointerAxisKey(u32 index, InputPointerAxis axis) 580 { 581 InputBindingKey key = {}; 582 key.data = static_cast<u32>(axis); 583 key.source_index = index; 584 key.source_type = InputSourceType::Pointer; 585 key.source_subtype = InputSubclass::PointerAxis; 586 return key; 587 } 588 589 InputBindingKey InputManager::MakeSensorAxisKey(InputSubclass sensor, u32 axis) 590 { 591 InputBindingKey key = {}; 592 key.data = static_cast<u32>(axis); 593 key.source_index = 0; 594 key.source_type = InputSourceType::Sensor; 595 key.source_subtype = sensor; 596 return key; 597 } 598 599 // ------------------------------------------------------------------------ 600 // Bind Encoders 601 // ------------------------------------------------------------------------ 602 603 static std::array<const char*, static_cast<u32>(InputSourceType::Count)> s_input_class_names = {{ 604 "Keyboard", 605 "Pointer", 606 "Sensor", 607 #ifdef _WIN32 608 "DInput", 609 "XInput", 610 #endif 611 #ifndef __ANDROID__ 612 "SDL", 613 "RawInput", 614 #else 615 "Android", 616 #endif 617 }}; 618 619 InputSource* InputManager::GetInputSourceInterface(InputSourceType type) 620 { 621 return s_input_sources[static_cast<u32>(type)].get(); 622 } 623 624 const char* InputManager::InputSourceToString(InputSourceType clazz) 625 { 626 return s_input_class_names[static_cast<u32>(clazz)]; 627 } 628 629 bool InputManager::GetInputSourceDefaultEnabled(InputSourceType type) 630 { 631 switch (type) 632 { 633 case InputSourceType::Keyboard: 634 case InputSourceType::Pointer: 635 return true; 636 637 #ifdef _WIN32 638 case InputSourceType::DInput: 639 return false; 640 641 case InputSourceType::XInput: 642 return false; 643 #endif 644 645 #ifndef __ANDROID__ 646 case InputSourceType::SDL: 647 return true; 648 case InputSourceType::RawInput: 649 return false; 650 #else 651 case InputSourceType::Android: 652 return true; 653 #endif 654 655 default: 656 return false; 657 } 658 } 659 660 std::optional<InputSourceType> InputManager::ParseInputSourceString(std::string_view str) 661 { 662 for (u32 i = 0; i < static_cast<u32>(InputSourceType::Count); i++) 663 { 664 if (str == s_input_class_names[i]) 665 return static_cast<InputSourceType>(i); 666 } 667 668 return std::nullopt; 669 } 670 671 std::optional<InputBindingKey> InputManager::ParseHostKeyboardKey(std::string_view source, std::string_view sub_binding) 672 { 673 if (source != "Keyboard") 674 return std::nullopt; 675 676 const std::optional<s32> code = ConvertHostKeyboardStringToCode(sub_binding); 677 if (!code.has_value()) 678 return std::nullopt; 679 680 InputBindingKey key = {}; 681 key.source_type = InputSourceType::Keyboard; 682 key.data = static_cast<u32>(code.value()); 683 return key; 684 } 685 686 std::optional<InputBindingKey> InputManager::ParsePointerKey(std::string_view source, std::string_view sub_binding) 687 { 688 const std::optional<s32> pointer_index = StringUtil::FromChars<s32>(source.substr(8)); 689 if (!pointer_index.has_value() || pointer_index.value() < 0) 690 return std::nullopt; 691 692 InputBindingKey key = {}; 693 key.source_type = InputSourceType::Pointer; 694 key.source_index = static_cast<u32>(pointer_index.value()); 695 696 if (sub_binding.starts_with("Button")) 697 { 698 const std::optional<s32> button_number = StringUtil::FromChars<s32>(sub_binding.substr(6)); 699 if (!button_number.has_value() || button_number.value() < 0) 700 return std::nullopt; 701 702 key.source_subtype = InputSubclass::PointerButton; 703 key.data = static_cast<u32>(button_number.value()); 704 return key; 705 } 706 707 for (u32 i = 0; i < s_pointer_axis_names.size(); i++) 708 { 709 if (sub_binding.starts_with(s_pointer_axis_names[i])) 710 { 711 key.source_subtype = InputSubclass::PointerAxis; 712 key.data = i; 713 714 const std::string_view dir_part(sub_binding.substr(std::strlen(s_pointer_axis_names[i]))); 715 if (dir_part == "+") 716 key.modifier = InputModifier::None; 717 else if (dir_part == "-") 718 key.modifier = InputModifier::Negate; 719 else 720 return std::nullopt; 721 722 return key; 723 } 724 } 725 726 for (u32 i = 0; i < s_pointer_button_names.size(); i++) 727 { 728 if (sub_binding == s_pointer_button_names[i]) 729 { 730 key.source_subtype = InputSubclass::PointerButton; 731 key.data = i; 732 return key; 733 } 734 } 735 736 return std::nullopt; 737 } 738 739 std::optional<u32> InputManager::GetIndexFromPointerBinding(std::string_view source) 740 { 741 if (!source.starts_with("Pointer-")) 742 return std::nullopt; 743 744 const std::optional<s32> pointer_index = StringUtil::FromChars<s32>(source.substr(8)); 745 if (!pointer_index.has_value() || pointer_index.value() < 0) 746 return std::nullopt; 747 748 return static_cast<u32>(pointer_index.value()); 749 } 750 751 std::string InputManager::GetPointerDeviceName(u32 pointer_index) 752 { 753 return fmt::format("Pointer-{}", pointer_index); 754 } 755 756 std::optional<InputBindingKey> InputManager::ParseSensorKey(std::string_view source, std::string_view sub_binding) 757 { 758 if (source != "Sensor") 759 return std::nullopt; 760 761 InputBindingKey key = {}; 762 key.source_type = InputSourceType::Sensor; 763 key.source_index = 0; 764 765 for (u32 i = 0; i < s_sensor_accelerometer_names.size(); i++) 766 { 767 if (sub_binding.starts_with(s_sensor_accelerometer_names[i])) 768 { 769 key.source_subtype = InputSubclass::SensorAccelerometer; 770 key.data = i; 771 772 const std::string_view dir_part(sub_binding.substr(std::strlen(s_sensor_accelerometer_names[i]))); 773 if (dir_part == "+") 774 key.modifier = InputModifier::None; 775 else if (dir_part == "-") 776 key.modifier = InputModifier::Negate; 777 else 778 return std::nullopt; 779 780 return key; 781 } 782 } 783 784 return std::nullopt; 785 } 786 787 // ------------------------------------------------------------------------ 788 // Binding Enumeration 789 // ------------------------------------------------------------------------ 790 791 float InputManager::ApplySingleBindingScale(float scale, float deadzone, float value) 792 { 793 const float svalue = std::clamp(value * scale, 0.0f, 1.0f); 794 return (deadzone > 0.0f && svalue < deadzone) ? 0.0f : svalue; 795 } 796 797 std::vector<const HotkeyInfo*> InputManager::GetHotkeyList() 798 { 799 std::vector<const HotkeyInfo*> ret; 800 for (const HotkeyInfo* hotkey_list : s_hotkey_list) 801 { 802 for (const HotkeyInfo* hotkey = hotkey_list; hotkey->name != nullptr; hotkey++) 803 ret.push_back(hotkey); 804 } 805 return ret; 806 } 807 808 void InputManager::AddHotkeyBindings(SettingsInterface& si) 809 { 810 for (const HotkeyInfo* hotkey_list : s_hotkey_list) 811 { 812 for (const HotkeyInfo* hotkey = hotkey_list; hotkey->name != nullptr; hotkey++) 813 { 814 const std::vector<std::string> bindings(si.GetStringList("Hotkeys", hotkey->name)); 815 if (bindings.empty()) 816 continue; 817 818 AddBindings(bindings, InputButtonEventHandler{hotkey->handler}); 819 } 820 } 821 } 822 823 void InputManager::AddPadBindings(SettingsInterface& si, const std::string& section, u32 pad_index, 824 const Controller::ControllerInfo* cinfo) 825 { 826 for (const Controller::ControllerBindingInfo& bi : cinfo->bindings) 827 { 828 const std::vector<std::string> bindings(si.GetStringList(section.c_str(), bi.name)); 829 830 switch (bi.type) 831 { 832 case InputBindingInfo::Type::Button: 833 case InputBindingInfo::Type::HalfAxis: 834 case InputBindingInfo::Type::Axis: 835 { 836 if (!bindings.empty()) 837 { 838 const float sensitivity = 839 si.GetFloatValue(section.c_str(), TinyString::from_format("{}Scale", bi.name), 1.0f); 840 const float deadzone = 841 si.GetFloatValue(section.c_str(), TinyString::from_format("{}Deadzone", bi.name), 0.0f); 842 AddBindings(bindings, InputAxisEventHandler{[pad_index, bind_index = bi.bind_index, sensitivity, 843 deadzone](float value) { 844 if (!System::IsValid()) 845 return; 846 847 Controller* c = System::GetController(pad_index); 848 if (c) 849 c->SetBindState(bind_index, ApplySingleBindingScale(sensitivity, deadzone, value)); 850 }}); 851 } 852 } 853 break; 854 855 case InputBindingInfo::Type::Pointer: 856 { 857 auto cb = [pad_index, base = bi.bind_index](InputBindingKey key, float value) { 858 if (!System::IsValid()) 859 return; 860 861 Controller* c = System::GetController(pad_index); 862 if (c) 863 c->SetBindState(base + key.data, value); 864 }; 865 866 // bind pointer 0 by default 867 if (bindings.empty()) 868 { 869 s_pointer_move_callbacks.emplace_back(0, std::move(cb)); 870 } 871 else 872 { 873 for (const std::string& binding : bindings) 874 { 875 const std::optional<u32> key(GetIndexFromPointerBinding(binding)); 876 if (!key.has_value()) 877 continue; 878 879 s_pointer_move_callbacks.emplace_back(key.value(), cb); 880 } 881 } 882 } 883 break; 884 885 default: 886 ERROR_LOG("Unhandled binding info type {}", static_cast<u32>(bi.type)); 887 break; 888 } 889 } 890 891 for (u32 macro_button_index = 0; macro_button_index < NUM_MACRO_BUTTONS_PER_CONTROLLER; macro_button_index++) 892 { 893 const std::vector<std::string> bindings( 894 si.GetStringList(section.c_str(), fmt::format("Macro{}", macro_button_index + 1u).c_str())); 895 if (!bindings.empty()) 896 { 897 AddBindings(bindings, InputButtonEventHandler{[pad_index, macro_button_index](bool state) { 898 if (!System::IsValid()) 899 return; 900 901 SetMacroButtonState(pad_index, macro_button_index, state); 902 }}); 903 } 904 } 905 906 if (cinfo->vibration_caps != Controller::VibrationCapabilities::NoVibration) 907 { 908 PadVibrationBinding vib; 909 vib.pad_index = pad_index; 910 911 bool has_any_bindings = false; 912 switch (cinfo->vibration_caps) 913 { 914 case Controller::VibrationCapabilities::LargeSmallMotors: 915 { 916 if (const std::string large_binding(si.GetStringValue(section.c_str(), "LargeMotor")); !large_binding.empty()) 917 has_any_bindings |= ParseBindingAndGetSource(large_binding, &vib.motors[0].binding, &vib.motors[0].source); 918 if (const std::string small_binding(si.GetStringValue(section.c_str(), "SmallMotor")); !small_binding.empty()) 919 has_any_bindings |= ParseBindingAndGetSource(small_binding, &vib.motors[1].binding, &vib.motors[1].source); 920 } 921 break; 922 923 case Controller::VibrationCapabilities::SingleMotor: 924 { 925 if (const std::string binding(si.GetStringValue(section.c_str(), "Motor")); !binding.empty()) 926 has_any_bindings |= ParseBindingAndGetSource(binding, &vib.motors[0].binding, &vib.motors[0].source); 927 } 928 break; 929 930 default: 931 break; 932 } 933 934 if (has_any_bindings) 935 s_pad_vibration_array.push_back(std::move(vib)); 936 } 937 } 938 939 // ------------------------------------------------------------------------ 940 // Event Handling 941 // ------------------------------------------------------------------------ 942 943 bool InputManager::HasAnyBindingsForKey(InputBindingKey key) 944 { 945 std::unique_lock lock(s_binding_map_write_lock); 946 return (s_binding_map.find(key.MaskDirection()) != s_binding_map.end()); 947 } 948 949 bool InputManager::HasAnyBindingsForSource(InputBindingKey key) 950 { 951 std::unique_lock lock(s_binding_map_write_lock); 952 for (const auto& it : s_binding_map) 953 { 954 const InputBindingKey& okey = it.first; 955 if (okey.source_type == key.source_type && okey.source_index == key.source_index && 956 okey.source_subtype == key.source_subtype) 957 { 958 return true; 959 } 960 } 961 962 return false; 963 } 964 965 bool InputManager::IsAxisHandler(const InputEventHandler& handler) 966 { 967 return std::holds_alternative<InputAxisEventHandler>(handler); 968 } 969 970 bool InputManager::InvokeEvents(InputBindingKey key, float value, GenericInputBinding generic_key) 971 { 972 if (DoEventHook(key, value)) 973 return true; 974 975 // If imgui ate the event, don't fire our handlers. 976 const bool skip_button_handlers = PreprocessEvent(key, value, generic_key); 977 return ProcessEvent(key, value, skip_button_handlers); 978 } 979 980 bool InputManager::ProcessEvent(InputBindingKey key, float value, bool skip_button_handlers) 981 { 982 // find all the bindings associated with this key 983 const InputBindingKey masked_key = key.MaskDirection(); 984 const auto range = s_binding_map.equal_range(masked_key); 985 if (range.first == s_binding_map.end()) 986 return false; 987 988 // Now we can actually fire/activate bindings. 989 u32 min_num_keys = 0; 990 for (auto it = range.first; it != range.second; ++it) 991 { 992 InputBinding* binding = it->second.get(); 993 994 // find the key which matches us 995 for (u32 i = 0; i < binding->num_keys; i++) 996 { 997 if (binding->keys[i].MaskDirection() != masked_key) 998 continue; 999 1000 const u8 bit = static_cast<u8>(1) << i; 1001 const bool negative = binding->keys[i].modifier == InputModifier::Negate; 1002 const bool new_state = (negative ? (value < 0.0f) : (value > 0.0f)); 1003 1004 float value_to_pass = 0.0f; 1005 switch (binding->keys[i].modifier) 1006 { 1007 case InputModifier::None: 1008 if (value > 0.0f) 1009 value_to_pass = value; 1010 break; 1011 case InputModifier::Negate: 1012 if (value < 0.0f) 1013 value_to_pass = -value; 1014 break; 1015 case InputModifier::FullAxis: 1016 value_to_pass = value * 0.5f + 0.5f; 1017 break; 1018 } 1019 1020 // handle inverting, needed for some wheels. 1021 value_to_pass = binding->keys[i].invert ? (1.0f - value_to_pass) : value_to_pass; 1022 1023 // axes are fired regardless of a state change, unless they're zero 1024 // (but going from not-zero to zero will still fire, because of the full state) 1025 // for buttons, we can use the state of the last chord key, because it'll be 1 on press, 1026 // and 0 on release (when the full state changes). 1027 if (IsAxisHandler(binding->handler)) 1028 { 1029 if (value_to_pass >= 0.0f && (!skip_button_handlers || value_to_pass == 0.0f)) 1030 std::get<InputAxisEventHandler>(binding->handler)(value_to_pass); 1031 } 1032 else if (binding->num_keys >= min_num_keys) 1033 { 1034 // update state based on whether the whole chord was activated 1035 const u8 new_mask = 1036 ((new_state && !skip_button_handlers) ? (binding->current_mask | bit) : (binding->current_mask & ~bit)); 1037 const bool prev_full_state = (binding->current_mask == binding->full_mask); 1038 const bool new_full_state = (new_mask == binding->full_mask); 1039 binding->current_mask = new_mask; 1040 1041 // Workaround for multi-key bindings that share the same keys. 1042 if (binding->num_keys > 1 && new_full_state && prev_full_state != new_full_state && range.first != range.second) 1043 { 1044 // Because the binding map isn't ordered, we could iterate in the order of Shift+F1 and then 1045 // F1, which would mean that F1 wouldn't get cancelled and still activate. So, to handle this 1046 // case, we skip activating any future bindings with a fewer number of keys. 1047 min_num_keys = std::max<u32>(min_num_keys, binding->num_keys); 1048 1049 // Basically, if we bind say, F1 and Shift+F1, and press shift and then F1, we'll fire bindings 1050 // for both F1 and Shift+F1, when we really only want to fire the binding for Shift+F1. So, 1051 // when we activate a multi-key chord (key press), we go through the binding map for all the 1052 // other keys in the chord, and cancel them if they have a shorter chord. If they're longer, 1053 // they could still activate and take precedence over us, so we leave them alone. 1054 for (u32 j = 0; j < binding->num_keys; j++) 1055 { 1056 const auto range2 = s_binding_map.equal_range(binding->keys[j].MaskDirection()); 1057 for (auto it2 = range2.first; it2 != range2.second; ++it2) 1058 { 1059 InputBinding* other_binding = it2->second.get(); 1060 if (other_binding == binding || IsAxisHandler(other_binding->handler) || 1061 other_binding->num_keys >= binding->num_keys) 1062 { 1063 continue; 1064 } 1065 1066 // We only need to cancel the binding if it was fully active before. Which in the above 1067 // case of Shift+F1 / F1, it will be. 1068 if (other_binding->current_mask == other_binding->full_mask) 1069 std::get<InputButtonEventHandler>(other_binding->handler)(-1); 1070 1071 // Zero out the current bits so that we don't release this binding, if the other part 1072 // of the chord releases first. 1073 other_binding->current_mask = 0; 1074 } 1075 } 1076 } 1077 1078 if (prev_full_state != new_full_state && binding->num_keys >= min_num_keys) 1079 { 1080 const s32 pressed = skip_button_handlers ? -1 : static_cast<s32>(value_to_pass > 0.0f); 1081 std::get<InputButtonEventHandler>(binding->handler)(pressed); 1082 } 1083 } 1084 1085 // bail out, since we shouldn't have the same key twice in the chord 1086 break; 1087 } 1088 } 1089 1090 return true; 1091 } 1092 1093 void InputManager::ClearBindStateFromSource(InputBindingKey key) 1094 { 1095 // Why are we doing it this way? Because any of the bindings could cause a reload and invalidate our iterators :(. 1096 // Axis handlers should be fine, so we'll do those as a first pass. 1097 for (const auto& [match_key, binding] : s_binding_map) 1098 { 1099 if (key.source_type != match_key.source_type || key.source_subtype != match_key.source_subtype || 1100 key.source_index != match_key.source_index || !IsAxisHandler(binding->handler)) 1101 { 1102 continue; 1103 } 1104 1105 for (u32 i = 0; i < binding->num_keys; i++) 1106 { 1107 if (binding->keys[i].MaskDirection() != match_key) 1108 continue; 1109 1110 std::get<InputAxisEventHandler>(binding->handler)(0.0f); 1111 break; 1112 } 1113 } 1114 1115 // Now go through the button handlers, and pick them off. 1116 bool matched; 1117 do 1118 { 1119 matched = false; 1120 1121 for (const auto& [match_key, binding] : s_binding_map) 1122 { 1123 if (key.source_type != match_key.source_type || key.source_subtype != match_key.source_subtype || 1124 key.source_index != match_key.source_index || IsAxisHandler(binding->handler)) 1125 { 1126 continue; 1127 } 1128 1129 for (u32 i = 0; i < binding->num_keys; i++) 1130 { 1131 if (binding->keys[i].MaskDirection() != match_key) 1132 continue; 1133 1134 // Skip if we weren't pressed. 1135 const u8 bit = static_cast<u8>(1) << i; 1136 if ((binding->current_mask & bit) == 0) 1137 continue; 1138 1139 // Only fire handler if we're changing from active state. 1140 const u8 current_mask = binding->current_mask; 1141 binding->current_mask &= ~bit; 1142 1143 if (current_mask == binding->full_mask) 1144 { 1145 std::get<InputButtonEventHandler>(binding->handler)(0); 1146 matched = true; 1147 break; 1148 } 1149 } 1150 1151 // Need to start again, might've reloaded. 1152 if (matched) 1153 break; 1154 } 1155 } while (matched); 1156 } 1157 1158 bool InputManager::PreprocessEvent(InputBindingKey key, float value, GenericInputBinding generic_key) 1159 { 1160 // does imgui want the event? 1161 if (key.source_type == InputSourceType::Keyboard) 1162 { 1163 if (ImGuiManager::ProcessHostKeyEvent(key, value)) 1164 return true; 1165 } 1166 else if (key.source_type == InputSourceType::Pointer && key.source_subtype == InputSubclass::PointerButton) 1167 { 1168 if (ImGuiManager::ProcessPointerButtonEvent(key, value)) 1169 return true; 1170 } 1171 else if (generic_key != GenericInputBinding::Unknown) 1172 { 1173 if (ImGuiManager::ProcessGenericInputEvent(generic_key, value) && value != 0.0f) 1174 return true; 1175 } 1176 1177 return false; 1178 } 1179 1180 void InputManager::GenerateRelativeMouseEvents() 1181 { 1182 const bool system_running = System::IsRunning(); 1183 1184 for (u32 device = 0; device < s_pointer_count; device++) 1185 { 1186 for (u32 axis = 0; axis < static_cast<u32>(static_cast<u8>(InputPointerAxis::Count)); axis++) 1187 { 1188 PointerAxisState& state = s_pointer_state[device][axis]; 1189 const float delta = static_cast<float>(state.delta.exchange(0, std::memory_order_acquire)) / 65536.0f; 1190 if (delta == 0.0f) 1191 continue; 1192 1193 const float unclamped_value = delta * s_pointer_axis_scale[axis]; 1194 1195 const InputBindingKey key(MakePointerAxisKey(device, static_cast<InputPointerAxis>(axis))); 1196 if (axis >= static_cast<u32>(InputPointerAxis::WheelX) && 1197 ImGuiManager::ProcessPointerAxisEvent(key, unclamped_value)) 1198 { 1199 continue; 1200 } 1201 1202 if (!system_running) 1203 continue; 1204 1205 const float value = std::clamp(unclamped_value, -1.0f, 1.0f); 1206 if (value != state.last_value) 1207 { 1208 state.last_value = value; 1209 InvokeEvents(key, value, GenericInputBinding::Unknown); 1210 } 1211 1212 if (delta != 0.0f) 1213 { 1214 for (const std::pair<u32, PointerMoveCallback>& pmc : s_pointer_move_callbacks) 1215 { 1216 if (pmc.first == device) 1217 pmc.second(key, delta); 1218 } 1219 } 1220 } 1221 } 1222 } 1223 1224 void InputManager::UpdatePointerCount() 1225 { 1226 if (!IsUsingRawInput()) 1227 { 1228 s_pointer_count = 1; 1229 return; 1230 } 1231 1232 #ifndef __ANDROID__ 1233 InputSource* ris = GetInputSourceInterface(InputSourceType::RawInput); 1234 DebugAssert(ris); 1235 1236 s_pointer_count = 0; 1237 for (const std::pair<std::string, std::string>& it : ris->EnumerateDevices()) 1238 { 1239 if (it.first.starts_with("Pointer-")) 1240 s_pointer_count++; 1241 } 1242 #endif 1243 } 1244 1245 u32 InputManager::GetPointerCount() 1246 { 1247 return s_pointer_count; 1248 } 1249 1250 std::pair<float, float> InputManager::GetPointerAbsolutePosition(u32 index) 1251 { 1252 DebugAssert(index < s_host_pointer_positions.size()); 1253 return std::make_pair(s_host_pointer_positions[index][static_cast<u8>(InputPointerAxis::X)], 1254 s_host_pointer_positions[index][static_cast<u8>(InputPointerAxis::Y)]); 1255 } 1256 1257 void InputManager::UpdatePointerAbsolutePosition(u32 index, float x, float y) 1258 { 1259 if (index >= MAX_POINTER_DEVICES || s_relative_mouse_mode_active) [[unlikely]] 1260 return; 1261 1262 const float dx = x - std::exchange(s_host_pointer_positions[index][static_cast<u8>(InputPointerAxis::X)], x); 1263 const float dy = y - std::exchange(s_host_pointer_positions[index][static_cast<u8>(InputPointerAxis::Y)], y); 1264 1265 if (dx != 0.0f) 1266 { 1267 s_pointer_state[index][static_cast<u8>(InputPointerAxis::X)].delta.fetch_add(static_cast<s32>(dx * 65536.0f), 1268 std::memory_order_release); 1269 } 1270 if (dy != 0.0f) 1271 { 1272 s_pointer_state[index][static_cast<u8>(InputPointerAxis::Y)].delta.fetch_add(static_cast<s32>(dy * 65536.0f), 1273 std::memory_order_release); 1274 } 1275 1276 if (index == 0) 1277 ImGuiManager::UpdateMousePosition(x, y); 1278 } 1279 1280 void InputManager::UpdatePointerRelativeDelta(u32 index, InputPointerAxis axis, float d, bool raw_input) 1281 { 1282 if (index >= MAX_POINTER_DEVICES || (axis < InputPointerAxis::WheelX && !s_relative_mouse_mode_active)) 1283 return; 1284 1285 s_host_pointer_positions[index][static_cast<u8>(axis)] += d; 1286 s_pointer_state[index][static_cast<u8>(axis)].delta.fetch_add(static_cast<s32>(d * 65536.0f), 1287 std::memory_order_release); 1288 1289 // We need to clamp the position ourselves in relative mode. 1290 if (axis <= InputPointerAxis::Y) 1291 { 1292 s_host_pointer_positions[index][static_cast<u8>(axis)] = 1293 std::clamp(s_host_pointer_positions[index][static_cast<u8>(axis)], 0.0f, s_window_size[static_cast<u8>(axis)]); 1294 1295 // Imgui also needs to be updated, since the absolute position won't be set above. 1296 if (index == 0) 1297 ImGuiManager::UpdateMousePosition(s_host_pointer_positions[0][0], s_host_pointer_positions[0][1]); 1298 } 1299 } 1300 1301 void InputManager::UpdateRelativeMouseMode() 1302 { 1303 // Check for relative mode bindings, and enable if there's anything using it. 1304 bool has_relative_mode_bindings = !s_pointer_move_callbacks.empty(); 1305 if (!has_relative_mode_bindings) 1306 { 1307 for (const auto& it : s_binding_map) 1308 { 1309 const InputBindingKey& key = it.first; 1310 if (key.source_type == InputSourceType::Pointer && key.source_subtype == InputSubclass::PointerAxis && 1311 key.data >= static_cast<u32>(InputPointerAxis::X) && key.data <= static_cast<u32>(InputPointerAxis::Y)) 1312 { 1313 has_relative_mode_bindings = true; 1314 break; 1315 } 1316 } 1317 } 1318 1319 const bool hide_mouse_cursor = has_relative_mode_bindings || ImGuiManager::HasSoftwareCursor(0); 1320 if (s_relative_mouse_mode == has_relative_mode_bindings && s_hide_host_mouse_cursor == hide_mouse_cursor) 1321 return; 1322 1323 s_relative_mouse_mode = has_relative_mode_bindings; 1324 s_hide_host_mouse_cursor = hide_mouse_cursor; 1325 UpdateRelativeMouseMode(); 1326 } 1327 1328 void InputManager::UpdateHostMouseMode() 1329 { 1330 const bool can_change = System::IsRunning(); 1331 const bool wanted_relative_mouse_mode = (s_relative_mouse_mode && can_change); 1332 const bool wanted_hide_host_mouse_cursor = (s_hide_host_mouse_cursor && can_change); 1333 if (wanted_relative_mouse_mode == s_relative_mouse_mode_active && 1334 wanted_hide_host_mouse_cursor == s_hide_host_mouse_cusor_active) 1335 { 1336 return; 1337 } 1338 1339 s_relative_mouse_mode_active = wanted_relative_mouse_mode; 1340 s_hide_host_mouse_cusor_active = wanted_hide_host_mouse_cursor; 1341 Host::SetMouseMode(wanted_relative_mouse_mode, wanted_hide_host_mouse_cursor); 1342 } 1343 1344 bool InputManager::IsUsingRawInput() 1345 { 1346 #if defined(_WIN32) 1347 return static_cast<bool>(s_input_sources[static_cast<u32>(InputSourceType::RawInput)]); 1348 #else 1349 return false; 1350 #endif 1351 } 1352 1353 void InputManager::SetDisplayWindowSize(float width, float height) 1354 { 1355 s_window_size[0] = width; 1356 s_window_size[1] = height; 1357 } 1358 1359 void InputManager::SetDefaultSourceConfig(SettingsInterface& si) 1360 { 1361 si.ClearSection("InputSources"); 1362 si.SetBoolValue("InputSources", "SDL", true); 1363 si.SetBoolValue("InputSources", "SDLControllerEnhancedMode", false); 1364 si.SetBoolValue("InputSources", "SDLPS5PlayerLED", false); 1365 si.SetBoolValue("InputSources", "XInput", false); 1366 si.SetBoolValue("InputSources", "RawInput", false); 1367 } 1368 1369 void InputManager::ClearPortBindings(SettingsInterface& si, u32 port) 1370 { 1371 const std::string section(Controller::GetSettingsSection(port)); 1372 const std::string type(si.GetStringValue(section.c_str(), "Type", Controller::GetDefaultPadType(port))); 1373 1374 const Controller::ControllerInfo* info = Controller::GetControllerInfo(type); 1375 if (!info) 1376 return; 1377 1378 for (const Controller::ControllerBindingInfo& bi : info->bindings) 1379 si.DeleteValue(section.c_str(), bi.name); 1380 } 1381 1382 void InputManager::CopyConfiguration(SettingsInterface* dest_si, const SettingsInterface& src_si, 1383 bool copy_pad_config /*= true*/, bool copy_pad_bindings /*= true*/, 1384 bool copy_hotkey_bindings /*= true*/) 1385 { 1386 if (copy_pad_config) 1387 dest_si->CopyStringValue(src_si, "ControllerPorts", "MultitapMode"); 1388 1389 for (u32 port = 0; port < NUM_CONTROLLER_AND_CARD_PORTS; port++) 1390 { 1391 if (Controller::PadIsMultitapSlot(port)) 1392 { 1393 const auto [mt_port, mt_slot] = Controller::ConvertPadToPortAndSlot(port); 1394 if (!g_settings.IsMultitapPortEnabled(mt_port)) 1395 continue; 1396 } 1397 1398 const std::string section(Controller::GetSettingsSection(port)); 1399 const std::string type(src_si.GetStringValue(section.c_str(), "Type", Controller::GetDefaultPadType(port))); 1400 if (copy_pad_config) 1401 dest_si->SetStringValue(section.c_str(), "Type", type.c_str()); 1402 1403 const Controller::ControllerInfo* info = Controller::GetControllerInfo(type); 1404 if (!info) 1405 return; 1406 1407 if (copy_pad_bindings) 1408 { 1409 for (const Controller::ControllerBindingInfo& bi : info->bindings) 1410 dest_si->CopyStringListValue(src_si, section.c_str(), bi.name); 1411 1412 for (u32 i = 0; i < NUM_MACRO_BUTTONS_PER_CONTROLLER; i++) 1413 { 1414 dest_si->CopyStringListValue(src_si, section.c_str(), TinyString::from_format("Macro{}", i + 1)); 1415 dest_si->CopyStringValue(src_si, section.c_str(), TinyString::from_format("Macro{}Binds", i + 1)); 1416 dest_si->CopyUIntValue(src_si, section.c_str(), TinyString::from_format("Macro{}Frequency", i + 1)); 1417 dest_si->CopyBoolValue(src_si, section.c_str(), TinyString::from_format("Macro{}Toggle", i + 1)); 1418 } 1419 } 1420 1421 if (copy_pad_config) 1422 { 1423 for (const SettingInfo& csi : info->settings) 1424 { 1425 switch (csi.type) 1426 { 1427 case SettingInfo::Type::Boolean: 1428 dest_si->CopyBoolValue(src_si, section.c_str(), csi.name); 1429 break; 1430 case SettingInfo::Type::Integer: 1431 case SettingInfo::Type::IntegerList: 1432 dest_si->CopyIntValue(src_si, section.c_str(), csi.name); 1433 break; 1434 case SettingInfo::Type::Float: 1435 dest_si->CopyFloatValue(src_si, section.c_str(), csi.name); 1436 break; 1437 case SettingInfo::Type::String: 1438 case SettingInfo::Type::Path: 1439 dest_si->CopyStringValue(src_si, section.c_str(), csi.name); 1440 break; 1441 default: 1442 break; 1443 } 1444 } 1445 } 1446 } 1447 1448 if (copy_hotkey_bindings) 1449 { 1450 std::vector<const HotkeyInfo*> hotkeys(InputManager::GetHotkeyList()); 1451 for (const HotkeyInfo* hki : hotkeys) 1452 dest_si->CopyStringListValue(src_si, "Hotkeys", hki->name); 1453 } 1454 } 1455 1456 static u32 TryMapGenericMapping(SettingsInterface& si, const std::string& section, 1457 const GenericInputBindingMapping& mapping, GenericInputBinding generic_name, 1458 const char* bind_name) 1459 { 1460 // find the mapping it corresponds to 1461 const std::string* found_mapping = nullptr; 1462 for (const std::pair<GenericInputBinding, std::string>& it : mapping) 1463 { 1464 if (it.first == generic_name) 1465 { 1466 found_mapping = &it.second; 1467 break; 1468 } 1469 } 1470 1471 if (found_mapping) 1472 { 1473 INFO_LOG("Map {}/{} to '{}'", section, bind_name, *found_mapping); 1474 si.SetStringValue(section.c_str(), bind_name, found_mapping->c_str()); 1475 return 1; 1476 } 1477 else 1478 { 1479 si.DeleteValue(section.c_str(), bind_name); 1480 return 0; 1481 } 1482 } 1483 1484 bool InputManager::MapController(SettingsInterface& si, u32 controller, 1485 const std::vector<std::pair<GenericInputBinding, std::string>>& mapping) 1486 { 1487 const std::string section(Controller::GetSettingsSection(controller)); 1488 const std::string type(si.GetStringValue(section.c_str(), "Type", Controller::GetDefaultPadType(controller))); 1489 const Controller::ControllerInfo* info = Controller::GetControllerInfo(type); 1490 if (!info) 1491 return false; 1492 1493 u32 num_mappings = 0; 1494 for (const Controller::ControllerBindingInfo& bi : info->bindings) 1495 { 1496 if (bi.generic_mapping == GenericInputBinding::Unknown) 1497 continue; 1498 1499 num_mappings += TryMapGenericMapping(si, section, mapping, bi.generic_mapping, bi.name); 1500 } 1501 if (info->vibration_caps == Controller::VibrationCapabilities::LargeSmallMotors) 1502 { 1503 num_mappings += TryMapGenericMapping(si, section, mapping, GenericInputBinding::SmallMotor, "SmallMotor"); 1504 num_mappings += TryMapGenericMapping(si, section, mapping, GenericInputBinding::LargeMotor, "LargeMotor"); 1505 } 1506 else if (info->vibration_caps == Controller::VibrationCapabilities::SingleMotor) 1507 { 1508 if (TryMapGenericMapping(si, section, mapping, GenericInputBinding::LargeMotor, "Motor") == 0) 1509 num_mappings += TryMapGenericMapping(si, section, mapping, GenericInputBinding::SmallMotor, "Motor"); 1510 else 1511 num_mappings++; 1512 } 1513 1514 return (num_mappings > 0); 1515 } 1516 1517 std::vector<std::string> InputManager::GetInputProfileNames() 1518 { 1519 FileSystem::FindResultsArray results; 1520 FileSystem::FindFiles(EmuFolders::InputProfiles.c_str(), "*.ini", 1521 FILESYSTEM_FIND_FILES | FILESYSTEM_FIND_HIDDEN_FILES | FILESYSTEM_FIND_RELATIVE_PATHS | 1522 FILESYSTEM_FIND_SORT_BY_NAME, 1523 &results); 1524 1525 std::vector<std::string> ret; 1526 ret.reserve(results.size()); 1527 for (FILESYSTEM_FIND_DATA& fd : results) 1528 ret.emplace_back(Path::GetFileTitle(fd.FileName)); 1529 1530 return ret; 1531 } 1532 1533 void InputManager::OnInputDeviceConnected(std::string_view identifier, std::string_view device_name) 1534 { 1535 INFO_LOG("Device '{}' connected: '{}'", identifier, device_name); 1536 Host::OnInputDeviceConnected(identifier, device_name); 1537 } 1538 1539 void InputManager::OnInputDeviceDisconnected(InputBindingKey key, std::string_view identifier) 1540 { 1541 INFO_LOG("Device '{}' disconnected", identifier); 1542 Host::OnInputDeviceDisconnected(key, identifier); 1543 } 1544 1545 // ------------------------------------------------------------------------ 1546 // Vibration 1547 // ------------------------------------------------------------------------ 1548 1549 void InputManager::SetPadVibrationIntensity(u32 pad_index, float large_or_single_motor_intensity, 1550 float small_motor_intensity) 1551 { 1552 for (PadVibrationBinding& pad : s_pad_vibration_array) 1553 { 1554 if (pad.pad_index != pad_index) 1555 continue; 1556 1557 PadVibrationBinding::Motor& large_motor = pad.motors[0]; 1558 PadVibrationBinding::Motor& small_motor = pad.motors[1]; 1559 if (large_motor.last_intensity == large_or_single_motor_intensity && 1560 small_motor.last_intensity == small_motor_intensity) 1561 continue; 1562 1563 if (pad.AreMotorsCombined()) 1564 { 1565 // if the motors are combined, we need to adjust to the maximum of both 1566 const float report_intensity = std::max(large_or_single_motor_intensity, small_motor_intensity); 1567 if (large_motor.source) 1568 { 1569 large_motor.last_update_time = Common::Timer::GetCurrentValue(); 1570 large_motor.source->UpdateMotorState(large_motor.binding, report_intensity); 1571 } 1572 } 1573 else if (large_motor.source == small_motor.source) 1574 { 1575 // both motors are bound to the same source, do an optimal update 1576 large_motor.last_update_time = Common::Timer::GetCurrentValue(); 1577 large_motor.source->UpdateMotorState(large_motor.binding, small_motor.binding, large_or_single_motor_intensity, 1578 small_motor_intensity); 1579 } 1580 else 1581 { 1582 // update motors independently 1583 if (large_motor.source && large_motor.last_intensity != large_or_single_motor_intensity) 1584 { 1585 large_motor.last_update_time = Common::Timer::GetCurrentValue(); 1586 large_motor.source->UpdateMotorState(large_motor.binding, large_or_single_motor_intensity); 1587 } 1588 if (small_motor.source && small_motor.last_intensity != small_motor_intensity) 1589 { 1590 small_motor.last_update_time = Common::Timer::GetCurrentValue(); 1591 small_motor.source->UpdateMotorState(small_motor.binding, small_motor_intensity); 1592 } 1593 } 1594 1595 large_motor.last_intensity = large_or_single_motor_intensity; 1596 small_motor.last_intensity = small_motor_intensity; 1597 } 1598 } 1599 1600 void InputManager::PauseVibration() 1601 { 1602 for (PadVibrationBinding& binding : s_pad_vibration_array) 1603 { 1604 for (u32 motor_index = 0; motor_index < MAX_MOTORS_PER_PAD; motor_index++) 1605 { 1606 PadVibrationBinding::Motor& motor = binding.motors[motor_index]; 1607 if (!motor.source || motor.last_intensity == 0.0f) 1608 continue; 1609 1610 // we deliberately don't zero the intensity here, so it can resume later 1611 motor.last_update_time = 0; 1612 motor.source->UpdateMotorState(motor.binding, 0.0f); 1613 } 1614 } 1615 } 1616 1617 void InputManager::UpdateContinuedVibration() 1618 { 1619 // update vibration intensities, so if the game does a long effect, it continues 1620 const u64 current_time = Common::Timer::GetCurrentValue(); 1621 for (PadVibrationBinding& pad : s_pad_vibration_array) 1622 { 1623 if (pad.AreMotorsCombined()) 1624 { 1625 // motors are combined 1626 PadVibrationBinding::Motor& large_motor = pad.motors[0]; 1627 if (!large_motor.source) 1628 continue; 1629 1630 // so only check the first one 1631 const double dt = Common::Timer::ConvertValueToSeconds(current_time - large_motor.last_update_time); 1632 if (dt < VIBRATION_UPDATE_INTERVAL_SECONDS) 1633 continue; 1634 1635 // but take max of both motors for the intensity 1636 const float intensity = pad.GetCombinedIntensity(); 1637 if (intensity == 0.0f) 1638 continue; 1639 1640 large_motor.last_update_time = current_time; 1641 large_motor.source->UpdateMotorState(large_motor.binding, intensity); 1642 } 1643 else 1644 { 1645 // independent motor control 1646 for (u32 i = 0; i < MAX_MOTORS_PER_PAD; i++) 1647 { 1648 PadVibrationBinding::Motor& motor = pad.motors[i]; 1649 if (!motor.source || motor.last_intensity == 0.0f) 1650 continue; 1651 1652 const double dt = Common::Timer::ConvertValueToSeconds(current_time - motor.last_update_time); 1653 if (dt < VIBRATION_UPDATE_INTERVAL_SECONDS) 1654 continue; 1655 1656 // re-notify the source of the continued effect 1657 motor.last_update_time = current_time; 1658 motor.source->UpdateMotorState(motor.binding, motor.last_intensity); 1659 } 1660 } 1661 } 1662 } 1663 1664 // ------------------------------------------------------------------------ 1665 // Macros 1666 // ------------------------------------------------------------------------ 1667 1668 void InputManager::LoadMacroButtonConfig(SettingsInterface& si, const std::string& section, u32 pad, 1669 const Controller::ControllerInfo* cinfo) 1670 { 1671 s_macro_buttons[pad] = {}; 1672 if (cinfo->bindings.empty()) 1673 return; 1674 1675 for (u32 i = 0; i < NUM_MACRO_BUTTONS_PER_CONTROLLER; i++) 1676 { 1677 std::string binds_string; 1678 if (!si.GetStringValue(section.c_str(), TinyString::from_format("Macro{}Binds", i + 1u), &binds_string)) 1679 continue; 1680 1681 const u32 frequency = 1682 std::min<u32>(si.GetUIntValue(section.c_str(), TinyString::from_format("Macro{}Frequency", i + 1u), 0u), 1683 std::numeric_limits<u16>::max()); 1684 const bool toggle = si.GetBoolValue(section.c_str(), TinyString::from_format("Macro{}Toggle", i + 1u), false); 1685 1686 // convert binds 1687 std::vector<u32> bind_indices; 1688 std::vector<std::string_view> buttons_split(StringUtil::SplitString(binds_string, '&', true)); 1689 if (buttons_split.empty()) 1690 continue; 1691 for (const std::string_view& button : buttons_split) 1692 { 1693 const Controller::ControllerBindingInfo* binding = nullptr; 1694 for (const Controller::ControllerBindingInfo& bi : cinfo->bindings) 1695 { 1696 if (button == bi.name) 1697 { 1698 binding = &bi; 1699 break; 1700 } 1701 } 1702 if (!binding) 1703 { 1704 DEV_LOG("Invalid bind '{}' in macro button {} for pad {}", button, pad, i); 1705 continue; 1706 } 1707 1708 bind_indices.push_back(binding->bind_index); 1709 } 1710 if (bind_indices.empty()) 1711 continue; 1712 1713 s_macro_buttons[pad][i].buttons = std::move(bind_indices); 1714 s_macro_buttons[pad][i].toggle_frequency = static_cast<u16>(frequency); 1715 s_macro_buttons[pad][i].trigger_toggle = toggle; 1716 } 1717 } 1718 1719 void InputManager::SetMacroButtonState(u32 pad, u32 index, bool state) 1720 { 1721 if (pad >= NUM_CONTROLLER_AND_CARD_PORTS || index >= NUM_MACRO_BUTTONS_PER_CONTROLLER) 1722 return; 1723 1724 MacroButton& mb = s_macro_buttons[pad][index]; 1725 if (mb.buttons.empty()) 1726 return; 1727 1728 const bool trigger_state = (mb.trigger_toggle ? (state ? !mb.trigger_state : mb.trigger_state) : state); 1729 if (mb.trigger_state == trigger_state) 1730 return; 1731 1732 mb.toggle_counter = mb.toggle_frequency; 1733 mb.trigger_state = trigger_state; 1734 if (mb.toggle_state != trigger_state) 1735 { 1736 mb.toggle_state = trigger_state; 1737 ApplyMacroButton(pad, mb); 1738 } 1739 } 1740 1741 void InputManager::ApplyMacroButton(u32 pad, const MacroButton& mb) 1742 { 1743 Controller* const controller = System::GetController(pad); 1744 if (!controller) 1745 return; 1746 1747 const float value = mb.toggle_state ? 1.0f : 0.0f; 1748 for (const u32 btn : mb.buttons) 1749 controller->SetBindState(btn, value); 1750 } 1751 1752 void InputManager::UpdateMacroButtons() 1753 { 1754 for (u32 pad = 0; pad < NUM_CONTROLLER_AND_CARD_PORTS; pad++) 1755 { 1756 for (u32 index = 0; index < NUM_MACRO_BUTTONS_PER_CONTROLLER; index++) 1757 { 1758 MacroButton& mb = s_macro_buttons[pad][index]; 1759 if (!mb.trigger_state || mb.toggle_frequency == 0) 1760 continue; 1761 1762 mb.toggle_counter--; 1763 if (mb.toggle_counter > 0) 1764 continue; 1765 1766 mb.toggle_counter = mb.toggle_frequency; 1767 mb.toggle_state = !mb.toggle_state; 1768 ApplyMacroButton(pad, mb); 1769 } 1770 } 1771 } 1772 1773 // ------------------------------------------------------------------------ 1774 // Hooks/Event Intercepting 1775 // ------------------------------------------------------------------------ 1776 1777 void InputManager::SetHook(InputInterceptHook::Callback callback) 1778 { 1779 std::unique_lock<std::mutex> lock(m_event_intercept_mutex); 1780 DebugAssert(!m_event_intercept_callback); 1781 m_event_intercept_callback = std::move(callback); 1782 } 1783 1784 void InputManager::RemoveHook() 1785 { 1786 std::unique_lock<std::mutex> lock(m_event_intercept_mutex); 1787 if (m_event_intercept_callback) 1788 m_event_intercept_callback = {}; 1789 } 1790 1791 bool InputManager::HasHook() 1792 { 1793 std::unique_lock<std::mutex> lock(m_event_intercept_mutex); 1794 return (bool)m_event_intercept_callback; 1795 } 1796 1797 bool InputManager::DoEventHook(InputBindingKey key, float value) 1798 { 1799 std::unique_lock<std::mutex> lock(m_event_intercept_mutex); 1800 if (!m_event_intercept_callback) 1801 return false; 1802 1803 const InputInterceptHook::CallbackResult action = m_event_intercept_callback(key, value); 1804 if (action >= InputInterceptHook::CallbackResult::RemoveHookAndStopProcessingEvent) 1805 m_event_intercept_callback = {}; 1806 1807 return (action == InputInterceptHook::CallbackResult::RemoveHookAndStopProcessingEvent || 1808 action == InputInterceptHook::CallbackResult::StopProcessingEvent); 1809 } 1810 1811 // ------------------------------------------------------------------------ 1812 // Binding Updater 1813 // ------------------------------------------------------------------------ 1814 1815 void InputManager::ReloadBindings(SettingsInterface& binding_si, SettingsInterface& hotkey_binding_si) 1816 { 1817 PauseVibration(); 1818 1819 std::unique_lock lock(s_binding_map_write_lock); 1820 1821 s_binding_map.clear(); 1822 s_pad_vibration_array.clear(); 1823 s_pointer_move_callbacks.clear(); 1824 1825 Host::AddFixedInputBindings(binding_si); 1826 1827 // Hotkeys use the base configuration, except if the custom hotkeys option is enabled. 1828 AddHotkeyBindings(hotkey_binding_si); 1829 1830 // If there's an input profile, we load pad bindings from it alone, rather than 1831 // falling back to the base configuration. 1832 for (u32 pad = 0; pad < NUM_CONTROLLER_AND_CARD_PORTS; pad++) 1833 { 1834 const Controller::ControllerInfo* cinfo = Controller::GetControllerInfo(g_settings.controller_types[pad]); 1835 if (!cinfo || cinfo->type == ControllerType::None) 1836 continue; 1837 1838 const std::string section(Controller::GetSettingsSection(pad)); 1839 AddPadBindings(binding_si, section, pad, cinfo); 1840 LoadMacroButtonConfig(binding_si, section, pad, cinfo); 1841 } 1842 1843 for (u32 axis = 0; axis < static_cast<u32>(InputPointerAxis::Count); axis++) 1844 { 1845 // From lilypad: 1 mouse pixel = 1/8th way down. 1846 const float default_scale = (axis <= static_cast<u32>(InputPointerAxis::Y)) ? 8.0f : 1.0f; 1847 s_pointer_axis_scale[axis] = 1848 1.0f / std::max(binding_si.GetFloatValue("Pad", fmt::format("Pointer{}Scale", s_pointer_axis_names[axis]).c_str(), 1849 default_scale), 1850 1.0f); 1851 } 1852 1853 UpdateRelativeMouseMode(); 1854 } 1855 1856 // ------------------------------------------------------------------------ 1857 // Source Management 1858 // ------------------------------------------------------------------------ 1859 1860 bool InputManager::ReloadDevices() 1861 { 1862 bool changed = false; 1863 1864 for (u32 i = FIRST_EXTERNAL_INPUT_SOURCE; i < LAST_EXTERNAL_INPUT_SOURCE; i++) 1865 { 1866 if (s_input_sources[i]) 1867 changed |= s_input_sources[i]->ReloadDevices(); 1868 } 1869 1870 UpdatePointerCount(); 1871 1872 return changed; 1873 } 1874 1875 void InputManager::CloseSources() 1876 { 1877 for (u32 i = FIRST_EXTERNAL_INPUT_SOURCE; i < LAST_EXTERNAL_INPUT_SOURCE; i++) 1878 { 1879 if (s_input_sources[i]) 1880 { 1881 s_input_sources[i]->Shutdown(); 1882 s_input_sources[i].reset(); 1883 } 1884 } 1885 } 1886 1887 void InputManager::PollSources() 1888 { 1889 for (u32 i = FIRST_EXTERNAL_INPUT_SOURCE; i < LAST_EXTERNAL_INPUT_SOURCE; i++) 1890 { 1891 if (s_input_sources[i]) 1892 s_input_sources[i]->PollEvents(); 1893 } 1894 1895 GenerateRelativeMouseEvents(); 1896 1897 if (System::GetState() == System::State::Running) 1898 { 1899 UpdateMacroButtons(); 1900 if (!s_pad_vibration_array.empty()) 1901 UpdateContinuedVibration(); 1902 } 1903 } 1904 1905 std::vector<std::pair<std::string, std::string>> InputManager::EnumerateDevices() 1906 { 1907 std::vector<std::pair<std::string, std::string>> ret; 1908 1909 ret.emplace_back("Keyboard", "Keyboard"); 1910 ret.emplace_back("Mouse", "Mouse"); 1911 1912 for (u32 i = FIRST_EXTERNAL_INPUT_SOURCE; i < LAST_EXTERNAL_INPUT_SOURCE; i++) 1913 { 1914 if (s_input_sources[i]) 1915 { 1916 std::vector<std::pair<std::string, std::string>> devs(s_input_sources[i]->EnumerateDevices()); 1917 if (ret.empty()) 1918 ret = std::move(devs); 1919 else 1920 std::move(devs.begin(), devs.end(), std::back_inserter(ret)); 1921 } 1922 } 1923 1924 return ret; 1925 } 1926 1927 std::vector<InputBindingKey> InputManager::EnumerateMotors() 1928 { 1929 std::vector<InputBindingKey> ret; 1930 1931 for (u32 i = FIRST_EXTERNAL_INPUT_SOURCE; i < LAST_EXTERNAL_INPUT_SOURCE; i++) 1932 { 1933 if (s_input_sources[i]) 1934 { 1935 std::vector<InputBindingKey> devs(s_input_sources[i]->EnumerateMotors()); 1936 if (ret.empty()) 1937 ret = std::move(devs); 1938 else 1939 std::move(devs.begin(), devs.end(), std::back_inserter(ret)); 1940 } 1941 } 1942 1943 return ret; 1944 } 1945 1946 static void GetKeyboardGenericBindingMapping(std::vector<std::pair<GenericInputBinding, std::string>>* mapping) 1947 { 1948 mapping->emplace_back(GenericInputBinding::DPadUp, "Keyboard/Up"); 1949 mapping->emplace_back(GenericInputBinding::DPadRight, "Keyboard/Right"); 1950 mapping->emplace_back(GenericInputBinding::DPadDown, "Keyboard/Down"); 1951 mapping->emplace_back(GenericInputBinding::DPadLeft, "Keyboard/Left"); 1952 mapping->emplace_back(GenericInputBinding::LeftStickUp, "Keyboard/W"); 1953 mapping->emplace_back(GenericInputBinding::LeftStickRight, "Keyboard/D"); 1954 mapping->emplace_back(GenericInputBinding::LeftStickDown, "Keyboard/S"); 1955 mapping->emplace_back(GenericInputBinding::LeftStickLeft, "Keyboard/A"); 1956 mapping->emplace_back(GenericInputBinding::RightStickUp, "Keyboard/T"); 1957 mapping->emplace_back(GenericInputBinding::RightStickRight, "Keyboard/H"); 1958 mapping->emplace_back(GenericInputBinding::RightStickDown, "Keyboard/G"); 1959 mapping->emplace_back(GenericInputBinding::RightStickLeft, "Keyboard/F"); 1960 mapping->emplace_back(GenericInputBinding::Start, "Keyboard/Return"); 1961 mapping->emplace_back(GenericInputBinding::Select, "Keyboard/Backspace"); 1962 mapping->emplace_back(GenericInputBinding::Triangle, "Keyboard/I"); 1963 mapping->emplace_back(GenericInputBinding::Circle, "Keyboard/L"); 1964 mapping->emplace_back(GenericInputBinding::Cross, "Keyboard/K"); 1965 mapping->emplace_back(GenericInputBinding::Square, "Keyboard/J"); 1966 mapping->emplace_back(GenericInputBinding::L1, "Keyboard/Q"); 1967 mapping->emplace_back(GenericInputBinding::L2, "Keyboard/1"); 1968 mapping->emplace_back(GenericInputBinding::L3, "Keyboard/2"); 1969 mapping->emplace_back(GenericInputBinding::R1, "Keyboard/E"); 1970 mapping->emplace_back(GenericInputBinding::R2, "Keyboard/3"); 1971 mapping->emplace_back(GenericInputBinding::R3, "Keyboard/4"); 1972 } 1973 1974 static bool GetInternalGenericBindingMapping(std::string_view device, GenericInputBindingMapping* mapping) 1975 { 1976 if (device == "Keyboard") 1977 { 1978 GetKeyboardGenericBindingMapping(mapping); 1979 return true; 1980 } 1981 1982 return false; 1983 } 1984 1985 GenericInputBindingMapping InputManager::GetGenericBindingMapping(std::string_view device) 1986 { 1987 GenericInputBindingMapping mapping; 1988 1989 if (!GetInternalGenericBindingMapping(device, &mapping)) 1990 { 1991 for (u32 i = FIRST_EXTERNAL_INPUT_SOURCE; i < LAST_EXTERNAL_INPUT_SOURCE; i++) 1992 { 1993 if (s_input_sources[i] && s_input_sources[i]->GetGenericBindingMapping(device, &mapping)) 1994 break; 1995 } 1996 } 1997 1998 return mapping; 1999 } 2000 2001 bool InputManager::IsInputSourceEnabled(SettingsInterface& si, InputSourceType type) 2002 { 2003 #ifdef __ANDROID__ 2004 // Force Android source to always be enabled so nobody accidentally breaks it via ini. 2005 if (type == InputSourceType::Android) 2006 return true; 2007 #endif 2008 2009 return si.GetBoolValue("InputSources", InputManager::InputSourceToString(type), GetInputSourceDefaultEnabled(type)); 2010 } 2011 2012 void InputManager::UpdateInputSourceState(SettingsInterface& si, std::unique_lock<std::mutex>& settings_lock, 2013 InputSourceType type, std::unique_ptr<InputSource> (*factory_function)()) 2014 { 2015 const bool enabled = IsInputSourceEnabled(si, type); 2016 if (enabled) 2017 { 2018 if (s_input_sources[static_cast<u32>(type)]) 2019 { 2020 s_input_sources[static_cast<u32>(type)]->UpdateSettings(si, settings_lock); 2021 } 2022 else 2023 { 2024 std::unique_ptr<InputSource> source(factory_function()); 2025 if (!source->Initialize(si, settings_lock)) 2026 { 2027 ERROR_LOG("Source '{}' failed to initialize.", InputManager::InputSourceToString(type)); 2028 return; 2029 } 2030 2031 s_input_sources[static_cast<u32>(type)] = std::move(source); 2032 } 2033 } 2034 else 2035 { 2036 if (s_input_sources[static_cast<u32>(type)]) 2037 { 2038 s_input_sources[static_cast<u32>(type)]->Shutdown(); 2039 s_input_sources[static_cast<u32>(type)].reset(); 2040 } 2041 } 2042 } 2043 2044 void InputManager::ReloadSources(SettingsInterface& si, std::unique_lock<std::mutex>& settings_lock) 2045 { 2046 #ifdef _WIN32 2047 UpdateInputSourceState(si, settings_lock, InputSourceType::DInput, &InputSource::CreateDInputSource); 2048 UpdateInputSourceState(si, settings_lock, InputSourceType::XInput, &InputSource::CreateXInputSource); 2049 UpdateInputSourceState(si, settings_lock, InputSourceType::RawInput, &InputSource::CreateWin32RawInputSource); 2050 #endif 2051 #ifndef __ANDROID__ 2052 UpdateInputSourceState(si, settings_lock, InputSourceType::SDL, &InputSource::CreateSDLSource); 2053 #else 2054 UpdateInputSourceState(si, settings_lock, InputSourceType::Android, &InputSource::CreateAndroidSource); 2055 #endif 2056 2057 UpdatePointerCount(); 2058 }