From 262331504fb4dc2414bdd1b4a3e6e1dab8802e04 Mon Sep 17 00:00:00 2001 From: Connor McLaughlin Date: Tue, 18 Feb 2020 00:06:28 +0900 Subject: [PATCH] Qt: Support binding controller axes --- src/duckstation-qt/portsettingswidget.cpp | 41 +++++++++++++++-- src/duckstation-qt/qthostinterface.cpp | 55 ++++++++++++++++++++++- src/duckstation-qt/qthostinterface.h | 2 + 3 files changed, 94 insertions(+), 4 deletions(-) diff --git a/src/duckstation-qt/portsettingswidget.cpp b/src/duckstation-qt/portsettingswidget.cpp index 84481829d..883fb3e14 100644 --- a/src/duckstation-qt/portsettingswidget.cpp +++ b/src/duckstation-qt/portsettingswidget.cpp @@ -77,15 +77,15 @@ void PortSettingsWidget::createPortBindingSettingsUi(int index, PortSettingsUI* layout->setContentsMargins(0, 0, 0, 0); const auto buttons = Controller::GetButtonNames(ctype); + int start_row = 0; if (!buttons.empty()) { QFrame* line = new QFrame(container); line->setFrameShape(QFrame::HLine); line->setFrameShadow(QFrame::Sunken); - layout->addWidget(line, 0, 0, 1, 4); - layout->addWidget(new QLabel(tr("Button Bindings:"), container), 1, 0, 1, 4); + layout->addWidget(line, start_row++, 0, 1, 4); + layout->addWidget(new QLabel(tr("Button Bindings:"), container), start_row++, 0, 1, 4); - const int start_row = 2; const int num_rows = (static_cast(buttons.size()) + 1) / 2; int current_row = 0; int current_column = 0; @@ -106,6 +106,41 @@ void PortSettingsWidget::createPortBindingSettingsUi(int index, PortSettingsUI* current_row++; } + + start_row += num_rows; + } + + const auto axises = Controller::GetAxisNames(ctype); + if (!axises.empty()) + { + QFrame* line = new QFrame(container); + line->setFrameShape(QFrame::HLine); + line->setFrameShadow(QFrame::Sunken); + layout->addWidget(line, start_row++, 0, 1, 4); + layout->addWidget(new QLabel(tr("Axis Bindings:"), container), start_row++, 0, 1, 4); + + const int num_rows = (static_cast(axises.size()) + 1) / 2; + int current_row = 0; + int current_column = 0; + for (const auto& [axis_name, axis_code] : axises) + { + if (current_row == num_rows) + { + current_row = 0; + current_column += 2; + } + + const QString axis_name_q = QString::fromStdString(axis_name); + const QString setting_name = QStringLiteral("Controller%1/Axis%2").arg(index + 1).arg(axis_name_q); + QLabel* label = new QLabel(axis_name_q, container); + InputAxisBindingWidget* button = new InputAxisBindingWidget(m_host_interface, setting_name, container); + layout->addWidget(label, start_row + current_row, current_column); + layout->addWidget(button, start_row + current_row, current_column + 1); + + current_row++; + } + + start_row += num_rows; } if (ui->button_binding_container) diff --git a/src/duckstation-qt/qthostinterface.cpp b/src/duckstation-qt/qthostinterface.cpp index 9ee385ded..2ee4be074 100644 --- a/src/duckstation-qt/qthostinterface.cpp +++ b/src/duckstation-qt/qthostinterface.cpp @@ -391,6 +391,27 @@ void QtHostInterface::updateControllerInputMap() controller->SetButtonState(button_code, pressed); }); } + + const auto axis_names = Controller::GetAxisNames(ctype); + for (const auto& it : axis_names) + { + const std::string& axis_name = it.first; + const s32 axis_code = it.second; + + QVariant var = m_qsettings.value( + QStringLiteral("Controller%1/Axis%2").arg(controller_index + 1).arg(QString::fromStdString(axis_name))); + if (!var.isValid()) + continue; + + addAxisToInputMap(var.toString(), [this, controller_index, axis_code](float value) { + if (!m_system) + return; + + Controller* controller = m_system->GetController(controller_index); + if (controller) + controller->SetAxisState(axis_code, value); + }); + } } } @@ -505,12 +526,12 @@ void QtHostInterface::addButtonToInputMap(const QString& binding, InputButtonHan { bool controller_index_okay; const int controller_index = device.mid(10).toInt(&controller_index_okay); - if (!controller_index_okay || controller_index < 0) { qWarning() << "Malformed controller binding: " << binding; return; } + if (button.startsWith(QStringLiteral("Button"))) { bool button_index_okay; @@ -540,6 +561,38 @@ void QtHostInterface::addButtonToInputMap(const QString& binding, InputButtonHan } } +void QtHostInterface::addAxisToInputMap(const QString& binding, InputAxisHandler handler) +{ + const QString device = binding.section('/', 0, 0); + const QString axis = binding.section('/', 1, 1); + if (device.startsWith(QStringLiteral("Controller"))) + { + bool controller_index_okay; + const int controller_index = device.mid(10).toInt(&controller_index_okay); + if (!controller_index_okay || controller_index < 0) + { + qWarning() << "Malformed controller binding: " << binding; + return; + } + + if (axis.startsWith(QStringLiteral("Axis"))) + { + bool axis_index_okay; + const int axis_index = axis.mid(4).toInt(&axis_index_okay); + if (!axis_index_okay || + !g_sdl_controller_interface.BindControllerAxis(controller_index, axis_index, std::move(handler))) + { + qWarning() << "Failed to bind " << binding; + } + } + } + else + { + qWarning() << "Unknown input device: " << binding; + return; + } +} + void QtHostInterface::powerOffSystem() { if (!isOnWorkerThread()) diff --git a/src/duckstation-qt/qthostinterface.h b/src/duckstation-qt/qthostinterface.h index 0844470a8..f82598cea 100644 --- a/src/duckstation-qt/qthostinterface.h +++ b/src/duckstation-qt/qthostinterface.h @@ -124,6 +124,7 @@ private: }; using InputButtonHandler = std::function; + using InputAxisHandler = std::function; class Thread : public QThread { @@ -146,6 +147,7 @@ private: void updateControllerInputMap(); void updateHotkeyInputMap(); void addButtonToInputMap(const QString& binding, InputButtonHandler handler); + void addAxisToInputMap(const QString& binding, InputAxisHandler handler); void createThread(); void stopThread(); void threadEntryPoint();