From 102630f2b29b654146a50c8075316eefadbff763 Mon Sep 17 00:00:00 2001 From: Morph <39850852+Morph1984@users.noreply.github.com> Date: Fri, 20 Nov 2020 09:48:26 -0500 Subject: [PATCH] configure_input_player: Use the npad style set to show the available controllers This will reduce the likelihood of an invalid controller type to be set within a game --- .../configuration/configure_input_player.cpp | 138 +++++++++++------- .../configuration/configure_input_player.h | 13 ++ 2 files changed, 96 insertions(+), 55 deletions(-) diff --git a/src/yuzu/configuration/configure_input_player.cpp b/src/yuzu/configuration/configure_input_player.cpp index 56ab32a35..918bfb56b 100644 --- a/src/yuzu/configuration/configure_input_player.cpp +++ b/src/yuzu/configuration/configure_input_player.cpp @@ -27,6 +27,8 @@ #include "yuzu/configuration/input_profiles.h" #include "yuzu/util/limitable_input_dialog.h" +using namespace Service::HID; + const std::array ConfigureInputPlayer::analog_sub_buttons{{ "up", @@ -47,48 +49,12 @@ void UpdateController(Settings::ControllerType controller_type, std::size_t npad } Service::SM::ServiceManager& sm = system.ServiceManager(); - auto& npad = - sm.GetService("hid") - ->GetAppletResource() - ->GetController(Service::HID::HidController::NPad); + auto& npad = sm.GetService("hid")->GetAppletResource()->GetController( + HidController::NPad); npad.UpdateControllerAt(npad.MapSettingsTypeToNPad(controller_type), npad_index, connected); } -/// Maps the controller type combobox index to Controller Type enum -constexpr Settings::ControllerType GetControllerTypeFromIndex(int index) { - switch (index) { - case 0: - default: - return Settings::ControllerType::ProController; - case 1: - return Settings::ControllerType::DualJoyconDetached; - case 2: - return Settings::ControllerType::LeftJoycon; - case 3: - return Settings::ControllerType::RightJoycon; - case 4: - return Settings::ControllerType::Handheld; - } -} - -/// Maps the Controller Type enum to controller type combobox index -constexpr int GetIndexFromControllerType(Settings::ControllerType type) { - switch (type) { - case Settings::ControllerType::ProController: - default: - return 0; - case Settings::ControllerType::DualJoyconDetached: - return 1; - case Settings::ControllerType::LeftJoycon: - return 2; - case Settings::ControllerType::RightJoycon: - return 3; - case Settings::ControllerType::Handheld: - return 4; - } -} - QString GetKeyName(int key_code) { switch (key_code) { case Qt::LeftButton: @@ -453,18 +419,7 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i connect(ui->groupConnectedController, &QGroupBox::toggled, [this](bool checked) { emit Connected(checked); }); - // Set up controller type. Only Player 1 can choose Handheld. - ui->comboControllerType->clear(); - - QStringList controller_types = { - tr("Pro Controller"), - tr("Dual Joycons"), - tr("Left Joycon"), - tr("Right Joycon"), - }; - if (player_index == 0) { - controller_types.append(tr("Handheld")); connect(ui->comboControllerType, qOverload(&QComboBox::currentIndexChanged), [this](int index) { emit HandheldStateChanged(GetControllerTypeFromIndex(index) == @@ -480,12 +435,9 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i if (debug) { ui->buttonScreenshot->setEnabled(false); ui->buttonHome->setEnabled(false); - QStringList debug_controller_types = { - tr("Pro Controller"), - }; - ui->comboControllerType->addItems(debug_controller_types); + ui->comboControllerType->addItem(tr("Pro Controller")); } else { - ui->comboControllerType->addItems(controller_types); + SetConnectableControllers(); } UpdateControllerIcon(); @@ -667,7 +619,7 @@ void ConfigureInputPlayer::LoadConfiguration() { return; } - ui->comboControllerType->setCurrentIndex(static_cast(player.controller_type)); + ui->comboControllerType->setCurrentIndex(GetIndexFromControllerType(player.controller_type)); ui->groupConnectedController->setChecked( player.connected || (player_index == 0 && Settings::values.players.GetValue()[HANDHELD_INDEX].connected)); @@ -841,6 +793,82 @@ void ConfigureInputPlayer::UpdateUI() { } } +void ConfigureInputPlayer::SetConnectableControllers() { + const auto add_controllers = [this](bool enable_all, + Controller_NPad::NpadStyleSet npad_style_set = {}) { + index_controller_type_pairs.clear(); + ui->comboControllerType->clear(); + + if (enable_all || npad_style_set.pro_controller == 1) { + index_controller_type_pairs.emplace_back(ui->comboControllerType->count(), + Settings::ControllerType::ProController); + ui->comboControllerType->addItem(tr("Pro Controller")); + } + + if (enable_all || npad_style_set.joycon_dual == 1) { + index_controller_type_pairs.emplace_back(ui->comboControllerType->count(), + Settings::ControllerType::DualJoyconDetached); + ui->comboControllerType->addItem(tr("Dual Joycons")); + } + + if (enable_all || npad_style_set.joycon_left == 1) { + index_controller_type_pairs.emplace_back(ui->comboControllerType->count(), + Settings::ControllerType::LeftJoycon); + ui->comboControllerType->addItem(tr("Left Joycon")); + } + + if (enable_all || npad_style_set.joycon_right == 1) { + index_controller_type_pairs.emplace_back(ui->comboControllerType->count(), + Settings::ControllerType::RightJoycon); + ui->comboControllerType->addItem(tr("Right Joycon")); + } + + if (player_index == 0 && (enable_all || npad_style_set.handheld == 1)) { + index_controller_type_pairs.emplace_back(ui->comboControllerType->count(), + Settings::ControllerType::Handheld); + ui->comboControllerType->addItem(tr("Handheld")); + } + }; + + Core::System& system{Core::System::GetInstance()}; + + if (!system.IsPoweredOn()) { + add_controllers(true); + return; + } + + Service::SM::ServiceManager& sm = system.ServiceManager(); + + auto& npad = sm.GetService("hid")->GetAppletResource()->GetController( + HidController::NPad); + + add_controllers(false, npad.GetSupportedStyleSet()); +} + +Settings::ControllerType ConfigureInputPlayer::GetControllerTypeFromIndex(int index) const { + const auto it = + std::find_if(index_controller_type_pairs.begin(), index_controller_type_pairs.end(), + [index](const auto& pair) { return pair.first == index; }); + + if (it == index_controller_type_pairs.end()) { + return Settings::ControllerType::ProController; + } + + return it->second; +} + +int ConfigureInputPlayer::GetIndexFromControllerType(Settings::ControllerType type) const { + const auto it = + std::find_if(index_controller_type_pairs.begin(), index_controller_type_pairs.end(), + [type](const auto& pair) { return pair.second == type; }); + + if (it == index_controller_type_pairs.end()) { + return -1; + } + + return it->first; +} + void ConfigureInputPlayer::UpdateInputDevices() { input_devices = input_subsystem->GetInputDevices(); ui->comboDevices->clear(); diff --git a/src/yuzu/configuration/configure_input_player.h b/src/yuzu/configuration/configure_input_player.h index 23cf6f958..9c30879a2 100644 --- a/src/yuzu/configuration/configure_input_player.h +++ b/src/yuzu/configuration/configure_input_player.h @@ -9,6 +9,7 @@ #include #include #include +#include #include @@ -112,6 +113,15 @@ private: /// Update UI to reflect current configuration. void UpdateUI(); + /// Sets the available controllers. + void SetConnectableControllers(); + + /// Gets the Controller Type for a given controller combobox index. + Settings::ControllerType GetControllerTypeFromIndex(int index) const; + + /// Gets the controller combobox index for a given Controller Type. + int GetIndexFromControllerType(Settings::ControllerType type) const; + /// Update the available input devices. void UpdateInputDevices(); @@ -151,6 +161,9 @@ private: std::unique_ptr timeout_timer; std::unique_ptr poll_timer; + /// Stores a pair of "Connected Controllers" combobox index and Controller Type enum. + std::vector> index_controller_type_pairs; + static constexpr int PLAYER_COUNT = 8; std::array player_connected_checkbox;