diff options
| author | 2021-10-18 23:15:46 -0500 | |
|---|---|---|
| committer | 2021-11-24 20:30:24 -0600 | |
| commit | 4d308fd0b4fc8f14754c47811e751bf068b330b8 (patch) | |
| tree | 3ea29a0c024fdc9ad7681aaf6160e46511ceb2a6 /src/core/hle | |
| parent | core/hid: Documment some files (diff) | |
| download | yuzu-4d308fd0b4fc8f14754c47811e751bf068b330b8.tar.gz yuzu-4d308fd0b4fc8f14754c47811e751bf068b330b8.tar.xz yuzu-4d308fd0b4fc8f14754c47811e751bf068b330b8.zip | |
hid: Fix controller connection/disconnection
Diffstat (limited to 'src/core/hle')
| -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 |
3 files changed, 56 insertions, 26 deletions
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 | ||