diff options
Diffstat (limited to 'src/yuzu/configuration/configure_input_player.cpp')
| -rw-r--r-- | src/yuzu/configuration/configure_input_player.cpp | 259 |
1 files changed, 201 insertions, 58 deletions
diff --git a/src/yuzu/configuration/configure_input_player.cpp b/src/yuzu/configuration/configure_input_player.cpp index 46ea026e4..21d0d3449 100644 --- a/src/yuzu/configuration/configure_input_player.cpp +++ b/src/yuzu/configuration/configure_input_player.cpp @@ -23,6 +23,7 @@ #include "ui_configure_input_player.h" #include "yuzu/configuration/config.h" #include "yuzu/configuration/configure_input_player.h" +#include "yuzu/configuration/configure_input_player_widget.h" #include "yuzu/configuration/configure_vibration.h" #include "yuzu/configuration/input_profiles.h" #include "yuzu/util/limitable_input_dialog.h" @@ -254,11 +255,12 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i analog_map_range_groupbox = {ui->buttonLStickRangeGroup, ui->buttonRStickRangeGroup}; analog_map_range_spinbox = {ui->spinboxLStickRange, ui->spinboxRStickRange}; - const auto ConfigureButtonClick = [&](QPushButton* button, Common::ParamPackage* param, - int default_val, InputCommon::Polling::DeviceType type) { + const auto ConfigureButtonClick = [&](QPushButton* button, std::size_t button_id, + Common::ParamPackage* param, int default_val, + InputCommon::Polling::DeviceType type) { connect(button, &QPushButton::clicked, [=, this] { HandleClick( - button, + button, button_id, [=, this](Common::ParamPackage params) { // Workaround for ZL & ZR for analog triggers like on XBOX // controllers. Analog triggers (from controllers like the XBOX @@ -286,12 +288,11 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i continue; } - ConfigureButtonClick(button_map[button_id], &buttons_param[button_id], + ConfigureButtonClick(button_map[button_id], button_id, &buttons_param[button_id], Config::default_buttons[button_id], InputCommon::Polling::DeviceType::Button); button->setContextMenuPolicy(Qt::CustomContextMenu); - connect(button, &QPushButton::customContextMenuRequested, [=, this](const QPoint& menu_location) { QMenu context_menu; @@ -300,6 +301,7 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i button_map[button_id]->setText(tr("[not set]")); }); context_menu.exec(button_map[button_id]->mapToGlobal(menu_location)); + ui->controllerFrame->SetPlayerInput(player_index, buttons_param, analogs_param); }); } @@ -309,7 +311,7 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i continue; } - ConfigureButtonClick(motion_map[motion_id], &motions_param[motion_id], + ConfigureButtonClick(motion_map[motion_id], motion_id, &motions_param[motion_id], Config::default_motions[motion_id], InputCommon::Polling::DeviceType::Motion); @@ -348,7 +350,7 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i } } HandleClick( - analog_map_buttons[analog_id][sub_button_id], + analog_map_buttons[analog_id][sub_button_id], analog_id, [=, this](const Common::ParamPackage& params) { SetAnalogParam(params, analogs_param[analog_id], analog_sub_buttons[sub_button_id]); @@ -358,41 +360,43 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i analog_button->setContextMenuPolicy(Qt::CustomContextMenu); - connect(analog_button, &QPushButton::customContextMenuRequested, - [=, this](const QPoint& menu_location) { - QMenu context_menu; - context_menu.addAction(tr("Clear"), [&] { - analogs_param[analog_id].Clear(); - analog_map_buttons[analog_id][sub_button_id]->setText(tr("[not set]")); - }); - context_menu.addAction(tr("Invert axis"), [&] { - if (sub_button_id == 2 || sub_button_id == 3) { - const bool invert_value = - analogs_param[analog_id].Get("invert_x", "+") == "-"; - const std::string invert_str = invert_value ? "+" : "-"; - analogs_param[analog_id].Set("invert_x", invert_str); - } - if (sub_button_id == 0 || sub_button_id == 1) { - const bool invert_value = - analogs_param[analog_id].Get("invert_y", "+") == "-"; - const std::string invert_str = invert_value ? "+" : "-"; - analogs_param[analog_id].Set("invert_y", invert_str); - } - for (int sub_button_id = 0; sub_button_id < ANALOG_SUB_BUTTONS_NUM; - ++sub_button_id) { - analog_map_buttons[analog_id][sub_button_id]->setText(AnalogToText( - analogs_param[analog_id], analog_sub_buttons[sub_button_id])); - } - }); - context_menu.exec(analog_map_buttons[analog_id][sub_button_id]->mapToGlobal( - menu_location)); + connect( + analog_button, &QPushButton::customContextMenuRequested, + [=, this](const QPoint& menu_location) { + QMenu context_menu; + context_menu.addAction(tr("Clear"), [&] { + analogs_param[analog_id].Clear(); + analog_map_buttons[analog_id][sub_button_id]->setText(tr("[not set]")); + }); + context_menu.addAction(tr("Invert axis"), [&] { + if (sub_button_id == 2 || sub_button_id == 3) { + const bool invert_value = + analogs_param[analog_id].Get("invert_x", "+") == "-"; + const std::string invert_str = invert_value ? "+" : "-"; + analogs_param[analog_id].Set("invert_x", invert_str); + } + if (sub_button_id == 0 || sub_button_id == 1) { + const bool invert_value = + analogs_param[analog_id].Get("invert_y", "+") == "-"; + const std::string invert_str = invert_value ? "+" : "-"; + analogs_param[analog_id].Set("invert_y", invert_str); + } + for (int sub_button_id = 0; sub_button_id < ANALOG_SUB_BUTTONS_NUM; + ++sub_button_id) { + analog_map_buttons[analog_id][sub_button_id]->setText(AnalogToText( + analogs_param[analog_id], analog_sub_buttons[sub_button_id])); + } }); + context_menu.exec( + analog_map_buttons[analog_id][sub_button_id]->mapToGlobal(menu_location)); + ui->controllerFrame->SetPlayerInput(player_index, buttons_param, analogs_param); + }); } // Handle clicks for the modifier buttons as well. connect(analog_map_modifier_button[analog_id], &QPushButton::clicked, [=, this] { HandleClick( - analog_map_modifier_button[analog_id], + analog_map_modifier_button[analog_id], analog_id, [=, this](const Common::ParamPackage& params) { analogs_param[analog_id].Set("modifier", params.Serialize()); }, @@ -416,12 +420,14 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i [=, this] { const auto spinbox_value = analog_map_range_spinbox[analog_id]->value(); analogs_param[analog_id].Set("range", spinbox_value / 100.0f); + ui->controllerFrame->SetPlayerInput(player_index, buttons_param, analogs_param); }); connect(analog_map_deadzone_slider[analog_id], &QSlider::valueChanged, [=, this] { const auto slider_value = analog_map_deadzone_slider[analog_id]->value(); analog_map_deadzone_label[analog_id]->setText(tr("Deadzone: %1%").arg(slider_value)); analogs_param[analog_id].Set("deadzone", slider_value / 100.0f); + ui->controllerFrame->SetPlayerInput(player_index, buttons_param, analogs_param); }); connect(analog_map_modifier_slider[analog_id], &QSlider::valueChanged, [=, this] { @@ -433,8 +439,10 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i } // Player Connected checkbox - connect(ui->groupConnectedController, &QGroupBox::toggled, - [this](bool checked) { emit Connected(checked); }); + connect(ui->groupConnectedController, &QGroupBox::toggled, [this](bool checked) { + emit Connected(checked); + ui->controllerFrame->SetConnectedStatus(checked); + }); if (player_index == 0) { connect(ui->comboControllerType, qOverload<int>(&QComboBox::currentIndexChanged), @@ -459,10 +467,14 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i UpdateControllerIcon(); UpdateControllerAvailableButtons(); + UpdateControllerEnabledButtons(); + UpdateControllerButtonNames(); UpdateMotionButtons(); connect(ui->comboControllerType, qOverload<int>(&QComboBox::currentIndexChanged), [this](int) { UpdateControllerIcon(); UpdateControllerAvailableButtons(); + UpdateControllerEnabledButtons(); + UpdateControllerButtonNames(); UpdateMotionButtons(); }); @@ -550,9 +562,8 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i &ConfigureInputPlayer::SaveProfile); LoadConfiguration(); - - // TODO(wwylele): enable this when we actually emulate it - ui->buttonHome->setEnabled(false); + ui->controllerFrame->SetPlayerInput(player_index, buttons_param, analogs_param); + ui->controllerFrame->SetConnectedStatus(ui->groupConnectedController->isChecked()); } ConfigureInputPlayer::~ConfigureInputPlayer() = default; @@ -575,6 +586,14 @@ void ConfigureInputPlayer::ApplyConfiguration() { std::transform(motions_param.begin(), motions_param.end(), motions.begin(), [](const Common::ParamPackage& param) { return param.Serialize(); }); + + // Apply configuration for handheld + if (player_index == 0) { + auto& handheld = Settings::values.players.GetValue()[HANDHELD_INDEX]; + const auto handheld_connected = handheld.connected; + handheld = player; + handheld.connected = handheld_connected; + } } void ConfigureInputPlayer::TryConnectSelectedController() { @@ -585,6 +604,18 @@ void ConfigureInputPlayer::TryConnectSelectedController() { const auto player_connected = ui->groupConnectedController->isChecked() && controller_type != Settings::ControllerType::Handheld; + // Connect Handheld depending on Player 1's controller configuration. + if (player_index == 0) { + auto& handheld = Settings::values.players.GetValue()[HANDHELD_INDEX]; + const auto handheld_connected = ui->groupConnectedController->isChecked() && + controller_type == Settings::ControllerType::Handheld; + // Connect only if handheld is going from disconnected to connected + if (!handheld.connected && handheld_connected) { + UpdateController(controller_type, HANDHELD_INDEX, true); + } + handheld.connected = handheld_connected; + } + if (player.controller_type == controller_type && player.connected == player_connected) { // Set vibration devices in the event that the input device has changed. ConfigureVibration::SetVibrationDevices(player_index); @@ -596,22 +627,11 @@ void ConfigureInputPlayer::TryConnectSelectedController() { ConfigureVibration::SetVibrationDevices(player_index); - // Connect/Disconnect Handheld depending on Player 1's controller configuration. - if (player_index == 0) { - auto& handheld = Settings::values.players.GetValue()[HANDHELD_INDEX]; - if (controller_type == Settings::ControllerType::Handheld) { - handheld = player; - } - handheld.connected = ui->groupConnectedController->isChecked() && - controller_type == Settings::ControllerType::Handheld; - UpdateController(Settings::ControllerType::Handheld, HANDHELD_INDEX, handheld.connected); - } - if (!player.connected) { return; } - UpdateController(controller_type, player_index, player_connected); + UpdateController(controller_type, player_index, true); } void ConfigureInputPlayer::TryDisconnectSelectedController() { @@ -622,11 +642,28 @@ void ConfigureInputPlayer::TryDisconnectSelectedController() { const auto player_connected = ui->groupConnectedController->isChecked() && controller_type != Settings::ControllerType::Handheld; + // Disconnect Handheld depending on Player 1's controller configuration. + if (player_index == 0 && player.controller_type == Settings::ControllerType::Handheld) { + const auto& handheld = Settings::values.players.GetValue()[HANDHELD_INDEX]; + const auto handheld_connected = ui->groupConnectedController->isChecked() && + controller_type == Settings::ControllerType::Handheld; + // Disconnect only if handheld is going from connected to disconnected + if (handheld.connected && !handheld_connected) { + UpdateController(controller_type, HANDHELD_INDEX, false); + } + return; + } + // Do not do anything if the controller configuration has not changed. if (player.controller_type == controller_type && player.connected == player_connected) { return; } + // Do not disconnect if the controller is already disconnected + if (!player.connected) { + return; + } + // Disconnect the controller first. UpdateController(controller_type, player_index, false); } @@ -849,6 +886,7 @@ void ConfigureInputPlayer::UpdateUI() { modifier_label->setVisible(!is_controller); modifier_slider->setVisible(!is_controller); range_groupbox->setVisible(is_controller); + ui->controllerFrame->SetPlayerInput(player_index, buttons_param, analogs_param); } } @@ -858,7 +896,7 @@ void ConfigureInputPlayer::SetConnectableControllers() { index_controller_type_pairs.clear(); ui->comboControllerType->clear(); - if (enable_all || npad_style_set.pro_controller == 1) { + if (enable_all || npad_style_set.fullkey == 1) { index_controller_type_pairs.emplace_back(ui->comboControllerType->count(), Settings::ControllerType::ProController); ui->comboControllerType->addItem(tr("Pro Controller")); @@ -887,6 +925,12 @@ void ConfigureInputPlayer::SetConnectableControllers() { Settings::ControllerType::Handheld); ui->comboControllerType->addItem(tr("Handheld")); } + + if (enable_all || npad_style_set.gamecube == 1) { + index_controller_type_pairs.emplace_back(ui->comboControllerType->count(), + Settings::ControllerType::GameCube); + ui->comboControllerType->addItem(tr("GameCube Controller")); + } }; Core::System& system{Core::System::GetInstance()}; @@ -965,8 +1009,8 @@ void ConfigureInputPlayer::UpdateControllerIcon() { return QString{}; } }(); - - ui->controllerFrame->setStyleSheet(stylesheet.arg(theme)); + ui->controllerFrame->SetControllerType( + GetControllerTypeFromIndex(ui->comboControllerType->currentIndex())); } void ConfigureInputPlayer::UpdateControllerAvailableButtons() { @@ -977,7 +1021,7 @@ void ConfigureInputPlayer::UpdateControllerAvailableButtons() { // List of all the widgets that will be hidden by any of the following layouts that need // "unhidden" after the controller type changes - const std::array<QWidget*, 9> layout_show = { + const std::array<QWidget*, 11> layout_show = { ui->buttonShoulderButtonsSLSR, ui->horizontalSpacerShoulderButtonsWidget, ui->horizontalSpacerShoulderButtonsWidget2, @@ -987,6 +1031,8 @@ void ConfigureInputPlayer::UpdateControllerAvailableButtons() { ui->buttonShoulderButtonsRight, ui->buttonMiscButtonsPlusHome, ui->bottomRight, + ui->buttonMiscButtonsMinusGroup, + ui->buttonMiscButtonsScreenshotGroup, }; for (auto* widget : layout_show) { @@ -1019,6 +1065,14 @@ void ConfigureInputPlayer::UpdateControllerAvailableButtons() { ui->bottomLeft, }; break; + case Settings::ControllerType::GameCube: + layout_hidden = { + ui->buttonShoulderButtonsSLSR, + ui->horizontalSpacerShoulderButtonsWidget2, + ui->buttonMiscButtonsMinusGroup, + ui->buttonMiscButtonsScreenshotGroup, + }; + break; } for (auto* widget : layout_hidden) { @@ -1026,6 +1080,52 @@ void ConfigureInputPlayer::UpdateControllerAvailableButtons() { } } +void ConfigureInputPlayer::UpdateControllerEnabledButtons() { + auto layout = GetControllerTypeFromIndex(ui->comboControllerType->currentIndex()); + if (debug) { + layout = Settings::ControllerType::ProController; + } + + // List of all the widgets that will be disabled by any of the following layouts that need + // "enabled" after the controller type changes + const std::array<QWidget*, 4> layout_enable = { + ui->buttonHome, + ui->buttonLStickPressedGroup, + ui->groupRStickPressed, + ui->buttonShoulderButtonsButtonLGroup, + }; + + for (auto* widget : layout_enable) { + widget->setEnabled(true); + } + + std::vector<QWidget*> layout_disable; + switch (layout) { + case Settings::ControllerType::ProController: + case Settings::ControllerType::DualJoyconDetached: + case Settings::ControllerType::Handheld: + case Settings::ControllerType::LeftJoycon: + case Settings::ControllerType::RightJoycon: + // TODO(wwylele): enable this when we actually emulate it + layout_disable = { + ui->buttonHome, + }; + break; + case Settings::ControllerType::GameCube: + layout_disable = { + ui->buttonHome, + ui->buttonLStickPressedGroup, + ui->groupRStickPressed, + ui->buttonShoulderButtonsButtonLGroup, + }; + break; + } + + for (auto* widget : layout_disable) { + widget->setEnabled(false); + } +} + void ConfigureInputPlayer::UpdateMotionButtons() { if (debug) { // Motion isn't used with the debug controller, hide both groupboxes. @@ -1048,6 +1148,11 @@ void ConfigureInputPlayer::UpdateMotionButtons() { ui->buttonMotionLeftGroup->hide(); ui->buttonMotionRightGroup->show(); break; + case Settings::ControllerType::GameCube: + // Hide both "Motion 1/2". + ui->buttonMotionLeftGroup->hide(); + ui->buttonMotionRightGroup->hide(); + break; case Settings::ControllerType::DualJoyconDetached: default: // Show both "Motion 1/2". @@ -1057,6 +1162,36 @@ void ConfigureInputPlayer::UpdateMotionButtons() { } } +void ConfigureInputPlayer::UpdateControllerButtonNames() { + auto layout = GetControllerTypeFromIndex(ui->comboControllerType->currentIndex()); + if (debug) { + layout = Settings::ControllerType::ProController; + } + + switch (layout) { + case Settings::ControllerType::ProController: + case Settings::ControllerType::DualJoyconDetached: + case Settings::ControllerType::Handheld: + case Settings::ControllerType::LeftJoycon: + case Settings::ControllerType::RightJoycon: + ui->buttonMiscButtonsPlusGroup->setTitle(tr("Plus")); + ui->buttonShoulderButtonsButtonZLGroup->setTitle(tr("ZL")); + ui->buttonShoulderButtonsZRGroup->setTitle(tr("ZR")); + ui->buttonShoulderButtonsRGroup->setTitle(tr("R")); + ui->LStick->setTitle(tr("Left Stick")); + ui->RStick->setTitle(tr("Right Stick")); + break; + case Settings::ControllerType::GameCube: + ui->buttonMiscButtonsPlusGroup->setTitle(tr("Start / Pause")); + ui->buttonShoulderButtonsButtonZLGroup->setTitle(tr("L")); + ui->buttonShoulderButtonsZRGroup->setTitle(tr("R")); + ui->buttonShoulderButtonsRGroup->setTitle(tr("Z")); + ui->LStick->setTitle(tr("Control Stick")); + ui->RStick->setTitle(tr("C-Stick")); + break; + } +} + void ConfigureInputPlayer::UpdateMappingWithDefaults() { if (ui->comboDevices->currentIndex() == 0) { return; @@ -1103,7 +1238,8 @@ void ConfigureInputPlayer::UpdateMappingWithDefaults() { } void ConfigureInputPlayer::HandleClick( - QPushButton* button, std::function<void(const Common::ParamPackage&)> new_input_setter, + QPushButton* button, std::size_t button_id, + std::function<void(const Common::ParamPackage&)> new_input_setter, InputCommon::Polling::DeviceType type) { if (button == ui->buttonMotionLeft || button == ui->buttonMotionRight) { button->setText(tr("Shake!")); @@ -1147,6 +1283,12 @@ void ConfigureInputPlayer::HandleClick( input_subsystem->GetMouseTouch()->BeginConfiguration(); } + if (type == InputCommon::Polling::DeviceType::Button) { + ui->controllerFrame->BeginMappingButton(button_id); + } else if (type == InputCommon::Polling::DeviceType::AnalogPreferred) { + ui->controllerFrame->BeginMappingAnalog(button_id); + } + timeout_timer->start(2500); // Cancel after 2.5 seconds poll_timer->start(50); // Check for new inputs every 50ms } @@ -1177,6 +1319,7 @@ void ConfigureInputPlayer::SetPollingResult(const Common::ParamPackage& params, UpdateUI(); UpdateInputDeviceCombobox(); + ui->controllerFrame->EndMapping(); input_setter = std::nullopt; } |
