فهرست منبع

service/hid: Match shared memory closer to HW

german77 4 سال پیش
والد
کامیت
e2e5f1beaf
2فایلهای تغییر یافته به همراه75 افزوده شده و 26 حذف شده
  1. 40 18
      src/core/hle/service/hid/controllers/npad.cpp
  2. 35 8
      src/core/hle/service/hid/controllers/npad.h

+ 40 - 18
src/core/hle/service/hid/controllers/npad.cpp

@@ -123,8 +123,8 @@ Controller_NPad::~Controller_NPad() {
 void Controller_NPad::ControllerUpdate(Core::HID::ControllerTriggerType type,
 void Controller_NPad::ControllerUpdate(Core::HID::ControllerTriggerType type,
                                        std::size_t controller_idx) {
                                        std::size_t controller_idx) {
     if (type == Core::HID::ControllerTriggerType::All) {
     if (type == Core::HID::ControllerTriggerType::All) {
-        ControllerUpdate(Core::HID::ControllerTriggerType::Type, controller_idx);
         ControllerUpdate(Core::HID::ControllerTriggerType::Connected, controller_idx);
         ControllerUpdate(Core::HID::ControllerTriggerType::Connected, controller_idx);
+        ControllerUpdate(Core::HID::ControllerTriggerType::Battery, controller_idx);
         return;
         return;
     }
     }
 
 
@@ -139,11 +139,15 @@ void Controller_NPad::ControllerUpdate(Core::HID::ControllerTriggerType type,
         }
         }
         UpdateControllerAt(npad_type, controller_idx, is_connected);
         UpdateControllerAt(npad_type, controller_idx, is_connected);
         break;
         break;
-    case Core::HID::ControllerTriggerType::Type: {
-        if (npad_type == controller.npad_type) {
+    case Core::HID::ControllerTriggerType::Battery: {
+        if (!controller.is_connected) {
             return;
             return;
         }
         }
-        // UpdateControllerAt(npad_type, controller_idx, is_connected);
+        auto& shared_memory = controller.shared_memory_entry;
+        const auto& battery_level = controller.device->GetBattery();
+        shared_memory.battery_level_dual = battery_level.dual.battery_level;
+        shared_memory.battery_level_left = battery_level.left.battery_level;
+        shared_memory.battery_level_right = battery_level.right.battery_level;
         break;
         break;
     }
     }
     default:
     default:
@@ -153,7 +157,7 @@ void Controller_NPad::ControllerUpdate(Core::HID::ControllerTriggerType type,
 
 
 void Controller_NPad::InitNewlyAddedController(std::size_t controller_idx) {
 void Controller_NPad::InitNewlyAddedController(std::size_t controller_idx) {
     auto& controller = controller_data[controller_idx];
     auto& controller = controller_data[controller_idx];
-    LOG_ERROR(Service_HID, "Connect {} {}", controller_idx, controller.is_connected);
+    LOG_WARNING(Service_HID, "Connect {} {}", controller_idx, controller.is_connected);
     const auto controller_type = controller.device->GetNpadType();
     const auto controller_type = controller.device->GetNpadType();
     auto& shared_memory = controller.shared_memory_entry;
     auto& shared_memory = controller.shared_memory_entry;
     if (controller_type == Core::HID::NpadType::None) {
     if (controller_type == Core::HID::NpadType::None) {
@@ -277,20 +281,29 @@ void Controller_NPad::OnInit() {
     std::memcpy(supported_npad_id_types.data(), npad_id_list.data(),
     std::memcpy(supported_npad_id_types.data(), npad_id_list.data(),
                 npad_id_list.size() * sizeof(u32));
                 npad_id_list.size() * sizeof(u32));
 
 
-    for (std::size_t i = 0; i < controller_data.size(); ++i) {
-        auto& controller = controller_data[i].device;
-        if (controller->IsConnected()) {
-            AddNewControllerAt(controller->GetNpadType(), i);
-        }
-    }
-
     // Prefill controller buffers
     // Prefill controller buffers
     for (auto& controller : controller_data) {
     for (auto& controller : controller_data) {
         auto& npad = controller.shared_memory_entry;
         auto& npad = controller.shared_memory_entry;
+        npad.fullkey_color = {
+            .attribute = ColorAttribute::NoController,
+        };
+        npad.joycon_color = {
+            .attribute = ColorAttribute::NoController,
+        };
+        // HW seems to initialize the first 19 entries
         for (std::size_t i = 0; i < 19; ++i) {
         for (std::size_t i = 0; i < 19; ++i) {
             WriteEmptyEntry(npad);
             WriteEmptyEntry(npad);
         }
         }
     }
     }
+
+    // Connect controllers
+    for (auto& controller : controller_data) {
+        const auto& device = controller.device;
+        if (device->IsConnected()) {
+            const std::size_t index = Core::HID::NpadIdTypeToIndex(device->GetNpadIdType());
+            AddNewControllerAt(device->GetNpadType(), index);
+        }
+    }
 }
 }
 
 
 void Controller_NPad::WriteEmptyEntry(NpadInternalState& npad) {
 void Controller_NPad::WriteEmptyEntry(NpadInternalState& npad) {
@@ -618,8 +631,14 @@ void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing
         sixaxis_right_lifo_state.sampling_number =
         sixaxis_right_lifo_state.sampling_number =
             npad.sixaxis_right_lifo.ReadCurrentEntry().state.sampling_number + 1;
             npad.sixaxis_right_lifo.ReadCurrentEntry().state.sampling_number + 1;
 
 
-        npad.sixaxis_fullkey_lifo.WriteNextEntry(sixaxis_fullkey_state);
-        npad.sixaxis_handheld_lifo.WriteNextEntry(sixaxis_handheld_state);
+        if (Core::HID::IndexToNpadIdType(i) == Core::HID::NpadIdType::Handheld) {
+            // This buffer only is updated on handheld on HW
+            npad.sixaxis_handheld_lifo.WriteNextEntry(sixaxis_handheld_state);
+        } else {
+            // Hanheld doesn't update this buffer on HW
+            npad.sixaxis_fullkey_lifo.WriteNextEntry(sixaxis_fullkey_state);
+        }
+
         npad.sixaxis_dual_left_lifo.WriteNextEntry(sixaxis_dual_left_state);
         npad.sixaxis_dual_left_lifo.WriteNextEntry(sixaxis_dual_left_state);
         npad.sixaxis_dual_right_lifo.WriteNextEntry(sixaxis_dual_right_state);
         npad.sixaxis_dual_right_lifo.WriteNextEntry(sixaxis_dual_right_state);
         npad.sixaxis_left_lifo.WriteNextEntry(sixaxis_left_lifo_state);
         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
     }
     }
 
 
     controller.device->SetNpadType(type);
     controller.device->SetNpadType(type);
-    controller.device->Connect();
     InitNewlyAddedController(npad_index);
     InitNewlyAddedController(npad_index);
 }
 }
 
 
@@ -874,7 +892,7 @@ void Controller_NPad::DisconnectNpad(u32 npad_id) {
 
 
 void Controller_NPad::DisconnectNpadAtIndex(std::size_t npad_index) {
 void Controller_NPad::DisconnectNpadAtIndex(std::size_t npad_index) {
     auto& controller = controller_data[npad_index];
     auto& controller = controller_data[npad_index];
-    LOG_ERROR(Service_HID, "Disconnect {} {}", npad_index, controller.is_connected);
+    LOG_WARNING(Service_HID, "Disconnect {} {}", npad_index, controller.is_connected);
     for (std::size_t device_idx = 0; device_idx < controller.vibration.size(); ++device_idx) {
     for (std::size_t device_idx = 0; device_idx < controller.vibration.size(); ++device_idx) {
         // Send an empty vibration to stop any vibrations.
         // Send an empty vibration to stop any vibrations.
         VibrateControllerAtIndex(npad_index, device_idx, {});
         VibrateControllerAtIndex(npad_index, device_idx, {});
@@ -889,8 +907,12 @@ void Controller_NPad::DisconnectNpadAtIndex(std::size_t npad_index) {
     shared_memory_entry.battery_level_dual = 0;
     shared_memory_entry.battery_level_dual = 0;
     shared_memory_entry.battery_level_left = 0;
     shared_memory_entry.battery_level_left = 0;
     shared_memory_entry.battery_level_right = 0;
     shared_memory_entry.battery_level_right = 0;
-    shared_memory_entry.fullkey_color = {};
-    shared_memory_entry.joycon_color = {};
+    shared_memory_entry.fullkey_color = {
+        .attribute = ColorAttribute::NoController,
+    };
+    shared_memory_entry.joycon_color = {
+        .attribute = ColorAttribute::NoController,
+    };
     shared_memory_entry.assignment_mode = NpadJoyAssignmentMode::Dual;
     shared_memory_entry.assignment_mode = NpadJoyAssignmentMode::Dual;
     shared_memory_entry.footer_type = AppletFooterUiType::None;
     shared_memory_entry.footer_type = AppletFooterUiType::None;
 
 

+ 35 - 8
src/core/hle/service/hid/controllers/npad.h

@@ -334,10 +334,7 @@ private:
         };
         };
     };
     };
 
 
-    struct NfcXcdHandle {
-        INSERT_PADDING_BYTES(0x60);
-    };
-
+    // This is nn::hid::system::AppletFooterUiAttributesSet
     struct AppletFooterUiAttributes {
     struct AppletFooterUiAttributes {
         INSERT_PADDING_BYTES(0x4);
         INSERT_PADDING_BYTES(0x4);
     };
     };
@@ -368,6 +365,31 @@ private:
         Lagon = 21,
         Lagon = 21,
     };
     };
 
 
+    // This is nn::hid::NpadLarkType
+    enum class NpadLarkType : u32 {
+        Invalid,
+        H1,
+        H2,
+        NL,
+        NR,
+    };
+
+    // This is nn::hid::NpadLuciaType
+    enum class NpadLuciaType : u32 {
+        Invalid,
+        J,
+        E,
+        U,
+    };
+
+    // This is nn::hid::NpadLagerType
+    enum class NpadLagerType : u32 {
+        Invalid,
+        J,
+        E,
+        U,
+    };
+
     // This is nn::hid::detail::NpadInternalState
     // This is nn::hid::detail::NpadInternalState
     struct NpadInternalState {
     struct NpadInternalState {
         Core::HID::NpadStyleTag style_set;
         Core::HID::NpadStyleTag style_set;
@@ -396,11 +418,16 @@ private:
         Core::HID::BatteryLevel battery_level_right;
         Core::HID::BatteryLevel battery_level_right;
         AppletFooterUiAttributes footer_attributes;
         AppletFooterUiAttributes footer_attributes;
         AppletFooterUiType footer_type;
         AppletFooterUiType footer_type;
-        // nfc_states needs to be checked switchbrew doesn't match with HW
-        NfcXcdHandle nfc_states;
-        INSERT_PADDING_BYTES(0x18); // Unknown
+        // GetXcdHandleForNpadWithNfc needs to be checked switchbrew doesn't match with HW
+        INSERT_PADDING_BYTES(0x78); // Unknown
         Lifo<NpadGcTriggerState> gc_trigger_lifo;
         Lifo<NpadGcTriggerState> gc_trigger_lifo;
-        INSERT_PADDING_BYTES(0xc1f); // Unknown
+        NpadLarkType lark_type_l;
+        NpadLarkType lark_type_r;
+        NpadLuciaType lucia_type;
+        NpadLagerType lager_type;
+        INSERT_PADDING_BYTES(
+            0x8); // FW 13.x Investigate there is some sort of bitflag related to joycons
+        INSERT_PADDING_BYTES(0xc08); // Unknown
     };
     };
     static_assert(sizeof(NpadInternalState) == 0x5000, "NpadInternalState is an invalid size");
     static_assert(sizeof(NpadInternalState) == 0x5000, "NpadInternalState is an invalid size");