diff options
| author | bunnei <bunneidev@gmail.com> | 2020-11-25 11:20:46 -0800 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-11-25 11:20:46 -0800 | 
| commit | dcfa1992ea5fa450b64a75503ba487fba401e757 (patch) | |
| tree | 68adf47f034e256d19985aed5e578fb0b91d27d9 | |
| parent | b7f1095980d614842f6264667d9ddd38186d57ff (diff) | |
| parent | 8758378dc40e65239db9a1212e123c86200a3bdc (diff) | |
Merge pull request #4959 from Morph1984/emulated-controller-styleset
configure_input_player: Use the NpadStyleSet to limit the available controllers shown
| -rw-r--r-- | src/yuzu/applets/controller.cpp | 123 | ||||
| -rw-r--r-- | src/yuzu/applets/controller.h | 17 | ||||
| -rw-r--r-- | src/yuzu/configuration/configure_input_player.cpp | 138 | ||||
| -rw-r--r-- | src/yuzu/configuration/configure_input_player.h | 13 | 
4 files changed, 192 insertions, 99 deletions
diff --git a/src/yuzu/applets/controller.cpp b/src/yuzu/applets/controller.cpp index 8ecfec770..6944478f3 100644 --- a/src/yuzu/applets/controller.cpp +++ b/src/yuzu/applets/controller.cpp @@ -72,40 +72,6 @@ bool IsControllerCompatible(Settings::ControllerType controller_type,      }  } -/// 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; -    } -} -  } // namespace  QtControllerSelectorDialog::QtControllerSelectorDialog( @@ -184,6 +150,11 @@ QtControllerSelectorDialog::QtControllerSelectorDialog(      // This avoids unintentionally changing the states of elements while loading them in.      SetSupportedControllers();      DisableUnsupportedPlayers(); + +    for (std::size_t player_index = 0; player_index < NUM_PLAYERS; ++player_index) { +        SetEmulatedControllers(player_index); +    } +      LoadConfiguration();      for (std::size_t i = 0; i < NUM_PLAYERS; ++i) { @@ -223,8 +194,8 @@ QtControllerSelectorDialog::QtControllerSelectorDialog(          if (i == 0) {              connect(emulated_controllers[i], qOverload<int>(&QComboBox::currentIndexChanged), -                    [this](int index) { -                        UpdateDockedState(GetControllerTypeFromIndex(index) == +                    [this, i](int index) { +                        UpdateDockedState(GetControllerTypeFromIndex(index, i) ==                                            Settings::ControllerType::Handheld);                      });          } @@ -281,8 +252,8 @@ void QtControllerSelectorDialog::LoadConfiguration() {              (index == 0 && Settings::values.players.GetValue()[HANDHELD_INDEX].connected);          player_groupboxes[index]->setChecked(connected);          connected_controller_checkboxes[index]->setChecked(connected); -        emulated_controllers[index]->setCurrentIndex( -            GetIndexFromControllerType(Settings::values.players.GetValue()[index].controller_type)); +        emulated_controllers[index]->setCurrentIndex(GetIndexFromControllerType( +            Settings::values.players.GetValue()[index].controller_type, index));      }      UpdateDockedState(Settings::values.players.GetValue()[HANDHELD_INDEX].connected); @@ -338,7 +309,7 @@ bool QtControllerSelectorDialog::CheckIfParametersMet() {              }              const auto compatible = IsControllerCompatible( -                GetControllerTypeFromIndex(emulated_controllers[index]->currentIndex()), +                GetControllerTypeFromIndex(emulated_controllers[index]->currentIndex(), index),                  parameters);              // If any controller is found to be incompatible, return false early. @@ -422,6 +393,63 @@ void QtControllerSelectorDialog::SetSupportedControllers() {      }  } +void QtControllerSelectorDialog::SetEmulatedControllers(std::size_t player_index) { +    auto& pairs = index_controller_type_pairs[player_index]; + +    pairs.clear(); +    emulated_controllers[player_index]->clear(); + +    pairs.emplace_back(emulated_controllers[player_index]->count(), +                       Settings::ControllerType::ProController); +    emulated_controllers[player_index]->addItem(tr("Pro Controller")); + +    pairs.emplace_back(emulated_controllers[player_index]->count(), +                       Settings::ControllerType::DualJoyconDetached); +    emulated_controllers[player_index]->addItem(tr("Dual Joycons")); + +    pairs.emplace_back(emulated_controllers[player_index]->count(), +                       Settings::ControllerType::LeftJoycon); +    emulated_controllers[player_index]->addItem(tr("Left Joycon")); + +    pairs.emplace_back(emulated_controllers[player_index]->count(), +                       Settings::ControllerType::RightJoycon); +    emulated_controllers[player_index]->addItem(tr("Right Joycon")); + +    if (player_index == 0) { +        pairs.emplace_back(emulated_controllers[player_index]->count(), +                           Settings::ControllerType::Handheld); +        emulated_controllers[player_index]->addItem(tr("Handheld")); +    } +} + +Settings::ControllerType QtControllerSelectorDialog::GetControllerTypeFromIndex( +    int index, std::size_t player_index) const { +    const auto& pairs = index_controller_type_pairs[player_index]; + +    const auto it = std::find_if(pairs.begin(), pairs.end(), +                                 [index](const auto& pair) { return pair.first == index; }); + +    if (it == pairs.end()) { +        return Settings::ControllerType::ProController; +    } + +    return it->second; +} + +int QtControllerSelectorDialog::GetIndexFromControllerType(Settings::ControllerType type, +                                                           std::size_t player_index) const { +    const auto& pairs = index_controller_type_pairs[player_index]; + +    const auto it = std::find_if(pairs.begin(), pairs.end(), +                                 [type](const auto& pair) { return pair.second == type; }); + +    if (it == pairs.end()) { +        return 0; +    } + +    return it->first; +} +  void QtControllerSelectorDialog::UpdateControllerIcon(std::size_t player_index) {      if (!player_groupboxes[player_index]->isChecked()) {          connected_controller_icons[player_index]->setStyleSheet(QString{}); @@ -430,7 +458,8 @@ void QtControllerSelectorDialog::UpdateControllerIcon(std::size_t player_index)      }      const QString stylesheet = [this, player_index] { -        switch (GetControllerTypeFromIndex(emulated_controllers[player_index]->currentIndex())) { +        switch (GetControllerTypeFromIndex(emulated_controllers[player_index]->currentIndex(), +                                           player_index)) {          case Settings::ControllerType::ProController:              return QStringLiteral("image: url(:/controller/applet_pro_controller%0); ");          case Settings::ControllerType::DualJoyconDetached: @@ -446,6 +475,12 @@ void QtControllerSelectorDialog::UpdateControllerIcon(std::size_t player_index)          }      }(); +    if (stylesheet.isEmpty()) { +        connected_controller_icons[player_index]->setStyleSheet(QString{}); +        player_labels[player_index]->show(); +        return; +    } +      const QString theme = [] {          if (QIcon::themeName().contains(QStringLiteral("dark"))) {              return QStringLiteral("_dark"); @@ -463,8 +498,8 @@ void QtControllerSelectorDialog::UpdateControllerIcon(std::size_t player_index)  void QtControllerSelectorDialog::UpdateControllerState(std::size_t player_index) {      auto& player = Settings::values.players.GetValue()[player_index]; -    const auto controller_type = -        GetControllerTypeFromIndex(emulated_controllers[player_index]->currentIndex()); +    const auto controller_type = GetControllerTypeFromIndex( +        emulated_controllers[player_index]->currentIndex(), player_index);      const auto player_connected = player_groupboxes[player_index]->isChecked() &&                                    controller_type != Settings::ControllerType::Handheld; @@ -507,8 +542,8 @@ void QtControllerSelectorDialog::UpdateControllerState(std::size_t player_index)  void QtControllerSelectorDialog::UpdateLEDPattern(std::size_t player_index) {      if (!player_groupboxes[player_index]->isChecked() || -        GetControllerTypeFromIndex(emulated_controllers[player_index]->currentIndex()) == -            Settings::ControllerType::Handheld) { +        GetControllerTypeFromIndex(emulated_controllers[player_index]->currentIndex(), +                                   player_index) == Settings::ControllerType::Handheld) {          led_patterns_boxes[player_index][0]->setChecked(false);          led_patterns_boxes[player_index][1]->setChecked(false);          led_patterns_boxes[player_index][2]->setChecked(false); diff --git a/src/yuzu/applets/controller.h b/src/yuzu/applets/controller.h index 4344e1dd0..7a421d856 100644 --- a/src/yuzu/applets/controller.h +++ b/src/yuzu/applets/controller.h @@ -22,6 +22,10 @@ namespace InputCommon {  class InputSubsystem;  } +namespace Settings { +enum class ControllerType; +} +  namespace Ui {  class QtControllerSelectorDialog;  } @@ -57,6 +61,15 @@ private:      // Sets the controller icons for "Supported Controller Types".      void SetSupportedControllers(); +    // Sets the emulated controllers per player. +    void SetEmulatedControllers(std::size_t player_index); + +    // Gets the Controller Type for a given controller combobox index per player. +    Settings::ControllerType GetControllerTypeFromIndex(int index, std::size_t player_index) const; + +    // Gets the controller combobox index for a given Controller Type per player. +    int GetIndexFromControllerType(Settings::ControllerType type, std::size_t player_index) const; +      // Updates the controller icons per player.      void UpdateControllerIcon(std::size_t player_index); @@ -114,6 +127,10 @@ private:      // Comboboxes with a list of emulated controllers per player.      std::array<QComboBox*, NUM_PLAYERS> emulated_controllers; +    /// Pairs of emulated controller index and Controller Type enum per player. +    std::array<std::vector<std::pair<int, Settings::ControllerType>>, NUM_PLAYERS> +        index_controller_type_pairs; +      // Labels representing the number of connected controllers      // above the "Connected Controllers" checkboxes.      std::array<QLabel*, NUM_PLAYERS> connected_controller_labels; 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<std::string, ConfigureInputPlayer::ANALOG_SUB_BUTTONS_NUM>      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<Service::HID::Hid>("hid") -            ->GetAppletResource() -            ->GetController<Service::HID::Controller_NPad>(Service::HID::HidController::NPad); +    auto& npad = sm.GetService<Hid>("hid")->GetAppletResource()->GetController<Controller_NPad>( +        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<int>(&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<int>(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>("hid")->GetAppletResource()->GetController<Controller_NPad>( +        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 <memory>  #include <optional>  #include <string> +#include <vector>  #include <QWidget> @@ -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<QTimer> timeout_timer;      std::unique_ptr<QTimer> poll_timer; +    /// Stores a pair of "Connected Controllers" combobox index and Controller Type enum. +    std::vector<std::pair<int, Settings::ControllerType>> index_controller_type_pairs; +      static constexpr int PLAYER_COUNT = 8;      std::array<QCheckBox*, PLAYER_COUNT> player_connected_checkbox;  | 
