diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/frontend/applets/controller.h | 1 | ||||
| -rw-r--r-- | src/core/hle/service/hid/controllers/npad.cpp | 63 | ||||
| -rw-r--r-- | src/core/hle/service/hid/controllers/npad.h | 26 | ||||
| -rw-r--r-- | src/input_common/settings.h | 1 | ||||
| -rw-r--r-- | src/yuzu/applets/controller.cpp | 9 | ||||
| -rw-r--r-- | src/yuzu/configuration/configure_input_player.cpp | 106 | ||||
| -rw-r--r-- | src/yuzu/configuration/configure_input_player.h | 6 | ||||
| -rw-r--r-- | src/yuzu/configuration/configure_input_player_widget.cpp | 3 |
8 files changed, 209 insertions, 6 deletions
diff --git a/src/core/frontend/applets/controller.h b/src/core/frontend/applets/controller.h index dff71d8d9..b0626a0f9 100644 --- a/src/core/frontend/applets/controller.h +++ b/src/core/frontend/applets/controller.h | |||
| @@ -31,6 +31,7 @@ struct ControllerParameters { | |||
| 31 | bool allow_dual_joycons{}; | 31 | bool allow_dual_joycons{}; |
| 32 | bool allow_left_joycon{}; | 32 | bool allow_left_joycon{}; |
| 33 | bool allow_right_joycon{}; | 33 | bool allow_right_joycon{}; |
| 34 | bool allow_gamecube_controller{}; | ||
| 34 | }; | 35 | }; |
| 35 | 36 | ||
| 36 | class ControllerApplet { | 37 | class ControllerApplet { |
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp index dbf198345..70b9f3824 100644 --- a/src/core/hle/service/hid/controllers/npad.cpp +++ b/src/core/hle/service/hid/controllers/npad.cpp | |||
| @@ -21,6 +21,7 @@ | |||
| 21 | 21 | ||
| 22 | namespace Service::HID { | 22 | namespace Service::HID { |
| 23 | constexpr s32 HID_JOYSTICK_MAX = 0x7fff; | 23 | constexpr s32 HID_JOYSTICK_MAX = 0x7fff; |
| 24 | constexpr s32 HID_TRIGGER_MAX = 0x7fff; | ||
| 24 | [[maybe_unused]] constexpr s32 HID_JOYSTICK_MIN = -0x7fff; | 25 | [[maybe_unused]] constexpr s32 HID_JOYSTICK_MIN = -0x7fff; |
| 25 | constexpr std::size_t NPAD_OFFSET = 0x9A00; | 26 | constexpr std::size_t NPAD_OFFSET = 0x9A00; |
| 26 | constexpr u32 BATTERY_FULL = 2; | 27 | constexpr u32 BATTERY_FULL = 2; |
| @@ -48,6 +49,8 @@ Controller_NPad::NPadControllerType Controller_NPad::MapSettingsTypeToNPad( | |||
| 48 | return NPadControllerType::JoyRight; | 49 | return NPadControllerType::JoyRight; |
| 49 | case Settings::ControllerType::Handheld: | 50 | case Settings::ControllerType::Handheld: |
| 50 | return NPadControllerType::Handheld; | 51 | return NPadControllerType::Handheld; |
| 52 | case Settings::ControllerType::GameCube: | ||
| 53 | return NPadControllerType::GameCube; | ||
| 51 | default: | 54 | default: |
| 52 | UNREACHABLE(); | 55 | UNREACHABLE(); |
| 53 | return NPadControllerType::ProController; | 56 | return NPadControllerType::ProController; |
| @@ -67,6 +70,8 @@ Settings::ControllerType Controller_NPad::MapNPadToSettingsType( | |||
| 67 | return Settings::ControllerType::RightJoycon; | 70 | return Settings::ControllerType::RightJoycon; |
| 68 | case NPadControllerType::Handheld: | 71 | case NPadControllerType::Handheld: |
| 69 | return Settings::ControllerType::Handheld; | 72 | return Settings::ControllerType::Handheld; |
| 73 | case NPadControllerType::GameCube: | ||
| 74 | return Settings::ControllerType::GameCube; | ||
| 70 | default: | 75 | default: |
| 71 | UNREACHABLE(); | 76 | UNREACHABLE(); |
| 72 | return Settings::ControllerType::ProController; | 77 | return Settings::ControllerType::ProController; |
| @@ -209,6 +214,13 @@ void Controller_NPad::InitNewlyAddedController(std::size_t controller_idx) { | |||
| 209 | controller.assignment_mode = NpadAssignments::Single; | 214 | controller.assignment_mode = NpadAssignments::Single; |
| 210 | controller.footer_type = AppletFooterUiType::JoyRightHorizontal; | 215 | controller.footer_type = AppletFooterUiType::JoyRightHorizontal; |
| 211 | break; | 216 | break; |
| 217 | case NPadControllerType::GameCube: | ||
| 218 | controller.style_set.gamecube.Assign(1); | ||
| 219 | // The GC Controller behaves like a wired Pro Controller | ||
| 220 | controller.device_type.fullkey.Assign(1); | ||
| 221 | controller.system_properties.is_vertical.Assign(1); | ||
| 222 | controller.system_properties.use_plus.Assign(1); | ||
| 223 | break; | ||
| 212 | case NPadControllerType::Pokeball: | 224 | case NPadControllerType::Pokeball: |
| 213 | controller.style_set.palma.Assign(1); | 225 | controller.style_set.palma.Assign(1); |
| 214 | controller.device_type.palma.Assign(1); | 226 | controller.device_type.palma.Assign(1); |
| @@ -259,6 +271,7 @@ void Controller_NPad::OnInit() { | |||
| 259 | style.joycon_right.Assign(1); | 271 | style.joycon_right.Assign(1); |
| 260 | style.joycon_dual.Assign(1); | 272 | style.joycon_dual.Assign(1); |
| 261 | style.fullkey.Assign(1); | 273 | style.fullkey.Assign(1); |
| 274 | style.gamecube.Assign(1); | ||
| 262 | style.palma.Assign(1); | 275 | style.palma.Assign(1); |
| 263 | } | 276 | } |
| 264 | 277 | ||
| @@ -339,6 +352,7 @@ void Controller_NPad::RequestPadStateUpdate(u32 npad_id) { | |||
| 339 | auto& pad_state = npad_pad_states[controller_idx].pad_states; | 352 | auto& pad_state = npad_pad_states[controller_idx].pad_states; |
| 340 | auto& lstick_entry = npad_pad_states[controller_idx].l_stick; | 353 | auto& lstick_entry = npad_pad_states[controller_idx].l_stick; |
| 341 | auto& rstick_entry = npad_pad_states[controller_idx].r_stick; | 354 | auto& rstick_entry = npad_pad_states[controller_idx].r_stick; |
| 355 | auto& trigger_entry = npad_trigger_states[controller_idx]; | ||
| 342 | const auto& button_state = buttons[controller_idx]; | 356 | const auto& button_state = buttons[controller_idx]; |
| 343 | const auto& analog_state = sticks[controller_idx]; | 357 | const auto& analog_state = sticks[controller_idx]; |
| 344 | const auto [stick_l_x_f, stick_l_y_f] = | 358 | const auto [stick_l_x_f, stick_l_y_f] = |
| @@ -404,6 +418,17 @@ void Controller_NPad::RequestPadStateUpdate(u32 npad_id) { | |||
| 404 | pad_state.left_sl.Assign(button_state[SL - BUTTON_HID_BEGIN]->GetStatus()); | 418 | pad_state.left_sl.Assign(button_state[SL - BUTTON_HID_BEGIN]->GetStatus()); |
| 405 | pad_state.left_sr.Assign(button_state[SR - BUTTON_HID_BEGIN]->GetStatus()); | 419 | pad_state.left_sr.Assign(button_state[SR - BUTTON_HID_BEGIN]->GetStatus()); |
| 406 | } | 420 | } |
| 421 | |||
| 422 | if (controller_type == NPadControllerType::GameCube) { | ||
| 423 | trigger_entry.l_analog = static_cast<s32>( | ||
| 424 | button_state[ZL - BUTTON_HID_BEGIN]->GetStatus() ? HID_TRIGGER_MAX : 0); | ||
| 425 | trigger_entry.r_analog = static_cast<s32>( | ||
| 426 | button_state[ZR - BUTTON_HID_BEGIN]->GetStatus() ? HID_TRIGGER_MAX : 0); | ||
| 427 | pad_state.zl.Assign(false); | ||
| 428 | pad_state.zr.Assign(button_state[R - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 429 | pad_state.l.Assign(button_state[ZL - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 430 | pad_state.r.Assign(button_state[ZR - BUTTON_HID_BEGIN]->GetStatus()); | ||
| 431 | } | ||
| 407 | } | 432 | } |
| 408 | 433 | ||
| 409 | void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, | 434 | void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, |
| @@ -418,6 +443,11 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* | |||
| 418 | &npad.joy_left_states, &npad.joy_right_states, &npad.palma_states, | 443 | &npad.joy_left_states, &npad.joy_right_states, &npad.palma_states, |
| 419 | &npad.system_ext_states}; | 444 | &npad.system_ext_states}; |
| 420 | 445 | ||
| 446 | // There is the posibility to have more controllers with analog triggers | ||
| 447 | const std::array<TriggerGeneric*, 1> controller_triggers{ | ||
| 448 | &npad.gc_trigger_states, | ||
| 449 | }; | ||
| 450 | |||
| 421 | for (auto* main_controller : controller_npads) { | 451 | for (auto* main_controller : controller_npads) { |
| 422 | main_controller->common.entry_count = 16; | 452 | main_controller->common.entry_count = 16; |
| 423 | main_controller->common.total_entry_count = 17; | 453 | main_controller->common.total_entry_count = 17; |
| @@ -435,6 +465,21 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* | |||
| 435 | cur_entry.timestamp2 = cur_entry.timestamp; | 465 | cur_entry.timestamp2 = cur_entry.timestamp; |
| 436 | } | 466 | } |
| 437 | 467 | ||
| 468 | for (auto* analog_trigger : controller_triggers) { | ||
| 469 | analog_trigger->entry_count = 16; | ||
| 470 | analog_trigger->total_entry_count = 17; | ||
| 471 | |||
| 472 | const auto& last_entry = analog_trigger->trigger[analog_trigger->last_entry_index]; | ||
| 473 | |||
| 474 | analog_trigger->timestamp = core_timing.GetCPUTicks(); | ||
| 475 | analog_trigger->last_entry_index = (analog_trigger->last_entry_index + 1) % 17; | ||
| 476 | |||
| 477 | auto& cur_entry = analog_trigger->trigger[analog_trigger->last_entry_index]; | ||
| 478 | |||
| 479 | cur_entry.timestamp = last_entry.timestamp + 1; | ||
| 480 | cur_entry.timestamp2 = cur_entry.timestamp; | ||
| 481 | } | ||
| 482 | |||
| 438 | const auto& controller_type = connected_controllers[i].type; | 483 | const auto& controller_type = connected_controllers[i].type; |
| 439 | 484 | ||
| 440 | if (controller_type == NPadControllerType::None || !connected_controllers[i].is_connected) { | 485 | if (controller_type == NPadControllerType::None || !connected_controllers[i].is_connected) { |
| @@ -444,6 +489,7 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* | |||
| 444 | 489 | ||
| 445 | RequestPadStateUpdate(npad_index); | 490 | RequestPadStateUpdate(npad_index); |
| 446 | auto& pad_state = npad_pad_states[npad_index]; | 491 | auto& pad_state = npad_pad_states[npad_index]; |
| 492 | auto& trigger_state = npad_trigger_states[npad_index]; | ||
| 447 | 493 | ||
| 448 | auto& main_controller = | 494 | auto& main_controller = |
| 449 | npad.fullkey_states.npad[npad.fullkey_states.common.last_entry_index]; | 495 | npad.fullkey_states.npad[npad.fullkey_states.common.last_entry_index]; |
| @@ -456,6 +502,8 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* | |||
| 456 | auto& pokeball_entry = npad.palma_states.npad[npad.palma_states.common.last_entry_index]; | 502 | auto& pokeball_entry = npad.palma_states.npad[npad.palma_states.common.last_entry_index]; |
| 457 | auto& libnx_entry = | 503 | auto& libnx_entry = |
| 458 | npad.system_ext_states.npad[npad.system_ext_states.common.last_entry_index]; | 504 | npad.system_ext_states.npad[npad.system_ext_states.common.last_entry_index]; |
| 505 | auto& trigger_entry = | ||
| 506 | npad.gc_trigger_states.trigger[npad.gc_trigger_states.last_entry_index]; | ||
| 459 | 507 | ||
| 460 | libnx_entry.connection_status.raw = 0; | 508 | libnx_entry.connection_status.raw = 0; |
| 461 | libnx_entry.connection_status.is_connected.Assign(1); | 509 | libnx_entry.connection_status.is_connected.Assign(1); |
| @@ -524,6 +572,18 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* | |||
| 524 | 572 | ||
| 525 | libnx_entry.connection_status.is_right_connected.Assign(1); | 573 | libnx_entry.connection_status.is_right_connected.Assign(1); |
| 526 | break; | 574 | break; |
| 575 | case NPadControllerType::GameCube: | ||
| 576 | main_controller.connection_status.raw = 0; | ||
| 577 | main_controller.connection_status.is_connected.Assign(1); | ||
| 578 | main_controller.connection_status.is_wired.Assign(1); | ||
| 579 | main_controller.pad.pad_states.raw = pad_state.pad_states.raw; | ||
| 580 | main_controller.pad.l_stick = pad_state.l_stick; | ||
| 581 | main_controller.pad.r_stick = pad_state.r_stick; | ||
| 582 | trigger_entry.l_analog = trigger_state.l_analog; | ||
| 583 | trigger_entry.r_analog = trigger_state.r_analog; | ||
| 584 | |||
| 585 | libnx_entry.connection_status.is_wired.Assign(1); | ||
| 586 | break; | ||
| 527 | case NPadControllerType::Pokeball: | 587 | case NPadControllerType::Pokeball: |
| 528 | pokeball_entry.connection_status.raw = 0; | 588 | pokeball_entry.connection_status.raw = 0; |
| 529 | pokeball_entry.connection_status.is_connected.Assign(1); | 589 | pokeball_entry.connection_status.is_connected.Assign(1); |
| @@ -674,6 +734,7 @@ void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing | |||
| 674 | right_sixaxis_entry.orientation = motion_devices[1].orientation; | 734 | right_sixaxis_entry.orientation = motion_devices[1].orientation; |
| 675 | } | 735 | } |
| 676 | break; | 736 | break; |
| 737 | case NPadControllerType::GameCube: | ||
| 677 | case NPadControllerType::Pokeball: | 738 | case NPadControllerType::Pokeball: |
| 678 | break; | 739 | break; |
| 679 | } | 740 | } |
| @@ -1135,6 +1196,8 @@ bool Controller_NPad::IsControllerSupported(NPadControllerType controller) const | |||
| 1135 | return style.joycon_left; | 1196 | return style.joycon_left; |
| 1136 | case NPadControllerType::JoyRight: | 1197 | case NPadControllerType::JoyRight: |
| 1137 | return style.joycon_right; | 1198 | return style.joycon_right; |
| 1199 | case NPadControllerType::GameCube: | ||
| 1200 | return style.gamecube; | ||
| 1138 | case NPadControllerType::Pokeball: | 1201 | case NPadControllerType::Pokeball: |
| 1139 | return style.palma; | 1202 | return style.palma; |
| 1140 | default: | 1203 | default: |
diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h index 48bab988c..bc2e6779d 100644 --- a/src/core/hle/service/hid/controllers/npad.h +++ b/src/core/hle/service/hid/controllers/npad.h | |||
| @@ -51,6 +51,7 @@ public: | |||
| 51 | JoyDual, | 51 | JoyDual, |
| 52 | JoyLeft, | 52 | JoyLeft, |
| 53 | JoyRight, | 53 | JoyRight, |
| 54 | GameCube, | ||
| 54 | Pokeball, | 55 | Pokeball, |
| 55 | }; | 56 | }; |
| 56 | 57 | ||
| @@ -60,6 +61,7 @@ public: | |||
| 60 | JoyconDual = 5, | 61 | JoyconDual = 5, |
| 61 | JoyconLeft = 6, | 62 | JoyconLeft = 6, |
| 62 | JoyconRight = 7, | 63 | JoyconRight = 7, |
| 64 | GameCube = 8, | ||
| 63 | Pokeball = 9, | 65 | Pokeball = 9, |
| 64 | MaxNpadType = 10, | 66 | MaxNpadType = 10, |
| 65 | }; | 67 | }; |
| @@ -389,6 +391,25 @@ private: | |||
| 389 | }; | 391 | }; |
| 390 | static_assert(sizeof(SixAxisGeneric) == 0x708, "SixAxisGeneric is an invalid size"); | 392 | static_assert(sizeof(SixAxisGeneric) == 0x708, "SixAxisGeneric is an invalid size"); |
| 391 | 393 | ||
| 394 | struct TriggerState { | ||
| 395 | s64_le timestamp{}; | ||
| 396 | s64_le timestamp2{}; | ||
| 397 | s32_le l_analog{}; | ||
| 398 | s32_le r_analog{}; | ||
| 399 | }; | ||
| 400 | static_assert(sizeof(TriggerState) == 0x18, "TriggerState is an invalid size"); | ||
| 401 | |||
| 402 | struct TriggerGeneric { | ||
| 403 | INSERT_PADDING_BYTES(0x4); | ||
| 404 | s64_le timestamp; | ||
| 405 | INSERT_PADDING_BYTES(0x4); | ||
| 406 | s64_le total_entry_count; | ||
| 407 | s64_le last_entry_index; | ||
| 408 | s64_le entry_count; | ||
| 409 | std::array<TriggerState, 17> trigger{}; | ||
| 410 | }; | ||
| 411 | static_assert(sizeof(TriggerGeneric) == 0x1C8, "TriggerGeneric is an invalid size"); | ||
| 412 | |||
| 392 | struct NPadSystemProperties { | 413 | struct NPadSystemProperties { |
| 393 | union { | 414 | union { |
| 394 | s64_le raw{}; | 415 | s64_le raw{}; |
| @@ -509,7 +530,9 @@ private: | |||
| 509 | AppletFooterUiType footer_type; | 530 | AppletFooterUiType footer_type; |
| 510 | // nfc_states needs to be checked switchbrew does not match with HW | 531 | // nfc_states needs to be checked switchbrew does not match with HW |
| 511 | NfcXcdHandle nfc_states; | 532 | NfcXcdHandle nfc_states; |
| 512 | INSERT_PADDING_BYTES(0xdef); | 533 | INSERT_PADDING_BYTES(0x8); // Mutex |
| 534 | TriggerGeneric gc_trigger_states; | ||
| 535 | INSERT_PADDING_BYTES(0xc1f); | ||
| 513 | }; | 536 | }; |
| 514 | static_assert(sizeof(NPadEntry) == 0x5000, "NPadEntry is an invalid size"); | 537 | static_assert(sizeof(NPadEntry) == 0x5000, "NPadEntry is an invalid size"); |
| 515 | 538 | ||
| @@ -560,6 +583,7 @@ private: | |||
| 560 | f32 sixaxis_fusion_parameter2{}; | 583 | f32 sixaxis_fusion_parameter2{}; |
| 561 | bool sixaxis_at_rest{true}; | 584 | bool sixaxis_at_rest{true}; |
| 562 | std::array<ControllerPad, 10> npad_pad_states{}; | 585 | std::array<ControllerPad, 10> npad_pad_states{}; |
| 586 | std::array<TriggerState, 10> npad_trigger_states{}; | ||
| 563 | bool is_in_lr_assignment_mode{false}; | 587 | bool is_in_lr_assignment_mode{false}; |
| 564 | Core::System& system; | 588 | Core::System& system; |
| 565 | }; | 589 | }; |
diff --git a/src/input_common/settings.h b/src/input_common/settings.h index 75486554b..a59f5d461 100644 --- a/src/input_common/settings.h +++ b/src/input_common/settings.h | |||
| @@ -340,6 +340,7 @@ enum class ControllerType { | |||
| 340 | LeftJoycon, | 340 | LeftJoycon, |
| 341 | RightJoycon, | 341 | RightJoycon, |
| 342 | Handheld, | 342 | Handheld, |
| 343 | GameCube, | ||
| 343 | }; | 344 | }; |
| 344 | 345 | ||
| 345 | struct PlayerInput { | 346 | struct PlayerInput { |
diff --git a/src/yuzu/applets/controller.cpp b/src/yuzu/applets/controller.cpp index c680fd2c2..b92cd6886 100644 --- a/src/yuzu/applets/controller.cpp +++ b/src/yuzu/applets/controller.cpp | |||
| @@ -67,6 +67,8 @@ bool IsControllerCompatible(Settings::ControllerType controller_type, | |||
| 67 | return parameters.allow_right_joycon; | 67 | return parameters.allow_right_joycon; |
| 68 | case Settings::ControllerType::Handheld: | 68 | case Settings::ControllerType::Handheld: |
| 69 | return parameters.enable_single_mode && parameters.allow_handheld; | 69 | return parameters.enable_single_mode && parameters.allow_handheld; |
| 70 | case Settings::ControllerType::GameCube: | ||
| 71 | return parameters.allow_gamecube_controller; | ||
| 70 | default: | 72 | default: |
| 71 | return false; | 73 | return false; |
| 72 | } | 74 | } |
| @@ -370,7 +372,7 @@ void QtControllerSelectorDialog::SetSupportedControllers() { | |||
| 370 | QStringLiteral("image: url(:/controller/applet_joycon_right%0_disabled); ").arg(theme)); | 372 | QStringLiteral("image: url(:/controller/applet_joycon_right%0_disabled); ").arg(theme)); |
| 371 | } | 373 | } |
| 372 | 374 | ||
| 373 | if (parameters.allow_pro_controller) { | 375 | if (parameters.allow_pro_controller || parameters.allow_gamecube_controller) { |
| 374 | ui->controllerSupported5->setStyleSheet( | 376 | ui->controllerSupported5->setStyleSheet( |
| 375 | QStringLiteral("image: url(:/controller/applet_pro_controller%0); ").arg(theme)); | 377 | QStringLiteral("image: url(:/controller/applet_pro_controller%0); ").arg(theme)); |
| 376 | } else { | 378 | } else { |
| @@ -420,6 +422,10 @@ void QtControllerSelectorDialog::SetEmulatedControllers(std::size_t player_index | |||
| 420 | Settings::ControllerType::Handheld); | 422 | Settings::ControllerType::Handheld); |
| 421 | emulated_controllers[player_index]->addItem(tr("Handheld")); | 423 | emulated_controllers[player_index]->addItem(tr("Handheld")); |
| 422 | } | 424 | } |
| 425 | |||
| 426 | pairs.emplace_back(emulated_controllers[player_index]->count(), | ||
| 427 | Settings::ControllerType::GameCube); | ||
| 428 | emulated_controllers[player_index]->addItem(tr("GameCube Controller")); | ||
| 423 | } | 429 | } |
| 424 | 430 | ||
| 425 | Settings::ControllerType QtControllerSelectorDialog::GetControllerTypeFromIndex( | 431 | Settings::ControllerType QtControllerSelectorDialog::GetControllerTypeFromIndex( |
| @@ -461,6 +467,7 @@ void QtControllerSelectorDialog::UpdateControllerIcon(std::size_t player_index) | |||
| 461 | switch (GetControllerTypeFromIndex(emulated_controllers[player_index]->currentIndex(), | 467 | switch (GetControllerTypeFromIndex(emulated_controllers[player_index]->currentIndex(), |
| 462 | player_index)) { | 468 | player_index)) { |
| 463 | case Settings::ControllerType::ProController: | 469 | case Settings::ControllerType::ProController: |
| 470 | case Settings::ControllerType::GameCube: | ||
| 464 | return QStringLiteral("image: url(:/controller/applet_pro_controller%0); "); | 471 | return QStringLiteral("image: url(:/controller/applet_pro_controller%0); "); |
| 465 | case Settings::ControllerType::DualJoyconDetached: | 472 | case Settings::ControllerType::DualJoyconDetached: |
| 466 | return QStringLiteral("image: url(:/controller/applet_dual_joycon%0); "); | 473 | return QStringLiteral("image: url(:/controller/applet_dual_joycon%0); "); |
diff --git a/src/yuzu/configuration/configure_input_player.cpp b/src/yuzu/configuration/configure_input_player.cpp index c9d19c948..21d0d3449 100644 --- a/src/yuzu/configuration/configure_input_player.cpp +++ b/src/yuzu/configuration/configure_input_player.cpp | |||
| @@ -467,10 +467,14 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i | |||
| 467 | 467 | ||
| 468 | UpdateControllerIcon(); | 468 | UpdateControllerIcon(); |
| 469 | UpdateControllerAvailableButtons(); | 469 | UpdateControllerAvailableButtons(); |
| 470 | UpdateControllerEnabledButtons(); | ||
| 471 | UpdateControllerButtonNames(); | ||
| 470 | UpdateMotionButtons(); | 472 | UpdateMotionButtons(); |
| 471 | connect(ui->comboControllerType, qOverload<int>(&QComboBox::currentIndexChanged), [this](int) { | 473 | connect(ui->comboControllerType, qOverload<int>(&QComboBox::currentIndexChanged), [this](int) { |
| 472 | UpdateControllerIcon(); | 474 | UpdateControllerIcon(); |
| 473 | UpdateControllerAvailableButtons(); | 475 | UpdateControllerAvailableButtons(); |
| 476 | UpdateControllerEnabledButtons(); | ||
| 477 | UpdateControllerButtonNames(); | ||
| 474 | UpdateMotionButtons(); | 478 | UpdateMotionButtons(); |
| 475 | }); | 479 | }); |
| 476 | 480 | ||
| @@ -558,9 +562,6 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i | |||
| 558 | &ConfigureInputPlayer::SaveProfile); | 562 | &ConfigureInputPlayer::SaveProfile); |
| 559 | 563 | ||
| 560 | LoadConfiguration(); | 564 | LoadConfiguration(); |
| 561 | |||
| 562 | // TODO(wwylele): enable this when we actually emulate it | ||
| 563 | ui->buttonHome->setEnabled(false); | ||
| 564 | ui->controllerFrame->SetPlayerInput(player_index, buttons_param, analogs_param); | 565 | ui->controllerFrame->SetPlayerInput(player_index, buttons_param, analogs_param); |
| 565 | ui->controllerFrame->SetConnectedStatus(ui->groupConnectedController->isChecked()); | 566 | ui->controllerFrame->SetConnectedStatus(ui->groupConnectedController->isChecked()); |
| 566 | } | 567 | } |
| @@ -924,6 +925,12 @@ void ConfigureInputPlayer::SetConnectableControllers() { | |||
| 924 | Settings::ControllerType::Handheld); | 925 | Settings::ControllerType::Handheld); |
| 925 | ui->comboControllerType->addItem(tr("Handheld")); | 926 | ui->comboControllerType->addItem(tr("Handheld")); |
| 926 | } | 927 | } |
| 928 | |||
| 929 | if (enable_all || npad_style_set.gamecube == 1) { | ||
| 930 | index_controller_type_pairs.emplace_back(ui->comboControllerType->count(), | ||
| 931 | Settings::ControllerType::GameCube); | ||
| 932 | ui->comboControllerType->addItem(tr("GameCube Controller")); | ||
| 933 | } | ||
| 927 | }; | 934 | }; |
| 928 | 935 | ||
| 929 | Core::System& system{Core::System::GetInstance()}; | 936 | Core::System& system{Core::System::GetInstance()}; |
| @@ -1014,7 +1021,7 @@ void ConfigureInputPlayer::UpdateControllerAvailableButtons() { | |||
| 1014 | 1021 | ||
| 1015 | // List of all the widgets that will be hidden by any of the following layouts that need | 1022 | // List of all the widgets that will be hidden by any of the following layouts that need |
| 1016 | // "unhidden" after the controller type changes | 1023 | // "unhidden" after the controller type changes |
| 1017 | const std::array<QWidget*, 9> layout_show = { | 1024 | const std::array<QWidget*, 11> layout_show = { |
| 1018 | ui->buttonShoulderButtonsSLSR, | 1025 | ui->buttonShoulderButtonsSLSR, |
| 1019 | ui->horizontalSpacerShoulderButtonsWidget, | 1026 | ui->horizontalSpacerShoulderButtonsWidget, |
| 1020 | ui->horizontalSpacerShoulderButtonsWidget2, | 1027 | ui->horizontalSpacerShoulderButtonsWidget2, |
| @@ -1024,6 +1031,8 @@ void ConfigureInputPlayer::UpdateControllerAvailableButtons() { | |||
| 1024 | ui->buttonShoulderButtonsRight, | 1031 | ui->buttonShoulderButtonsRight, |
| 1025 | ui->buttonMiscButtonsPlusHome, | 1032 | ui->buttonMiscButtonsPlusHome, |
| 1026 | ui->bottomRight, | 1033 | ui->bottomRight, |
| 1034 | ui->buttonMiscButtonsMinusGroup, | ||
| 1035 | ui->buttonMiscButtonsScreenshotGroup, | ||
| 1027 | }; | 1036 | }; |
| 1028 | 1037 | ||
| 1029 | for (auto* widget : layout_show) { | 1038 | for (auto* widget : layout_show) { |
| @@ -1056,6 +1065,14 @@ void ConfigureInputPlayer::UpdateControllerAvailableButtons() { | |||
| 1056 | ui->bottomLeft, | 1065 | ui->bottomLeft, |
| 1057 | }; | 1066 | }; |
| 1058 | break; | 1067 | break; |
| 1068 | case Settings::ControllerType::GameCube: | ||
| 1069 | layout_hidden = { | ||
| 1070 | ui->buttonShoulderButtonsSLSR, | ||
| 1071 | ui->horizontalSpacerShoulderButtonsWidget2, | ||
| 1072 | ui->buttonMiscButtonsMinusGroup, | ||
| 1073 | ui->buttonMiscButtonsScreenshotGroup, | ||
| 1074 | }; | ||
| 1075 | break; | ||
| 1059 | } | 1076 | } |
| 1060 | 1077 | ||
| 1061 | for (auto* widget : layout_hidden) { | 1078 | for (auto* widget : layout_hidden) { |
| @@ -1063,6 +1080,52 @@ void ConfigureInputPlayer::UpdateControllerAvailableButtons() { | |||
| 1063 | } | 1080 | } |
| 1064 | } | 1081 | } |
| 1065 | 1082 | ||
| 1083 | void ConfigureInputPlayer::UpdateControllerEnabledButtons() { | ||
| 1084 | auto layout = GetControllerTypeFromIndex(ui->comboControllerType->currentIndex()); | ||
| 1085 | if (debug) { | ||
| 1086 | layout = Settings::ControllerType::ProController; | ||
| 1087 | } | ||
| 1088 | |||
| 1089 | // List of all the widgets that will be disabled by any of the following layouts that need | ||
| 1090 | // "enabled" after the controller type changes | ||
| 1091 | const std::array<QWidget*, 4> layout_enable = { | ||
| 1092 | ui->buttonHome, | ||
| 1093 | ui->buttonLStickPressedGroup, | ||
| 1094 | ui->groupRStickPressed, | ||
| 1095 | ui->buttonShoulderButtonsButtonLGroup, | ||
| 1096 | }; | ||
| 1097 | |||
| 1098 | for (auto* widget : layout_enable) { | ||
| 1099 | widget->setEnabled(true); | ||
| 1100 | } | ||
| 1101 | |||
| 1102 | std::vector<QWidget*> layout_disable; | ||
| 1103 | switch (layout) { | ||
| 1104 | case Settings::ControllerType::ProController: | ||
| 1105 | case Settings::ControllerType::DualJoyconDetached: | ||
| 1106 | case Settings::ControllerType::Handheld: | ||
| 1107 | case Settings::ControllerType::LeftJoycon: | ||
| 1108 | case Settings::ControllerType::RightJoycon: | ||
| 1109 | // TODO(wwylele): enable this when we actually emulate it | ||
| 1110 | layout_disable = { | ||
| 1111 | ui->buttonHome, | ||
| 1112 | }; | ||
| 1113 | break; | ||
| 1114 | case Settings::ControllerType::GameCube: | ||
| 1115 | layout_disable = { | ||
| 1116 | ui->buttonHome, | ||
| 1117 | ui->buttonLStickPressedGroup, | ||
| 1118 | ui->groupRStickPressed, | ||
| 1119 | ui->buttonShoulderButtonsButtonLGroup, | ||
| 1120 | }; | ||
| 1121 | break; | ||
| 1122 | } | ||
| 1123 | |||
| 1124 | for (auto* widget : layout_disable) { | ||
| 1125 | widget->setEnabled(false); | ||
| 1126 | } | ||
| 1127 | } | ||
| 1128 | |||
| 1066 | void ConfigureInputPlayer::UpdateMotionButtons() { | 1129 | void ConfigureInputPlayer::UpdateMotionButtons() { |
| 1067 | if (debug) { | 1130 | if (debug) { |
| 1068 | // Motion isn't used with the debug controller, hide both groupboxes. | 1131 | // Motion isn't used with the debug controller, hide both groupboxes. |
| @@ -1085,6 +1148,11 @@ void ConfigureInputPlayer::UpdateMotionButtons() { | |||
| 1085 | ui->buttonMotionLeftGroup->hide(); | 1148 | ui->buttonMotionLeftGroup->hide(); |
| 1086 | ui->buttonMotionRightGroup->show(); | 1149 | ui->buttonMotionRightGroup->show(); |
| 1087 | break; | 1150 | break; |
| 1151 | case Settings::ControllerType::GameCube: | ||
| 1152 | // Hide both "Motion 1/2". | ||
| 1153 | ui->buttonMotionLeftGroup->hide(); | ||
| 1154 | ui->buttonMotionRightGroup->hide(); | ||
| 1155 | break; | ||
| 1088 | case Settings::ControllerType::DualJoyconDetached: | 1156 | case Settings::ControllerType::DualJoyconDetached: |
| 1089 | default: | 1157 | default: |
| 1090 | // Show both "Motion 1/2". | 1158 | // Show both "Motion 1/2". |
| @@ -1094,6 +1162,36 @@ void ConfigureInputPlayer::UpdateMotionButtons() { | |||
| 1094 | } | 1162 | } |
| 1095 | } | 1163 | } |
| 1096 | 1164 | ||
| 1165 | void ConfigureInputPlayer::UpdateControllerButtonNames() { | ||
| 1166 | auto layout = GetControllerTypeFromIndex(ui->comboControllerType->currentIndex()); | ||
| 1167 | if (debug) { | ||
| 1168 | layout = Settings::ControllerType::ProController; | ||
| 1169 | } | ||
| 1170 | |||
| 1171 | switch (layout) { | ||
| 1172 | case Settings::ControllerType::ProController: | ||
| 1173 | case Settings::ControllerType::DualJoyconDetached: | ||
| 1174 | case Settings::ControllerType::Handheld: | ||
| 1175 | case Settings::ControllerType::LeftJoycon: | ||
| 1176 | case Settings::ControllerType::RightJoycon: | ||
| 1177 | ui->buttonMiscButtonsPlusGroup->setTitle(tr("Plus")); | ||
| 1178 | ui->buttonShoulderButtonsButtonZLGroup->setTitle(tr("ZL")); | ||
| 1179 | ui->buttonShoulderButtonsZRGroup->setTitle(tr("ZR")); | ||
| 1180 | ui->buttonShoulderButtonsRGroup->setTitle(tr("R")); | ||
| 1181 | ui->LStick->setTitle(tr("Left Stick")); | ||
| 1182 | ui->RStick->setTitle(tr("Right Stick")); | ||
| 1183 | break; | ||
| 1184 | case Settings::ControllerType::GameCube: | ||
| 1185 | ui->buttonMiscButtonsPlusGroup->setTitle(tr("Start / Pause")); | ||
| 1186 | ui->buttonShoulderButtonsButtonZLGroup->setTitle(tr("L")); | ||
| 1187 | ui->buttonShoulderButtonsZRGroup->setTitle(tr("R")); | ||
| 1188 | ui->buttonShoulderButtonsRGroup->setTitle(tr("Z")); | ||
| 1189 | ui->LStick->setTitle(tr("Control Stick")); | ||
| 1190 | ui->RStick->setTitle(tr("C-Stick")); | ||
| 1191 | break; | ||
| 1192 | } | ||
| 1193 | } | ||
| 1194 | |||
| 1097 | void ConfigureInputPlayer::UpdateMappingWithDefaults() { | 1195 | void ConfigureInputPlayer::UpdateMappingWithDefaults() { |
| 1098 | if (ui->comboDevices->currentIndex() == 0) { | 1196 | if (ui->comboDevices->currentIndex() == 0) { |
| 1099 | return; | 1197 | return; |
diff --git a/src/yuzu/configuration/configure_input_player.h b/src/yuzu/configuration/configure_input_player.h index da2b89136..efe953fbc 100644 --- a/src/yuzu/configuration/configure_input_player.h +++ b/src/yuzu/configuration/configure_input_player.h | |||
| @@ -143,9 +143,15 @@ private: | |||
| 143 | /// Hides and disables controller settings based on the current controller type. | 143 | /// Hides and disables controller settings based on the current controller type. |
| 144 | void UpdateControllerAvailableButtons(); | 144 | void UpdateControllerAvailableButtons(); |
| 145 | 145 | ||
| 146 | /// Disables controller settings based on the current controller type. | ||
| 147 | void UpdateControllerEnabledButtons(); | ||
| 148 | |||
| 146 | /// Shows or hides motion groupboxes based on the current controller type. | 149 | /// Shows or hides motion groupboxes based on the current controller type. |
| 147 | void UpdateMotionButtons(); | 150 | void UpdateMotionButtons(); |
| 148 | 151 | ||
| 152 | /// Alters the button names based on the current controller type. | ||
| 153 | void UpdateControllerButtonNames(); | ||
| 154 | |||
| 149 | /// Gets the default controller mapping for this device and auto configures the input to match. | 155 | /// Gets the default controller mapping for this device and auto configures the input to match. |
| 150 | void UpdateMappingWithDefaults(); | 156 | void UpdateMappingWithDefaults(); |
| 151 | 157 | ||
diff --git a/src/yuzu/configuration/configure_input_player_widget.cpp b/src/yuzu/configuration/configure_input_player_widget.cpp index 0e8a964d2..61ba91cef 100644 --- a/src/yuzu/configuration/configure_input_player_widget.cpp +++ b/src/yuzu/configuration/configure_input_player_widget.cpp | |||
| @@ -227,6 +227,9 @@ void PlayerControlPreview::paintEvent(QPaintEvent* event) { | |||
| 227 | case Settings::ControllerType::RightJoycon: | 227 | case Settings::ControllerType::RightJoycon: |
| 228 | DrawRightController(p, center); | 228 | DrawRightController(p, center); |
| 229 | break; | 229 | break; |
| 230 | case Settings::ControllerType::GameCube: | ||
| 231 | DrawGCController(p, center); | ||
| 232 | break; | ||
| 230 | case Settings::ControllerType::ProController: | 233 | case Settings::ControllerType::ProController: |
| 231 | default: | 234 | default: |
| 232 | DrawProController(p, center); | 235 | DrawProController(p, center); |