From 0e33b19ae0292dd7b99241bc4e6fc8936bd89e5c Mon Sep 17 00:00:00 2001 From: Morph <39850852+Morph1984@users.noreply.github.com> Date: Thu, 27 Aug 2020 13:27:03 -0400 Subject: [PATCH] hid: Implement MergeSingleJoyasDualJoy - Used in multiple games such as Super Mario Odyssey. --- src/core/hle/service/hid/controllers/npad.cpp | 16 ++++++++++++++++ src/core/hle/service/hid/controllers/npad.h | 1 + src/core/hle/service/hid/hid.cpp | 12 +++++++----- 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp index 45fde8df25..e742497e12 100644 --- a/src/core/hle/service/hid/controllers/npad.cpp +++ b/src/core/hle/service/hid/controllers/npad.cpp @@ -574,6 +574,22 @@ Controller_NPad::GyroscopeZeroDriftMode Controller_NPad::GetGyroscopeZeroDriftMo return gyroscope_zero_drift_mode; } +void Controller_NPad::MergeSingleJoyAsDualJoy(u32 npad_id_1, u32 npad_id_2) { + const auto npad_index_1 = NPadIdToIndex(npad_id_1); + const auto npad_index_2 = NPadIdToIndex(npad_id_2); + + // If the controllers at both npad indices form a pair of left and right joycons, merge them. + // Otherwise, do nothing. + if ((connected_controllers[npad_index_1].type == NPadControllerType::JoyLeft && + connected_controllers[npad_index_2].type == NPadControllerType::JoyRight) || + (connected_controllers[npad_index_2].type == NPadControllerType::JoyLeft && + connected_controllers[npad_index_1].type == NPadControllerType::JoyRight)) { + // Disconnect the joycon at the second id and connect the dual joycon at the first index. + DisconnectNPad(npad_id_2); + AddNewControllerAt(NPadControllerType::JoyDual, npad_index_1); + } +} + void Controller_NPad::StartLRAssignmentMode() { // Nothing internally is used for lr assignment mode. Since we have the ability to set the // controller types from boot, it doesn't really matter about showing a selection screen diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h index 75ce5b7313..ad25c6fbf0 100644 --- a/src/core/hle/service/hid/controllers/npad.h +++ b/src/core/hle/service/hid/controllers/npad.h @@ -134,6 +134,7 @@ public: void ConnectAllDisconnectedControllers(); void ClearAllControllers(); + void MergeSingleJoyAsDualJoy(u32 npad_id_1, u32 npad_id_2); void StartLRAssignmentMode(); void StopLRAssignmentMode(); bool SwapNpadAssignment(u32 npad_id_1, u32 npad_id_2); diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index 33416b5dd3..bd3c2f26b9 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp @@ -671,13 +671,15 @@ void Hid::SetNpadJoyAssignmentModeDual(Kernel::HLERequestContext& ctx) { void Hid::MergeSingleJoyAsDualJoy(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; - const auto unknown_1{rp.Pop()}; - const auto unknown_2{rp.Pop()}; + const auto npad_id_1{rp.Pop()}; + const auto npad_id_2{rp.Pop()}; const auto applet_resource_user_id{rp.Pop()}; - LOG_WARNING(Service_HID, - "(STUBBED) called, unknown_1={}, unknown_2={}, applet_resource_user_id={}", - unknown_1, unknown_2, applet_resource_user_id); + LOG_DEBUG(Service_HID, "called, npad_id_1={}, npad_id_2={}, applet_resource_user_id={}", + npad_id_1, npad_id_2, applet_resource_user_id); + + auto& controller = applet_resource->GetController(HidController::NPad); + controller.MergeSingleJoyAsDualJoy(npad_id_1, npad_id_2); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS);