diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp index 282953bab2..069e0d5dec 100644 --- a/src/core/hle/service/hid/controllers/npad.cpp +++ b/src/core/hle/service/hid/controllers/npad.cpp @@ -41,6 +41,7 @@ void Controller_NPad::InitNewlyAddedControler(std::size_t controller_idx) { controller.joy_styles.raw = 0; // Zero out controller.device_type.raw = 0; switch (controller_type) { + case NPadControllerType::HandheldVariant: case NPadControllerType::Handheld: controller.joy_styles.handheld.Assign(1); controller.device_type.handheld.Assign(1); @@ -220,9 +221,12 @@ void Controller_NPad::OnUpdate(u8* data, std::size_t data_len) { } switch (controller_type) { + case NPadControllerType::HandheldVariant: case NPadControllerType::Handheld: handheld_entry.connection_status.IsConnected.Assign(1); - handheld_entry.connection_status.IsWired.Assign(1); + if (!Settings::values.use_docked_mode) { + handheld_entry.connection_status.IsWired.Assign(1); + } handheld_entry.pad_states.raw = pad_state.raw; handheld_entry.l_stick = lstick_entry; handheld_entry.r_stick = rstick_entry; @@ -334,7 +338,7 @@ void Controller_NPad::AddNewController(NPadControllerType controller) { LOG_ERROR(Service_HID, "Cannot connect any more controllers!"); return; } - if (controller == NPadControllerType::Handheld) { + if (controller == NPadControllerType::HandheldVariant) { connected_controllers[8] = {controller, true}; InitNewlyAddedControler(8); return; @@ -354,4 +358,32 @@ void Controller_NPad::DisconnectNPad(u32 npad_id) { return; connected_controllers[npad_id].is_connected = false; } + +Controller_NPad::LedPattern Controller_NPad::GetLedPattern(u32 npad_id) { + if (npad_id == npad_id_list.back() || npad_id == npad_id_list[npad_id_list.size() - 2]) { + // These are controllers without led patterns + return LedPattern{0, 0, 0, 0}; + } + switch (npad_id) { + case 0: + return LedPattern{1, 0, 0, 0}; + case 1: + return LedPattern{0, 1, 0, 0}; + case 2: + return LedPattern{0, 0, 1, 0}; + case 3: + return LedPattern{0, 0, 0, 1}; + case 4: + return LedPattern{1, 0, 0, 1}; + case 5: + return LedPattern{1, 0, 1, 0}; + case 6: + return LedPattern{1, 0, 1, 1}; + case 7: + return LedPattern{0, 1, 1, 0}; + default: + UNIMPLEMENTED_MSG("Unhandled npad_id {}", npad_id); + return LedPattern{0, 0, 0, 0}; + }; +} } // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h index 86ab0e4290..28c89768c1 100644 --- a/src/core/hle/service/hid/controllers/npad.h +++ b/src/core/hle/service/hid/controllers/npad.h @@ -65,12 +65,29 @@ public: None, ProController, Handheld, + HandheldVariant, // Games which require the handheld controller to be at index 8 JoyLeft, JoyRight, Tabletop, Pokeball, }; + struct LedPattern { + explicit LedPattern(u64 light1, u64 light2, u64 light3, u64 light4) { + position1.Assign(light1); + position1.Assign(light2); + position1.Assign(light3); + position1.Assign(light4); + }; + union { + u64 raw{}; + BitField<0, 1, u64> position1; + BitField<1, 1, u64> position2; + BitField<2, 1, u64> position3; + BitField<3, 1, u64> position4; + }; + }; + void SetSupportedStyleSet(NPadType style_set); NPadType GetSupportedStyleSet() const; @@ -93,6 +110,7 @@ public: void ConnectNPad(u32 npad_id); void DisconnectNPad(u32 npad_id); + LedPattern GetLedPattern(u32 npad_id); private: struct CommonHeader { @@ -255,8 +273,8 @@ private: std::size_t dump_idx{}; Vibration last_processed_vibration{}; std::size_t controller_count{}; - static constexpr std::array npad_id_list{0, 1, 2, 3, 4, 5, 6, 7, 32}; - std::array connected_controllers{}; + static constexpr std::array npad_id_list{0, 1, 2, 3, 4, 5, 6, 7, 32, 16}; + std::array connected_controllers{}; void InitNewlyAddedControler(std::size_t controller_idx); }; diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index dfee289d2e..4c0d96cc20 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp @@ -421,9 +421,14 @@ private: } void GetPlayerLedPattern(Kernel::HLERequestContext& ctx) { - IPC::ResponseBuilder rb{ctx, 2}; + IPC::RequestParser rp{ctx}; + auto npad_id = rp.PopRaw(); + IPC::ResponseBuilder rb{ctx, 4}; rb.Push(RESULT_SUCCESS); - LOG_WARNING(Service_HID, "(STUBBED) called"); + rb.PushRaw(applet_resource->GetController(HidController::NPad) + .GetLedPattern(npad_id) + .raw); + LOG_DEBUG(Service_HID, "called"); } void SetNpadJoyHoldType(Kernel::HLERequestContext& ctx) { @@ -513,6 +518,8 @@ private: } void SetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + auto mode = rp.PopRaw(); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); LOG_WARNING(Service_HID, "(STUBBED) called");