summaryrefslogtreecommitdiff
path: root/src/yuzu/configuration/configure_ringcon.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/yuzu/configuration/configure_ringcon.cpp')
-rw-r--r--src/yuzu/configuration/configure_ringcon.cpp497
1 files changed, 0 insertions, 497 deletions
diff --git a/src/yuzu/configuration/configure_ringcon.cpp b/src/yuzu/configuration/configure_ringcon.cpp
deleted file mode 100644
index 9fd094ab6..000000000
--- a/src/yuzu/configuration/configure_ringcon.cpp
+++ /dev/null
@@ -1,497 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include <memory>
-#include <QKeyEvent>
-#include <QMenu>
-#include <QMessageBox>
-#include <QTimer>
-#include <fmt/format.h>
-
-#include "configuration/qt_config.h"
-#include "hid_core/frontend/emulated_controller.h"
-#include "hid_core/hid_core.h"
-#include "input_common/drivers/keyboard.h"
-#include "input_common/drivers/mouse.h"
-#include "input_common/main.h"
-#include "ui_configure_ringcon.h"
-#include "yuzu/bootmanager.h"
-#include "yuzu/configuration/configure_ringcon.h"
-
-const std::array<std::string, ConfigureRingController::ANALOG_SUB_BUTTONS_NUM>
- ConfigureRingController::analog_sub_buttons{{
- "left",
- "right",
- }};
-
-namespace {
-
-QString GetKeyName(int key_code) {
- switch (key_code) {
- case Qt::Key_Shift:
- return QObject::tr("Shift");
- case Qt::Key_Control:
- return QObject::tr("Ctrl");
- case Qt::Key_Alt:
- return QObject::tr("Alt");
- case Qt::Key_Meta:
- return {};
- default:
- return QKeySequence(key_code).toString();
- }
-}
-
-QString GetButtonName(Common::Input::ButtonNames button_name) {
- switch (button_name) {
- case Common::Input::ButtonNames::ButtonLeft:
- return QObject::tr("Left");
- case Common::Input::ButtonNames::ButtonRight:
- return QObject::tr("Right");
- case Common::Input::ButtonNames::ButtonDown:
- return QObject::tr("Down");
- case Common::Input::ButtonNames::ButtonUp:
- return QObject::tr("Up");
- case Common::Input::ButtonNames::TriggerZ:
- return QObject::tr("Z");
- case Common::Input::ButtonNames::TriggerR:
- return QObject::tr("R");
- case Common::Input::ButtonNames::TriggerL:
- return QObject::tr("L");
- case Common::Input::ButtonNames::ButtonA:
- return QObject::tr("A");
- case Common::Input::ButtonNames::ButtonB:
- return QObject::tr("B");
- case Common::Input::ButtonNames::ButtonX:
- return QObject::tr("X");
- case Common::Input::ButtonNames::ButtonY:
- return QObject::tr("Y");
- case Common::Input::ButtonNames::ButtonStart:
- return QObject::tr("Start");
- case Common::Input::ButtonNames::L1:
- return QObject::tr("L1");
- case Common::Input::ButtonNames::L2:
- return QObject::tr("L2");
- case Common::Input::ButtonNames::L3:
- return QObject::tr("L3");
- case Common::Input::ButtonNames::R1:
- return QObject::tr("R1");
- case Common::Input::ButtonNames::R2:
- return QObject::tr("R2");
- case Common::Input::ButtonNames::R3:
- return QObject::tr("R3");
- case Common::Input::ButtonNames::Circle:
- return QObject::tr("Circle");
- case Common::Input::ButtonNames::Cross:
- return QObject::tr("Cross");
- case Common::Input::ButtonNames::Square:
- return QObject::tr("Square");
- case Common::Input::ButtonNames::Triangle:
- return QObject::tr("Triangle");
- case Common::Input::ButtonNames::Share:
- return QObject::tr("Share");
- case Common::Input::ButtonNames::Options:
- return QObject::tr("Options");
- default:
- return QObject::tr("[undefined]");
- }
-}
-
-void SetAnalogParam(const Common::ParamPackage& input_param, Common::ParamPackage& analog_param,
- const std::string& button_name) {
- // The poller returned a complete axis, so set all the buttons
- if (input_param.Has("axis_x") && input_param.Has("axis_y")) {
- analog_param = input_param;
- return;
- }
- // Check if the current configuration has either no engine or an axis binding.
- // Clears out the old binding and adds one with analog_from_button.
- if (!analog_param.Has("engine") || analog_param.Has("axis_x") || analog_param.Has("axis_y")) {
- analog_param = {
- {"engine", "analog_from_button"},
- };
- }
- analog_param.Set(button_name, input_param.Serialize());
-}
-} // namespace
-
-ConfigureRingController::ConfigureRingController(QWidget* parent,
- InputCommon::InputSubsystem* input_subsystem_,
- Core::HID::HIDCore& hid_core_)
- : QDialog(parent), timeout_timer(std::make_unique<QTimer>()),
- poll_timer(std::make_unique<QTimer>()), input_subsystem{input_subsystem_},
-
- ui(std::make_unique<Ui::ConfigureRingController>()) {
- ui->setupUi(this);
-
- analog_map_buttons = {
- ui->buttonRingAnalogPull,
- ui->buttonRingAnalogPush,
- };
-
- emulated_controller = hid_core_.GetEmulatedController(Core::HID::NpadIdType::Player1);
- emulated_controller->SaveCurrentConfig();
- emulated_controller->EnableConfiguration();
-
- Core::HID::ControllerUpdateCallback engine_callback{
- .on_change = [this](Core::HID::ControllerTriggerType type) { ControllerUpdate(type); },
- .is_npad_service = false,
- };
- callback_key = emulated_controller->SetCallback(engine_callback);
- is_controller_set = true;
-
- LoadConfiguration();
-
- for (int sub_button_id = 0; sub_button_id < ANALOG_SUB_BUTTONS_NUM; ++sub_button_id) {
- auto* const analog_button = analog_map_buttons[sub_button_id];
-
- if (analog_button == nullptr) {
- continue;
- }
-
- connect(analog_button, &QPushButton::clicked, [=, this] {
- HandleClick(
- analog_map_buttons[sub_button_id],
- [=, this](const Common::ParamPackage& params) {
- Common::ParamPackage param = emulated_controller->GetRingParam();
- SetAnalogParam(params, param, analog_sub_buttons[sub_button_id]);
- emulated_controller->SetRingParam(param);
- },
- InputCommon::Polling::InputType::Stick);
- });
-
- analog_button->setContextMenuPolicy(Qt::CustomContextMenu);
-
- connect(analog_button, &QPushButton::customContextMenuRequested,
- [=, this](const QPoint& menu_location) {
- QMenu context_menu;
- Common::ParamPackage param = emulated_controller->GetRingParam();
- context_menu.addAction(tr("Clear"), [&] {
- emulated_controller->SetRingParam(param);
- analog_map_buttons[sub_button_id]->setText(tr("[not set]"));
- });
- context_menu.addAction(tr("Invert axis"), [&] {
- const bool invert_value = param.Get("invert_x", "+") == "-";
- const std::string invert_str = invert_value ? "+" : "-";
- param.Set("invert_x", invert_str);
- emulated_controller->SetRingParam(param);
- for (int sub_button_id2 = 0; sub_button_id2 < ANALOG_SUB_BUTTONS_NUM;
- ++sub_button_id2) {
- analog_map_buttons[sub_button_id2]->setText(
- AnalogToText(param, analog_sub_buttons[sub_button_id2]));
- }
- });
- context_menu.exec(
- analog_map_buttons[sub_button_id]->mapToGlobal(menu_location));
- });
- }
-
- connect(ui->sliderRingAnalogDeadzone, &QSlider::valueChanged, [=, this] {
- Common::ParamPackage param = emulated_controller->GetRingParam();
- const auto slider_value = ui->sliderRingAnalogDeadzone->value();
- ui->labelRingAnalogDeadzone->setText(tr("Deadzone: %1%").arg(slider_value));
- param.Set("deadzone", slider_value / 100.0f);
- emulated_controller->SetRingParam(param);
- });
-
- connect(ui->restore_defaults_button, &QPushButton::clicked, this,
- &ConfigureRingController::RestoreDefaults);
-
- connect(ui->enable_ring_controller_button, &QPushButton::clicked, this,
- &ConfigureRingController::EnableRingController);
-
- timeout_timer->setSingleShot(true);
- connect(timeout_timer.get(), &QTimer::timeout, [this] { SetPollingResult({}, true); });
-
- connect(poll_timer.get(), &QTimer::timeout, [this] {
- const auto& params = input_subsystem->GetNextInput();
- if (params.Has("engine") && IsInputAcceptable(params)) {
- SetPollingResult(params, false);
- return;
- }
- });
-
- resize(0, 0);
-}
-
-ConfigureRingController::~ConfigureRingController() {
- emulated_controller->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
- Common::Input::PollingMode::Active);
- emulated_controller->DisableConfiguration();
-
- if (is_controller_set) {
- emulated_controller->DeleteCallback(callback_key);
- is_controller_set = false;
- }
-};
-
-void ConfigureRingController::changeEvent(QEvent* event) {
- if (event->type() == QEvent::LanguageChange) {
- RetranslateUI();
- }
-
- QDialog::changeEvent(event);
-}
-
-void ConfigureRingController::RetranslateUI() {
- ui->retranslateUi(this);
-}
-
-void ConfigureRingController::UpdateUI() {
- RetranslateUI();
- const Common::ParamPackage param = emulated_controller->GetRingParam();
-
- for (int sub_button_id = 0; sub_button_id < ANALOG_SUB_BUTTONS_NUM; ++sub_button_id) {
- auto* const analog_button = analog_map_buttons[sub_button_id];
-
- if (analog_button == nullptr) {
- continue;
- }
-
- analog_button->setText(AnalogToText(param, analog_sub_buttons[sub_button_id]));
- }
-
- const auto deadzone_label = ui->labelRingAnalogDeadzone;
- const auto deadzone_slider = ui->sliderRingAnalogDeadzone;
-
- int slider_value = static_cast<int>(param.Get("deadzone", 0.15f) * 100);
- deadzone_label->setText(tr("Deadzone: %1%").arg(slider_value));
- deadzone_slider->setValue(slider_value);
-}
-
-void ConfigureRingController::ApplyConfiguration() {
- emulated_controller->DisableConfiguration();
- emulated_controller->SaveCurrentConfig();
- emulated_controller->EnableConfiguration();
-}
-
-void ConfigureRingController::LoadConfiguration() {
- UpdateUI();
-}
-
-void ConfigureRingController::RestoreDefaults() {
- const std::string default_ring_string = InputCommon::GenerateAnalogParamFromKeys(
- 0, 0, QtConfig::default_ringcon_analogs[0], QtConfig::default_ringcon_analogs[1], 0, 0.05f);
- emulated_controller->SetRingParam(Common::ParamPackage(default_ring_string));
- UpdateUI();
-}
-
-void ConfigureRingController::EnableRingController() {
- const auto dialog_title = tr("Error enabling ring input");
-
- is_ring_enabled = false;
- ui->ring_controller_sensor_value->setText(tr("Not connected"));
-
- if (!Settings::values.enable_joycon_driver) {
- QMessageBox::warning(this, dialog_title, tr("Direct Joycon driver is not enabled"));
- return;
- }
-
- ui->enable_ring_controller_button->setEnabled(false);
- ui->enable_ring_controller_button->setText(tr("Configuring"));
- // SetPollingMode is blocking. Allow to update the button status before calling the command
- repaint();
-
- const auto result = emulated_controller->SetPollingMode(
- Core::HID::EmulatedDeviceIndex::RightIndex, Common::Input::PollingMode::Ring);
- switch (result) {
- case Common::Input::DriverResult::Success:
- is_ring_enabled = true;
- break;
- case Common::Input::DriverResult::NotSupported:
- QMessageBox::warning(this, dialog_title,
- tr("The current mapped device doesn't support the ring controller"));
- break;
- case Common::Input::DriverResult::NoDeviceDetected:
- QMessageBox::warning(this, dialog_title,
- tr("The current mapped device doesn't have a ring attached"));
- break;
- case Common::Input::DriverResult::InvalidHandle:
- QMessageBox::warning(this, dialog_title, tr("The current mapped device is not connected"));
- break;
- default:
- QMessageBox::warning(this, dialog_title,
- tr("Unexpected driver result %1").arg(static_cast<int>(result)));
- break;
- }
- ui->enable_ring_controller_button->setEnabled(true);
- ui->enable_ring_controller_button->setText(tr("Enable"));
-}
-
-void ConfigureRingController::ControllerUpdate(Core::HID::ControllerTriggerType type) {
- if (!is_ring_enabled) {
- return;
- }
- if (type != Core::HID::ControllerTriggerType::RingController) {
- return;
- }
-
- const auto value = emulated_controller->GetRingSensorValues();
- const auto tex_value = QString::fromStdString(fmt::format("{:.3f}", value.raw_value));
- ui->ring_controller_sensor_value->setText(tex_value);
-}
-
-void ConfigureRingController::HandleClick(
- QPushButton* button, std::function<void(const Common::ParamPackage&)> new_input_setter,
- InputCommon::Polling::InputType type) {
- button->setText(tr("[waiting]"));
- button->setFocus();
-
- input_setter = new_input_setter;
-
- input_subsystem->BeginMapping(type);
-
- QWidget::grabMouse();
- QWidget::grabKeyboard();
-
- timeout_timer->start(2500); // Cancel after 2.5 seconds
- poll_timer->start(25); // Check for new inputs every 25ms
-}
-
-void ConfigureRingController::SetPollingResult(const Common::ParamPackage& params, bool abort) {
- timeout_timer->stop();
- poll_timer->stop();
- input_subsystem->StopMapping();
-
- QWidget::releaseMouse();
- QWidget::releaseKeyboard();
-
- if (!abort) {
- (*input_setter)(params);
- }
-
- UpdateUI();
-
- input_setter = std::nullopt;
-}
-
-bool ConfigureRingController::IsInputAcceptable(const Common::ParamPackage& params) const {
- return true;
-}
-
-void ConfigureRingController::mousePressEvent(QMouseEvent* event) {
- if (!input_setter || !event) {
- return;
- }
-
- const auto button = GRenderWindow::QtButtonToMouseButton(event->button());
- input_subsystem->GetMouse()->PressButton(0, 0, button);
-}
-
-void ConfigureRingController::keyPressEvent(QKeyEvent* event) {
- if (!input_setter || !event) {
- return;
- }
- event->ignore();
- if (event->key() != Qt::Key_Escape) {
- input_subsystem->GetKeyboard()->PressKey(event->key());
- }
-}
-
-QString ConfigureRingController::ButtonToText(const Common::ParamPackage& param) {
- if (!param.Has("engine")) {
- return QObject::tr("[not set]");
- }
-
- const QString toggle = QString::fromStdString(param.Get("toggle", false) ? "~" : "");
- const QString inverted = QString::fromStdString(param.Get("inverted", false) ? "!" : "");
- const auto common_button_name = input_subsystem->GetButtonName(param);
-
- // Retrieve the names from Qt
- if (param.Get("engine", "") == "keyboard") {
- const QString button_str = GetKeyName(param.Get("code", 0));
- return QObject::tr("%1%2").arg(toggle, button_str);
- }
-
- if (common_button_name == Common::Input::ButtonNames::Invalid) {
- return QObject::tr("[invalid]");
- }
-
- if (common_button_name == Common::Input::ButtonNames::Engine) {
- return QString::fromStdString(param.Get("engine", ""));
- }
-
- if (common_button_name == Common::Input::ButtonNames::Value) {
- if (param.Has("hat")) {
- const QString hat = QString::fromStdString(param.Get("direction", ""));
- return QObject::tr("%1%2Hat %3").arg(toggle, inverted, hat);
- }
- if (param.Has("axis")) {
- const QString axis = QString::fromStdString(param.Get("axis", ""));
- return QObject::tr("%1%2Axis %3").arg(toggle, inverted, axis);
- }
- if (param.Has("axis_x") && param.Has("axis_y") && param.Has("axis_z")) {
- const QString axis_x = QString::fromStdString(param.Get("axis_x", ""));
- const QString axis_y = QString::fromStdString(param.Get("axis_y", ""));
- const QString axis_z = QString::fromStdString(param.Get("axis_z", ""));
- return QObject::tr("%1%2Axis %3,%4,%5").arg(toggle, inverted, axis_x, axis_y, axis_z);
- }
- if (param.Has("motion")) {
- const QString motion = QString::fromStdString(param.Get("motion", ""));
- return QObject::tr("%1%2Motion %3").arg(toggle, inverted, motion);
- }
- if (param.Has("button")) {
- const QString button = QString::fromStdString(param.Get("button", ""));
- return QObject::tr("%1%2Button %3").arg(toggle, inverted, button);
- }
- }
-
- QString button_name = GetButtonName(common_button_name);
- if (param.Has("hat")) {
- return QObject::tr("%1%2Hat %3").arg(toggle, inverted, button_name);
- }
- if (param.Has("axis")) {
- return QObject::tr("%1%2Axis %3").arg(toggle, inverted, button_name);
- }
- if (param.Has("motion")) {
- return QObject::tr("%1%2Axis %3").arg(toggle, inverted, button_name);
- }
- if (param.Has("button")) {
- return QObject::tr("%1%2Button %3").arg(toggle, inverted, button_name);
- }
-
- return QObject::tr("[unknown]");
-}
-
-QString ConfigureRingController::AnalogToText(const Common::ParamPackage& param,
- const std::string& dir) {
- if (!param.Has("engine")) {
- return QObject::tr("[not set]");
- }
-
- if (param.Get("engine", "") == "analog_from_button") {
- return ButtonToText(Common::ParamPackage{param.Get(dir, "")});
- }
-
- if (!param.Has("axis_x") || !param.Has("axis_y")) {
- return QObject::tr("[unknown]");
- }
-
- const auto engine_str = param.Get("engine", "");
- const QString axis_x_str = QString::fromStdString(param.Get("axis_x", ""));
- const QString axis_y_str = QString::fromStdString(param.Get("axis_y", ""));
- const bool invert_x = param.Get("invert_x", "+") == "-";
- const bool invert_y = param.Get("invert_y", "+") == "-";
-
- if (dir == "modifier") {
- return QObject::tr("[unused]");
- }
-
- if (dir == "left") {
- const QString invert_x_str = QString::fromStdString(invert_x ? "+" : "-");
- return QObject::tr("Axis %1%2").arg(axis_x_str, invert_x_str);
- }
- if (dir == "right") {
- const QString invert_x_str = QString::fromStdString(invert_x ? "-" : "+");
- return QObject::tr("Axis %1%2").arg(axis_x_str, invert_x_str);
- }
- if (dir == "up") {
- const QString invert_y_str = QString::fromStdString(invert_y ? "-" : "+");
- return QObject::tr("Axis %1%2").arg(axis_y_str, invert_y_str);
- }
- if (dir == "down") {
- const QString invert_y_str = QString::fromStdString(invert_y ? "+" : "-");
- return QObject::tr("Axis %1%2").arg(axis_y_str, invert_y_str);
- }
-
- return QObject::tr("[unknown]");
-}