From 7fe455e42ea1a8d5e702258212d54f21f1f31610 Mon Sep 17 00:00:00 2001 From: german77 Date: Sat, 4 Dec 2021 19:37:03 -0600 Subject: core/hid: Ensure only valid npad are connected --- src/core/hid/emulated_controller.cpp | 43 +++++++ src/core/hid/emulated_controller.h | 14 +++ src/core/hid/hid_core.cpp | 10 ++ src/core/hid/hid_core.h | 2 +- src/core/hid/hid_types.h | 2 + src/core/hle/service/hid/controllers/npad.cpp | 30 +++-- src/yuzu/configuration/configure_input_player.cpp | 131 ++++++++++------------ src/yuzu/main.cpp | 3 + 8 files changed, 147 insertions(+), 88 deletions(-) diff --git a/src/core/hid/emulated_controller.cpp b/src/core/hid/emulated_controller.cpp index 466ff5542..720706794 100644 --- a/src/core/hid/emulated_controller.cpp +++ b/src/core/hid/emulated_controller.cpp @@ -866,7 +866,50 @@ void EmulatedController::SetLedPattern() { } } +void EmulatedController::SetSupportedNpadStyleTag(NpadStyleTag supported_styles) { + supported_style_tag = supported_styles; + if (!is_connected) { + return; + } + if (!IsControllerSupported()) { + LOG_ERROR(Service_HID, "Controller type {} is not supported. Disconnecting controller", + npad_type); + Disconnect(); + } +} + +bool EmulatedController::IsControllerSupported() const { + switch (npad_type) { + case NpadStyleIndex::ProController: + return supported_style_tag.fullkey; + case NpadStyleIndex::JoyconDual: + return supported_style_tag.joycon_dual; + case NpadStyleIndex::JoyconLeft: + return supported_style_tag.joycon_left; + case NpadStyleIndex::JoyconRight: + return supported_style_tag.joycon_right; + case NpadStyleIndex::GameCube: + return supported_style_tag.gamecube; + case NpadStyleIndex::Pokeball: + return supported_style_tag.palma; + case NpadStyleIndex::NES: + return supported_style_tag.lark; + case NpadStyleIndex::SNES: + return supported_style_tag.lucia; + case NpadStyleIndex::N64: + return supported_style_tag.lagoon; + case NpadStyleIndex::SegaGenesis: + return supported_style_tag.lager; + default: + return false; + } +} + void EmulatedController::Connect() { + if (!IsControllerSupported()) { + LOG_ERROR(Service_HID, "Controller type {} is not supported", npad_type); + return; + } { std::lock_guard lock{mutex}; if (is_configuring) { diff --git a/src/core/hid/emulated_controller.h b/src/core/hid/emulated_controller.h index 5887e3e38..425b3e7c4 100644 --- a/src/core/hid/emulated_controller.h +++ b/src/core/hid/emulated_controller.h @@ -160,6 +160,13 @@ public: */ NpadStyleIndex GetNpadStyleIndex(bool get_temporary_value = false) const; + /** + * Sets the supported controller types. Disconnects the controller if current type is not + * supported + * @param supported_styles bitflag with supported types + */ + void SetSupportedNpadStyleTag(NpadStyleTag supported_styles); + /// Sets the connected status to true void Connect(); @@ -310,6 +317,12 @@ private: /// Set the params for TAS devices void LoadTASParams(); + /** + * Checks the current controller type against the supported_style_tag + * @return true if the controller is supported + */ + bool IsControllerSupported() const; + /** * Updates the button status of the controller * @param callback A CallbackStatus containing the button status @@ -354,6 +367,7 @@ private: NpadIdType npad_id_type; NpadStyleIndex npad_type{NpadStyleIndex::None}; + NpadStyleTag supported_style_tag{NpadStyleSet::All}; bool is_connected{false}; bool is_configuring{false}; f32 motion_sensitivity{0.01f}; diff --git a/src/core/hid/hid_core.cpp b/src/core/hid/hid_core.cpp index 946adde00..0c3eb5a62 100644 --- a/src/core/hid/hid_core.cpp +++ b/src/core/hid/hid_core.cpp @@ -108,6 +108,16 @@ const EmulatedController* HIDCore::GetEmulatedControllerByIndex(std::size_t inde void HIDCore::SetSupportedStyleTag(NpadStyleTag style_tag) { supported_style_tag.raw = style_tag.raw; + player_1->SetSupportedNpadStyleTag(supported_style_tag); + player_2->SetSupportedNpadStyleTag(supported_style_tag); + player_3->SetSupportedNpadStyleTag(supported_style_tag); + player_4->SetSupportedNpadStyleTag(supported_style_tag); + player_5->SetSupportedNpadStyleTag(supported_style_tag); + player_6->SetSupportedNpadStyleTag(supported_style_tag); + player_7->SetSupportedNpadStyleTag(supported_style_tag); + player_8->SetSupportedNpadStyleTag(supported_style_tag); + other->SetSupportedNpadStyleTag(supported_style_tag); + handheld->SetSupportedNpadStyleTag(supported_style_tag); } NpadStyleTag HIDCore::GetSupportedStyleTag() const { diff --git a/src/core/hid/hid_core.h b/src/core/hid/hid_core.h index 140a0e962..2fb0f7e19 100644 --- a/src/core/hid/hid_core.h +++ b/src/core/hid/hid_core.h @@ -73,7 +73,7 @@ private: std::unique_ptr handheld; std::unique_ptr console; std::unique_ptr devices; - NpadStyleTag supported_style_tag; + NpadStyleTag supported_style_tag{NpadStyleSet::All}; }; } // namespace Core::HID diff --git a/src/core/hid/hid_types.h b/src/core/hid/hid_types.h index 780659b86..7c12f01fc 100644 --- a/src/core/hid/hid_types.h +++ b/src/core/hid/hid_types.h @@ -256,6 +256,8 @@ enum class NpadStyleSet : u32 { Lager = 1U << 11, SystemExt = 1U << 29, System = 1U << 30, + + All = 0xFFFFFFFFU, }; static_assert(sizeof(NpadStyleSet) == 4, "NpadStyleSet is an invalid size"); diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp index 6916930f7..ae56f10cf 100644 --- a/src/core/hle/service/hid/controllers/npad.cpp +++ b/src/core/hle/service/hid/controllers/npad.cpp @@ -126,8 +126,11 @@ void Controller_NPad::ControllerUpdate(Core::HID::ControllerTriggerType type, } void Controller_NPad::InitNewlyAddedController(Core::HID::NpadIdType npad_id) { - LOG_DEBUG(Service_HID, "Npad connected {}", npad_id); auto& controller = GetControllerFromNpadIdType(npad_id); + if (!IsControllerSupported(controller.device->GetNpadStyleIndex())) { + return; + } + LOG_DEBUG(Service_HID, "Npad connected {}", npad_id); const auto controller_type = controller.device->GetNpadStyleIndex(); auto& shared_memory = controller.shared_memory_entry; if (controller_type == Core::HID::NpadStyleIndex::None) { @@ -255,19 +258,7 @@ void Controller_NPad::OnInit() { if (hid_core.GetSupportedStyleTag().raw == Core::HID::NpadStyleSet::None) { // We want to support all controllers - Core::HID::NpadStyleTag style{}; - style.handheld.Assign(1); - style.joycon_left.Assign(1); - style.joycon_right.Assign(1); - style.joycon_dual.Assign(1); - style.fullkey.Assign(1); - style.gamecube.Assign(1); - style.palma.Assign(1); - style.lark.Assign(1); - style.lucia.Assign(1); - style.lagoon.Assign(1); - style.lager.Assign(1); - hid_core.SetSupportedStyleTag(style); + hid_core.SetSupportedStyleTag({Core::HID::NpadStyleSet::All}); } supported_npad_id_types.resize(npad_id_list.size()); @@ -1072,13 +1063,18 @@ bool Controller_NPad::SwapNpadAssignment(Core::HID::NpadIdType npad_id_1, const auto& controller_2 = GetControllerFromNpadIdType(npad_id_2).device; const auto type_index_1 = controller_1->GetNpadStyleIndex(); const auto type_index_2 = controller_2->GetNpadStyleIndex(); + const auto is_connected_1 = controller_1->IsConnected(); + const auto is_connected_2 = controller_2->IsConnected(); - if (!IsControllerSupported(type_index_1) || !IsControllerSupported(type_index_2)) { + if (!IsControllerSupported(type_index_1) && is_connected_1) { + return false; + } + if (!IsControllerSupported(type_index_2) && is_connected_2) { return false; } - AddNewControllerAt(type_index_2, npad_id_1); - AddNewControllerAt(type_index_1, npad_id_2); + UpdateControllerAt(type_index_2, npad_id_1, is_connected_2); + UpdateControllerAt(type_index_1, npad_id_2, is_connected_1); return true; } diff --git a/src/yuzu/configuration/configure_input_player.cpp b/src/yuzu/configuration/configure_input_player.cpp index 34099bc83..8a8be8e40 100644 --- a/src/yuzu/configuration/configure_input_player.cpp +++ b/src/yuzu/configuration/configure_input_player.cpp @@ -907,88 +907,79 @@ void ConfigureInputPlayer::UpdateUI() { } void ConfigureInputPlayer::SetConnectableControllers() { - const auto add_controllers = [this](bool enable_all, - Core::HID::NpadStyleTag npad_style_set = {}) { - index_controller_type_pairs.clear(); - ui->comboControllerType->clear(); - - if (enable_all || npad_style_set.fullkey == 1) { - index_controller_type_pairs.emplace_back(ui->comboControllerType->count(), - Core::HID::NpadStyleIndex::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(), - Core::HID::NpadStyleIndex::JoyconDual); - ui->comboControllerType->addItem(tr("Dual Joycons")); - } + Core::HID::NpadStyleTag npad_style_set = hid_core.GetSupportedStyleTag(); + index_controller_type_pairs.clear(); + ui->comboControllerType->clear(); - if (enable_all || npad_style_set.joycon_left == 1) { - index_controller_type_pairs.emplace_back(ui->comboControllerType->count(), - Core::HID::NpadStyleIndex::JoyconLeft); - ui->comboControllerType->addItem(tr("Left Joycon")); - } + if (npad_style_set.fullkey == 1) { + index_controller_type_pairs.emplace_back(ui->comboControllerType->count(), + Core::HID::NpadStyleIndex::ProController); + ui->comboControllerType->addItem(tr("Pro Controller")); + } - if (enable_all || npad_style_set.joycon_right == 1) { - index_controller_type_pairs.emplace_back(ui->comboControllerType->count(), - Core::HID::NpadStyleIndex::JoyconRight); - ui->comboControllerType->addItem(tr("Right Joycon")); - } + if (npad_style_set.joycon_dual == 1) { + index_controller_type_pairs.emplace_back(ui->comboControllerType->count(), + Core::HID::NpadStyleIndex::JoyconDual); + ui->comboControllerType->addItem(tr("Dual Joycons")); + } - if (player_index == 0 && (enable_all || npad_style_set.handheld == 1)) { - index_controller_type_pairs.emplace_back(ui->comboControllerType->count(), - Core::HID::NpadStyleIndex::Handheld); - ui->comboControllerType->addItem(tr("Handheld")); - } + if (npad_style_set.joycon_left == 1) { + index_controller_type_pairs.emplace_back(ui->comboControllerType->count(), + Core::HID::NpadStyleIndex::JoyconLeft); + ui->comboControllerType->addItem(tr("Left Joycon")); + } - if (enable_all || npad_style_set.gamecube == 1) { - index_controller_type_pairs.emplace_back(ui->comboControllerType->count(), - Core::HID::NpadStyleIndex::GameCube); - ui->comboControllerType->addItem(tr("GameCube Controller")); - } + if (npad_style_set.joycon_right == 1) { + index_controller_type_pairs.emplace_back(ui->comboControllerType->count(), + Core::HID::NpadStyleIndex::JoyconRight); + ui->comboControllerType->addItem(tr("Right Joycon")); + } - // Disable all unsupported controllers - if (!Settings::values.enable_all_controllers) { - return; - } - if (enable_all || npad_style_set.palma == 1) { - index_controller_type_pairs.emplace_back(ui->comboControllerType->count(), - Core::HID::NpadStyleIndex::Pokeball); - ui->comboControllerType->addItem(tr("Poke Ball Plus")); - } + if (player_index == 0 && npad_style_set.handheld == 1) { + index_controller_type_pairs.emplace_back(ui->comboControllerType->count(), + Core::HID::NpadStyleIndex::Handheld); + ui->comboControllerType->addItem(tr("Handheld")); + } - if (enable_all || npad_style_set.lark == 1) { - index_controller_type_pairs.emplace_back(ui->comboControllerType->count(), - Core::HID::NpadStyleIndex::NES); - ui->comboControllerType->addItem(tr("NES Controller")); - } + if (npad_style_set.gamecube == 1) { + index_controller_type_pairs.emplace_back(ui->comboControllerType->count(), + Core::HID::NpadStyleIndex::GameCube); + ui->comboControllerType->addItem(tr("GameCube Controller")); + } - if (enable_all || npad_style_set.lucia == 1) { - index_controller_type_pairs.emplace_back(ui->comboControllerType->count(), - Core::HID::NpadStyleIndex::SNES); - ui->comboControllerType->addItem(tr("SNES Controller")); - } + // Disable all unsupported controllers + if (!Settings::values.enable_all_controllers) { + return; + } + if (npad_style_set.palma == 1) { + index_controller_type_pairs.emplace_back(ui->comboControllerType->count(), + Core::HID::NpadStyleIndex::Pokeball); + ui->comboControllerType->addItem(tr("Poke Ball Plus")); + } - if (enable_all || npad_style_set.lagoon == 1) { - index_controller_type_pairs.emplace_back(ui->comboControllerType->count(), - Core::HID::NpadStyleIndex::N64); - ui->comboControllerType->addItem(tr("N64 Controller")); - } + if (npad_style_set.lark == 1) { + index_controller_type_pairs.emplace_back(ui->comboControllerType->count(), + Core::HID::NpadStyleIndex::NES); + ui->comboControllerType->addItem(tr("NES Controller")); + } - if (enable_all || npad_style_set.lager == 1) { - index_controller_type_pairs.emplace_back(ui->comboControllerType->count(), - Core::HID::NpadStyleIndex::SegaGenesis); - ui->comboControllerType->addItem(tr("Sega Genesis")); - } - }; + if (npad_style_set.lucia == 1) { + index_controller_type_pairs.emplace_back(ui->comboControllerType->count(), + Core::HID::NpadStyleIndex::SNES); + ui->comboControllerType->addItem(tr("SNES Controller")); + } - if (!is_powered_on) { - add_controllers(true); - return; + if (npad_style_set.lagoon == 1) { + index_controller_type_pairs.emplace_back(ui->comboControllerType->count(), + Core::HID::NpadStyleIndex::N64); + ui->comboControllerType->addItem(tr("N64 Controller")); } - add_controllers(false, hid_core.GetSupportedStyleTag()); + if (npad_style_set.lager == 1) { + index_controller_type_pairs.emplace_back(ui->comboControllerType->count(), + Core::HID::NpadStyleIndex::SegaGenesis); + ui->comboControllerType->addItem(tr("Sega Genesis")); + } } Core::HID::NpadStyleIndex ConfigureInputPlayer::GetControllerTypeFromIndex(int index) const { diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index f266fd963..5a9dec8f3 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -1516,6 +1516,9 @@ void GMainWindow::ShutdownGame() { input_subsystem->GetTas()->Stop(); OnTasStateChanged(); + // Enable all controllers + system->HIDCore().SetSupportedStyleTag({Core::HID::NpadStyleSet::All}); + render_window->removeEventFilter(render_window); render_window->setAttribute(Qt::WA_Hover, false); -- cgit v1.2.3