diff options
| -rw-r--r-- | src/core/hid/emulated_console.cpp | 1 | ||||
| -rw-r--r-- | src/core/hid/emulated_controller.cpp | 98 | ||||
| -rw-r--r-- | src/core/hid/emulated_controller.h | 18 | ||||
| -rw-r--r-- | src/core/hid/hid_types.h | 8 | ||||
| -rw-r--r-- | src/core/hle/service/hid/controllers/controller_base.cpp | 2 | ||||
| -rw-r--r-- | src/core/hle/service/hid/controllers/npad.cpp | 77 | ||||
| -rw-r--r-- | src/core/hle/service/hid/controllers/npad.h | 3 | ||||
| -rw-r--r-- | src/yuzu/configuration/configure_input.cpp | 1 | ||||
| -rw-r--r-- | src/yuzu/configuration/configure_input_player.cpp | 81 | ||||
| -rw-r--r-- | src/yuzu/configuration/configure_input_player_widget.cpp | 2 |
10 files changed, 226 insertions, 65 deletions
diff --git a/src/core/hid/emulated_console.cpp b/src/core/hid/emulated_console.cpp index c65d05041..7f7c8fd59 100644 --- a/src/core/hid/emulated_console.cpp +++ b/src/core/hid/emulated_console.cpp | |||
| @@ -53,7 +53,6 @@ void EmulatedConsole::ReloadInput() { | |||
| 53 | touch_button_params.Set("x", x); | 53 | touch_button_params.Set("x", x); |
| 54 | touch_button_params.Set("y", y); | 54 | touch_button_params.Set("y", y); |
| 55 | touch_button_params.Set("touch_id", static_cast<int>(index)); | 55 | touch_button_params.Set("touch_id", static_cast<int>(index)); |
| 56 | LOG_ERROR(Common, "{} ", touch_button_params.Serialize()); | ||
| 57 | touch_devices[index] = | 56 | touch_devices[index] = |
| 58 | Input::CreateDeviceFromString<Input::InputDevice>(touch_button_params.Serialize()); | 57 | Input::CreateDeviceFromString<Input::InputDevice>(touch_button_params.Serialize()); |
| 59 | if (!touch_devices[index]) { | 58 | if (!touch_devices[index]) { |
diff --git a/src/core/hid/emulated_controller.cpp b/src/core/hid/emulated_controller.cpp index b04ab4cd8..7ef6ef118 100644 --- a/src/core/hid/emulated_controller.cpp +++ b/src/core/hid/emulated_controller.cpp | |||
| @@ -54,6 +54,7 @@ Settings::ControllerType EmulatedController::MapNPadToSettingsType(NpadType type | |||
| 54 | } | 54 | } |
| 55 | 55 | ||
| 56 | void EmulatedController::ReloadFromSettings() { | 56 | void EmulatedController::ReloadFromSettings() { |
| 57 | //LOG_ERROR(Service_HID, "reload config from settings {}", NpadIdTypeToIndex(npad_id_type)); | ||
| 57 | const auto player_index = NpadIdTypeToIndex(npad_id_type); | 58 | const auto player_index = NpadIdTypeToIndex(npad_id_type); |
| 58 | const auto& player = Settings::values.players.GetValue()[player_index]; | 59 | const auto& player = Settings::values.players.GetValue()[player_index]; |
| 59 | 60 | ||
| @@ -91,6 +92,7 @@ void EmulatedController::ReloadFromSettings() { | |||
| 91 | } | 92 | } |
| 92 | 93 | ||
| 93 | void EmulatedController::ReloadInput() { | 94 | void EmulatedController::ReloadInput() { |
| 95 | //LOG_ERROR(Service_HID, "reload config {}", NpadIdTypeToIndex(npad_id_type)); | ||
| 94 | // If you load any device here add the equivalent to the UnloadInput() function | 96 | // If you load any device here add the equivalent to the UnloadInput() function |
| 95 | const auto player_index = NpadIdTypeToIndex(npad_id_type); | 97 | const auto player_index = NpadIdTypeToIndex(npad_id_type); |
| 96 | const auto left_side = button_params[Settings::NativeButton::ZL]; | 98 | const auto left_side = button_params[Settings::NativeButton::ZL]; |
| @@ -187,11 +189,29 @@ void EmulatedController::UnloadInput() { | |||
| 187 | 189 | ||
| 188 | void EmulatedController::EnableConfiguration() { | 190 | void EmulatedController::EnableConfiguration() { |
| 189 | is_configuring = true; | 191 | is_configuring = true; |
| 190 | SaveCurrentConfig(); | 192 | temporary_is_connected = is_connected; |
| 193 | temporary_npad_type = npad_type; | ||
| 191 | } | 194 | } |
| 192 | 195 | ||
| 193 | void EmulatedController::DisableConfiguration() { | 196 | void EmulatedController::DisableConfiguration() { |
| 194 | is_configuring = false; | 197 | is_configuring = false; |
| 198 | |||
| 199 | // Apply temporary npad type to the real controller | ||
| 200 | if (temporary_npad_type != npad_type) { | ||
| 201 | if (is_connected) { | ||
| 202 | Disconnect(); | ||
| 203 | } | ||
| 204 | SetNpadType(temporary_npad_type); | ||
| 205 | } | ||
| 206 | |||
| 207 | // Apply temporary connected status to the real controller | ||
| 208 | if (temporary_is_connected != is_connected) { | ||
| 209 | if (temporary_is_connected) { | ||
| 210 | Connect(); | ||
| 211 | return; | ||
| 212 | } | ||
| 213 | Disconnect(); | ||
| 214 | } | ||
| 195 | } | 215 | } |
| 196 | 216 | ||
| 197 | bool EmulatedController::IsConfiguring() const { | 217 | bool EmulatedController::IsConfiguring() const { |
| @@ -199,10 +219,6 @@ bool EmulatedController::IsConfiguring() const { | |||
| 199 | } | 219 | } |
| 200 | 220 | ||
| 201 | void EmulatedController::SaveCurrentConfig() { | 221 | void EmulatedController::SaveCurrentConfig() { |
| 202 | if (!is_configuring) { | ||
| 203 | return; | ||
| 204 | } | ||
| 205 | |||
| 206 | const auto player_index = NpadIdTypeToIndex(npad_id_type); | 222 | const auto player_index = NpadIdTypeToIndex(npad_id_type); |
| 207 | auto& player = Settings::values.players.GetValue()[player_index]; | 223 | auto& player = Settings::values.players.GetValue()[player_index]; |
| 208 | player.connected = is_connected; | 224 | player.connected = is_connected; |
| @@ -657,26 +673,47 @@ void EmulatedController::SetLedPattern() { | |||
| 657 | } | 673 | } |
| 658 | 674 | ||
| 659 | void EmulatedController::Connect() { | 675 | void EmulatedController::Connect() { |
| 660 | std::lock_guard lock{mutex}; | 676 | { |
| 661 | if (is_connected) { | 677 | std::lock_guard lock{mutex}; |
| 662 | LOG_WARNING(Service_HID, "Tried to turn on a connected controller {}", npad_id_type); | 678 | if (is_configuring) { |
| 663 | return; | 679 | temporary_is_connected = true; |
| 680 | TriggerOnChange(ControllerTriggerType::Connected); | ||
| 681 | return; | ||
| 682 | } | ||
| 683 | |||
| 684 | if (is_connected) { | ||
| 685 | return; | ||
| 686 | } | ||
| 687 | is_connected = true; | ||
| 664 | } | 688 | } |
| 665 | is_connected = true; | 689 | LOG_ERROR(Service_HID, "Connected controller {}", NpadIdTypeToIndex(npad_id_type)); |
| 666 | TriggerOnChange(ControllerTriggerType::Connected); | 690 | TriggerOnChange(ControllerTriggerType::Connected); |
| 667 | } | 691 | } |
| 668 | 692 | ||
| 669 | void EmulatedController::Disconnect() { | 693 | void EmulatedController::Disconnect() { |
| 670 | std::lock_guard lock{mutex}; | 694 | { |
| 671 | if (!is_connected) { | 695 | std::lock_guard lock{mutex}; |
| 672 | LOG_WARNING(Service_HID, "Tried to turn off a disconnected controller {}", npad_id_type); | 696 | if (is_configuring) { |
| 673 | return; | 697 | temporary_is_connected = false; |
| 698 | LOG_ERROR(Service_HID, "Disconnected temporal controller {}", | ||
| 699 | NpadIdTypeToIndex(npad_id_type)); | ||
| 700 | TriggerOnChange(ControllerTriggerType::Disconnected); | ||
| 701 | return; | ||
| 702 | } | ||
| 703 | |||
| 704 | if (!is_connected) { | ||
| 705 | return; | ||
| 706 | } | ||
| 707 | is_connected = false; | ||
| 674 | } | 708 | } |
| 675 | is_connected = false; | 709 | LOG_ERROR(Service_HID, "Disconnected controller {}", NpadIdTypeToIndex(npad_id_type)); |
| 676 | TriggerOnChange(ControllerTriggerType::Disconnected); | 710 | TriggerOnChange(ControllerTriggerType::Disconnected); |
| 677 | } | 711 | } |
| 678 | 712 | ||
| 679 | bool EmulatedController::IsConnected() const { | 713 | bool EmulatedController::IsConnected(bool temporary) const { |
| 714 | if (temporary) { | ||
| 715 | return temporary_is_connected; | ||
| 716 | } | ||
| 680 | return is_connected; | 717 | return is_connected; |
| 681 | } | 718 | } |
| 682 | 719 | ||
| @@ -688,16 +725,35 @@ NpadIdType EmulatedController::GetNpadIdType() const { | |||
| 688 | return npad_id_type; | 725 | return npad_id_type; |
| 689 | } | 726 | } |
| 690 | 727 | ||
| 691 | NpadType EmulatedController::GetNpadType() const { | 728 | NpadType EmulatedController::GetNpadType(bool temporary) const { |
| 729 | if (temporary) { | ||
| 730 | return temporary_npad_type; | ||
| 731 | } | ||
| 692 | return npad_type; | 732 | return npad_type; |
| 693 | } | 733 | } |
| 694 | 734 | ||
| 695 | void EmulatedController::SetNpadType(NpadType npad_type_) { | 735 | void EmulatedController::SetNpadType(NpadType npad_type_) { |
| 696 | std::lock_guard lock{mutex}; | 736 | { |
| 697 | if (npad_type == npad_type_) { | 737 | std::lock_guard lock{mutex}; |
| 698 | return; | 738 | |
| 739 | if (is_configuring) { | ||
| 740 | if (temporary_npad_type == npad_type_) { | ||
| 741 | return; | ||
| 742 | } | ||
| 743 | temporary_npad_type = npad_type_; | ||
| 744 | TriggerOnChange(ControllerTriggerType::Type); | ||
| 745 | return; | ||
| 746 | } | ||
| 747 | |||
| 748 | if (npad_type == npad_type_) { | ||
| 749 | return; | ||
| 750 | } | ||
| 751 | if (is_connected) { | ||
| 752 | LOG_WARNING(Service_HID, "Controller {} type changed while it's connected", | ||
| 753 | NpadIdTypeToIndex(npad_id_type)); | ||
| 754 | } | ||
| 755 | npad_type = npad_type_; | ||
| 699 | } | 756 | } |
| 700 | npad_type = npad_type_; | ||
| 701 | TriggerOnChange(ControllerTriggerType::Type); | 757 | TriggerOnChange(ControllerTriggerType::Type); |
| 702 | } | 758 | } |
| 703 | 759 | ||
diff --git a/src/core/hid/emulated_controller.h b/src/core/hid/emulated_controller.h index 096fe1705..6a6dc1892 100644 --- a/src/core/hid/emulated_controller.h +++ b/src/core/hid/emulated_controller.h | |||
| @@ -139,8 +139,12 @@ public: | |||
| 139 | /// Sets the NpadType for this controller | 139 | /// Sets the NpadType for this controller |
| 140 | void SetNpadType(NpadType npad_type_); | 140 | void SetNpadType(NpadType npad_type_); |
| 141 | 141 | ||
| 142 | /// Gets the NpadType for this controller | 142 | /** |
| 143 | NpadType GetNpadType() const; | 143 | * Gets the NpadType for this controller |
| 144 | * @param Returns the temporary value if true | ||
| 145 | * @return NpadType set on the controller | ||
| 146 | */ | ||
| 147 | NpadType GetNpadType(bool temporary = false) const; | ||
| 144 | 148 | ||
| 145 | /// Sets the connected status to true | 149 | /// Sets the connected status to true |
| 146 | void Connect(); | 150 | void Connect(); |
| @@ -148,8 +152,12 @@ public: | |||
| 148 | /// Sets the connected status to false | 152 | /// Sets the connected status to false |
| 149 | void Disconnect(); | 153 | void Disconnect(); |
| 150 | 154 | ||
| 151 | /// Returns true if the controller has the connected status | 155 | /** |
| 152 | bool IsConnected() const; | 156 | * Is the emulated connected |
| 157 | * @param Returns the temporary value if true | ||
| 158 | * @return true if the controller has the connected status | ||
| 159 | */ | ||
| 160 | bool IsConnected(bool temporary = false) const; | ||
| 153 | 161 | ||
| 154 | /// Returns true if vibration is enabled | 162 | /// Returns true if vibration is enabled |
| 155 | bool IsVibrationEnabled() const; | 163 | bool IsVibrationEnabled() const; |
| @@ -323,7 +331,9 @@ private: | |||
| 323 | 331 | ||
| 324 | NpadIdType npad_id_type; | 332 | NpadIdType npad_id_type; |
| 325 | NpadType npad_type{NpadType::None}; | 333 | NpadType npad_type{NpadType::None}; |
| 334 | NpadType temporary_npad_type{NpadType::None}; | ||
| 326 | bool is_connected{false}; | 335 | bool is_connected{false}; |
| 336 | bool temporary_is_connected{false}; | ||
| 327 | bool is_configuring{false}; | 337 | bool is_configuring{false}; |
| 328 | bool is_vibration_enabled{true}; | 338 | bool is_vibration_enabled{true}; |
| 329 | f32 motion_sensitivity{0.01f}; | 339 | f32 motion_sensitivity{0.01f}; |
diff --git a/src/core/hid/hid_types.h b/src/core/hid/hid_types.h index f12a14cb8..539436283 100644 --- a/src/core/hid/hid_types.h +++ b/src/core/hid/hid_types.h | |||
| @@ -47,9 +47,9 @@ constexpr size_t NpadIdTypeToIndex(NpadIdType npad_id_type) { | |||
| 47 | return 6; | 47 | return 6; |
| 48 | case NpadIdType::Player8: | 48 | case NpadIdType::Player8: |
| 49 | return 7; | 49 | return 7; |
| 50 | case NpadIdType::Other: | ||
| 51 | return 8; | ||
| 52 | case NpadIdType::Handheld: | 50 | case NpadIdType::Handheld: |
| 51 | return 8; | ||
| 52 | case NpadIdType::Other: | ||
| 53 | return 9; | 53 | return 9; |
| 54 | default: | 54 | default: |
| 55 | return 0; | 55 | return 0; |
| @@ -76,9 +76,9 @@ constexpr NpadIdType IndexToNpadIdType(size_t index) { | |||
| 76 | case 7: | 76 | case 7: |
| 77 | return NpadIdType::Player8; | 77 | return NpadIdType::Player8; |
| 78 | case 8: | 78 | case 8: |
| 79 | return NpadIdType::Other; | ||
| 80 | case 9: | ||
| 81 | return NpadIdType::Handheld; | 79 | return NpadIdType::Handheld; |
| 80 | case 9: | ||
| 81 | return NpadIdType::Other; | ||
| 82 | default: | 82 | default: |
| 83 | return NpadIdType::Invalid; | 83 | return NpadIdType::Invalid; |
| 84 | } | 84 | } |
diff --git a/src/core/hle/service/hid/controllers/controller_base.cpp b/src/core/hle/service/hid/controllers/controller_base.cpp index 9d1e6db6a..74a394784 100644 --- a/src/core/hle/service/hid/controllers/controller_base.cpp +++ b/src/core/hle/service/hid/controllers/controller_base.cpp | |||
| @@ -11,7 +11,7 @@ ControllerBase::~ControllerBase() = default; | |||
| 11 | 11 | ||
| 12 | void ControllerBase::ActivateController() { | 12 | void ControllerBase::ActivateController() { |
| 13 | if (is_activated) { | 13 | if (is_activated) { |
| 14 | OnRelease(); | 14 | return; |
| 15 | } | 15 | } |
| 16 | is_activated = true; | 16 | is_activated = true; |
| 17 | OnInit(); | 17 | OnInit(); |
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp index a2e9ddf4d..144abab65 100644 --- a/src/core/hle/service/hid/controllers/npad.cpp +++ b/src/core/hle/service/hid/controllers/npad.cpp | |||
| @@ -125,18 +125,22 @@ void Controller_NPad::ControllerUpdate(Core::HID::ControllerTriggerType type, | |||
| 125 | return; | 125 | return; |
| 126 | } | 126 | } |
| 127 | 127 | ||
| 128 | auto& controller = controller_data[controller_idx]; | ||
| 129 | const auto is_connected = controller.device->IsConnected(); | ||
| 130 | const auto npad_type = controller.device->GetNpadType(); | ||
| 128 | switch (type) { | 131 | switch (type) { |
| 129 | case Core::HID::ControllerTriggerType::Connected: | 132 | case Core::HID::ControllerTriggerType::Connected: |
| 130 | InitNewlyAddedController(controller_idx); | ||
| 131 | break; | ||
| 132 | case Core::HID::ControllerTriggerType::Disconnected: | 133 | case Core::HID::ControllerTriggerType::Disconnected: |
| 133 | DisconnectNpadAtIndex(controller_idx); | 134 | if (is_connected == controller.is_connected) { |
| 135 | return; | ||
| 136 | } | ||
| 137 | UpdateControllerAt(npad_type, controller_idx, is_connected); | ||
| 134 | break; | 138 | break; |
| 135 | case Core::HID::ControllerTriggerType::Type: { | 139 | case Core::HID::ControllerTriggerType::Type: { |
| 136 | auto& controller = controller_data[controller_idx]; | 140 | if (npad_type == controller.npad_type) { |
| 137 | if (controller.device->IsConnected()) { | 141 | return; |
| 138 | LOG_ERROR(Service_HID, "Controller type changed without turning off the controller"); | ||
| 139 | } | 142 | } |
| 143 | // UpdateControllerAt(npad_type, controller_idx, is_connected); | ||
| 140 | break; | 144 | break; |
| 141 | } | 145 | } |
| 142 | default: | 146 | default: |
| @@ -146,6 +150,7 @@ void Controller_NPad::ControllerUpdate(Core::HID::ControllerTriggerType type, | |||
| 146 | 150 | ||
| 147 | void Controller_NPad::InitNewlyAddedController(std::size_t controller_idx) { | 151 | void Controller_NPad::InitNewlyAddedController(std::size_t controller_idx) { |
| 148 | auto& controller = controller_data[controller_idx]; | 152 | auto& controller = controller_data[controller_idx]; |
| 153 | LOG_ERROR(Service_HID, "Connect {} {}", controller_idx, controller.is_connected); | ||
| 149 | const auto controller_type = controller.device->GetNpadType(); | 154 | const auto controller_type = controller.device->GetNpadType(); |
| 150 | auto& shared_memory = controller.shared_memory_entry; | 155 | auto& shared_memory = controller.shared_memory_entry; |
| 151 | if (controller_type == Core::HID::NpadType::None) { | 156 | if (controller_type == Core::HID::NpadType::None) { |
| @@ -235,20 +240,23 @@ void Controller_NPad::InitNewlyAddedController(std::size_t controller_idx) { | |||
| 235 | shared_memory.battery_level_left = battery_level.left.battery_level; | 240 | shared_memory.battery_level_left = battery_level.left.battery_level; |
| 236 | shared_memory.battery_level_right = battery_level.right.battery_level; | 241 | shared_memory.battery_level_right = battery_level.right.battery_level; |
| 237 | 242 | ||
| 243 | controller.is_connected = true; | ||
| 244 | controller.device->Connect(); | ||
| 238 | SignalStyleSetChangedEvent(IndexToNPad(controller_idx)); | 245 | SignalStyleSetChangedEvent(IndexToNPad(controller_idx)); |
| 246 | WriteEmptyEntry(controller.shared_memory_entry); | ||
| 239 | } | 247 | } |
| 240 | 248 | ||
| 241 | void Controller_NPad::OnInit() { | 249 | void Controller_NPad::OnInit() { |
| 250 | if (!IsControllerActivated()) { | ||
| 251 | return; | ||
| 252 | } | ||
| 253 | |||
| 242 | for (std::size_t i = 0; i < controller_data.size(); ++i) { | 254 | for (std::size_t i = 0; i < controller_data.size(); ++i) { |
| 243 | auto& controller = controller_data[i]; | 255 | auto& controller = controller_data[i]; |
| 244 | controller.styleset_changed_event = | 256 | controller.styleset_changed_event = |
| 245 | service_context.CreateEvent(fmt::format("npad:NpadStyleSetChanged_{}", i)); | 257 | service_context.CreateEvent(fmt::format("npad:NpadStyleSetChanged_{}", i)); |
| 246 | } | 258 | } |
| 247 | 259 | ||
| 248 | if (!IsControllerActivated()) { | ||
| 249 | return; | ||
| 250 | } | ||
| 251 | |||
| 252 | if (system.HIDCore().GetSupportedStyleTag().raw == 0) { | 260 | if (system.HIDCore().GetSupportedStyleTag().raw == 0) { |
| 253 | // We want to support all controllers | 261 | // We want to support all controllers |
| 254 | Core::HID::NpadStyleTag style{}; | 262 | Core::HID::NpadStyleTag style{}; |
| @@ -277,20 +285,33 @@ void Controller_NPad::OnInit() { | |||
| 277 | for (auto& controller : controller_data) { | 285 | for (auto& controller : controller_data) { |
| 278 | NPadGenericState dummy_pad_state{}; | 286 | NPadGenericState dummy_pad_state{}; |
| 279 | auto& npad = controller.shared_memory_entry; | 287 | auto& npad = controller.shared_memory_entry; |
| 280 | for (std::size_t i = 0; i < 17; ++i) { | 288 | for (std::size_t i = 0; i < 19; ++i) { |
| 281 | dummy_pad_state.sampling_number = | 289 | WriteEmptyEntry(npad); |
| 282 | npad.fullkey_lifo.ReadCurrentEntry().sampling_number + 1; | ||
| 283 | npad.fullkey_lifo.WriteNextEntry(dummy_pad_state); | ||
| 284 | npad.handheld_lifo.WriteNextEntry(dummy_pad_state); | ||
| 285 | npad.joy_dual_lifo.WriteNextEntry(dummy_pad_state); | ||
| 286 | npad.joy_left_lifo.WriteNextEntry(dummy_pad_state); | ||
| 287 | npad.joy_right_lifo.WriteNextEntry(dummy_pad_state); | ||
| 288 | npad.joy_right_lifo.WriteNextEntry(dummy_pad_state); | ||
| 289 | npad.palma_lifo.WriteNextEntry(dummy_pad_state); | ||
| 290 | } | 290 | } |
| 291 | } | 291 | } |
| 292 | } | 292 | } |
| 293 | 293 | ||
| 294 | void Controller_NPad::WriteEmptyEntry(NpadInternalState& npad) { | ||
| 295 | NPadGenericState dummy_pad_state{}; | ||
| 296 | NpadGcTriggerState dummy_gc_state{}; | ||
| 297 | dummy_pad_state.sampling_number = npad.fullkey_lifo.ReadCurrentEntry().sampling_number + 1; | ||
| 298 | npad.fullkey_lifo.WriteNextEntry(dummy_pad_state); | ||
| 299 | dummy_pad_state.sampling_number = npad.handheld_lifo.ReadCurrentEntry().sampling_number + 1; | ||
| 300 | npad.handheld_lifo.WriteNextEntry(dummy_pad_state); | ||
| 301 | dummy_pad_state.sampling_number = npad.joy_dual_lifo.ReadCurrentEntry().sampling_number + 1; | ||
| 302 | npad.joy_dual_lifo.WriteNextEntry(dummy_pad_state); | ||
| 303 | dummy_pad_state.sampling_number = npad.joy_left_lifo.ReadCurrentEntry().sampling_number + 1; | ||
| 304 | npad.joy_left_lifo.WriteNextEntry(dummy_pad_state); | ||
| 305 | dummy_pad_state.sampling_number = npad.joy_right_lifo.ReadCurrentEntry().sampling_number + 1; | ||
| 306 | npad.joy_right_lifo.WriteNextEntry(dummy_pad_state); | ||
| 307 | dummy_pad_state.sampling_number = npad.palma_lifo.ReadCurrentEntry().sampling_number + 1; | ||
| 308 | npad.palma_lifo.WriteNextEntry(dummy_pad_state); | ||
| 309 | dummy_pad_state.sampling_number = npad.system_ext_lifo.ReadCurrentEntry().sampling_number + 1; | ||
| 310 | npad.system_ext_lifo.WriteNextEntry(dummy_pad_state); | ||
| 311 | dummy_gc_state.sampling_number = npad.gc_trigger_lifo.ReadCurrentEntry().sampling_number + 1; | ||
| 312 | npad.gc_trigger_lifo.WriteNextEntry(dummy_gc_state); | ||
| 313 | } | ||
| 314 | |||
| 294 | void Controller_NPad::OnRelease() { | 315 | void Controller_NPad::OnRelease() { |
| 295 | for (std::size_t i = 0; i < controller_data.size(); ++i) { | 316 | for (std::size_t i = 0; i < controller_data.size(); ++i) { |
| 296 | auto& controller = controller_data[i]; | 317 | auto& controller = controller_data[i]; |
| @@ -359,6 +380,7 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* | |||
| 359 | if (!IsControllerActivated()) { | 380 | if (!IsControllerActivated()) { |
| 360 | return; | 381 | return; |
| 361 | } | 382 | } |
| 383 | |||
| 362 | for (std::size_t i = 0; i < controller_data.size(); ++i) { | 384 | for (std::size_t i = 0; i < controller_data.size(); ++i) { |
| 363 | auto& controller = controller_data[i]; | 385 | auto& controller = controller_data[i]; |
| 364 | auto& npad = controller.shared_memory_entry; | 386 | auto& npad = controller.shared_memory_entry; |
| @@ -366,6 +388,9 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* | |||
| 366 | const auto& controller_type = controller.device->GetNpadType(); | 388 | const auto& controller_type = controller.device->GetNpadType(); |
| 367 | 389 | ||
| 368 | if (controller_type == Core::HID::NpadType::None || !controller.device->IsConnected()) { | 390 | if (controller_type == Core::HID::NpadType::None || !controller.device->IsConnected()) { |
| 391 | // Refresh shared memory | ||
| 392 | std::memcpy(data + NPAD_OFFSET + (i * sizeof(NpadInternalState)), | ||
| 393 | &controller.shared_memory_entry, sizeof(NpadInternalState)); | ||
| 369 | continue; | 394 | continue; |
| 370 | } | 395 | } |
| 371 | const u32 npad_index = static_cast<u32>(i); | 396 | const u32 npad_index = static_cast<u32>(i); |
| @@ -830,14 +855,14 @@ void Controller_NPad::AddNewControllerAt(Core::HID::NpadType controller, std::si | |||
| 830 | 855 | ||
| 831 | void Controller_NPad::UpdateControllerAt(Core::HID::NpadType type, std::size_t npad_index, | 856 | void Controller_NPad::UpdateControllerAt(Core::HID::NpadType type, std::size_t npad_index, |
| 832 | bool connected) { | 857 | bool connected) { |
| 833 | auto& controller = controller_data[npad_index].device; | 858 | auto& controller = controller_data[npad_index]; |
| 834 | if (!connected) { | 859 | if (!connected) { |
| 835 | DisconnectNpadAtIndex(npad_index); | 860 | DisconnectNpadAtIndex(npad_index); |
| 836 | return; | 861 | return; |
| 837 | } | 862 | } |
| 838 | 863 | ||
| 839 | controller->SetNpadType(type); | 864 | controller.device->SetNpadType(type); |
| 840 | controller->Connect(); | 865 | controller.device->Connect(); |
| 841 | InitNewlyAddedController(npad_index); | 866 | InitNewlyAddedController(npad_index); |
| 842 | } | 867 | } |
| 843 | 868 | ||
| @@ -847,14 +872,13 @@ void Controller_NPad::DisconnectNpad(u32 npad_id) { | |||
| 847 | 872 | ||
| 848 | void Controller_NPad::DisconnectNpadAtIndex(std::size_t npad_index) { | 873 | void Controller_NPad::DisconnectNpadAtIndex(std::size_t npad_index) { |
| 849 | auto& controller = controller_data[npad_index]; | 874 | auto& controller = controller_data[npad_index]; |
| 875 | LOG_ERROR(Service_HID, "Disconnect {} {}", npad_index, controller.is_connected); | ||
| 850 | for (std::size_t device_idx = 0; device_idx < controller.vibration.size(); ++device_idx) { | 876 | for (std::size_t device_idx = 0; device_idx < controller.vibration.size(); ++device_idx) { |
| 851 | // Send an empty vibration to stop any vibrations. | 877 | // Send an empty vibration to stop any vibrations. |
| 852 | VibrateControllerAtIndex(npad_index, device_idx, {}); | 878 | VibrateControllerAtIndex(npad_index, device_idx, {}); |
| 853 | controller.vibration[device_idx].device_mounted = false; | 879 | controller.vibration[device_idx].device_mounted = false; |
| 854 | } | 880 | } |
| 855 | 881 | ||
| 856 | controller.device->Disconnect(); | ||
| 857 | |||
| 858 | auto& shared_memory_entry = controller.shared_memory_entry; | 882 | auto& shared_memory_entry = controller.shared_memory_entry; |
| 859 | shared_memory_entry.style_set.raw = 0; // Zero out | 883 | shared_memory_entry.style_set.raw = 0; // Zero out |
| 860 | shared_memory_entry.device_type.raw = 0; | 884 | shared_memory_entry.device_type.raw = 0; |
| @@ -868,7 +892,10 @@ void Controller_NPad::DisconnectNpadAtIndex(std::size_t npad_index) { | |||
| 868 | shared_memory_entry.assignment_mode = NpadJoyAssignmentMode::Dual; | 892 | shared_memory_entry.assignment_mode = NpadJoyAssignmentMode::Dual; |
| 869 | shared_memory_entry.footer_type = AppletFooterUiType::None; | 893 | shared_memory_entry.footer_type = AppletFooterUiType::None; |
| 870 | 894 | ||
| 895 | controller.is_connected = false; | ||
| 896 | controller.device->Disconnect(); | ||
| 871 | SignalStyleSetChangedEvent(IndexToNPad(npad_index)); | 897 | SignalStyleSetChangedEvent(IndexToNPad(npad_index)); |
| 898 | WriteEmptyEntry(controller.shared_memory_entry); | ||
| 872 | } | 899 | } |
| 873 | 900 | ||
| 874 | void Controller_NPad::SetGyroscopeZeroDriftMode(GyroscopeZeroDriftMode drift_mode) { | 901 | void Controller_NPad::SetGyroscopeZeroDriftMode(GyroscopeZeroDriftMode drift_mode) { |
diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h index b0e2f8430..d805ccb97 100644 --- a/src/core/hle/service/hid/controllers/npad.h +++ b/src/core/hle/service/hid/controllers/npad.h | |||
| @@ -417,6 +417,8 @@ private: | |||
| 417 | 417 | ||
| 418 | std::array<VibrationData, 2> vibration{}; | 418 | std::array<VibrationData, 2> vibration{}; |
| 419 | bool unintended_home_button_input_protection{}; | 419 | bool unintended_home_button_input_protection{}; |
| 420 | bool is_connected{}; | ||
| 421 | Core::HID::NpadType npad_type{Core::HID::NpadType::None}; | ||
| 420 | 422 | ||
| 421 | // Current pad state | 423 | // Current pad state |
| 422 | NPadGenericState npad_pad_state{}; | 424 | NPadGenericState npad_pad_state{}; |
| @@ -435,6 +437,7 @@ private: | |||
| 435 | void InitNewlyAddedController(std::size_t controller_idx); | 437 | void InitNewlyAddedController(std::size_t controller_idx); |
| 436 | bool IsControllerSupported(Core::HID::NpadType controller) const; | 438 | bool IsControllerSupported(Core::HID::NpadType controller) const; |
| 437 | void RequestPadStateUpdate(u32 npad_id); | 439 | void RequestPadStateUpdate(u32 npad_id); |
| 440 | void WriteEmptyEntry(NpadInternalState& npad); | ||
| 438 | 441 | ||
| 439 | std::atomic<u32> press_state{}; | 442 | std::atomic<u32> press_state{}; |
| 440 | 443 | ||
diff --git a/src/yuzu/configuration/configure_input.cpp b/src/yuzu/configuration/configure_input.cpp index a8611f77f..67faa8be8 100644 --- a/src/yuzu/configuration/configure_input.cpp +++ b/src/yuzu/configuration/configure_input.cpp | |||
| @@ -114,6 +114,7 @@ void ConfigureInput::Initialize(InputCommon::InputSubsystem* input_subsystem, Co | |||
| 114 | player_tabs[i]->setLayout(new QHBoxLayout(player_tabs[i])); | 114 | player_tabs[i]->setLayout(new QHBoxLayout(player_tabs[i])); |
| 115 | player_tabs[i]->layout()->addWidget(player_controllers[i]); | 115 | player_tabs[i]->layout()->addWidget(player_controllers[i]); |
| 116 | connect(player_controllers[i], &ConfigureInputPlayer::Connected, [&, i](bool is_connected) { | 116 | connect(player_controllers[i], &ConfigureInputPlayer::Connected, [&, i](bool is_connected) { |
| 117 | // Ensures that the controllers are always connected in sequential order | ||
| 117 | if (is_connected) { | 118 | if (is_connected) { |
| 118 | for (std::size_t index = 0; index <= i; ++index) { | 119 | for (std::size_t index = 0; index <= i; ++index) { |
| 119 | player_connected[index]->setChecked(is_connected); | 120 | player_connected[index]->setChecked(is_connected); |
diff --git a/src/yuzu/configuration/configure_input_player.cpp b/src/yuzu/configuration/configure_input_player.cpp index ed9c3facf..81310a5b3 100644 --- a/src/yuzu/configuration/configure_input_player.cpp +++ b/src/yuzu/configuration/configure_input_player.cpp | |||
| @@ -143,8 +143,26 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i | |||
| 143 | timeout_timer(std::make_unique<QTimer>()), poll_timer(std::make_unique<QTimer>()), | 143 | timeout_timer(std::make_unique<QTimer>()), poll_timer(std::make_unique<QTimer>()), |
| 144 | bottom_row(bottom_row), system{system_} { | 144 | bottom_row(bottom_row), system{system_} { |
| 145 | 145 | ||
| 146 | emulated_controller = system_.HIDCore().GetEmulatedControllerByIndex(player_index); | 146 | if (player_index == 0) { |
| 147 | emulated_controller->EnableConfiguration(); | 147 | auto* emulated_controller_p1 = |
| 148 | system.HIDCore().GetEmulatedController(Core::HID::NpadIdType::Player1); | ||
| 149 | auto* emulated_controller_hanheld = | ||
| 150 | system.HIDCore().GetEmulatedController(Core::HID::NpadIdType::Handheld); | ||
| 151 | emulated_controller_p1->SaveCurrentConfig(); | ||
| 152 | emulated_controller_p1->EnableConfiguration(); | ||
| 153 | emulated_controller_hanheld->SaveCurrentConfig(); | ||
| 154 | emulated_controller_hanheld->EnableConfiguration(); | ||
| 155 | if (emulated_controller_hanheld->IsConnected(true)) { | ||
| 156 | emulated_controller_p1->Disconnect(); | ||
| 157 | emulated_controller = emulated_controller_hanheld; | ||
| 158 | } else { | ||
| 159 | emulated_controller = emulated_controller_p1; | ||
| 160 | } | ||
| 161 | } else { | ||
| 162 | emulated_controller = system_.HIDCore().GetEmulatedControllerByIndex(player_index); | ||
| 163 | emulated_controller->SaveCurrentConfig(); | ||
| 164 | emulated_controller->EnableConfiguration(); | ||
| 165 | } | ||
| 148 | ui->setupUi(this); | 166 | ui->setupUi(this); |
| 149 | 167 | ||
| 150 | setFocusPolicy(Qt::ClickFocus); | 168 | setFocusPolicy(Qt::ClickFocus); |
| @@ -460,13 +478,36 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i | |||
| 460 | UpdateControllerEnabledButtons(); | 478 | UpdateControllerEnabledButtons(); |
| 461 | UpdateControllerButtonNames(); | 479 | UpdateControllerButtonNames(); |
| 462 | UpdateMotionButtons(); | 480 | UpdateMotionButtons(); |
| 463 | connect(ui->comboControllerType, qOverload<int>(&QComboBox::currentIndexChanged), [this](int) { | 481 | connect(ui->comboControllerType, qOverload<int>(&QComboBox::currentIndexChanged), [this, player_index](int) { |
| 464 | UpdateControllerAvailableButtons(); | 482 | UpdateControllerAvailableButtons(); |
| 465 | UpdateControllerEnabledButtons(); | 483 | UpdateControllerEnabledButtons(); |
| 466 | UpdateControllerButtonNames(); | 484 | UpdateControllerButtonNames(); |
| 467 | UpdateMotionButtons(); | 485 | UpdateMotionButtons(); |
| 468 | emulated_controller->SetNpadType( | 486 | const Core::HID::NpadType type = GetControllerTypeFromIndex(ui->comboControllerType->currentIndex()); |
| 469 | GetControllerTypeFromIndex(ui->comboControllerType->currentIndex())); | 487 | |
| 488 | if (player_index == 0) { | ||
| 489 | auto* emulated_controller_p1 = | ||
| 490 | system.HIDCore().GetEmulatedController(Core::HID::NpadIdType::Player1); | ||
| 491 | auto* emulated_controller_hanheld = | ||
| 492 | system.HIDCore().GetEmulatedController(Core::HID::NpadIdType::Handheld); | ||
| 493 | bool is_connected = emulated_controller->IsConnected(true); | ||
| 494 | |||
| 495 | emulated_controller_p1->SetNpadType(type); | ||
| 496 | emulated_controller_hanheld->SetNpadType(type); | ||
| 497 | if (is_connected) { | ||
| 498 | if (type == Core::HID::NpadType::Handheld) { | ||
| 499 | emulated_controller_p1->Disconnect(); | ||
| 500 | emulated_controller_hanheld->Connect(); | ||
| 501 | emulated_controller = emulated_controller_hanheld; | ||
| 502 | } else { | ||
| 503 | emulated_controller_hanheld->Disconnect(); | ||
| 504 | emulated_controller_p1->Connect(); | ||
| 505 | emulated_controller = emulated_controller_p1; | ||
| 506 | } | ||
| 507 | } | ||
| 508 | ui->controllerFrame->SetController(emulated_controller); | ||
| 509 | } | ||
| 510 | emulated_controller->SetNpadType(type); | ||
| 470 | }); | 511 | }); |
| 471 | 512 | ||
| 472 | connect(ui->comboDevices, qOverload<int>(&QComboBox::activated), this, | 513 | connect(ui->comboDevices, qOverload<int>(&QComboBox::activated), this, |
| @@ -504,11 +545,35 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i | |||
| 504 | } | 545 | } |
| 505 | 546 | ||
| 506 | ConfigureInputPlayer::~ConfigureInputPlayer() { | 547 | ConfigureInputPlayer::~ConfigureInputPlayer() { |
| 507 | emulated_controller->DisableConfiguration(); | 548 | if (player_index == 0) { |
| 549 | auto* emulated_controller_p1 = | ||
| 550 | system.HIDCore().GetEmulatedController(Core::HID::NpadIdType::Player1); | ||
| 551 | auto* emulated_controller_hanheld = | ||
| 552 | system.HIDCore().GetEmulatedController(Core::HID::NpadIdType::Handheld); | ||
| 553 | emulated_controller_p1->DisableConfiguration(); | ||
| 554 | emulated_controller_hanheld->DisableConfiguration(); | ||
| 555 | } else { | ||
| 556 | emulated_controller->DisableConfiguration(); | ||
| 557 | } | ||
| 508 | }; | 558 | }; |
| 509 | 559 | ||
| 510 | void ConfigureInputPlayer::ApplyConfiguration() { | 560 | void ConfigureInputPlayer::ApplyConfiguration() { |
| 561 | if (player_index == 0) { | ||
| 562 | auto* emulated_controller_p1 = | ||
| 563 | system.HIDCore().GetEmulatedController(Core::HID::NpadIdType::Player1); | ||
| 564 | auto* emulated_controller_hanheld = | ||
| 565 | system.HIDCore().GetEmulatedController(Core::HID::NpadIdType::Handheld); | ||
| 566 | emulated_controller_p1->DisableConfiguration(); | ||
| 567 | emulated_controller_p1->SaveCurrentConfig(); | ||
| 568 | emulated_controller_p1->EnableConfiguration(); | ||
| 569 | emulated_controller_hanheld->DisableConfiguration(); | ||
| 570 | emulated_controller_hanheld->SaveCurrentConfig(); | ||
| 571 | emulated_controller_hanheld->EnableConfiguration(); | ||
| 572 | return; | ||
| 573 | } | ||
| 574 | emulated_controller->DisableConfiguration(); | ||
| 511 | emulated_controller->SaveCurrentConfig(); | 575 | emulated_controller->SaveCurrentConfig(); |
| 576 | emulated_controller->EnableConfiguration(); | ||
| 512 | } | 577 | } |
| 513 | 578 | ||
| 514 | void ConfigureInputPlayer::showEvent(QShowEvent* event) { | 579 | void ConfigureInputPlayer::showEvent(QShowEvent* event) { |
| @@ -535,9 +600,9 @@ void ConfigureInputPlayer::RetranslateUI() { | |||
| 535 | void ConfigureInputPlayer::LoadConfiguration() { | 600 | void ConfigureInputPlayer::LoadConfiguration() { |
| 536 | UpdateUI(); | 601 | UpdateUI(); |
| 537 | UpdateInputDeviceCombobox(); | 602 | UpdateInputDeviceCombobox(); |
| 538 | const int comboBoxIndex = GetIndexFromControllerType(emulated_controller->GetNpadType()); | 603 | const int comboBoxIndex = GetIndexFromControllerType(emulated_controller->GetNpadType(true)); |
| 539 | ui->comboControllerType->setCurrentIndex(comboBoxIndex); | 604 | ui->comboControllerType->setCurrentIndex(comboBoxIndex); |
| 540 | ui->groupConnectedController->setChecked(emulated_controller->IsConnected()); | 605 | ui->groupConnectedController->setChecked(emulated_controller->IsConnected(true)); |
| 541 | } | 606 | } |
| 542 | 607 | ||
| 543 | void ConfigureInputPlayer::ConnectPlayer(bool connected) { | 608 | void ConfigureInputPlayer::ConnectPlayer(bool connected) { |
diff --git a/src/yuzu/configuration/configure_input_player_widget.cpp b/src/yuzu/configuration/configure_input_player_widget.cpp index 446b72e55..3b79b6076 100644 --- a/src/yuzu/configuration/configure_input_player_widget.cpp +++ b/src/yuzu/configuration/configure_input_player_widget.cpp | |||
| @@ -145,7 +145,7 @@ void PlayerControlPreview::ControllerUpdate(Core::HID::ControllerTriggerType typ | |||
| 145 | needs_redraw = true; | 145 | needs_redraw = true; |
| 146 | break; | 146 | break; |
| 147 | case Core::HID::ControllerTriggerType::Type: | 147 | case Core::HID::ControllerTriggerType::Type: |
| 148 | controller_type = controller->GetNpadType(); | 148 | controller_type = controller->GetNpadType(true); |
| 149 | needs_redraw = true; | 149 | needs_redraw = true; |
| 150 | break; | 150 | break; |
| 151 | case Core::HID::ControllerTriggerType::Color: | 151 | case Core::HID::ControllerTriggerType::Color: |