summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/core/hle/service/hid/controllers/npad.cpp111
-rw-r--r--src/core/hle/service/hid/controllers/npad.h3
-rw-r--r--src/core/hle/service/hid/errors.h2
-rw-r--r--src/core/hle/service/hid/hid.cpp6
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
1278void Controller_NPad::MergeSingleJoyAsDualJoy(Core::HID::NpadIdType npad_id_1, 1278ResultCode 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
1351void Controller_NPad::StartLRAssignmentMode() { 1340void 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
10constexpr ResultCode NpadInvalidHandle{ErrorModule::HID, 100}; 10constexpr ResultCode NpadInvalidHandle{ErrorModule::HID, 100};
11constexpr ResultCode InvalidSixAxisFusionRange{ErrorModule::HID, 423}; 11constexpr ResultCode InvalidSixAxisFusionRange{ErrorModule::HID, 423};
12constexpr ResultCode NpadIsDualJoycon{ErrorModule::HID, 601};
13constexpr ResultCode NpadIsSameType{ErrorModule::HID, 602};
12constexpr ResultCode InvalidNpadId{ErrorModule::HID, 709}; 14constexpr ResultCode InvalidNpadId{ErrorModule::HID, 709};
13constexpr ResultCode NpadNotConnected{ErrorModule::HID, 710}; 15constexpr 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
1103void Hid::StartLrAssignmentMode(Kernel::HLERequestContext& ctx) { 1103void Hid::StartLrAssignmentMode(Kernel::HLERequestContext& ctx) {