service: hid: Implement MergeSingleJoyAsDualJoy according to RE
This commit is contained in:
parent
7aa1d10655
commit
3cf15af31e
4 changed files with 55 additions and 63 deletions
|
@ -1275,77 +1275,66 @@ ResultCode Controller_NPad::GetSixAxisFusionParameters(
|
||||||
return ResultSuccess;
|
return ResultSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Controller_NPad::MergeSingleJoyAsDualJoy(Core::HID::NpadIdType npad_id_1,
|
ResultCode Controller_NPad::MergeSingleJoyAsDualJoy(Core::HID::NpadIdType npad_id_1,
|
||||||
Core::HID::NpadIdType npad_id_2) {
|
Core::HID::NpadIdType npad_id_2) {
|
||||||
if (!IsNpadIdValid(npad_id_1) || !IsNpadIdValid(npad_id_2)) {
|
if (!IsNpadIdValid(npad_id_1) || !IsNpadIdValid(npad_id_2)) {
|
||||||
LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id_1:{}, npad_id_2:{}", npad_id_1,
|
LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id_1:{}, npad_id_2:{}", npad_id_1,
|
||||||
npad_id_2);
|
npad_id_2);
|
||||||
return;
|
return InvalidNpadId;
|
||||||
}
|
}
|
||||||
auto& controller_1 = GetControllerFromNpadIdType(npad_id_1);
|
auto& controller_1 = GetControllerFromNpadIdType(npad_id_1);
|
||||||
auto& controller_2 = GetControllerFromNpadIdType(npad_id_2);
|
auto& controller_2 = GetControllerFromNpadIdType(npad_id_2);
|
||||||
const auto controller_style_1 = controller_1.device->GetNpadStyleIndex();
|
auto controller_style_1 = controller_1.device->GetNpadStyleIndex();
|
||||||
const auto controller_style_2 = controller_2.device->GetNpadStyleIndex();
|
auto controller_style_2 = controller_2.device->GetNpadStyleIndex();
|
||||||
bool merge_controllers = false;
|
|
||||||
|
|
||||||
// If the controllers at both npad indices form a pair of left and right joycons, merge them.
|
// Simplify this code by converting dualjoycon with only a side connected to single joycons
|
||||||
// Otherwise, do nothing.
|
if (controller_style_1 == Core::HID::NpadStyleIndex::JoyconDual) {
|
||||||
|
if (controller_1.is_dual_left_connected && !controller_1.is_dual_right_connected) {
|
||||||
|
controller_style_1 = Core::HID::NpadStyleIndex::JoyconLeft;
|
||||||
|
}
|
||||||
|
if (!controller_1.is_dual_left_connected && controller_1.is_dual_right_connected) {
|
||||||
|
controller_style_1 = Core::HID::NpadStyleIndex::JoyconRight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (controller_style_2 == Core::HID::NpadStyleIndex::JoyconDual) {
|
||||||
|
if (controller_2.is_dual_left_connected && !controller_2.is_dual_right_connected) {
|
||||||
|
controller_style_2 = Core::HID::NpadStyleIndex::JoyconLeft;
|
||||||
|
}
|
||||||
|
if (!controller_2.is_dual_left_connected && controller_2.is_dual_right_connected) {
|
||||||
|
controller_style_2 = Core::HID::NpadStyleIndex::JoyconRight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invalid merge errors
|
||||||
|
if (controller_style_1 == Core::HID::NpadStyleIndex::JoyconDual ||
|
||||||
|
controller_style_2 == Core::HID::NpadStyleIndex::JoyconDual) {
|
||||||
|
return NpadIsDualJoycon;
|
||||||
|
}
|
||||||
if (controller_style_1 == Core::HID::NpadStyleIndex::JoyconLeft &&
|
if (controller_style_1 == Core::HID::NpadStyleIndex::JoyconLeft &&
|
||||||
|
controller_style_2 == Core::HID::NpadStyleIndex::JoyconLeft) {
|
||||||
|
return NpadIsSameType;
|
||||||
|
}
|
||||||
|
if (controller_style_1 == Core::HID::NpadStyleIndex::JoyconRight &&
|
||||||
controller_style_2 == Core::HID::NpadStyleIndex::JoyconRight) {
|
controller_style_2 == Core::HID::NpadStyleIndex::JoyconRight) {
|
||||||
merge_controllers = true;
|
return NpadIsSameType;
|
||||||
}
|
|
||||||
if (controller_style_2 == Core::HID::NpadStyleIndex::JoyconLeft &&
|
|
||||||
controller_style_1 == Core::HID::NpadStyleIndex::JoyconRight) {
|
|
||||||
merge_controllers = true;
|
|
||||||
}
|
|
||||||
if (controller_style_1 == Core::HID::NpadStyleIndex::JoyconDual &&
|
|
||||||
controller_style_2 == Core::HID::NpadStyleIndex::JoyconRight &&
|
|
||||||
controller_1.is_dual_left_connected && !controller_1.is_dual_right_connected) {
|
|
||||||
merge_controllers = true;
|
|
||||||
}
|
|
||||||
if (controller_style_1 == Core::HID::NpadStyleIndex::JoyconDual &&
|
|
||||||
controller_style_2 == Core::HID::NpadStyleIndex::JoyconLeft &&
|
|
||||||
!controller_1.is_dual_left_connected && controller_1.is_dual_right_connected) {
|
|
||||||
merge_controllers = true;
|
|
||||||
}
|
|
||||||
if (controller_style_2 == Core::HID::NpadStyleIndex::JoyconDual &&
|
|
||||||
controller_style_1 == Core::HID::NpadStyleIndex::JoyconRight &&
|
|
||||||
controller_2.is_dual_left_connected && !controller_2.is_dual_right_connected) {
|
|
||||||
merge_controllers = true;
|
|
||||||
}
|
|
||||||
if (controller_style_2 == Core::HID::NpadStyleIndex::JoyconDual &&
|
|
||||||
controller_style_1 == Core::HID::NpadStyleIndex::JoyconLeft &&
|
|
||||||
!controller_2.is_dual_left_connected && controller_2.is_dual_right_connected) {
|
|
||||||
merge_controllers = true;
|
|
||||||
}
|
|
||||||
if (controller_style_1 == Core::HID::NpadStyleIndex::JoyconDual &&
|
|
||||||
controller_style_2 == Core::HID::NpadStyleIndex::JoyconDual &&
|
|
||||||
controller_1.is_dual_left_connected && !controller_1.is_dual_right_connected &&
|
|
||||||
!controller_2.is_dual_left_connected && controller_2.is_dual_right_connected) {
|
|
||||||
merge_controllers = true;
|
|
||||||
}
|
|
||||||
if (controller_style_1 == Core::HID::NpadStyleIndex::JoyconDual &&
|
|
||||||
controller_style_2 == Core::HID::NpadStyleIndex::JoyconDual &&
|
|
||||||
!controller_1.is_dual_left_connected && controller_1.is_dual_right_connected &&
|
|
||||||
controller_2.is_dual_left_connected && !controller_2.is_dual_right_connected) {
|
|
||||||
merge_controllers = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (merge_controllers) {
|
// These exceptions are handled as if they where dual joycon
|
||||||
// Disconnect the joycon at the second id and connect the dual joycon at the first index.
|
if (controller_style_1 != Core::HID::NpadStyleIndex::JoyconLeft &&
|
||||||
DisconnectNpad(npad_id_2);
|
controller_style_1 != Core::HID::NpadStyleIndex::JoyconRight) {
|
||||||
controller_1.is_dual_left_connected = true;
|
return NpadIsDualJoycon;
|
||||||
controller_1.is_dual_right_connected = true;
|
|
||||||
AddNewControllerAt(Core::HID::NpadStyleIndex::JoyconDual, npad_id_1);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
LOG_WARNING(Service_HID,
|
if (controller_style_2 != Core::HID::NpadStyleIndex::JoyconLeft &&
|
||||||
"Controllers can't be merged npad_id_1:{}, npad_id_2:{}, type_1:{}, type_2:{}, "
|
controller_style_2 != Core::HID::NpadStyleIndex::JoyconRight) {
|
||||||
"dual_1(left/right):{}/{}, dual_2(left/right):{}/{}",
|
return NpadIsDualJoycon;
|
||||||
npad_id_1, npad_id_2, controller_1.device->GetNpadStyleIndex(),
|
}
|
||||||
controller_2.device->GetNpadStyleIndex(), controller_1.is_dual_left_connected,
|
|
||||||
controller_1.is_dual_right_connected, controller_2.is_dual_left_connected,
|
// Disconnect the joycon at the second id and connect the dual joycon at the first index.
|
||||||
controller_2.is_dual_right_connected);
|
DisconnectNpad(npad_id_2);
|
||||||
|
controller_1.is_dual_left_connected = true;
|
||||||
|
controller_1.is_dual_right_connected = true;
|
||||||
|
AddNewControllerAt(Core::HID::NpadStyleIndex::JoyconDual, npad_id_1);
|
||||||
|
return ResultSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Controller_NPad::StartLRAssignmentMode() {
|
void Controller_NPad::StartLRAssignmentMode() {
|
||||||
|
|
|
@ -174,7 +174,8 @@ public:
|
||||||
void ConnectAllDisconnectedControllers();
|
void ConnectAllDisconnectedControllers();
|
||||||
void ClearAllControllers();
|
void ClearAllControllers();
|
||||||
|
|
||||||
void MergeSingleJoyAsDualJoy(Core::HID::NpadIdType npad_id_1, Core::HID::NpadIdType npad_id_2);
|
ResultCode MergeSingleJoyAsDualJoy(Core::HID::NpadIdType npad_id_1,
|
||||||
|
Core::HID::NpadIdType npad_id_2);
|
||||||
void StartLRAssignmentMode();
|
void StartLRAssignmentMode();
|
||||||
void StopLRAssignmentMode();
|
void StopLRAssignmentMode();
|
||||||
ResultCode SwapNpadAssignment(Core::HID::NpadIdType npad_id_1, Core::HID::NpadIdType npad_id_2);
|
ResultCode SwapNpadAssignment(Core::HID::NpadIdType npad_id_1, Core::HID::NpadIdType npad_id_2);
|
||||||
|
|
|
@ -9,6 +9,8 @@ namespace Service::HID {
|
||||||
|
|
||||||
constexpr ResultCode NpadInvalidHandle{ErrorModule::HID, 100};
|
constexpr ResultCode NpadInvalidHandle{ErrorModule::HID, 100};
|
||||||
constexpr ResultCode InvalidSixAxisFusionRange{ErrorModule::HID, 423};
|
constexpr ResultCode InvalidSixAxisFusionRange{ErrorModule::HID, 423};
|
||||||
|
constexpr ResultCode NpadIsDualJoycon{ErrorModule::HID, 601};
|
||||||
|
constexpr ResultCode NpadIsSameType{ErrorModule::HID, 602};
|
||||||
constexpr ResultCode InvalidNpadId{ErrorModule::HID, 709};
|
constexpr ResultCode InvalidNpadId{ErrorModule::HID, 709};
|
||||||
constexpr ResultCode NpadNotConnected{ErrorModule::HID, 710};
|
constexpr ResultCode NpadNotConnected{ErrorModule::HID, 710};
|
||||||
|
|
||||||
|
|
|
@ -1090,14 +1090,14 @@ void Hid::MergeSingleJoyAsDualJoy(Kernel::HLERequestContext& ctx) {
|
||||||
const auto npad_id_2{rp.PopEnum<Core::HID::NpadIdType>()};
|
const auto npad_id_2{rp.PopEnum<Core::HID::NpadIdType>()};
|
||||||
const auto applet_resource_user_id{rp.Pop<u64>()};
|
const auto applet_resource_user_id{rp.Pop<u64>()};
|
||||||
|
|
||||||
applet_resource->GetController<Controller_NPad>(HidController::NPad)
|
auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
|
||||||
.MergeSingleJoyAsDualJoy(npad_id_1, npad_id_2);
|
const auto result = controller.MergeSingleJoyAsDualJoy(npad_id_1, npad_id_2);
|
||||||
|
|
||||||
LOG_DEBUG(Service_HID, "called, npad_id_1={}, npad_id_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);
|
npad_id_1, npad_id_2, applet_resource_user_id);
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 2};
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
rb.Push(ResultSuccess);
|
rb.Push(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Hid::StartLrAssignmentMode(Kernel::HLERequestContext& ctx) {
|
void Hid::StartLrAssignmentMode(Kernel::HLERequestContext& ctx) {
|
||||||
|
|
Loading…
Reference in a new issue