diff options
| -rw-r--r-- | src/core/hle/service/hid/controllers/npad.cpp | 111 | ||||
| -rw-r--r-- | src/core/hle/service/hid/controllers/npad.h | 3 | ||||
| -rw-r--r-- | src/core/hle/service/hid/errors.h | 2 | ||||
| -rw-r--r-- | src/core/hle/service/hid/hid.cpp | 6 |
4 files changed, 57 insertions, 65 deletions
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp index 5df49d22f..4095a0a3c 100644 --- a/src/core/hle/service/hid/controllers/npad.cpp +++ b/src/core/hle/service/hid/controllers/npad.cpp | |||
| @@ -1275,77 +1275,66 @@ ResultCode Controller_NPad::GetSixAxisFusionParameters( | |||
| 1275 | return ResultSuccess; | 1275 | return ResultSuccess; |
| 1276 | } | 1276 | } |
| 1277 | 1277 | ||
| 1278 | void Controller_NPad::MergeSingleJoyAsDualJoy(Core::HID::NpadIdType npad_id_1, | 1278 | ResultCode Controller_NPad::MergeSingleJoyAsDualJoy(Core::HID::NpadIdType npad_id_1, |
| 1279 | Core::HID::NpadIdType npad_id_2) { | 1279 | Core::HID::NpadIdType npad_id_2) { |
| 1280 | if (!IsNpadIdValid(npad_id_1) || !IsNpadIdValid(npad_id_2)) { | 1280 | if (!IsNpadIdValid(npad_id_1) || !IsNpadIdValid(npad_id_2)) { |
| 1281 | LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id_1:{}, npad_id_2:{}", npad_id_1, | 1281 | LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id_1:{}, npad_id_2:{}", npad_id_1, |
| 1282 | npad_id_2); | 1282 | npad_id_2); |
| 1283 | return; | 1283 | return InvalidNpadId; |
| 1284 | } | 1284 | } |
| 1285 | auto& controller_1 = GetControllerFromNpadIdType(npad_id_1); | 1285 | auto& controller_1 = GetControllerFromNpadIdType(npad_id_1); |
| 1286 | auto& controller_2 = GetControllerFromNpadIdType(npad_id_2); | 1286 | auto& controller_2 = GetControllerFromNpadIdType(npad_id_2); |
| 1287 | const auto controller_style_1 = controller_1.device->GetNpadStyleIndex(); | 1287 | auto controller_style_1 = controller_1.device->GetNpadStyleIndex(); |
| 1288 | const auto controller_style_2 = controller_2.device->GetNpadStyleIndex(); | 1288 | auto controller_style_2 = controller_2.device->GetNpadStyleIndex(); |
| 1289 | bool merge_controllers = false; | 1289 | |
| 1290 | // Simplify this code by converting dualjoycon with only a side connected to single joycons | ||
| 1291 | if (controller_style_1 == Core::HID::NpadStyleIndex::JoyconDual) { | ||
| 1292 | if (controller_1.is_dual_left_connected && !controller_1.is_dual_right_connected) { | ||
| 1293 | controller_style_1 = Core::HID::NpadStyleIndex::JoyconLeft; | ||
| 1294 | } | ||
| 1295 | if (!controller_1.is_dual_left_connected && controller_1.is_dual_right_connected) { | ||
| 1296 | controller_style_1 = Core::HID::NpadStyleIndex::JoyconRight; | ||
| 1297 | } | ||
| 1298 | } | ||
| 1299 | if (controller_style_2 == Core::HID::NpadStyleIndex::JoyconDual) { | ||
| 1300 | if (controller_2.is_dual_left_connected && !controller_2.is_dual_right_connected) { | ||
| 1301 | controller_style_2 = Core::HID::NpadStyleIndex::JoyconLeft; | ||
| 1302 | } | ||
| 1303 | if (!controller_2.is_dual_left_connected && controller_2.is_dual_right_connected) { | ||
| 1304 | controller_style_2 = Core::HID::NpadStyleIndex::JoyconRight; | ||
| 1305 | } | ||
| 1306 | } | ||
| 1290 | 1307 | ||
| 1291 | // If the controllers at both npad indices form a pair of left and right joycons, merge them. | 1308 | // Invalid merge errors |
| 1292 | // Otherwise, do nothing. | 1309 | if (controller_style_1 == Core::HID::NpadStyleIndex::JoyconDual || |
| 1310 | controller_style_2 == Core::HID::NpadStyleIndex::JoyconDual) { | ||
| 1311 | return NpadIsDualJoycon; | ||
| 1312 | } | ||
| 1293 | if (controller_style_1 == Core::HID::NpadStyleIndex::JoyconLeft && | 1313 | if (controller_style_1 == Core::HID::NpadStyleIndex::JoyconLeft && |
| 1314 | controller_style_2 == Core::HID::NpadStyleIndex::JoyconLeft) { | ||
| 1315 | return NpadIsSameType; | ||
| 1316 | } | ||
| 1317 | if (controller_style_1 == Core::HID::NpadStyleIndex::JoyconRight && | ||
| 1294 | controller_style_2 == Core::HID::NpadStyleIndex::JoyconRight) { | 1318 | controller_style_2 == Core::HID::NpadStyleIndex::JoyconRight) { |
| 1295 | merge_controllers = true; | 1319 | return NpadIsSameType; |
| 1296 | } | 1320 | } |
| 1297 | if (controller_style_2 == Core::HID::NpadStyleIndex::JoyconLeft && | 1321 | |
| 1298 | controller_style_1 == Core::HID::NpadStyleIndex::JoyconRight) { | 1322 | // These exceptions are handled as if they where dual joycon |
| 1299 | merge_controllers = true; | 1323 | if (controller_style_1 != Core::HID::NpadStyleIndex::JoyconLeft && |
| 1300 | } | 1324 | controller_style_1 != Core::HID::NpadStyleIndex::JoyconRight) { |
| 1301 | if (controller_style_1 == Core::HID::NpadStyleIndex::JoyconDual && | 1325 | return NpadIsDualJoycon; |
| 1302 | controller_style_2 == Core::HID::NpadStyleIndex::JoyconRight && | 1326 | } |
| 1303 | controller_1.is_dual_left_connected && !controller_1.is_dual_right_connected) { | 1327 | if (controller_style_2 != Core::HID::NpadStyleIndex::JoyconLeft && |
| 1304 | merge_controllers = true; | 1328 | controller_style_2 != Core::HID::NpadStyleIndex::JoyconRight) { |
| 1305 | } | 1329 | return NpadIsDualJoycon; |
| 1306 | if (controller_style_1 == Core::HID::NpadStyleIndex::JoyconDual && | ||
| 1307 | controller_style_2 == Core::HID::NpadStyleIndex::JoyconLeft && | ||
| 1308 | !controller_1.is_dual_left_connected && controller_1.is_dual_right_connected) { | ||
| 1309 | merge_controllers = true; | ||
| 1310 | } | ||
| 1311 | if (controller_style_2 == Core::HID::NpadStyleIndex::JoyconDual && | ||
| 1312 | controller_style_1 == Core::HID::NpadStyleIndex::JoyconRight && | ||
| 1313 | controller_2.is_dual_left_connected && !controller_2.is_dual_right_connected) { | ||
| 1314 | merge_controllers = true; | ||
| 1315 | } | ||
| 1316 | if (controller_style_2 == Core::HID::NpadStyleIndex::JoyconDual && | ||
| 1317 | controller_style_1 == Core::HID::NpadStyleIndex::JoyconLeft && | ||
| 1318 | !controller_2.is_dual_left_connected && controller_2.is_dual_right_connected) { | ||
| 1319 | merge_controllers = true; | ||
| 1320 | } | ||
| 1321 | if (controller_style_1 == Core::HID::NpadStyleIndex::JoyconDual && | ||
| 1322 | controller_style_2 == Core::HID::NpadStyleIndex::JoyconDual && | ||
| 1323 | controller_1.is_dual_left_connected && !controller_1.is_dual_right_connected && | ||
| 1324 | !controller_2.is_dual_left_connected && controller_2.is_dual_right_connected) { | ||
| 1325 | merge_controllers = true; | ||
| 1326 | } | ||
| 1327 | if (controller_style_1 == Core::HID::NpadStyleIndex::JoyconDual && | ||
| 1328 | controller_style_2 == Core::HID::NpadStyleIndex::JoyconDual && | ||
| 1329 | !controller_1.is_dual_left_connected && controller_1.is_dual_right_connected && | ||
| 1330 | controller_2.is_dual_left_connected && !controller_2.is_dual_right_connected) { | ||
| 1331 | merge_controllers = true; | ||
| 1332 | } | ||
| 1333 | |||
| 1334 | if (merge_controllers) { | ||
| 1335 | // Disconnect the joycon at the second id and connect the dual joycon at the first index. | ||
| 1336 | DisconnectNpad(npad_id_2); | ||
| 1337 | controller_1.is_dual_left_connected = true; | ||
| 1338 | controller_1.is_dual_right_connected = true; | ||
| 1339 | AddNewControllerAt(Core::HID::NpadStyleIndex::JoyconDual, npad_id_1); | ||
| 1340 | return; | ||
| 1341 | } | 1330 | } |
| 1342 | LOG_WARNING(Service_HID, | 1331 | |
| 1343 | "Controllers can't be merged npad_id_1:{}, npad_id_2:{}, type_1:{}, type_2:{}, " | 1332 | // Disconnect the joycon at the second id and connect the dual joycon at the first index. |
| 1344 | "dual_1(left/right):{}/{}, dual_2(left/right):{}/{}", | 1333 | DisconnectNpad(npad_id_2); |
| 1345 | npad_id_1, npad_id_2, controller_1.device->GetNpadStyleIndex(), | 1334 | controller_1.is_dual_left_connected = true; |
| 1346 | controller_2.device->GetNpadStyleIndex(), controller_1.is_dual_left_connected, | 1335 | controller_1.is_dual_right_connected = true; |
| 1347 | controller_1.is_dual_right_connected, controller_2.is_dual_left_connected, | 1336 | AddNewControllerAt(Core::HID::NpadStyleIndex::JoyconDual, npad_id_1); |
| 1348 | controller_2.is_dual_right_connected); | 1337 | return ResultSuccess; |
| 1349 | } | 1338 | } |
| 1350 | 1339 | ||
| 1351 | void Controller_NPad::StartLRAssignmentMode() { | 1340 | void Controller_NPad::StartLRAssignmentMode() { |
diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h index f03e9294d..5305e8cf8 100644 --- a/src/core/hle/service/hid/controllers/npad.h +++ b/src/core/hle/service/hid/controllers/npad.h | |||
| @@ -174,7 +174,8 @@ public: | |||
| 174 | void ConnectAllDisconnectedControllers(); | 174 | void ConnectAllDisconnectedControllers(); |
| 175 | void ClearAllControllers(); | 175 | void ClearAllControllers(); |
| 176 | 176 | ||
| 177 | void MergeSingleJoyAsDualJoy(Core::HID::NpadIdType npad_id_1, Core::HID::NpadIdType npad_id_2); | 177 | ResultCode MergeSingleJoyAsDualJoy(Core::HID::NpadIdType npad_id_1, |
| 178 | Core::HID::NpadIdType npad_id_2); | ||
| 178 | void StartLRAssignmentMode(); | 179 | void StartLRAssignmentMode(); |
| 179 | void StopLRAssignmentMode(); | 180 | void StopLRAssignmentMode(); |
| 180 | ResultCode SwapNpadAssignment(Core::HID::NpadIdType npad_id_1, Core::HID::NpadIdType npad_id_2); | 181 | ResultCode SwapNpadAssignment(Core::HID::NpadIdType npad_id_1, Core::HID::NpadIdType npad_id_2); |
diff --git a/src/core/hle/service/hid/errors.h b/src/core/hle/service/hid/errors.h index 279974ce9..d518fd069 100644 --- a/src/core/hle/service/hid/errors.h +++ b/src/core/hle/service/hid/errors.h | |||
| @@ -9,6 +9,8 @@ namespace Service::HID { | |||
| 9 | 9 | ||
| 10 | constexpr ResultCode NpadInvalidHandle{ErrorModule::HID, 100}; | 10 | constexpr ResultCode NpadInvalidHandle{ErrorModule::HID, 100}; |
| 11 | constexpr ResultCode InvalidSixAxisFusionRange{ErrorModule::HID, 423}; | 11 | constexpr ResultCode InvalidSixAxisFusionRange{ErrorModule::HID, 423}; |
| 12 | constexpr ResultCode NpadIsDualJoycon{ErrorModule::HID, 601}; | ||
| 13 | constexpr ResultCode NpadIsSameType{ErrorModule::HID, 602}; | ||
| 12 | constexpr ResultCode InvalidNpadId{ErrorModule::HID, 709}; | 14 | constexpr ResultCode InvalidNpadId{ErrorModule::HID, 709}; |
| 13 | constexpr ResultCode NpadNotConnected{ErrorModule::HID, 710}; | 15 | constexpr ResultCode NpadNotConnected{ErrorModule::HID, 710}; |
| 14 | 16 | ||
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index b41fc60d6..0520a8a38 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp | |||
| @@ -1090,14 +1090,14 @@ void Hid::MergeSingleJoyAsDualJoy(Kernel::HLERequestContext& ctx) { | |||
| 1090 | const auto npad_id_2{rp.PopEnum<Core::HID::NpadIdType>()}; | 1090 | const auto npad_id_2{rp.PopEnum<Core::HID::NpadIdType>()}; |
| 1091 | const auto applet_resource_user_id{rp.Pop<u64>()}; | 1091 | const auto applet_resource_user_id{rp.Pop<u64>()}; |
| 1092 | 1092 | ||
| 1093 | applet_resource->GetController<Controller_NPad>(HidController::NPad) | 1093 | auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad); |
| 1094 | .MergeSingleJoyAsDualJoy(npad_id_1, npad_id_2); | 1094 | const auto result = controller.MergeSingleJoyAsDualJoy(npad_id_1, npad_id_2); |
| 1095 | 1095 | ||
| 1096 | LOG_DEBUG(Service_HID, "called, npad_id_1={}, npad_id_2={}, applet_resource_user_id={}", | 1096 | LOG_DEBUG(Service_HID, "called, npad_id_1={}, npad_id_2={}, applet_resource_user_id={}", |
| 1097 | npad_id_1, npad_id_2, applet_resource_user_id); | 1097 | npad_id_1, npad_id_2, applet_resource_user_id); |
| 1098 | 1098 | ||
| 1099 | IPC::ResponseBuilder rb{ctx, 2}; | 1099 | IPC::ResponseBuilder rb{ctx, 2}; |
| 1100 | rb.Push(ResultSuccess); | 1100 | rb.Push(result); |
| 1101 | } | 1101 | } |
| 1102 | 1102 | ||
| 1103 | void Hid::StartLrAssignmentMode(Kernel::HLERequestContext& ctx) { | 1103 | void Hid::StartLrAssignmentMode(Kernel::HLERequestContext& ctx) { |