diff options
| author | 2021-10-22 22:31:37 -0500 | |
|---|---|---|
| committer | 2021-11-24 20:30:25 -0600 | |
| commit | e2e5f1beaf602f801bdd93d24c3cfc7862131890 (patch) | |
| tree | 020378385434e581ee1e236db7f231a7d4338897 | |
| parent | yuzu: Fix loading input profiles (diff) | |
| download | yuzu-e2e5f1beaf602f801bdd93d24c3cfc7862131890.tar.gz yuzu-e2e5f1beaf602f801bdd93d24c3cfc7862131890.tar.xz yuzu-e2e5f1beaf602f801bdd93d24c3cfc7862131890.zip | |
service/hid: Match shared memory closer to HW
| -rw-r--r-- | src/core/hle/service/hid/controllers/npad.cpp | 58 | ||||
| -rw-r--r-- | src/core/hle/service/hid/controllers/npad.h | 43 |
2 files changed, 75 insertions, 26 deletions
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp index 62b324080..aad298364 100644 --- a/src/core/hle/service/hid/controllers/npad.cpp +++ b/src/core/hle/service/hid/controllers/npad.cpp | |||
| @@ -123,8 +123,8 @@ Controller_NPad::~Controller_NPad() { | |||
| 123 | void Controller_NPad::ControllerUpdate(Core::HID::ControllerTriggerType type, | 123 | void Controller_NPad::ControllerUpdate(Core::HID::ControllerTriggerType type, |
| 124 | std::size_t controller_idx) { | 124 | std::size_t controller_idx) { |
| 125 | if (type == Core::HID::ControllerTriggerType::All) { | 125 | if (type == Core::HID::ControllerTriggerType::All) { |
| 126 | ControllerUpdate(Core::HID::ControllerTriggerType::Type, controller_idx); | ||
| 127 | ControllerUpdate(Core::HID::ControllerTriggerType::Connected, controller_idx); | 126 | ControllerUpdate(Core::HID::ControllerTriggerType::Connected, controller_idx); |
| 127 | ControllerUpdate(Core::HID::ControllerTriggerType::Battery, controller_idx); | ||
| 128 | return; | 128 | return; |
| 129 | } | 129 | } |
| 130 | 130 | ||
| @@ -139,11 +139,15 @@ void Controller_NPad::ControllerUpdate(Core::HID::ControllerTriggerType type, | |||
| 139 | } | 139 | } |
| 140 | UpdateControllerAt(npad_type, controller_idx, is_connected); | 140 | UpdateControllerAt(npad_type, controller_idx, is_connected); |
| 141 | break; | 141 | break; |
| 142 | case Core::HID::ControllerTriggerType::Type: { | 142 | case Core::HID::ControllerTriggerType::Battery: { |
| 143 | if (npad_type == controller.npad_type) { | 143 | if (!controller.is_connected) { |
| 144 | return; | 144 | return; |
| 145 | } | 145 | } |
| 146 | // UpdateControllerAt(npad_type, controller_idx, is_connected); | 146 | auto& shared_memory = controller.shared_memory_entry; |
| 147 | const auto& battery_level = controller.device->GetBattery(); | ||
| 148 | shared_memory.battery_level_dual = battery_level.dual.battery_level; | ||
| 149 | shared_memory.battery_level_left = battery_level.left.battery_level; | ||
| 150 | shared_memory.battery_level_right = battery_level.right.battery_level; | ||
| 147 | break; | 151 | break; |
| 148 | } | 152 | } |
| 149 | default: | 153 | default: |
| @@ -153,7 +157,7 @@ void Controller_NPad::ControllerUpdate(Core::HID::ControllerTriggerType type, | |||
| 153 | 157 | ||
| 154 | void Controller_NPad::InitNewlyAddedController(std::size_t controller_idx) { | 158 | void Controller_NPad::InitNewlyAddedController(std::size_t controller_idx) { |
| 155 | auto& controller = controller_data[controller_idx]; | 159 | auto& controller = controller_data[controller_idx]; |
| 156 | LOG_ERROR(Service_HID, "Connect {} {}", controller_idx, controller.is_connected); | 160 | LOG_WARNING(Service_HID, "Connect {} {}", controller_idx, controller.is_connected); |
| 157 | const auto controller_type = controller.device->GetNpadType(); | 161 | const auto controller_type = controller.device->GetNpadType(); |
| 158 | auto& shared_memory = controller.shared_memory_entry; | 162 | auto& shared_memory = controller.shared_memory_entry; |
| 159 | if (controller_type == Core::HID::NpadType::None) { | 163 | if (controller_type == Core::HID::NpadType::None) { |
| @@ -277,20 +281,29 @@ void Controller_NPad::OnInit() { | |||
| 277 | std::memcpy(supported_npad_id_types.data(), npad_id_list.data(), | 281 | std::memcpy(supported_npad_id_types.data(), npad_id_list.data(), |
| 278 | npad_id_list.size() * sizeof(u32)); | 282 | npad_id_list.size() * sizeof(u32)); |
| 279 | 283 | ||
| 280 | for (std::size_t i = 0; i < controller_data.size(); ++i) { | ||
| 281 | auto& controller = controller_data[i].device; | ||
| 282 | if (controller->IsConnected()) { | ||
| 283 | AddNewControllerAt(controller->GetNpadType(), i); | ||
| 284 | } | ||
| 285 | } | ||
| 286 | |||
| 287 | // Prefill controller buffers | 284 | // Prefill controller buffers |
| 288 | for (auto& controller : controller_data) { | 285 | for (auto& controller : controller_data) { |
| 289 | auto& npad = controller.shared_memory_entry; | 286 | auto& npad = controller.shared_memory_entry; |
| 287 | npad.fullkey_color = { | ||
| 288 | .attribute = ColorAttribute::NoController, | ||
| 289 | }; | ||
| 290 | npad.joycon_color = { | ||
| 291 | .attribute = ColorAttribute::NoController, | ||
| 292 | }; | ||
| 293 | // HW seems to initialize the first 19 entries | ||
| 290 | for (std::size_t i = 0; i < 19; ++i) { | 294 | for (std::size_t i = 0; i < 19; ++i) { |
| 291 | WriteEmptyEntry(npad); | 295 | WriteEmptyEntry(npad); |
| 292 | } | 296 | } |
| 293 | } | 297 | } |
| 298 | |||
| 299 | // Connect controllers | ||
| 300 | for (auto& controller : controller_data) { | ||
| 301 | const auto& device = controller.device; | ||
| 302 | if (device->IsConnected()) { | ||
| 303 | const std::size_t index = Core::HID::NpadIdTypeToIndex(device->GetNpadIdType()); | ||
| 304 | AddNewControllerAt(device->GetNpadType(), index); | ||
| 305 | } | ||
| 306 | } | ||
| 294 | } | 307 | } |
| 295 | 308 | ||
| 296 | void Controller_NPad::WriteEmptyEntry(NpadInternalState& npad) { | 309 | void Controller_NPad::WriteEmptyEntry(NpadInternalState& npad) { |
| @@ -618,8 +631,14 @@ void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing | |||
| 618 | sixaxis_right_lifo_state.sampling_number = | 631 | sixaxis_right_lifo_state.sampling_number = |
| 619 | npad.sixaxis_right_lifo.ReadCurrentEntry().state.sampling_number + 1; | 632 | npad.sixaxis_right_lifo.ReadCurrentEntry().state.sampling_number + 1; |
| 620 | 633 | ||
| 621 | npad.sixaxis_fullkey_lifo.WriteNextEntry(sixaxis_fullkey_state); | 634 | if (Core::HID::IndexToNpadIdType(i) == Core::HID::NpadIdType::Handheld) { |
| 622 | npad.sixaxis_handheld_lifo.WriteNextEntry(sixaxis_handheld_state); | 635 | // This buffer only is updated on handheld on HW |
| 636 | npad.sixaxis_handheld_lifo.WriteNextEntry(sixaxis_handheld_state); | ||
| 637 | } else { | ||
| 638 | // Hanheld doesn't update this buffer on HW | ||
| 639 | npad.sixaxis_fullkey_lifo.WriteNextEntry(sixaxis_fullkey_state); | ||
| 640 | } | ||
| 641 | |||
| 623 | npad.sixaxis_dual_left_lifo.WriteNextEntry(sixaxis_dual_left_state); | 642 | npad.sixaxis_dual_left_lifo.WriteNextEntry(sixaxis_dual_left_state); |
| 624 | npad.sixaxis_dual_right_lifo.WriteNextEntry(sixaxis_dual_right_state); | 643 | npad.sixaxis_dual_right_lifo.WriteNextEntry(sixaxis_dual_right_state); |
| 625 | npad.sixaxis_left_lifo.WriteNextEntry(sixaxis_left_lifo_state); | 644 | npad.sixaxis_left_lifo.WriteNextEntry(sixaxis_left_lifo_state); |
| @@ -864,7 +883,6 @@ void Controller_NPad::UpdateControllerAt(Core::HID::NpadType type, std::size_t n | |||
| 864 | } | 883 | } |
| 865 | 884 | ||
| 866 | controller.device->SetNpadType(type); | 885 | controller.device->SetNpadType(type); |
| 867 | controller.device->Connect(); | ||
| 868 | InitNewlyAddedController(npad_index); | 886 | InitNewlyAddedController(npad_index); |
| 869 | } | 887 | } |
| 870 | 888 | ||
| @@ -874,7 +892,7 @@ void Controller_NPad::DisconnectNpad(u32 npad_id) { | |||
| 874 | 892 | ||
| 875 | void Controller_NPad::DisconnectNpadAtIndex(std::size_t npad_index) { | 893 | void Controller_NPad::DisconnectNpadAtIndex(std::size_t npad_index) { |
| 876 | auto& controller = controller_data[npad_index]; | 894 | auto& controller = controller_data[npad_index]; |
| 877 | LOG_ERROR(Service_HID, "Disconnect {} {}", npad_index, controller.is_connected); | 895 | LOG_WARNING(Service_HID, "Disconnect {} {}", npad_index, controller.is_connected); |
| 878 | for (std::size_t device_idx = 0; device_idx < controller.vibration.size(); ++device_idx) { | 896 | for (std::size_t device_idx = 0; device_idx < controller.vibration.size(); ++device_idx) { |
| 879 | // Send an empty vibration to stop any vibrations. | 897 | // Send an empty vibration to stop any vibrations. |
| 880 | VibrateControllerAtIndex(npad_index, device_idx, {}); | 898 | VibrateControllerAtIndex(npad_index, device_idx, {}); |
| @@ -889,8 +907,12 @@ void Controller_NPad::DisconnectNpadAtIndex(std::size_t npad_index) { | |||
| 889 | shared_memory_entry.battery_level_dual = 0; | 907 | shared_memory_entry.battery_level_dual = 0; |
| 890 | shared_memory_entry.battery_level_left = 0; | 908 | shared_memory_entry.battery_level_left = 0; |
| 891 | shared_memory_entry.battery_level_right = 0; | 909 | shared_memory_entry.battery_level_right = 0; |
| 892 | shared_memory_entry.fullkey_color = {}; | 910 | shared_memory_entry.fullkey_color = { |
| 893 | shared_memory_entry.joycon_color = {}; | 911 | .attribute = ColorAttribute::NoController, |
| 912 | }; | ||
| 913 | shared_memory_entry.joycon_color = { | ||
| 914 | .attribute = ColorAttribute::NoController, | ||
| 915 | }; | ||
| 894 | shared_memory_entry.assignment_mode = NpadJoyAssignmentMode::Dual; | 916 | shared_memory_entry.assignment_mode = NpadJoyAssignmentMode::Dual; |
| 895 | shared_memory_entry.footer_type = AppletFooterUiType::None; | 917 | shared_memory_entry.footer_type = AppletFooterUiType::None; |
| 896 | 918 | ||
diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h index 1c6ea6f88..7c534a32f 100644 --- a/src/core/hle/service/hid/controllers/npad.h +++ b/src/core/hle/service/hid/controllers/npad.h | |||
| @@ -334,10 +334,7 @@ private: | |||
| 334 | }; | 334 | }; |
| 335 | }; | 335 | }; |
| 336 | 336 | ||
| 337 | struct NfcXcdHandle { | 337 | // This is nn::hid::system::AppletFooterUiAttributesSet |
| 338 | INSERT_PADDING_BYTES(0x60); | ||
| 339 | }; | ||
| 340 | |||
| 341 | struct AppletFooterUiAttributes { | 338 | struct AppletFooterUiAttributes { |
| 342 | INSERT_PADDING_BYTES(0x4); | 339 | INSERT_PADDING_BYTES(0x4); |
| 343 | }; | 340 | }; |
| @@ -368,6 +365,31 @@ private: | |||
| 368 | Lagon = 21, | 365 | Lagon = 21, |
| 369 | }; | 366 | }; |
| 370 | 367 | ||
| 368 | // This is nn::hid::NpadLarkType | ||
| 369 | enum class NpadLarkType : u32 { | ||
| 370 | Invalid, | ||
| 371 | H1, | ||
| 372 | H2, | ||
| 373 | NL, | ||
| 374 | NR, | ||
| 375 | }; | ||
| 376 | |||
| 377 | // This is nn::hid::NpadLuciaType | ||
| 378 | enum class NpadLuciaType : u32 { | ||
| 379 | Invalid, | ||
| 380 | J, | ||
| 381 | E, | ||
| 382 | U, | ||
| 383 | }; | ||
| 384 | |||
| 385 | // This is nn::hid::NpadLagerType | ||
| 386 | enum class NpadLagerType : u32 { | ||
| 387 | Invalid, | ||
| 388 | J, | ||
| 389 | E, | ||
| 390 | U, | ||
| 391 | }; | ||
| 392 | |||
| 371 | // This is nn::hid::detail::NpadInternalState | 393 | // This is nn::hid::detail::NpadInternalState |
| 372 | struct NpadInternalState { | 394 | struct NpadInternalState { |
| 373 | Core::HID::NpadStyleTag style_set; | 395 | Core::HID::NpadStyleTag style_set; |
| @@ -396,11 +418,16 @@ private: | |||
| 396 | Core::HID::BatteryLevel battery_level_right; | 418 | Core::HID::BatteryLevel battery_level_right; |
| 397 | AppletFooterUiAttributes footer_attributes; | 419 | AppletFooterUiAttributes footer_attributes; |
| 398 | AppletFooterUiType footer_type; | 420 | AppletFooterUiType footer_type; |
| 399 | // nfc_states needs to be checked switchbrew doesn't match with HW | 421 | // GetXcdHandleForNpadWithNfc needs to be checked switchbrew doesn't match with HW |
| 400 | NfcXcdHandle nfc_states; | 422 | INSERT_PADDING_BYTES(0x78); // Unknown |
| 401 | INSERT_PADDING_BYTES(0x18); // Unknown | ||
| 402 | Lifo<NpadGcTriggerState> gc_trigger_lifo; | 423 | Lifo<NpadGcTriggerState> gc_trigger_lifo; |
| 403 | INSERT_PADDING_BYTES(0xc1f); // Unknown | 424 | NpadLarkType lark_type_l; |
| 425 | NpadLarkType lark_type_r; | ||
| 426 | NpadLuciaType lucia_type; | ||
| 427 | NpadLagerType lager_type; | ||
| 428 | INSERT_PADDING_BYTES( | ||
| 429 | 0x8); // FW 13.x Investigate there is some sort of bitflag related to joycons | ||
| 430 | INSERT_PADDING_BYTES(0xc08); // Unknown | ||
| 404 | }; | 431 | }; |
| 405 | static_assert(sizeof(NpadInternalState) == 0x5000, "NpadInternalState is an invalid size"); | 432 | static_assert(sizeof(NpadInternalState) == 0x5000, "NpadInternalState is an invalid size"); |
| 406 | 433 | ||