diff options
Diffstat (limited to 'src/core/hid/emulated_controller.cpp')
| -rw-r--r-- | src/core/hid/emulated_controller.cpp | 367 |
1 files changed, 203 insertions, 164 deletions
diff --git a/src/core/hid/emulated_controller.cpp b/src/core/hid/emulated_controller.cpp index 7e05666d6..4f3676ec3 100644 --- a/src/core/hid/emulated_controller.cpp +++ b/src/core/hid/emulated_controller.cpp | |||
| @@ -353,14 +353,17 @@ void EmulatedController::DisableConfiguration() { | |||
| 353 | } | 353 | } |
| 354 | 354 | ||
| 355 | void EmulatedController::EnableSystemButtons() { | 355 | void EmulatedController::EnableSystemButtons() { |
| 356 | std::lock_guard lock{mutex}; | ||
| 356 | system_buttons_enabled = true; | 357 | system_buttons_enabled = true; |
| 357 | } | 358 | } |
| 358 | 359 | ||
| 359 | void EmulatedController::DisableSystemButtons() { | 360 | void EmulatedController::DisableSystemButtons() { |
| 361 | std::lock_guard lock{mutex}; | ||
| 360 | system_buttons_enabled = false; | 362 | system_buttons_enabled = false; |
| 361 | } | 363 | } |
| 362 | 364 | ||
| 363 | void EmulatedController::ResetSystemButtons() { | 365 | void EmulatedController::ResetSystemButtons() { |
| 366 | std::lock_guard lock{mutex}; | ||
| 364 | controller.home_button_state.home.Assign(false); | 367 | controller.home_button_state.home.Assign(false); |
| 365 | controller.capture_button_state.capture.Assign(false); | 368 | controller.capture_button_state.capture.Assign(false); |
| 366 | } | 369 | } |
| @@ -494,139 +497,141 @@ void EmulatedController::SetButton(const Common::Input::CallbackStatus& callback | |||
| 494 | if (index >= controller.button_values.size()) { | 497 | if (index >= controller.button_values.size()) { |
| 495 | return; | 498 | return; |
| 496 | } | 499 | } |
| 497 | { | 500 | std::unique_lock lock{mutex}; |
| 498 | std::lock_guard lock{mutex}; | 501 | bool value_changed = false; |
| 499 | bool value_changed = false; | 502 | const auto new_status = TransformToButton(callback); |
| 500 | const auto new_status = TransformToButton(callback); | 503 | auto& current_status = controller.button_values[index]; |
| 501 | auto& current_status = controller.button_values[index]; | ||
| 502 | 504 | ||
| 503 | // Only read button values that have the same uuid or are pressed once | 505 | // Only read button values that have the same uuid or are pressed once |
| 504 | if (current_status.uuid != uuid) { | 506 | if (current_status.uuid != uuid) { |
| 505 | if (!new_status.value) { | 507 | if (!new_status.value) { |
| 506 | return; | 508 | return; |
| 507 | } | ||
| 508 | } | 509 | } |
| 510 | } | ||
| 509 | 511 | ||
| 510 | current_status.toggle = new_status.toggle; | 512 | current_status.toggle = new_status.toggle; |
| 511 | current_status.uuid = uuid; | 513 | current_status.uuid = uuid; |
| 512 | |||
| 513 | // Update button status with current | ||
| 514 | if (!current_status.toggle) { | ||
| 515 | current_status.locked = false; | ||
| 516 | if (current_status.value != new_status.value) { | ||
| 517 | current_status.value = new_status.value; | ||
| 518 | value_changed = true; | ||
| 519 | } | ||
| 520 | } else { | ||
| 521 | // Toggle button and lock status | ||
| 522 | if (new_status.value && !current_status.locked) { | ||
| 523 | current_status.locked = true; | ||
| 524 | current_status.value = !current_status.value; | ||
| 525 | value_changed = true; | ||
| 526 | } | ||
| 527 | 514 | ||
| 528 | // Unlock button ready for next press | 515 | // Update button status with current |
| 529 | if (!new_status.value && current_status.locked) { | 516 | if (!current_status.toggle) { |
| 530 | current_status.locked = false; | 517 | current_status.locked = false; |
| 531 | } | 518 | if (current_status.value != new_status.value) { |
| 519 | current_status.value = new_status.value; | ||
| 520 | value_changed = true; | ||
| 532 | } | 521 | } |
| 533 | 522 | } else { | |
| 534 | if (!value_changed) { | 523 | // Toggle button and lock status |
| 535 | return; | 524 | if (new_status.value && !current_status.locked) { |
| 525 | current_status.locked = true; | ||
| 526 | current_status.value = !current_status.value; | ||
| 527 | value_changed = true; | ||
| 536 | } | 528 | } |
| 537 | 529 | ||
| 538 | if (is_configuring) { | 530 | // Unlock button ready for next press |
| 539 | controller.npad_button_state.raw = NpadButton::None; | 531 | if (!new_status.value && current_status.locked) { |
| 540 | controller.debug_pad_button_state.raw = 0; | 532 | current_status.locked = false; |
| 541 | TriggerOnChange(ControllerTriggerType::Button, false); | ||
| 542 | return; | ||
| 543 | } | 533 | } |
| 534 | } | ||
| 544 | 535 | ||
| 545 | switch (index) { | 536 | if (!value_changed) { |
| 546 | case Settings::NativeButton::A: | 537 | return; |
| 547 | controller.npad_button_state.a.Assign(current_status.value); | 538 | } |
| 548 | controller.debug_pad_button_state.a.Assign(current_status.value); | 539 | |
| 549 | break; | 540 | if (is_configuring) { |
| 550 | case Settings::NativeButton::B: | 541 | controller.npad_button_state.raw = NpadButton::None; |
| 551 | controller.npad_button_state.b.Assign(current_status.value); | 542 | controller.debug_pad_button_state.raw = 0; |
| 552 | controller.debug_pad_button_state.b.Assign(current_status.value); | 543 | lock.unlock(); |
| 553 | break; | 544 | TriggerOnChange(ControllerTriggerType::Button, false); |
| 554 | case Settings::NativeButton::X: | 545 | return; |
| 555 | controller.npad_button_state.x.Assign(current_status.value); | 546 | } |
| 556 | controller.debug_pad_button_state.x.Assign(current_status.value); | 547 | |
| 557 | break; | 548 | switch (index) { |
| 558 | case Settings::NativeButton::Y: | 549 | case Settings::NativeButton::A: |
| 559 | controller.npad_button_state.y.Assign(current_status.value); | 550 | controller.npad_button_state.a.Assign(current_status.value); |
| 560 | controller.debug_pad_button_state.y.Assign(current_status.value); | 551 | controller.debug_pad_button_state.a.Assign(current_status.value); |
| 561 | break; | 552 | break; |
| 562 | case Settings::NativeButton::LStick: | 553 | case Settings::NativeButton::B: |
| 563 | controller.npad_button_state.stick_l.Assign(current_status.value); | 554 | controller.npad_button_state.b.Assign(current_status.value); |
| 564 | break; | 555 | controller.debug_pad_button_state.b.Assign(current_status.value); |
| 565 | case Settings::NativeButton::RStick: | 556 | break; |
| 566 | controller.npad_button_state.stick_r.Assign(current_status.value); | 557 | case Settings::NativeButton::X: |
| 567 | break; | 558 | controller.npad_button_state.x.Assign(current_status.value); |
| 568 | case Settings::NativeButton::L: | 559 | controller.debug_pad_button_state.x.Assign(current_status.value); |
| 569 | controller.npad_button_state.l.Assign(current_status.value); | 560 | break; |
| 570 | controller.debug_pad_button_state.l.Assign(current_status.value); | 561 | case Settings::NativeButton::Y: |
| 571 | break; | 562 | controller.npad_button_state.y.Assign(current_status.value); |
| 572 | case Settings::NativeButton::R: | 563 | controller.debug_pad_button_state.y.Assign(current_status.value); |
| 573 | controller.npad_button_state.r.Assign(current_status.value); | 564 | break; |
| 574 | controller.debug_pad_button_state.r.Assign(current_status.value); | 565 | case Settings::NativeButton::LStick: |
| 575 | break; | 566 | controller.npad_button_state.stick_l.Assign(current_status.value); |
| 576 | case Settings::NativeButton::ZL: | 567 | break; |
| 577 | controller.npad_button_state.zl.Assign(current_status.value); | 568 | case Settings::NativeButton::RStick: |
| 578 | controller.debug_pad_button_state.zl.Assign(current_status.value); | 569 | controller.npad_button_state.stick_r.Assign(current_status.value); |
| 579 | break; | 570 | break; |
| 580 | case Settings::NativeButton::ZR: | 571 | case Settings::NativeButton::L: |
| 581 | controller.npad_button_state.zr.Assign(current_status.value); | 572 | controller.npad_button_state.l.Assign(current_status.value); |
| 582 | controller.debug_pad_button_state.zr.Assign(current_status.value); | 573 | controller.debug_pad_button_state.l.Assign(current_status.value); |
| 583 | break; | 574 | break; |
| 584 | case Settings::NativeButton::Plus: | 575 | case Settings::NativeButton::R: |
| 585 | controller.npad_button_state.plus.Assign(current_status.value); | 576 | controller.npad_button_state.r.Assign(current_status.value); |
| 586 | controller.debug_pad_button_state.plus.Assign(current_status.value); | 577 | controller.debug_pad_button_state.r.Assign(current_status.value); |
| 587 | break; | 578 | break; |
| 588 | case Settings::NativeButton::Minus: | 579 | case Settings::NativeButton::ZL: |
| 589 | controller.npad_button_state.minus.Assign(current_status.value); | 580 | controller.npad_button_state.zl.Assign(current_status.value); |
| 590 | controller.debug_pad_button_state.minus.Assign(current_status.value); | 581 | controller.debug_pad_button_state.zl.Assign(current_status.value); |
| 591 | break; | 582 | break; |
| 592 | case Settings::NativeButton::DLeft: | 583 | case Settings::NativeButton::ZR: |
| 593 | controller.npad_button_state.left.Assign(current_status.value); | 584 | controller.npad_button_state.zr.Assign(current_status.value); |
| 594 | controller.debug_pad_button_state.d_left.Assign(current_status.value); | 585 | controller.debug_pad_button_state.zr.Assign(current_status.value); |
| 595 | break; | 586 | break; |
| 596 | case Settings::NativeButton::DUp: | 587 | case Settings::NativeButton::Plus: |
| 597 | controller.npad_button_state.up.Assign(current_status.value); | 588 | controller.npad_button_state.plus.Assign(current_status.value); |
| 598 | controller.debug_pad_button_state.d_up.Assign(current_status.value); | 589 | controller.debug_pad_button_state.plus.Assign(current_status.value); |
| 599 | break; | 590 | break; |
| 600 | case Settings::NativeButton::DRight: | 591 | case Settings::NativeButton::Minus: |
| 601 | controller.npad_button_state.right.Assign(current_status.value); | 592 | controller.npad_button_state.minus.Assign(current_status.value); |
| 602 | controller.debug_pad_button_state.d_right.Assign(current_status.value); | 593 | controller.debug_pad_button_state.minus.Assign(current_status.value); |
| 603 | break; | 594 | break; |
| 604 | case Settings::NativeButton::DDown: | 595 | case Settings::NativeButton::DLeft: |
| 605 | controller.npad_button_state.down.Assign(current_status.value); | 596 | controller.npad_button_state.left.Assign(current_status.value); |
| 606 | controller.debug_pad_button_state.d_down.Assign(current_status.value); | 597 | controller.debug_pad_button_state.d_left.Assign(current_status.value); |
| 607 | break; | 598 | break; |
| 608 | case Settings::NativeButton::SL: | 599 | case Settings::NativeButton::DUp: |
| 609 | controller.npad_button_state.left_sl.Assign(current_status.value); | 600 | controller.npad_button_state.up.Assign(current_status.value); |
| 610 | controller.npad_button_state.right_sl.Assign(current_status.value); | 601 | controller.debug_pad_button_state.d_up.Assign(current_status.value); |
| 611 | break; | 602 | break; |
| 612 | case Settings::NativeButton::SR: | 603 | case Settings::NativeButton::DRight: |
| 613 | controller.npad_button_state.left_sr.Assign(current_status.value); | 604 | controller.npad_button_state.right.Assign(current_status.value); |
| 614 | controller.npad_button_state.right_sr.Assign(current_status.value); | 605 | controller.debug_pad_button_state.d_right.Assign(current_status.value); |
| 615 | break; | 606 | break; |
| 616 | case Settings::NativeButton::Home: | 607 | case Settings::NativeButton::DDown: |
| 617 | if (!system_buttons_enabled) { | 608 | controller.npad_button_state.down.Assign(current_status.value); |
| 618 | break; | 609 | controller.debug_pad_button_state.d_down.Assign(current_status.value); |
| 619 | } | 610 | break; |
| 620 | controller.home_button_state.home.Assign(current_status.value); | 611 | case Settings::NativeButton::SL: |
| 612 | controller.npad_button_state.left_sl.Assign(current_status.value); | ||
| 613 | controller.npad_button_state.right_sl.Assign(current_status.value); | ||
| 614 | break; | ||
| 615 | case Settings::NativeButton::SR: | ||
| 616 | controller.npad_button_state.left_sr.Assign(current_status.value); | ||
| 617 | controller.npad_button_state.right_sr.Assign(current_status.value); | ||
| 618 | break; | ||
| 619 | case Settings::NativeButton::Home: | ||
| 620 | if (!system_buttons_enabled) { | ||
| 621 | break; | 621 | break; |
| 622 | case Settings::NativeButton::Screenshot: | 622 | } |
| 623 | if (!system_buttons_enabled) { | 623 | controller.home_button_state.home.Assign(current_status.value); |
| 624 | break; | 624 | break; |
| 625 | } | 625 | case Settings::NativeButton::Screenshot: |
| 626 | controller.capture_button_state.capture.Assign(current_status.value); | 626 | if (!system_buttons_enabled) { |
| 627 | break; | 627 | break; |
| 628 | } | 628 | } |
| 629 | controller.capture_button_state.capture.Assign(current_status.value); | ||
| 630 | break; | ||
| 629 | } | 631 | } |
| 632 | |||
| 633 | lock.unlock(); | ||
| 634 | |||
| 630 | if (!is_connected) { | 635 | if (!is_connected) { |
| 631 | if (npad_id_type == NpadIdType::Player1 && npad_type != NpadStyleIndex::Handheld) { | 636 | if (npad_id_type == NpadIdType::Player1 && npad_type != NpadStyleIndex::Handheld) { |
| 632 | Connect(); | 637 | Connect(); |
| @@ -643,7 +648,7 @@ void EmulatedController::SetStick(const Common::Input::CallbackStatus& callback, | |||
| 643 | if (index >= controller.stick_values.size()) { | 648 | if (index >= controller.stick_values.size()) { |
| 644 | return; | 649 | return; |
| 645 | } | 650 | } |
| 646 | std::lock_guard lock{mutex}; | 651 | std::unique_lock lock{mutex}; |
| 647 | const auto stick_value = TransformToStick(callback); | 652 | const auto stick_value = TransformToStick(callback); |
| 648 | 653 | ||
| 649 | // Only read stick values that have the same uuid or are over the threshold to avoid flapping | 654 | // Only read stick values that have the same uuid or are over the threshold to avoid flapping |
| @@ -659,6 +664,7 @@ void EmulatedController::SetStick(const Common::Input::CallbackStatus& callback, | |||
| 659 | if (is_configuring) { | 664 | if (is_configuring) { |
| 660 | controller.analog_stick_state.left = {}; | 665 | controller.analog_stick_state.left = {}; |
| 661 | controller.analog_stick_state.right = {}; | 666 | controller.analog_stick_state.right = {}; |
| 667 | lock.unlock(); | ||
| 662 | TriggerOnChange(ControllerTriggerType::Stick, false); | 668 | TriggerOnChange(ControllerTriggerType::Stick, false); |
| 663 | return; | 669 | return; |
| 664 | } | 670 | } |
| @@ -685,6 +691,7 @@ void EmulatedController::SetStick(const Common::Input::CallbackStatus& callback, | |||
| 685 | break; | 691 | break; |
| 686 | } | 692 | } |
| 687 | 693 | ||
| 694 | lock.unlock(); | ||
| 688 | TriggerOnChange(ControllerTriggerType::Stick, true); | 695 | TriggerOnChange(ControllerTriggerType::Stick, true); |
| 689 | } | 696 | } |
| 690 | 697 | ||
| @@ -693,7 +700,7 @@ void EmulatedController::SetTrigger(const Common::Input::CallbackStatus& callbac | |||
| 693 | if (index >= controller.trigger_values.size()) { | 700 | if (index >= controller.trigger_values.size()) { |
| 694 | return; | 701 | return; |
| 695 | } | 702 | } |
| 696 | std::lock_guard lock{mutex}; | 703 | std::unique_lock lock{mutex}; |
| 697 | const auto trigger_value = TransformToTrigger(callback); | 704 | const auto trigger_value = TransformToTrigger(callback); |
| 698 | 705 | ||
| 699 | // Only read trigger values that have the same uuid or are pressed once | 706 | // Only read trigger values that have the same uuid or are pressed once |
| @@ -709,6 +716,7 @@ void EmulatedController::SetTrigger(const Common::Input::CallbackStatus& callbac | |||
| 709 | if (is_configuring) { | 716 | if (is_configuring) { |
| 710 | controller.gc_trigger_state.left = 0; | 717 | controller.gc_trigger_state.left = 0; |
| 711 | controller.gc_trigger_state.right = 0; | 718 | controller.gc_trigger_state.right = 0; |
| 719 | lock.unlock(); | ||
| 712 | TriggerOnChange(ControllerTriggerType::Trigger, false); | 720 | TriggerOnChange(ControllerTriggerType::Trigger, false); |
| 713 | return; | 721 | return; |
| 714 | } | 722 | } |
| @@ -727,6 +735,7 @@ void EmulatedController::SetTrigger(const Common::Input::CallbackStatus& callbac | |||
| 727 | break; | 735 | break; |
| 728 | } | 736 | } |
| 729 | 737 | ||
| 738 | lock.unlock(); | ||
| 730 | TriggerOnChange(ControllerTriggerType::Trigger, true); | 739 | TriggerOnChange(ControllerTriggerType::Trigger, true); |
| 731 | } | 740 | } |
| 732 | 741 | ||
| @@ -735,7 +744,7 @@ void EmulatedController::SetMotion(const Common::Input::CallbackStatus& callback | |||
| 735 | if (index >= controller.motion_values.size()) { | 744 | if (index >= controller.motion_values.size()) { |
| 736 | return; | 745 | return; |
| 737 | } | 746 | } |
| 738 | std::lock_guard lock{mutex}; | 747 | std::unique_lock lock{mutex}; |
| 739 | auto& raw_status = controller.motion_values[index].raw_status; | 748 | auto& raw_status = controller.motion_values[index].raw_status; |
| 740 | auto& emulated = controller.motion_values[index].emulated; | 749 | auto& emulated = controller.motion_values[index].emulated; |
| 741 | 750 | ||
| @@ -756,6 +765,7 @@ void EmulatedController::SetMotion(const Common::Input::CallbackStatus& callback | |||
| 756 | force_update_motion = raw_status.force_update; | 765 | force_update_motion = raw_status.force_update; |
| 757 | 766 | ||
| 758 | if (is_configuring) { | 767 | if (is_configuring) { |
| 768 | lock.unlock(); | ||
| 759 | TriggerOnChange(ControllerTriggerType::Motion, false); | 769 | TriggerOnChange(ControllerTriggerType::Motion, false); |
| 760 | return; | 770 | return; |
| 761 | } | 771 | } |
| @@ -767,6 +777,7 @@ void EmulatedController::SetMotion(const Common::Input::CallbackStatus& callback | |||
| 767 | motion.orientation = emulated.GetOrientation(); | 777 | motion.orientation = emulated.GetOrientation(); |
| 768 | motion.is_at_rest = !emulated.IsMoving(motion_sensitivity); | 778 | motion.is_at_rest = !emulated.IsMoving(motion_sensitivity); |
| 769 | 779 | ||
| 780 | lock.unlock(); | ||
| 770 | TriggerOnChange(ControllerTriggerType::Motion, true); | 781 | TriggerOnChange(ControllerTriggerType::Motion, true); |
| 771 | } | 782 | } |
| 772 | 783 | ||
| @@ -775,10 +786,11 @@ void EmulatedController::SetBattery(const Common::Input::CallbackStatus& callbac | |||
| 775 | if (index >= controller.battery_values.size()) { | 786 | if (index >= controller.battery_values.size()) { |
| 776 | return; | 787 | return; |
| 777 | } | 788 | } |
| 778 | std::lock_guard lock{mutex}; | 789 | std::unique_lock lock{mutex}; |
| 779 | controller.battery_values[index] = TransformToBattery(callback); | 790 | controller.battery_values[index] = TransformToBattery(callback); |
| 780 | 791 | ||
| 781 | if (is_configuring) { | 792 | if (is_configuring) { |
| 793 | lock.unlock(); | ||
| 782 | TriggerOnChange(ControllerTriggerType::Battery, false); | 794 | TriggerOnChange(ControllerTriggerType::Battery, false); |
| 783 | return; | 795 | return; |
| 784 | } | 796 | } |
| @@ -835,6 +847,8 @@ void EmulatedController::SetBattery(const Common::Input::CallbackStatus& callbac | |||
| 835 | }; | 847 | }; |
| 836 | break; | 848 | break; |
| 837 | } | 849 | } |
| 850 | |||
| 851 | lock.unlock(); | ||
| 838 | TriggerOnChange(ControllerTriggerType::Battery, true); | 852 | TriggerOnChange(ControllerTriggerType::Battery, true); |
| 839 | } | 853 | } |
| 840 | 854 | ||
| @@ -932,6 +946,7 @@ void EmulatedController::SetSupportedNpadStyleTag(NpadStyleTag supported_styles) | |||
| 932 | } | 946 | } |
| 933 | 947 | ||
| 934 | bool EmulatedController::IsControllerFullkey(bool use_temporary_value) const { | 948 | bool EmulatedController::IsControllerFullkey(bool use_temporary_value) const { |
| 949 | std::lock_guard lock{mutex}; | ||
| 935 | const auto type = is_configuring && use_temporary_value ? tmp_npad_type : npad_type; | 950 | const auto type = is_configuring && use_temporary_value ? tmp_npad_type : npad_type; |
| 936 | switch (type) { | 951 | switch (type) { |
| 937 | case NpadStyleIndex::ProController: | 952 | case NpadStyleIndex::ProController: |
| @@ -947,6 +962,7 @@ bool EmulatedController::IsControllerFullkey(bool use_temporary_value) const { | |||
| 947 | } | 962 | } |
| 948 | 963 | ||
| 949 | bool EmulatedController::IsControllerSupported(bool use_temporary_value) const { | 964 | bool EmulatedController::IsControllerSupported(bool use_temporary_value) const { |
| 965 | std::lock_guard lock{mutex}; | ||
| 950 | const auto type = is_configuring && use_temporary_value ? tmp_npad_type : npad_type; | 966 | const auto type = is_configuring && use_temporary_value ? tmp_npad_type : npad_type; |
| 951 | switch (type) { | 967 | switch (type) { |
| 952 | case NpadStyleIndex::ProController: | 968 | case NpadStyleIndex::ProController: |
| @@ -982,40 +998,44 @@ void EmulatedController::Connect(bool use_temporary_value) { | |||
| 982 | LOG_ERROR(Service_HID, "Controller type {} is not supported", type); | 998 | LOG_ERROR(Service_HID, "Controller type {} is not supported", type); |
| 983 | return; | 999 | return; |
| 984 | } | 1000 | } |
| 985 | { | ||
| 986 | std::lock_guard lock{mutex}; | ||
| 987 | if (is_configuring) { | ||
| 988 | tmp_is_connected = true; | ||
| 989 | TriggerOnChange(ControllerTriggerType::Connected, false); | ||
| 990 | return; | ||
| 991 | } | ||
| 992 | 1001 | ||
| 993 | if (is_connected) { | 1002 | std::unique_lock lock{mutex}; |
| 994 | return; | 1003 | if (is_configuring) { |
| 995 | } | 1004 | tmp_is_connected = true; |
| 996 | is_connected = true; | 1005 | lock.unlock(); |
| 1006 | TriggerOnChange(ControllerTriggerType::Connected, false); | ||
| 1007 | return; | ||
| 1008 | } | ||
| 1009 | |||
| 1010 | if (is_connected) { | ||
| 1011 | return; | ||
| 997 | } | 1012 | } |
| 1013 | is_connected = true; | ||
| 1014 | |||
| 1015 | lock.unlock(); | ||
| 998 | TriggerOnChange(ControllerTriggerType::Connected, true); | 1016 | TriggerOnChange(ControllerTriggerType::Connected, true); |
| 999 | } | 1017 | } |
| 1000 | 1018 | ||
| 1001 | void EmulatedController::Disconnect() { | 1019 | void EmulatedController::Disconnect() { |
| 1002 | { | 1020 | std::unique_lock lock{mutex}; |
| 1003 | std::lock_guard lock{mutex}; | 1021 | if (is_configuring) { |
| 1004 | if (is_configuring) { | 1022 | tmp_is_connected = false; |
| 1005 | tmp_is_connected = false; | 1023 | lock.unlock(); |
| 1006 | TriggerOnChange(ControllerTriggerType::Disconnected, false); | 1024 | TriggerOnChange(ControllerTriggerType::Disconnected, false); |
| 1007 | return; | 1025 | return; |
| 1008 | } | 1026 | } |
| 1009 | 1027 | ||
| 1010 | if (!is_connected) { | 1028 | if (!is_connected) { |
| 1011 | return; | 1029 | return; |
| 1012 | } | ||
| 1013 | is_connected = false; | ||
| 1014 | } | 1030 | } |
| 1031 | is_connected = false; | ||
| 1032 | |||
| 1033 | lock.unlock(); | ||
| 1015 | TriggerOnChange(ControllerTriggerType::Disconnected, true); | 1034 | TriggerOnChange(ControllerTriggerType::Disconnected, true); |
| 1016 | } | 1035 | } |
| 1017 | 1036 | ||
| 1018 | bool EmulatedController::IsConnected(bool get_temporary_value) const { | 1037 | bool EmulatedController::IsConnected(bool get_temporary_value) const { |
| 1038 | std::lock_guard lock{mutex}; | ||
| 1019 | if (get_temporary_value && is_configuring) { | 1039 | if (get_temporary_value && is_configuring) { |
| 1020 | return tmp_is_connected; | 1040 | return tmp_is_connected; |
| 1021 | } | 1041 | } |
| @@ -1029,10 +1049,12 @@ bool EmulatedController::IsVibrationEnabled() const { | |||
| 1029 | } | 1049 | } |
| 1030 | 1050 | ||
| 1031 | NpadIdType EmulatedController::GetNpadIdType() const { | 1051 | NpadIdType EmulatedController::GetNpadIdType() const { |
| 1052 | std::lock_guard lock{mutex}; | ||
| 1032 | return npad_id_type; | 1053 | return npad_id_type; |
| 1033 | } | 1054 | } |
| 1034 | 1055 | ||
| 1035 | NpadStyleIndex EmulatedController::GetNpadStyleIndex(bool get_temporary_value) const { | 1056 | NpadStyleIndex EmulatedController::GetNpadStyleIndex(bool get_temporary_value) const { |
| 1057 | std::lock_guard lock{mutex}; | ||
| 1036 | if (get_temporary_value && is_configuring) { | 1058 | if (get_temporary_value && is_configuring) { |
| 1037 | return tmp_npad_type; | 1059 | return tmp_npad_type; |
| 1038 | } | 1060 | } |
| @@ -1040,27 +1062,28 @@ NpadStyleIndex EmulatedController::GetNpadStyleIndex(bool get_temporary_value) c | |||
| 1040 | } | 1062 | } |
| 1041 | 1063 | ||
| 1042 | void EmulatedController::SetNpadStyleIndex(NpadStyleIndex npad_type_) { | 1064 | void EmulatedController::SetNpadStyleIndex(NpadStyleIndex npad_type_) { |
| 1043 | { | 1065 | std::unique_lock lock{mutex}; |
| 1044 | std::lock_guard lock{mutex}; | ||
| 1045 | 1066 | ||
| 1046 | if (is_configuring) { | 1067 | if (is_configuring) { |
| 1047 | if (tmp_npad_type == npad_type_) { | 1068 | if (tmp_npad_type == npad_type_) { |
| 1048 | return; | ||
| 1049 | } | ||
| 1050 | tmp_npad_type = npad_type_; | ||
| 1051 | TriggerOnChange(ControllerTriggerType::Type, false); | ||
| 1052 | return; | 1069 | return; |
| 1053 | } | 1070 | } |
| 1071 | tmp_npad_type = npad_type_; | ||
| 1072 | lock.unlock(); | ||
| 1073 | TriggerOnChange(ControllerTriggerType::Type, false); | ||
| 1074 | return; | ||
| 1075 | } | ||
| 1054 | 1076 | ||
| 1055 | if (npad_type == npad_type_) { | 1077 | if (npad_type == npad_type_) { |
| 1056 | return; | 1078 | return; |
| 1057 | } | ||
| 1058 | if (is_connected) { | ||
| 1059 | LOG_WARNING(Service_HID, "Controller {} type changed while it's connected", | ||
| 1060 | NpadIdTypeToIndex(npad_id_type)); | ||
| 1061 | } | ||
| 1062 | npad_type = npad_type_; | ||
| 1063 | } | 1079 | } |
| 1080 | if (is_connected) { | ||
| 1081 | LOG_WARNING(Service_HID, "Controller {} type changed while it's connected", | ||
| 1082 | NpadIdTypeToIndex(npad_id_type)); | ||
| 1083 | } | ||
| 1084 | npad_type = npad_type_; | ||
| 1085 | |||
| 1086 | lock.unlock(); | ||
| 1064 | TriggerOnChange(ControllerTriggerType::Type, true); | 1087 | TriggerOnChange(ControllerTriggerType::Type, true); |
| 1065 | } | 1088 | } |
| 1066 | 1089 | ||
| @@ -1088,30 +1111,37 @@ LedPattern EmulatedController::GetLedPattern() const { | |||
| 1088 | } | 1111 | } |
| 1089 | 1112 | ||
| 1090 | ButtonValues EmulatedController::GetButtonsValues() const { | 1113 | ButtonValues EmulatedController::GetButtonsValues() const { |
| 1114 | std::lock_guard lock{mutex}; | ||
| 1091 | return controller.button_values; | 1115 | return controller.button_values; |
| 1092 | } | 1116 | } |
| 1093 | 1117 | ||
| 1094 | SticksValues EmulatedController::GetSticksValues() const { | 1118 | SticksValues EmulatedController::GetSticksValues() const { |
| 1119 | std::lock_guard lock{mutex}; | ||
| 1095 | return controller.stick_values; | 1120 | return controller.stick_values; |
| 1096 | } | 1121 | } |
| 1097 | 1122 | ||
| 1098 | TriggerValues EmulatedController::GetTriggersValues() const { | 1123 | TriggerValues EmulatedController::GetTriggersValues() const { |
| 1124 | std::lock_guard lock{mutex}; | ||
| 1099 | return controller.trigger_values; | 1125 | return controller.trigger_values; |
| 1100 | } | 1126 | } |
| 1101 | 1127 | ||
| 1102 | ControllerMotionValues EmulatedController::GetMotionValues() const { | 1128 | ControllerMotionValues EmulatedController::GetMotionValues() const { |
| 1129 | std::lock_guard lock{mutex}; | ||
| 1103 | return controller.motion_values; | 1130 | return controller.motion_values; |
| 1104 | } | 1131 | } |
| 1105 | 1132 | ||
| 1106 | ColorValues EmulatedController::GetColorsValues() const { | 1133 | ColorValues EmulatedController::GetColorsValues() const { |
| 1134 | std::lock_guard lock{mutex}; | ||
| 1107 | return controller.color_values; | 1135 | return controller.color_values; |
| 1108 | } | 1136 | } |
| 1109 | 1137 | ||
| 1110 | BatteryValues EmulatedController::GetBatteryValues() const { | 1138 | BatteryValues EmulatedController::GetBatteryValues() const { |
| 1139 | std::lock_guard lock{mutex}; | ||
| 1111 | return controller.battery_values; | 1140 | return controller.battery_values; |
| 1112 | } | 1141 | } |
| 1113 | 1142 | ||
| 1114 | HomeButtonState EmulatedController::GetHomeButtons() const { | 1143 | HomeButtonState EmulatedController::GetHomeButtons() const { |
| 1144 | std::lock_guard lock{mutex}; | ||
| 1115 | if (is_configuring) { | 1145 | if (is_configuring) { |
| 1116 | return {}; | 1146 | return {}; |
| 1117 | } | 1147 | } |
| @@ -1119,6 +1149,7 @@ HomeButtonState EmulatedController::GetHomeButtons() const { | |||
| 1119 | } | 1149 | } |
| 1120 | 1150 | ||
| 1121 | CaptureButtonState EmulatedController::GetCaptureButtons() const { | 1151 | CaptureButtonState EmulatedController::GetCaptureButtons() const { |
| 1152 | std::lock_guard lock{mutex}; | ||
| 1122 | if (is_configuring) { | 1153 | if (is_configuring) { |
| 1123 | return {}; | 1154 | return {}; |
| 1124 | } | 1155 | } |
| @@ -1126,6 +1157,7 @@ CaptureButtonState EmulatedController::GetCaptureButtons() const { | |||
| 1126 | } | 1157 | } |
| 1127 | 1158 | ||
| 1128 | NpadButtonState EmulatedController::GetNpadButtons() const { | 1159 | NpadButtonState EmulatedController::GetNpadButtons() const { |
| 1160 | std::lock_guard lock{mutex}; | ||
| 1129 | if (is_configuring) { | 1161 | if (is_configuring) { |
| 1130 | return {}; | 1162 | return {}; |
| 1131 | } | 1163 | } |
| @@ -1133,6 +1165,7 @@ NpadButtonState EmulatedController::GetNpadButtons() const { | |||
| 1133 | } | 1165 | } |
| 1134 | 1166 | ||
| 1135 | DebugPadButton EmulatedController::GetDebugPadButtons() const { | 1167 | DebugPadButton EmulatedController::GetDebugPadButtons() const { |
| 1168 | std::lock_guard lock{mutex}; | ||
| 1136 | if (is_configuring) { | 1169 | if (is_configuring) { |
| 1137 | return {}; | 1170 | return {}; |
| 1138 | } | 1171 | } |
| @@ -1140,6 +1173,7 @@ DebugPadButton EmulatedController::GetDebugPadButtons() const { | |||
| 1140 | } | 1173 | } |
| 1141 | 1174 | ||
| 1142 | AnalogSticks EmulatedController::GetSticks() const { | 1175 | AnalogSticks EmulatedController::GetSticks() const { |
| 1176 | std::lock_guard lock{mutex}; | ||
| 1143 | if (is_configuring) { | 1177 | if (is_configuring) { |
| 1144 | return {}; | 1178 | return {}; |
| 1145 | } | 1179 | } |
| @@ -1154,6 +1188,7 @@ AnalogSticks EmulatedController::GetSticks() const { | |||
| 1154 | } | 1188 | } |
| 1155 | 1189 | ||
| 1156 | NpadGcTriggerState EmulatedController::GetTriggers() const { | 1190 | NpadGcTriggerState EmulatedController::GetTriggers() const { |
| 1191 | std::lock_guard lock{mutex}; | ||
| 1157 | if (is_configuring) { | 1192 | if (is_configuring) { |
| 1158 | return {}; | 1193 | return {}; |
| 1159 | } | 1194 | } |
| @@ -1161,6 +1196,7 @@ NpadGcTriggerState EmulatedController::GetTriggers() const { | |||
| 1161 | } | 1196 | } |
| 1162 | 1197 | ||
| 1163 | MotionState EmulatedController::GetMotions() const { | 1198 | MotionState EmulatedController::GetMotions() const { |
| 1199 | std::lock_guard lock{mutex}; | ||
| 1164 | if (force_update_motion) { | 1200 | if (force_update_motion) { |
| 1165 | for (auto& device : motion_devices) { | 1201 | for (auto& device : motion_devices) { |
| 1166 | if (!device) { | 1202 | if (!device) { |
| @@ -1173,14 +1209,17 @@ MotionState EmulatedController::GetMotions() const { | |||
| 1173 | } | 1209 | } |
| 1174 | 1210 | ||
| 1175 | ControllerColors EmulatedController::GetColors() const { | 1211 | ControllerColors EmulatedController::GetColors() const { |
| 1212 | std::lock_guard lock{mutex}; | ||
| 1176 | return controller.colors_state; | 1213 | return controller.colors_state; |
| 1177 | } | 1214 | } |
| 1178 | 1215 | ||
| 1179 | BatteryLevelState EmulatedController::GetBattery() const { | 1216 | BatteryLevelState EmulatedController::GetBattery() const { |
| 1217 | std::lock_guard lock{mutex}; | ||
| 1180 | return controller.battery_state; | 1218 | return controller.battery_state; |
| 1181 | } | 1219 | } |
| 1182 | 1220 | ||
| 1183 | void EmulatedController::TriggerOnChange(ControllerTriggerType type, bool is_npad_service_update) { | 1221 | void EmulatedController::TriggerOnChange(ControllerTriggerType type, bool is_npad_service_update) { |
| 1222 | std::lock_guard lock{callback_mutex}; | ||
| 1184 | for (const auto& poller_pair : callback_list) { | 1223 | for (const auto& poller_pair : callback_list) { |
| 1185 | const ControllerUpdateCallback& poller = poller_pair.second; | 1224 | const ControllerUpdateCallback& poller = poller_pair.second; |
| 1186 | if (!is_npad_service_update && poller.is_npad_service) { | 1225 | if (!is_npad_service_update && poller.is_npad_service) { |
| @@ -1193,13 +1232,13 @@ void EmulatedController::TriggerOnChange(ControllerTriggerType type, bool is_npa | |||
| 1193 | } | 1232 | } |
| 1194 | 1233 | ||
| 1195 | int EmulatedController::SetCallback(ControllerUpdateCallback update_callback) { | 1234 | int EmulatedController::SetCallback(ControllerUpdateCallback update_callback) { |
| 1196 | std::lock_guard lock{mutex}; | 1235 | std::lock_guard lock{callback_mutex}; |
| 1197 | callback_list.insert_or_assign(last_callback_key, std::move(update_callback)); | 1236 | callback_list.insert_or_assign(last_callback_key, std::move(update_callback)); |
| 1198 | return last_callback_key++; | 1237 | return last_callback_key++; |
| 1199 | } | 1238 | } |
| 1200 | 1239 | ||
| 1201 | void EmulatedController::DeleteCallback(int key) { | 1240 | void EmulatedController::DeleteCallback(int key) { |
| 1202 | std::lock_guard lock{mutex}; | 1241 | std::lock_guard lock{callback_mutex}; |
| 1203 | const auto& iterator = callback_list.find(key); | 1242 | const auto& iterator = callback_list.find(key); |
| 1204 | if (iterator == callback_list.end()) { | 1243 | if (iterator == callback_list.end()) { |
| 1205 | LOG_ERROR(Input, "Tried to delete non-existent callback {}", key); | 1244 | LOG_ERROR(Input, "Tried to delete non-existent callback {}", key); |