diff options
| author | 2018-10-18 15:09:55 +1100 | |
|---|---|---|
| committer | 2018-11-18 23:21:33 -0500 | |
| commit | b9c1e4b0e75f13cde0508bc3d0bd252add03ae85 (patch) | |
| tree | 8fccfbd4de30cd33d9b1de5399204ae651c85720 /src | |
| parent | Added multi-input support and controller assignment at any port (diff) | |
| download | yuzu-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.cpp | 124 | ||||
| -rw-r--r-- | src/core/hle/service/hid/controllers/npad.h | 4 |
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 | ||
| 386 | void Controller_NPad::SetSupportedStyleSet(NPadType style_set) { | 386 | void 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 | ||
| 518 | void Controller_NPad::AddNewController(NPadControllerType controller) { | 518 | void 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 | ||
| 536 | void Controller_NPad::AddNewControllerAt(NPadControllerType controller, u32 npad_id) { | 537 | void 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 | ||
| 557 | Controller_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 | |||
| 643 | bool 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 | |||
| 555 | Controller_NPad::LedPattern Controller_NPad::GetLedPattern(u32 npad_id) { | 673 | Controller_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 |