diff --git a/pcsx2-qt/QtHost.cpp b/pcsx2-qt/QtHost.cpp index 39966a8460..7b65b85049 100644 --- a/pcsx2-qt/QtHost.cpp +++ b/pcsx2-qt/QtHost.cpp @@ -54,7 +54,6 @@ static bool InitializeConfig(); static void HookSignals(); static bool SetCriticalFolders(); static void SetDefaultConfig(); -static void QueueSettingsSave(); static void SaveSettings(); } @@ -177,6 +176,11 @@ void QtHost::SetDefaultConfig() PAD::SetDefaultConfig(si); } +SettingsInterface* QtHost::GetBaseSettingsInterface() +{ + return s_base_settings_interface.get(); +} + std::string QtHost::GetBaseStringSettingValue(const char* section, const char* key, const char* default_value /*= ""*/) { auto lock = Host::GetSettingsLock(); diff --git a/pcsx2-qt/QtHost.h b/pcsx2-qt/QtHost.h index 91108cde87..5f6d21b34f 100644 --- a/pcsx2-qt/QtHost.h +++ b/pcsx2-qt/QtHost.h @@ -38,6 +38,7 @@ namespace QtHost void UpdateLogging(); /// Thread-safe settings access. + SettingsInterface* GetBaseSettingsInterface(); std::string GetBaseStringSettingValue(const char* section, const char* key, const char* default_value = ""); bool GetBaseBoolSettingValue(const char* section, const char* key, bool default_value = false); int GetBaseIntSettingValue(const char* section, const char* key, int default_value = 0); @@ -51,4 +52,5 @@ namespace QtHost bool AddBaseValueToStringList(const char* section, const char* key, const char* value); bool RemoveBaseValueFromStringList(const char* section, const char* key, const char* value); void RemoveBaseSettingValue(const char* section, const char* key); + void QueueSettingsSave(); } // namespace QtHost diff --git a/pcsx2-qt/Settings/ControllerBindingWidgets.cpp b/pcsx2-qt/Settings/ControllerBindingWidgets.cpp index 8f5f9f156b..2bbec8ccad 100644 --- a/pcsx2-qt/Settings/ControllerBindingWidgets.cpp +++ b/pcsx2-qt/Settings/ControllerBindingWidgets.cpp @@ -15,6 +15,7 @@ #include "PrecompiledHeader.h" +#include #include #include @@ -39,13 +40,11 @@ ControllerBindingWidget::ControllerBindingWidget(QWidget* parent, ControllerSett onTypeChanged(); SettingWidgetBinder::BindWidgetToStringSetting(nullptr, m_ui.controllerType, m_config_section, "Type", "None"); - connect(m_ui.controllerType, QOverload::of(&QComboBox::currentIndexChanged), this, - &ControllerBindingWidget::onTypeChanged); + connect(m_ui.controllerType, QOverload::of(&QComboBox::currentIndexChanged), this, &ControllerBindingWidget::onTypeChanged); + connect(m_ui.automaticBinding, &QPushButton::clicked, this, &ControllerBindingWidget::doAutomaticBinding); } -ControllerBindingWidget::~ControllerBindingWidget() -{ -} +ControllerBindingWidget::~ControllerBindingWidget() = default; void ControllerBindingWidget::populateControllerTypes() { @@ -80,6 +79,56 @@ void ControllerBindingWidget::onTypeChanged() m_ui.verticalLayout->addWidget(m_current_widget, 1); } +void ControllerBindingWidget::doAutomaticBinding() +{ + QMenu menu(this); + bool added = false; + + for (const QPair& dev : m_dialog->getDeviceList()) + { + // we set it as data, because the device list could get invalidated while the menu is up + QAction* action = menu.addAction(QStringLiteral("%1 (%2)").arg(dev.first).arg(dev.second)); + action->setData(dev.first); + connect(action, &QAction::triggered, this, [this, action]() { + doDeviceAutomaticBinding(action->data().toString()); + }); + added = true; + } + + if (!added) + { + QAction* action = menu.addAction(tr("No devices available")); + action->setEnabled(false); + } + + menu.exec(QCursor::pos()); +} + +void ControllerBindingWidget::doDeviceAutomaticBinding(const QString& device) +{ + std::vector> mapping = InputManager::GetGenericBindingMapping(device.toStdString()); + if (mapping.empty()) + { + QMessageBox::critical(QtUtils::GetRootWidget(this), tr("Automatic Binding"), + tr("No generic bindings were generated for device '%1'").arg(device)); + return; + } + + bool result; + { + auto lock = Host::GetSettingsLock(); + result = PAD::MapController(*QtHost::GetBaseSettingsInterface(), m_port_number, mapping); + } + + if (result) + { + // force a refresh after mapping + onTypeChanged(); + QtHost::QueueSettingsSave(); + g_emu_thread->applySettings(); + } +} + ////////////////////////////////////////////////////////////////////////// ControllerBindingWidget_Base::ControllerBindingWidget_Base(ControllerBindingWidget* parent) diff --git a/pcsx2-qt/Settings/ControllerBindingWidgets.h b/pcsx2-qt/Settings/ControllerBindingWidgets.h index d516f7cf54..392e7e6916 100644 --- a/pcsx2-qt/Settings/ControllerBindingWidgets.h +++ b/pcsx2-qt/Settings/ControllerBindingWidgets.h @@ -39,9 +39,11 @@ public: private Q_SLOTS: void onTypeChanged(); + void doAutomaticBinding(); private: void populateControllerTypes(); + void doDeviceAutomaticBinding(const QString& device); Ui::ControllerBindingWidget m_ui; diff --git a/pcsx2-qt/Settings/ControllerSettingsDialog.cpp b/pcsx2-qt/Settings/ControllerSettingsDialog.cpp index f10dab90c9..3634192fbf 100644 --- a/pcsx2-qt/Settings/ControllerSettingsDialog.cpp +++ b/pcsx2-qt/Settings/ControllerSettingsDialog.cpp @@ -89,18 +89,29 @@ void ControllerSettingsDialog::onCategoryCurrentRowChanged(int row) void ControllerSettingsDialog::onInputDevicesEnumerated(const QList>& devices) { + m_device_list = devices; for (const QPair& device : devices) m_global_settings->addDeviceToList(device.first, device.second); } void ControllerSettingsDialog::onInputDeviceConnected(const QString& identifier, const QString& device_name) { + m_device_list.emplace_back(identifier, device_name); m_global_settings->addDeviceToList(identifier, device_name); g_emu_thread->enumerateVibrationMotors(); } void ControllerSettingsDialog::onInputDeviceDisconnected(const QString& identifier) { + for (auto iter = m_device_list.begin(); iter != m_device_list.end(); ++iter) + { + if (iter->first == identifier) + { + m_device_list.erase(iter); + break; + } + } + m_global_settings->removeDeviceFromList(identifier); g_emu_thread->enumerateVibrationMotors(); } diff --git a/pcsx2-qt/Settings/ControllerSettingsDialog.h b/pcsx2-qt/Settings/ControllerSettingsDialog.h index 5a5a982d6d..768d71320d 100644 --- a/pcsx2-qt/Settings/ControllerSettingsDialog.h +++ b/pcsx2-qt/Settings/ControllerSettingsDialog.h @@ -50,6 +50,7 @@ public: HotkeySettingsWidget* getHotkeySettingsWidget() const { return m_hotkey_settings; } + __fi const QList>& getDeviceList() const { return m_device_list; } __fi const QStringList& getVibrationMotors() const { return m_vibration_motors; } public Q_SLOTS: @@ -70,5 +71,6 @@ private: std::array m_port_bindings{}; HotkeySettingsWidget* m_hotkey_settings = nullptr; + QList> m_device_list; QStringList m_vibration_motors; };