hid: Fix controller connection/disconnection
This commit is contained in:
		| @@ -53,7 +53,6 @@ void EmulatedConsole::ReloadInput() { | ||||
|         touch_button_params.Set("x", x); | ||||
|         touch_button_params.Set("y", y); | ||||
|         touch_button_params.Set("touch_id", static_cast<int>(index)); | ||||
|         LOG_ERROR(Common, "{} ", touch_button_params.Serialize()); | ||||
|         touch_devices[index] = | ||||
|             Input::CreateDeviceFromString<Input::InputDevice>(touch_button_params.Serialize()); | ||||
|         if (!touch_devices[index]) { | ||||
|   | ||||
| @@ -54,6 +54,7 @@ Settings::ControllerType EmulatedController::MapNPadToSettingsType(NpadType type | ||||
| } | ||||
|  | ||||
| void EmulatedController::ReloadFromSettings() { | ||||
|     //LOG_ERROR(Service_HID, "reload config from settings {}", NpadIdTypeToIndex(npad_id_type)); | ||||
|     const auto player_index = NpadIdTypeToIndex(npad_id_type); | ||||
|     const auto& player = Settings::values.players.GetValue()[player_index]; | ||||
|  | ||||
| @@ -91,6 +92,7 @@ void EmulatedController::ReloadFromSettings() { | ||||
| } | ||||
|  | ||||
| void EmulatedController::ReloadInput() { | ||||
|     //LOG_ERROR(Service_HID, "reload config {}", NpadIdTypeToIndex(npad_id_type)); | ||||
|     // If you load any device here add the equivalent to the UnloadInput() function | ||||
|     const auto player_index = NpadIdTypeToIndex(npad_id_type); | ||||
|     const auto left_side = button_params[Settings::NativeButton::ZL]; | ||||
| @@ -187,11 +189,29 @@ void EmulatedController::UnloadInput() { | ||||
|  | ||||
| void EmulatedController::EnableConfiguration() { | ||||
|     is_configuring = true; | ||||
|     SaveCurrentConfig(); | ||||
|     temporary_is_connected = is_connected; | ||||
|     temporary_npad_type = npad_type; | ||||
| } | ||||
|  | ||||
| void EmulatedController::DisableConfiguration() { | ||||
|     is_configuring = false; | ||||
|  | ||||
|     // Apply temporary npad type to the real controller | ||||
|     if (temporary_npad_type != npad_type) { | ||||
|         if (is_connected) { | ||||
|             Disconnect(); | ||||
|         } | ||||
|         SetNpadType(temporary_npad_type); | ||||
|     } | ||||
|  | ||||
|     // Apply temporary connected status to the real controller | ||||
|     if (temporary_is_connected != is_connected) { | ||||
|         if (temporary_is_connected) { | ||||
|             Connect(); | ||||
|             return; | ||||
|         } | ||||
|         Disconnect(); | ||||
|     } | ||||
| } | ||||
|  | ||||
| bool EmulatedController::IsConfiguring() const { | ||||
| @@ -199,10 +219,6 @@ bool EmulatedController::IsConfiguring() const { | ||||
| } | ||||
|  | ||||
| void EmulatedController::SaveCurrentConfig() { | ||||
|     if (!is_configuring) { | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     const auto player_index = NpadIdTypeToIndex(npad_id_type); | ||||
|     auto& player = Settings::values.players.GetValue()[player_index]; | ||||
|     player.connected = is_connected; | ||||
| @@ -657,26 +673,47 @@ void EmulatedController::SetLedPattern() { | ||||
| } | ||||
|  | ||||
| void EmulatedController::Connect() { | ||||
|     std::lock_guard lock{mutex}; | ||||
|     if (is_connected) { | ||||
|         LOG_WARNING(Service_HID, "Tried to turn on a connected controller {}", npad_id_type); | ||||
|         return; | ||||
|     { | ||||
|         std::lock_guard lock{mutex}; | ||||
|         if (is_configuring) { | ||||
|             temporary_is_connected = true; | ||||
|             TriggerOnChange(ControllerTriggerType::Connected); | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         if (is_connected) { | ||||
|             return; | ||||
|         } | ||||
|         is_connected = true; | ||||
|     } | ||||
|     is_connected = true; | ||||
|     LOG_ERROR(Service_HID, "Connected controller {}", NpadIdTypeToIndex(npad_id_type)); | ||||
|     TriggerOnChange(ControllerTriggerType::Connected); | ||||
| } | ||||
|  | ||||
| void EmulatedController::Disconnect() { | ||||
|     std::lock_guard lock{mutex}; | ||||
|     if (!is_connected) { | ||||
|         LOG_WARNING(Service_HID, "Tried to turn off a disconnected controller {}", npad_id_type); | ||||
|         return; | ||||
|     { | ||||
|         std::lock_guard lock{mutex}; | ||||
|         if (is_configuring) { | ||||
|             temporary_is_connected = false; | ||||
|             LOG_ERROR(Service_HID, "Disconnected temporal controller {}", | ||||
|                       NpadIdTypeToIndex(npad_id_type)); | ||||
|             TriggerOnChange(ControllerTriggerType::Disconnected); | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         if (!is_connected) { | ||||
|             return; | ||||
|         } | ||||
|         is_connected = false; | ||||
|     } | ||||
|     is_connected = false; | ||||
|     LOG_ERROR(Service_HID, "Disconnected controller {}", NpadIdTypeToIndex(npad_id_type)); | ||||
|     TriggerOnChange(ControllerTriggerType::Disconnected); | ||||
| } | ||||
|  | ||||
| bool EmulatedController::IsConnected() const { | ||||
| bool EmulatedController::IsConnected(bool temporary) const { | ||||
|     if (temporary) { | ||||
|         return temporary_is_connected; | ||||
|     } | ||||
|     return is_connected; | ||||
| } | ||||
|  | ||||
| @@ -688,16 +725,35 @@ NpadIdType EmulatedController::GetNpadIdType() const { | ||||
|     return npad_id_type; | ||||
| } | ||||
|  | ||||
| NpadType EmulatedController::GetNpadType() const { | ||||
| NpadType EmulatedController::GetNpadType(bool temporary) const { | ||||
|     if (temporary) { | ||||
|         return temporary_npad_type; | ||||
|     } | ||||
|     return npad_type; | ||||
| } | ||||
|  | ||||
| void EmulatedController::SetNpadType(NpadType npad_type_) { | ||||
|     std::lock_guard lock{mutex}; | ||||
|     if (npad_type == npad_type_) { | ||||
|         return; | ||||
|     { | ||||
|         std::lock_guard lock{mutex}; | ||||
|  | ||||
|         if (is_configuring) { | ||||
|             if (temporary_npad_type == npad_type_) { | ||||
|                 return; | ||||
|             } | ||||
|             temporary_npad_type = npad_type_; | ||||
|             TriggerOnChange(ControllerTriggerType::Type); | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         if (npad_type == npad_type_) { | ||||
|             return; | ||||
|         } | ||||
|         if (is_connected) { | ||||
|             LOG_WARNING(Service_HID, "Controller {} type changed while it's connected", | ||||
|                         NpadIdTypeToIndex(npad_id_type)); | ||||
|         } | ||||
|         npad_type = npad_type_; | ||||
|     } | ||||
|     npad_type = npad_type_; | ||||
|     TriggerOnChange(ControllerTriggerType::Type); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -139,8 +139,12 @@ public: | ||||
|     /// Sets the NpadType for this controller | ||||
|     void SetNpadType(NpadType npad_type_); | ||||
|  | ||||
|     /// Gets the NpadType for this controller | ||||
|     NpadType GetNpadType() const; | ||||
|     /** | ||||
|      * Gets the NpadType for this controller | ||||
|      * @param Returns the temporary value if true | ||||
|      * @return NpadType set on the controller | ||||
|      */ | ||||
|     NpadType GetNpadType(bool temporary = false) const; | ||||
|  | ||||
|     /// Sets the connected status to true | ||||
|     void Connect(); | ||||
| @@ -148,8 +152,12 @@ public: | ||||
|     /// Sets the connected status to false | ||||
|     void Disconnect(); | ||||
|  | ||||
|     /// Returns true if the controller has the connected status | ||||
|     bool IsConnected() const; | ||||
|     /** | ||||
|      * Is the emulated connected | ||||
|      * @param Returns the temporary value if true | ||||
|      * @return true if the controller has the connected status | ||||
|      */ | ||||
|     bool IsConnected(bool temporary = false) const; | ||||
|  | ||||
|     /// Returns true if vibration is enabled | ||||
|     bool IsVibrationEnabled() const; | ||||
| @@ -323,7 +331,9 @@ private: | ||||
|  | ||||
|     NpadIdType npad_id_type; | ||||
|     NpadType npad_type{NpadType::None}; | ||||
|     NpadType temporary_npad_type{NpadType::None}; | ||||
|     bool is_connected{false}; | ||||
|     bool temporary_is_connected{false}; | ||||
|     bool is_configuring{false}; | ||||
|     bool is_vibration_enabled{true}; | ||||
|     f32 motion_sensitivity{0.01f}; | ||||
|   | ||||
| @@ -47,9 +47,9 @@ constexpr size_t NpadIdTypeToIndex(NpadIdType npad_id_type) { | ||||
|         return 6; | ||||
|     case NpadIdType::Player8: | ||||
|         return 7; | ||||
|     case NpadIdType::Other: | ||||
|         return 8; | ||||
|     case NpadIdType::Handheld: | ||||
|         return 8; | ||||
|     case NpadIdType::Other: | ||||
|         return 9; | ||||
|     default: | ||||
|         return 0; | ||||
| @@ -76,9 +76,9 @@ constexpr NpadIdType IndexToNpadIdType(size_t index) { | ||||
|     case 7: | ||||
|         return NpadIdType::Player8; | ||||
|     case 8: | ||||
|         return NpadIdType::Other; | ||||
|     case 9: | ||||
|         return NpadIdType::Handheld; | ||||
|     case 9: | ||||
|         return NpadIdType::Other; | ||||
|     default: | ||||
|         return NpadIdType::Invalid; | ||||
|     } | ||||
|   | ||||
| @@ -11,7 +11,7 @@ ControllerBase::~ControllerBase() = default; | ||||
|  | ||||
| void ControllerBase::ActivateController() { | ||||
|     if (is_activated) { | ||||
|         OnRelease(); | ||||
|         return; | ||||
|     } | ||||
|     is_activated = true; | ||||
|     OnInit(); | ||||
|   | ||||
| @@ -125,18 +125,22 @@ void Controller_NPad::ControllerUpdate(Core::HID::ControllerTriggerType type, | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     auto& controller = controller_data[controller_idx]; | ||||
|     const auto is_connected = controller.device->IsConnected(); | ||||
|     const auto npad_type = controller.device->GetNpadType(); | ||||
|     switch (type) { | ||||
|     case Core::HID::ControllerTriggerType::Connected: | ||||
|         InitNewlyAddedController(controller_idx); | ||||
|         break; | ||||
|     case Core::HID::ControllerTriggerType::Disconnected: | ||||
|         DisconnectNpadAtIndex(controller_idx); | ||||
|         if (is_connected == controller.is_connected) { | ||||
|             return; | ||||
|         } | ||||
|         UpdateControllerAt(npad_type, controller_idx, is_connected); | ||||
|         break; | ||||
|     case Core::HID::ControllerTriggerType::Type: { | ||||
|         auto& controller = controller_data[controller_idx]; | ||||
|         if (controller.device->IsConnected()) { | ||||
|             LOG_ERROR(Service_HID, "Controller type changed without turning off the controller"); | ||||
|         if (npad_type == controller.npad_type) { | ||||
|             return; | ||||
|         } | ||||
|         // UpdateControllerAt(npad_type, controller_idx, is_connected); | ||||
|         break; | ||||
|     } | ||||
|     default: | ||||
| @@ -146,6 +150,7 @@ void Controller_NPad::ControllerUpdate(Core::HID::ControllerTriggerType type, | ||||
|  | ||||
| void Controller_NPad::InitNewlyAddedController(std::size_t controller_idx) { | ||||
|     auto& controller = controller_data[controller_idx]; | ||||
|     LOG_ERROR(Service_HID, "Connect {} {}", controller_idx, controller.is_connected); | ||||
|     const auto controller_type = controller.device->GetNpadType(); | ||||
|     auto& shared_memory = controller.shared_memory_entry; | ||||
|     if (controller_type == Core::HID::NpadType::None) { | ||||
| @@ -235,20 +240,23 @@ void Controller_NPad::InitNewlyAddedController(std::size_t controller_idx) { | ||||
|     shared_memory.battery_level_left = battery_level.left.battery_level; | ||||
|     shared_memory.battery_level_right = battery_level.right.battery_level; | ||||
|  | ||||
|     controller.is_connected = true; | ||||
|     controller.device->Connect(); | ||||
|     SignalStyleSetChangedEvent(IndexToNPad(controller_idx)); | ||||
|     WriteEmptyEntry(controller.shared_memory_entry); | ||||
| } | ||||
|  | ||||
| void Controller_NPad::OnInit() { | ||||
|     if (!IsControllerActivated()) { | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     for (std::size_t i = 0; i < controller_data.size(); ++i) { | ||||
|         auto& controller = controller_data[i]; | ||||
|         controller.styleset_changed_event = | ||||
|             service_context.CreateEvent(fmt::format("npad:NpadStyleSetChanged_{}", i)); | ||||
|     } | ||||
|  | ||||
|     if (!IsControllerActivated()) { | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     if (system.HIDCore().GetSupportedStyleTag().raw == 0) { | ||||
|         // We want to support all controllers | ||||
|         Core::HID::NpadStyleTag style{}; | ||||
| @@ -277,20 +285,33 @@ void Controller_NPad::OnInit() { | ||||
|     for (auto& controller : controller_data) { | ||||
|         NPadGenericState dummy_pad_state{}; | ||||
|         auto& npad = controller.shared_memory_entry; | ||||
|         for (std::size_t i = 0; i < 17; ++i) { | ||||
|             dummy_pad_state.sampling_number = | ||||
|                 npad.fullkey_lifo.ReadCurrentEntry().sampling_number + 1; | ||||
|             npad.fullkey_lifo.WriteNextEntry(dummy_pad_state); | ||||
|             npad.handheld_lifo.WriteNextEntry(dummy_pad_state); | ||||
|             npad.joy_dual_lifo.WriteNextEntry(dummy_pad_state); | ||||
|             npad.joy_left_lifo.WriteNextEntry(dummy_pad_state); | ||||
|             npad.joy_right_lifo.WriteNextEntry(dummy_pad_state); | ||||
|             npad.joy_right_lifo.WriteNextEntry(dummy_pad_state); | ||||
|             npad.palma_lifo.WriteNextEntry(dummy_pad_state); | ||||
|         for (std::size_t i = 0; i < 19; ++i) { | ||||
|             WriteEmptyEntry(npad); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| void Controller_NPad::WriteEmptyEntry(NpadInternalState& npad) { | ||||
|     NPadGenericState dummy_pad_state{}; | ||||
|     NpadGcTriggerState dummy_gc_state{}; | ||||
|     dummy_pad_state.sampling_number = npad.fullkey_lifo.ReadCurrentEntry().sampling_number + 1; | ||||
|     npad.fullkey_lifo.WriteNextEntry(dummy_pad_state); | ||||
|     dummy_pad_state.sampling_number = npad.handheld_lifo.ReadCurrentEntry().sampling_number + 1; | ||||
|     npad.handheld_lifo.WriteNextEntry(dummy_pad_state); | ||||
|     dummy_pad_state.sampling_number = npad.joy_dual_lifo.ReadCurrentEntry().sampling_number + 1; | ||||
|     npad.joy_dual_lifo.WriteNextEntry(dummy_pad_state); | ||||
|     dummy_pad_state.sampling_number = npad.joy_left_lifo.ReadCurrentEntry().sampling_number + 1; | ||||
|     npad.joy_left_lifo.WriteNextEntry(dummy_pad_state); | ||||
|     dummy_pad_state.sampling_number = npad.joy_right_lifo.ReadCurrentEntry().sampling_number + 1; | ||||
|     npad.joy_right_lifo.WriteNextEntry(dummy_pad_state); | ||||
|     dummy_pad_state.sampling_number = npad.palma_lifo.ReadCurrentEntry().sampling_number + 1; | ||||
|     npad.palma_lifo.WriteNextEntry(dummy_pad_state); | ||||
|     dummy_pad_state.sampling_number = npad.system_ext_lifo.ReadCurrentEntry().sampling_number + 1; | ||||
|     npad.system_ext_lifo.WriteNextEntry(dummy_pad_state); | ||||
|     dummy_gc_state.sampling_number = npad.gc_trigger_lifo.ReadCurrentEntry().sampling_number + 1; | ||||
|     npad.gc_trigger_lifo.WriteNextEntry(dummy_gc_state); | ||||
| } | ||||
|  | ||||
| void Controller_NPad::OnRelease() { | ||||
|     for (std::size_t i = 0; i < controller_data.size(); ++i) { | ||||
|         auto& controller = controller_data[i]; | ||||
| @@ -359,6 +380,7 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* | ||||
|     if (!IsControllerActivated()) { | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     for (std::size_t i = 0; i < controller_data.size(); ++i) { | ||||
|         auto& controller = controller_data[i]; | ||||
|         auto& npad = controller.shared_memory_entry; | ||||
| @@ -366,6 +388,9 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* | ||||
|         const auto& controller_type = controller.device->GetNpadType(); | ||||
|  | ||||
|         if (controller_type == Core::HID::NpadType::None || !controller.device->IsConnected()) { | ||||
|             // Refresh shared memory | ||||
|             std::memcpy(data + NPAD_OFFSET + (i * sizeof(NpadInternalState)), | ||||
|                         &controller.shared_memory_entry, sizeof(NpadInternalState)); | ||||
|             continue; | ||||
|         } | ||||
|         const u32 npad_index = static_cast<u32>(i); | ||||
| @@ -830,14 +855,14 @@ void Controller_NPad::AddNewControllerAt(Core::HID::NpadType controller, std::si | ||||
|  | ||||
| void Controller_NPad::UpdateControllerAt(Core::HID::NpadType type, std::size_t npad_index, | ||||
|                                          bool connected) { | ||||
|     auto& controller = controller_data[npad_index].device; | ||||
|     auto& controller = controller_data[npad_index]; | ||||
|     if (!connected) { | ||||
|         DisconnectNpadAtIndex(npad_index); | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     controller->SetNpadType(type); | ||||
|     controller->Connect(); | ||||
|     controller.device->SetNpadType(type); | ||||
|     controller.device->Connect(); | ||||
|     InitNewlyAddedController(npad_index); | ||||
| } | ||||
|  | ||||
| @@ -847,14 +872,13 @@ void Controller_NPad::DisconnectNpad(u32 npad_id) { | ||||
|  | ||||
| void Controller_NPad::DisconnectNpadAtIndex(std::size_t npad_index) { | ||||
|     auto& controller = controller_data[npad_index]; | ||||
|     LOG_ERROR(Service_HID, "Disconnect {} {}", npad_index, controller.is_connected); | ||||
|     for (std::size_t device_idx = 0; device_idx < controller.vibration.size(); ++device_idx) { | ||||
|         // Send an empty vibration to stop any vibrations. | ||||
|         VibrateControllerAtIndex(npad_index, device_idx, {}); | ||||
|         controller.vibration[device_idx].device_mounted = false; | ||||
|     } | ||||
|  | ||||
|     controller.device->Disconnect(); | ||||
|  | ||||
|     auto& shared_memory_entry = controller.shared_memory_entry; | ||||
|     shared_memory_entry.style_set.raw = 0; // Zero out | ||||
|     shared_memory_entry.device_type.raw = 0; | ||||
| @@ -868,7 +892,10 @@ void Controller_NPad::DisconnectNpadAtIndex(std::size_t npad_index) { | ||||
|     shared_memory_entry.assignment_mode = NpadJoyAssignmentMode::Dual; | ||||
|     shared_memory_entry.footer_type = AppletFooterUiType::None; | ||||
|  | ||||
|     controller.is_connected = false; | ||||
|     controller.device->Disconnect(); | ||||
|     SignalStyleSetChangedEvent(IndexToNPad(npad_index)); | ||||
|     WriteEmptyEntry(controller.shared_memory_entry); | ||||
| } | ||||
|  | ||||
| void Controller_NPad::SetGyroscopeZeroDriftMode(GyroscopeZeroDriftMode drift_mode) { | ||||
|   | ||||
| @@ -417,6 +417,8 @@ private: | ||||
|  | ||||
|         std::array<VibrationData, 2> vibration{}; | ||||
|         bool unintended_home_button_input_protection{}; | ||||
|         bool is_connected{}; | ||||
|         Core::HID::NpadType npad_type{Core::HID::NpadType::None}; | ||||
|  | ||||
|         // Current pad state | ||||
|         NPadGenericState npad_pad_state{}; | ||||
| @@ -435,6 +437,7 @@ private: | ||||
|     void InitNewlyAddedController(std::size_t controller_idx); | ||||
|     bool IsControllerSupported(Core::HID::NpadType controller) const; | ||||
|     void RequestPadStateUpdate(u32 npad_id); | ||||
|     void WriteEmptyEntry(NpadInternalState& npad); | ||||
|  | ||||
|     std::atomic<u32> press_state{}; | ||||
|  | ||||
|   | ||||
| @@ -114,6 +114,7 @@ void ConfigureInput::Initialize(InputCommon::InputSubsystem* input_subsystem, Co | ||||
|         player_tabs[i]->setLayout(new QHBoxLayout(player_tabs[i])); | ||||
|         player_tabs[i]->layout()->addWidget(player_controllers[i]); | ||||
|         connect(player_controllers[i], &ConfigureInputPlayer::Connected, [&, i](bool is_connected) { | ||||
|             // Ensures that the controllers are always connected in sequential order | ||||
|             if (is_connected) { | ||||
|                 for (std::size_t index = 0; index <= i; ++index) { | ||||
|                     player_connected[index]->setChecked(is_connected); | ||||
|   | ||||
| @@ -143,8 +143,26 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i | ||||
|       timeout_timer(std::make_unique<QTimer>()), poll_timer(std::make_unique<QTimer>()), | ||||
|       bottom_row(bottom_row), system{system_} { | ||||
|  | ||||
|     emulated_controller = system_.HIDCore().GetEmulatedControllerByIndex(player_index); | ||||
|     emulated_controller->EnableConfiguration(); | ||||
|     if (player_index == 0) { | ||||
|         auto* emulated_controller_p1 = | ||||
|             system.HIDCore().GetEmulatedController(Core::HID::NpadIdType::Player1); | ||||
|         auto* emulated_controller_hanheld = | ||||
|             system.HIDCore().GetEmulatedController(Core::HID::NpadIdType::Handheld); | ||||
|         emulated_controller_p1->SaveCurrentConfig(); | ||||
|         emulated_controller_p1->EnableConfiguration(); | ||||
|         emulated_controller_hanheld->SaveCurrentConfig(); | ||||
|         emulated_controller_hanheld->EnableConfiguration(); | ||||
|         if (emulated_controller_hanheld->IsConnected(true)) { | ||||
|             emulated_controller_p1->Disconnect(); | ||||
|             emulated_controller = emulated_controller_hanheld; | ||||
|         } else { | ||||
|             emulated_controller = emulated_controller_p1; | ||||
|         } | ||||
|     } else { | ||||
|         emulated_controller = system_.HIDCore().GetEmulatedControllerByIndex(player_index); | ||||
|         emulated_controller->SaveCurrentConfig(); | ||||
|         emulated_controller->EnableConfiguration(); | ||||
|     } | ||||
|     ui->setupUi(this); | ||||
|  | ||||
|     setFocusPolicy(Qt::ClickFocus); | ||||
| @@ -460,13 +478,36 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i | ||||
|     UpdateControllerEnabledButtons(); | ||||
|     UpdateControllerButtonNames(); | ||||
|     UpdateMotionButtons(); | ||||
|     connect(ui->comboControllerType, qOverload<int>(&QComboBox::currentIndexChanged), [this](int) { | ||||
|     connect(ui->comboControllerType, qOverload<int>(&QComboBox::currentIndexChanged), [this, player_index](int) { | ||||
|         UpdateControllerAvailableButtons(); | ||||
|         UpdateControllerEnabledButtons(); | ||||
|         UpdateControllerButtonNames(); | ||||
|         UpdateMotionButtons(); | ||||
|         emulated_controller->SetNpadType( | ||||
|             GetControllerTypeFromIndex(ui->comboControllerType->currentIndex())); | ||||
|         const Core::HID::NpadType type = GetControllerTypeFromIndex(ui->comboControllerType->currentIndex()); | ||||
|  | ||||
|         if (player_index == 0) { | ||||
|             auto* emulated_controller_p1 = | ||||
|                 system.HIDCore().GetEmulatedController(Core::HID::NpadIdType::Player1); | ||||
|             auto* emulated_controller_hanheld = | ||||
|                 system.HIDCore().GetEmulatedController(Core::HID::NpadIdType::Handheld); | ||||
|             bool is_connected = emulated_controller->IsConnected(true); | ||||
|  | ||||
|             emulated_controller_p1->SetNpadType(type); | ||||
|             emulated_controller_hanheld->SetNpadType(type); | ||||
|             if (is_connected) { | ||||
|                 if (type == Core::HID::NpadType::Handheld) { | ||||
|                     emulated_controller_p1->Disconnect(); | ||||
|                     emulated_controller_hanheld->Connect(); | ||||
|                     emulated_controller = emulated_controller_hanheld; | ||||
|                 } else { | ||||
|                     emulated_controller_hanheld->Disconnect(); | ||||
|                     emulated_controller_p1->Connect(); | ||||
|                     emulated_controller = emulated_controller_p1; | ||||
|                 } | ||||
|             } | ||||
|             ui->controllerFrame->SetController(emulated_controller); | ||||
|         } | ||||
|         emulated_controller->SetNpadType(type); | ||||
|     }); | ||||
|  | ||||
|     connect(ui->comboDevices, qOverload<int>(&QComboBox::activated), this, | ||||
| @@ -504,11 +545,35 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i | ||||
| } | ||||
|  | ||||
| ConfigureInputPlayer::~ConfigureInputPlayer() { | ||||
|     emulated_controller->DisableConfiguration(); | ||||
|     if (player_index == 0) { | ||||
|         auto* emulated_controller_p1 = | ||||
|             system.HIDCore().GetEmulatedController(Core::HID::NpadIdType::Player1); | ||||
|         auto* emulated_controller_hanheld = | ||||
|             system.HIDCore().GetEmulatedController(Core::HID::NpadIdType::Handheld); | ||||
|         emulated_controller_p1->DisableConfiguration(); | ||||
|         emulated_controller_hanheld->DisableConfiguration(); | ||||
|     } else { | ||||
|         emulated_controller->DisableConfiguration(); | ||||
|     } | ||||
| }; | ||||
|  | ||||
| void ConfigureInputPlayer::ApplyConfiguration() { | ||||
|     if (player_index == 0) { | ||||
|         auto* emulated_controller_p1 = | ||||
|             system.HIDCore().GetEmulatedController(Core::HID::NpadIdType::Player1); | ||||
|         auto* emulated_controller_hanheld = | ||||
|             system.HIDCore().GetEmulatedController(Core::HID::NpadIdType::Handheld); | ||||
|         emulated_controller_p1->DisableConfiguration(); | ||||
|         emulated_controller_p1->SaveCurrentConfig(); | ||||
|         emulated_controller_p1->EnableConfiguration(); | ||||
|         emulated_controller_hanheld->DisableConfiguration(); | ||||
|         emulated_controller_hanheld->SaveCurrentConfig(); | ||||
|         emulated_controller_hanheld->EnableConfiguration(); | ||||
|         return; | ||||
|     } | ||||
|     emulated_controller->DisableConfiguration(); | ||||
|     emulated_controller->SaveCurrentConfig(); | ||||
|     emulated_controller->EnableConfiguration(); | ||||
| } | ||||
|  | ||||
| void ConfigureInputPlayer::showEvent(QShowEvent* event) { | ||||
| @@ -535,9 +600,9 @@ void ConfigureInputPlayer::RetranslateUI() { | ||||
| void ConfigureInputPlayer::LoadConfiguration() { | ||||
|     UpdateUI(); | ||||
|     UpdateInputDeviceCombobox(); | ||||
|     const int comboBoxIndex = GetIndexFromControllerType(emulated_controller->GetNpadType()); | ||||
|     const int comboBoxIndex = GetIndexFromControllerType(emulated_controller->GetNpadType(true)); | ||||
|     ui->comboControllerType->setCurrentIndex(comboBoxIndex); | ||||
|     ui->groupConnectedController->setChecked(emulated_controller->IsConnected()); | ||||
|     ui->groupConnectedController->setChecked(emulated_controller->IsConnected(true)); | ||||
| } | ||||
|  | ||||
| void ConfigureInputPlayer::ConnectPlayer(bool connected) { | ||||
|   | ||||
| @@ -145,7 +145,7 @@ void PlayerControlPreview::ControllerUpdate(Core::HID::ControllerTriggerType typ | ||||
|         needs_redraw = true; | ||||
|         break; | ||||
|     case Core::HID::ControllerTriggerType::Type: | ||||
|         controller_type = controller->GetNpadType(); | ||||
|         controller_type = controller->GetNpadType(true); | ||||
|         needs_redraw = true; | ||||
|         break; | ||||
|     case Core::HID::ControllerTriggerType::Color: | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 german77
					german77