summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar David Marcec2018-10-18 15:09:55 +1100
committerGravatar Zach Hilman2018-11-18 23:21:33 -0500
commitb9c1e4b0e75f13cde0508bc3d0bd252add03ae85 (patch)
tree8fccfbd4de30cd33d9b1de5399204ae651c85720 /src
parentAdded multi-input support and controller assignment at any port (diff)
downloadyuzu-b9c1e4b0e75f13cde0508bc3d0bd252add03ae85.tar.gz
yuzu-b9c1e4b0e75f13cde0508bc3d0bd252add03ae85.tar.xz
yuzu-b9c1e4b0e75f13cde0508bc3d0bd252add03ae85.zip
Added automatic npad switch based on supported stylesets
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/service/hid/controllers/npad.cpp124
-rw-r--r--src/core/hle/service/hid/controllers/npad.h4
2 files changed, 124 insertions, 4 deletions
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp
index 5b0ca57f8..a9060fa2c 100644
--- a/src/core/hle/service/hid/controllers/npad.cpp
+++ b/src/core/hle/service/hid/controllers/npad.cpp
@@ -89,12 +89,12 @@ void Controller_NPad::InitNewlyAddedControler(std::size_t controller_idx) {
89 case NPadControllerType::JoyLeft: 89 case NPadControllerType::JoyLeft:
90 controller.joy_styles.joycon_left.Assign(1); 90 controller.joy_styles.joycon_left.Assign(1);
91 controller.device_type.joycon_left.Assign(1); 91 controller.device_type.joycon_left.Assign(1);
92 controller.pad_assignment = NPadAssignments::Dual; 92 controller.pad_assignment = NPadAssignments::Single;
93 break; 93 break;
94 case NPadControllerType::JoyRight: 94 case NPadControllerType::JoyRight:
95 controller.joy_styles.joycon_right.Assign(1); 95 controller.joy_styles.joycon_right.Assign(1);
96 controller.device_type.joycon_right.Assign(1); 96 controller.device_type.joycon_right.Assign(1);
97 controller.pad_assignment = NPadAssignments::Dual; 97 controller.pad_assignment = NPadAssignments::Single;
98 break; 98 break;
99 case NPadControllerType::Pokeball: 99 case NPadControllerType::Pokeball:
100 controller.joy_styles.pokeball.Assign(1); 100 controller.joy_styles.pokeball.Assign(1);
@@ -381,7 +381,7 @@ void Controller_NPad::OnUpdate(u8* data, std::size_t data_len) {
381 } 381 }
382 std::memcpy(data + NPAD_OFFSET, shared_memory_entries.data(), 382 std::memcpy(data + NPAD_OFFSET, shared_memory_entries.data(),
383 shared_memory_entries.size() * sizeof(NPadEntry)); 383 shared_memory_entries.size() * sizeof(NPadEntry));
384} // namespace Service::HID 384}
385 385
386void Controller_NPad::SetSupportedStyleSet(NPadType style_set) { 386void Controller_NPad::SetSupportedStyleSet(NPadType style_set) {
387 style.raw = style_set.raw; 387 style.raw = style_set.raw;
@@ -516,6 +516,7 @@ u32 Controller_NPad::IndexToNPad(std::size_t index) {
516} 516}
517 517
518void Controller_NPad::AddNewController(NPadControllerType controller) { 518void Controller_NPad::AddNewController(NPadControllerType controller) {
519 controller = DecideBestController(controller);
519 if (controller == NPadControllerType::Handheld) { 520 if (controller == NPadControllerType::Handheld) {
520 connected_controllers[8] = {controller, true}; 521 connected_controllers[8] = {controller, true};
521 InitNewlyAddedControler(8); 522 InitNewlyAddedControler(8);
@@ -534,6 +535,7 @@ void Controller_NPad::AddNewController(NPadControllerType controller) {
534} 535}
535 536
536void Controller_NPad::AddNewControllerAt(NPadControllerType controller, u32 npad_id) { 537void Controller_NPad::AddNewControllerAt(NPadControllerType controller, u32 npad_id) {
538 controller = DecideBestController(controller);
537 if (controller == NPadControllerType::Handheld) { 539 if (controller == NPadControllerType::Handheld) {
538 connected_controllers[8] = {controller, true}; 540 connected_controllers[8] = {controller, true};
539 InitNewlyAddedControler(8); 541 InitNewlyAddedControler(8);
@@ -552,6 +554,122 @@ void Controller_NPad::DisconnectNPad(u32 npad_id) {
552 connected_controllers[NPadIdToIndex(npad_id)].is_connected = false; 554 connected_controllers[NPadIdToIndex(npad_id)].is_connected = false;
553} 555}
554 556
557Controller_NPad::NPadControllerType Controller_NPad::DecideBestController(
558 NPadControllerType priority) {
559 if (IsControllerSupported(priority)) {
560 return priority;
561 }
562 const auto is_docked = Settings::values->use_docked_mode;
563 if (is_docked && priority == NPadControllerType::Handheld) {
564 priority = NPadControllerType::JoyDual;
565 if (IsControllerSupported(priority)) {
566 return priority;
567 }
568 }
569 std::vector<NPadControllerType> priority_list{};
570 switch (priority) {
571 case NPadControllerType::ProController:
572 priority_list.push_back(NPadControllerType::JoyDual);
573 if (!is_docked) {
574 priority_list.push_back(NPadControllerType::Handheld);
575 }
576 priority_list.push_back(NPadControllerType::JoyLeft);
577 priority_list.push_back(NPadControllerType::JoyRight);
578 priority_list.push_back(NPadControllerType::Pokeball);
579 break;
580 case NPadControllerType::Handheld:
581 priority_list.push_back(NPadControllerType::JoyDual);
582 priority_list.push_back(NPadControllerType::ProController);
583 priority_list.push_back(NPadControllerType::JoyLeft);
584 priority_list.push_back(NPadControllerType::JoyRight);
585 priority_list.push_back(NPadControllerType::Pokeball);
586 break;
587 case NPadControllerType::JoyDual:
588 if (!is_docked) {
589 priority_list.push_back(NPadControllerType::Handheld);
590 }
591 priority_list.push_back(NPadControllerType::ProController);
592 priority_list.push_back(NPadControllerType::JoyLeft);
593 priority_list.push_back(NPadControllerType::JoyRight);
594 priority_list.push_back(NPadControllerType::Pokeball);
595 break;
596 case NPadControllerType::JoyLeft:
597 priority_list.push_back(NPadControllerType::JoyRight);
598 priority_list.push_back(NPadControllerType::JoyDual);
599 if (!is_docked) {
600 priority_list.push_back(NPadControllerType::Handheld);
601 }
602 priority_list.push_back(NPadControllerType::ProController);
603 priority_list.push_back(NPadControllerType::Pokeball);
604 break;
605 case NPadControllerType::JoyRight:
606 priority_list.push_back(NPadControllerType::JoyLeft);
607 priority_list.push_back(NPadControllerType::JoyDual);
608 if (!is_docked) {
609 priority_list.push_back(NPadControllerType::Handheld);
610 }
611 priority_list.push_back(NPadControllerType::ProController);
612 priority_list.push_back(NPadControllerType::Pokeball);
613 break;
614 case NPadControllerType::Pokeball:
615 priority_list.push_back(NPadControllerType::JoyLeft);
616 priority_list.push_back(NPadControllerType::JoyRight);
617 priority_list.push_back(NPadControllerType::JoyDual);
618 if (!is_docked) {
619 priority_list.push_back(NPadControllerType::Handheld);
620 }
621 priority_list.push_back(NPadControllerType::ProController);
622 break;
623 default:
624 priority_list.push_back(NPadControllerType::JoyDual);
625 if (!is_docked) {
626 priority_list.push_back(NPadControllerType::Handheld);
627 }
628 priority_list.push_back(NPadControllerType::ProController);
629 priority_list.push_back(NPadControllerType::JoyLeft);
630 priority_list.push_back(NPadControllerType::JoyRight);
631 priority_list.push_back(NPadControllerType::JoyDual);
632 }
633
634 for (const auto controller_type : priority_list) {
635 if (IsControllerSupported(controller_type)) {
636 return controller_type;
637 }
638 }
639 UNIMPLEMENTED_MSG("Could not find supported controller!");
640 return priority;
641}
642
643bool Controller_NPad::IsControllerSupported(NPadControllerType controller) {
644 if (controller == NPadControllerType::Handheld) {
645 // Handheld is not even a supported type, lets stop here
646 if (std::find(supported_npad_id_types.begin(), supported_npad_id_types.end(), 32) ==
647 supported_npad_id_types.end()) {
648 return false;
649 }
650 // Handheld should not be supported in docked mode
651 if (Settings::values->use_docked_mode) {
652 return false;
653 }
654 }
655 switch (controller) {
656 case NPadControllerType::ProController:
657 return style.pro_controller;
658 case NPadControllerType::Handheld:
659 return style.handheld;
660 case NPadControllerType::JoyDual:
661 return style.joycon_dual;
662 case NPadControllerType::JoyLeft:
663 return style.joycon_left;
664 case NPadControllerType::JoyRight:
665 return style.joycon_right;
666 case NPadControllerType::Pokeball:
667 return style.pokeball;
668 default:
669 return false;
670 }
671}
672
555Controller_NPad::LedPattern Controller_NPad::GetLedPattern(u32 npad_id) { 673Controller_NPad::LedPattern Controller_NPad::GetLedPattern(u32 npad_id) {
556 if (npad_id == npad_id_list.back() || npad_id == npad_id_list[npad_id_list.size() - 2]) { 674 if (npad_id == npad_id_list.back() || npad_id == npad_id_list[npad_id_list.size() - 2]) {
557 // These are controllers without led patterns 675 // These are controllers without led patterns
diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h
index 1192cfcd9..ea12646f8 100644
--- a/src/core/hle/service/hid/controllers/npad.h
+++ b/src/core/hle/service/hid/controllers/npad.h
@@ -272,7 +272,7 @@ private:
272 static_assert(sizeof(NPadEntry) == 0x5000, "NPadEntry is an invalid size"); 272 static_assert(sizeof(NPadEntry) == 0x5000, "NPadEntry is an invalid size");
273 273
274 struct ControllerHolder { 274 struct ControllerHolder {
275 Controller_NPad::NPadControllerType type; 275 NPadControllerType type;
276 bool is_connected; 276 bool is_connected;
277 }; 277 };
278 278
@@ -295,5 +295,7 @@ private:
295 std::size_t NPadIdToIndex(u32 npad_id); 295 std::size_t NPadIdToIndex(u32 npad_id);
296 u32 IndexToNPad(std::size_t index); 296 u32 IndexToNPad(std::size_t index);
297 std::array<ControllerPad, 10> npad_pad_states{}; 297 std::array<ControllerPad, 10> npad_pad_states{};
298 NPadControllerType DecideBestController(NPadControllerType priority);
299 bool IsControllerSupported(NPadControllerType controller);
298}; 300};
299} // namespace Service::HID 301} // namespace Service::HID