aboutsummaryrefslogtreecommitdiff
path: root/src/yuzu/configuration/configure_input.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/yuzu/configuration/configure_input.cpp')
-rw-r--r--src/yuzu/configuration/configure_input.cpp406
1 files changed, 118 insertions, 288 deletions
diff --git a/src/yuzu/configuration/configure_input.cpp b/src/yuzu/configuration/configure_input.cpp
index 42a7beac67..9ae9827feb 100644
--- a/src/yuzu/configuration/configure_input.cpp
+++ b/src/yuzu/configuration/configure_input.cpp
@@ -9,334 +9,164 @@
#include <QMessageBox>
#include <QTimer>
#include "common/param_package.h"
+#include "configuration/configure_touchscreen_advanced.h"
+#include "core/core.h"
#include "input_common/main.h"
+#include "ui_configure_input.h"
+#include "ui_configure_input_player.h"
+#include "ui_configure_mouse_advanced.h"
+#include "ui_configure_touchscreen_advanced.h"
#include "yuzu/configuration/config.h"
#include "yuzu/configuration/configure_input.h"
-
-const std::array<std::string, ConfigureInput::ANALOG_SUB_BUTTONS_NUM>
- ConfigureInput::analog_sub_buttons{{
- "up",
- "down",
- "left",
- "right",
- "modifier",
- }};
-
-static 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();
- }
-}
-
-static void SetAnalogButton(const Common::ParamPackage& input_param,
- Common::ParamPackage& analog_param, const std::string& button_name) {
- if (analog_param.Get("engine", "") != "analog_from_button") {
- analog_param = {
- {"engine", "analog_from_button"},
- {"modifier_scale", "0.5"},
- };
- }
- analog_param.Set(button_name, input_param.Serialize());
-}
-
-static QString ButtonToText(const Common::ParamPackage& param) {
- if (!param.Has("engine")) {
- return QObject::tr("[not set]");
- } else if (param.Get("engine", "") == "keyboard") {
- return getKeyName(param.Get("code", 0));
- } else if (param.Get("engine", "") == "sdl") {
- if (param.Has("hat")) {
- return QString(QObject::tr("Hat %1 %2"))
- .arg(param.Get("hat", "").c_str(), param.Get("direction", "").c_str());
- }
- if (param.Has("axis")) {
- return QString(QObject::tr("Axis %1%2"))
- .arg(param.Get("axis", "").c_str(), param.Get("direction", "").c_str());
- }
- if (param.Has("button")) {
- return QString(QObject::tr("Button %1")).arg(param.Get("button", "").c_str());
- }
- return QString();
- } else {
- return QObject::tr("[unknown]");
- }
-};
-
-static QString AnalogToText(const Common::ParamPackage& param, const std::string& dir) {
- if (!param.Has("engine")) {
- return QObject::tr("[not set]");
- } else if (param.Get("engine", "") == "analog_from_button") {
- return ButtonToText(Common::ParamPackage{param.Get(dir, "")});
- } else if (param.Get("engine", "") == "sdl") {
- if (dir == "modifier") {
- return QString(QObject::tr("[unused]"));
- }
-
- if (dir == "left" || dir == "right") {
- return QString(QObject::tr("Axis %1")).arg(param.Get("axis_x", "").c_str());
- } else if (dir == "up" || dir == "down") {
- return QString(QObject::tr("Axis %1")).arg(param.Get("axis_y", "").c_str());
- }
- return QString();
- } else {
- return QObject::tr("[unknown]");
- }
-};
+#include "yuzu/configuration/configure_input_player.h"
+#include "yuzu/configuration/configure_mouse_advanced.h"
ConfigureInput::ConfigureInput(QWidget* parent)
- : QWidget(parent), ui(std::make_unique<Ui::ConfigureInput>()),
- timeout_timer(std::make_unique<QTimer>()), poll_timer(std::make_unique<QTimer>()) {
-
+ : QWidget(parent), ui(std::make_unique<Ui::ConfigureInput>()) {
ui->setupUi(this);
- setFocusPolicy(Qt::ClickFocus);
- button_map = {
- ui->buttonA, ui->buttonB, ui->buttonX, ui->buttonY,
- ui->buttonLStick, ui->buttonRStick, ui->buttonL, ui->buttonR,
- ui->buttonZL, ui->buttonZR, ui->buttonPlus, ui->buttonMinus,
- ui->buttonDpadLeft, ui->buttonDpadUp, ui->buttonDpadRight, ui->buttonDpadDown,
- ui->buttonLStickLeft, ui->buttonLStickUp, ui->buttonLStickRight, ui->buttonLStickDown,
- ui->buttonRStickLeft, ui->buttonRStickUp, ui->buttonRStickRight, ui->buttonRStickDown,
- ui->buttonSL, ui->buttonSR, ui->buttonHome, ui->buttonScreenshot,
+ players_enabled = {
+ ui->player1_checkbox, ui->player2_checkbox, ui->player3_checkbox, ui->player4_checkbox,
+ ui->player5_checkbox, ui->player6_checkbox, ui->player7_checkbox, ui->player8_checkbox,
};
- analog_map_buttons = {{
- {
- ui->buttonLStickUp,
- ui->buttonLStickDown,
- ui->buttonLStickLeft,
- ui->buttonLStickRight,
- ui->buttonLStickMod,
- },
- {
- ui->buttonRStickUp,
- ui->buttonRStickDown,
- ui->buttonRStickLeft,
- ui->buttonRStickRight,
- ui->buttonRStickMod,
- },
- }};
+ player_controller = {
+ ui->player1_combobox, ui->player2_combobox, ui->player3_combobox, ui->player4_combobox,
+ ui->player5_combobox, ui->player6_combobox, ui->player7_combobox, ui->player8_combobox,
+ };
- analog_map_stick = {ui->buttonLStickAnalog, ui->buttonRStickAnalog};
+ player_configure = {
+ ui->player1_configure, ui->player2_configure, ui->player3_configure, ui->player4_configure,
+ ui->player5_configure, ui->player6_configure, ui->player7_configure, ui->player8_configure,
+ };
- for (int button_id = 0; button_id < Settings::NativeButton::NumButtons; button_id++) {
- if (!button_map[button_id])
- continue;
- button_map[button_id]->setContextMenuPolicy(Qt::CustomContextMenu);
- connect(button_map[button_id], &QPushButton::released, [=]() {
- handleClick(
- button_map[button_id],
- [=](const Common::ParamPackage& params) { buttons_param[button_id] = params; },
- InputCommon::Polling::DeviceType::Button);
- });
- connect(button_map[button_id], &QPushButton::customContextMenuRequested,
- [=](const QPoint& menu_location) {
- QMenu context_menu;
- context_menu.addAction(tr("Clear"), [&] {
- buttons_param[button_id].Clear();
- button_map[button_id]->setText(tr("[not set]"));
- });
- context_menu.addAction(tr("Restore Default"), [&] {
- buttons_param[button_id] = Common::ParamPackage{
- InputCommon::GenerateKeyboardParam(Config::default_buttons[button_id])};
- button_map[button_id]->setText(ButtonToText(buttons_param[button_id]));
- });
- context_menu.exec(button_map[button_id]->mapToGlobal(menu_location));
- });
+ for (auto* controller_box : player_controller) {
+ controller_box->addItems(
+ {"Pro Controller", "Dual Joycons", "Single Right Joycon", "Single Left Joycon"});
}
- for (int analog_id = 0; analog_id < Settings::NativeAnalog::NumAnalogs; analog_id++) {
- for (int sub_button_id = 0; sub_button_id < ANALOG_SUB_BUTTONS_NUM; sub_button_id++) {
- if (!analog_map_buttons[analog_id][sub_button_id])
- continue;
- analog_map_buttons[analog_id][sub_button_id]->setContextMenuPolicy(
- Qt::CustomContextMenu);
- connect(analog_map_buttons[analog_id][sub_button_id], &QPushButton::released, [=]() {
- handleClick(analog_map_buttons[analog_id][sub_button_id],
- [=](const Common::ParamPackage& params) {
- SetAnalogButton(params, analogs_param[analog_id],
- analog_sub_buttons[sub_button_id]);
- },
- InputCommon::Polling::DeviceType::Button);
- });
- connect(analog_map_buttons[analog_id][sub_button_id],
- &QPushButton::customContextMenuRequested, [=](const QPoint& menu_location) {
- QMenu context_menu;
- context_menu.addAction(tr("Clear"), [&] {
- analogs_param[analog_id].Erase(analog_sub_buttons[sub_button_id]);
- analog_map_buttons[analog_id][sub_button_id]->setText(tr("[not set]"));
- });
- context_menu.addAction(tr("Restore Default"), [&] {
- Common::ParamPackage params{InputCommon::GenerateKeyboardParam(
- Config::default_analogs[analog_id][sub_button_id])};
- SetAnalogButton(params, analogs_param[analog_id],
- analog_sub_buttons[sub_button_id]);
- analog_map_buttons[analog_id][sub_button_id]->setText(AnalogToText(
- analogs_param[analog_id], analog_sub_buttons[sub_button_id]));
- });
- context_menu.exec(analog_map_buttons[analog_id][sub_button_id]->mapToGlobal(
- menu_location));
- });
- }
- connect(analog_map_stick[analog_id], &QPushButton::released, [=]() {
- QMessageBox::information(this, tr("Information"),
- tr("After pressing OK, first move your joystick horizontally, "
- "and then vertically."));
- handleClick(
- analog_map_stick[analog_id],
- [=](const Common::ParamPackage& params) { analogs_param[analog_id] = params; },
- InputCommon::Polling::DeviceType::Analog);
- });
- }
+ this->loadConfiguration();
+ updateUIEnabled();
- connect(ui->buttonClearAll, &QPushButton::released, [this] { ClearAll(); });
- connect(ui->buttonRestoreDefaults, &QPushButton::released, [this]() { restoreDefaults(); });
+ connect(ui->restore_defaults_button, &QPushButton::pressed, this,
+ &ConfigureInput::restoreDefaults);
- timeout_timer->setSingleShot(true);
- connect(timeout_timer.get(), &QTimer::timeout, [this]() { setPollingResult({}, true); });
+ for (auto* enabled : players_enabled)
+ connect(enabled, &QCheckBox::stateChanged, this, &ConfigureInput::updateUIEnabled);
+ connect(ui->use_docked_mode, &QCheckBox::stateChanged, this, &ConfigureInput::updateUIEnabled);
+ connect(ui->handheld_connected, &QCheckBox::stateChanged, this,
+ &ConfigureInput::updateUIEnabled);
+ connect(ui->mouse_enabled, &QCheckBox::stateChanged, this, &ConfigureInput::updateUIEnabled);
+ connect(ui->keyboard_enabled, &QCheckBox::stateChanged, this, &ConfigureInput::updateUIEnabled);
+ connect(ui->debug_enabled, &QCheckBox::stateChanged, this, &ConfigureInput::updateUIEnabled);
+ connect(ui->touchscreen_enabled, &QCheckBox::stateChanged, this,
+ &ConfigureInput::updateUIEnabled);
- connect(poll_timer.get(), &QTimer::timeout, [this]() {
- Common::ParamPackage params;
- for (auto& poller : device_pollers) {
- params = poller->GetNextInput();
- if (params.Has("engine")) {
- setPollingResult(params, false);
- return;
- }
- }
- });
+ for (std::size_t i = 0; i < player_configure.size(); ++i) {
+ connect(player_configure[i], &QPushButton::pressed, this,
+ [this, i]() { CallConfigureDialog<ConfigureInputPlayer>(i, false); });
+ }
- this->loadConfiguration();
+ connect(ui->handheld_configure, &QPushButton::pressed, this,
+ [this]() { CallConfigureDialog<ConfigureInputPlayer>(8, false); });
- // TODO(wwylele): enable this when we actually emulate it
- ui->buttonHome->setEnabled(false);
-}
+ connect(ui->debug_configure, &QPushButton::pressed, this,
+ [this]() { CallConfigureDialog<ConfigureInputPlayer>(9, true); });
-void ConfigureInput::applyConfiguration() {
- std::transform(buttons_param.begin(), buttons_param.end(), Settings::values.buttons.begin(),
- [](const Common::ParamPackage& param) { return param.Serialize(); });
- std::transform(analogs_param.begin(), analogs_param.end(), Settings::values.analogs.begin(),
- [](const Common::ParamPackage& param) { return param.Serialize(); });
-}
+ connect(ui->mouse_advanced, &QPushButton::pressed, this,
+ [this]() { CallConfigureDialog<ConfigureMouseAdvanced>(); });
-void ConfigureInput::loadConfiguration() {
- std::transform(Settings::values.buttons.begin(), Settings::values.buttons.end(),
- buttons_param.begin(),
- [](const std::string& str) { return Common::ParamPackage(str); });
- std::transform(Settings::values.analogs.begin(), Settings::values.analogs.end(),
- analogs_param.begin(),
- [](const std::string& str) { return Common::ParamPackage(str); });
- updateButtonLabels();
+ connect(ui->touchscreen_advanced, &QPushButton::pressed, this,
+ [this]() { CallConfigureDialog<ConfigureTouchscreenAdvanced>(); });
+
+ ui->use_docked_mode->setEnabled(!Core::System::GetInstance().IsPoweredOn());
}
-void ConfigureInput::restoreDefaults() {
- for (int button_id = 0; button_id < Settings::NativeButton::NumButtons; button_id++) {
- buttons_param[button_id] = Common::ParamPackage{
- InputCommon::GenerateKeyboardParam(Config::default_buttons[button_id])};
- }
+template <typename Dialog, typename... Args>
+void ConfigureInput::CallConfigureDialog(Args... args) {
+ this->applyConfiguration();
+ Dialog dialog(this, args...);
- for (int analog_id = 0; analog_id < Settings::NativeAnalog::NumAnalogs; analog_id++) {
- for (int sub_button_id = 0; sub_button_id < ANALOG_SUB_BUTTONS_NUM; sub_button_id++) {
- Common::ParamPackage params{InputCommon::GenerateKeyboardParam(
- Config::default_analogs[analog_id][sub_button_id])};
- SetAnalogButton(params, analogs_param[analog_id], analog_sub_buttons[sub_button_id]);
- }
+ const auto res = dialog.exec();
+ if (res == QDialog::Accepted) {
+ dialog.applyConfiguration();
}
- updateButtonLabels();
}
-void ConfigureInput::ClearAll() {
- for (int button_id = 0; button_id < Settings::NativeButton::NumButtons; button_id++) {
- if (button_map[button_id] && button_map[button_id]->isEnabled())
- buttons_param[button_id].Clear();
- }
- for (int analog_id = 0; analog_id < Settings::NativeAnalog::NumAnalogs; analog_id++) {
- for (int sub_button_id = 0; sub_button_id < ANALOG_SUB_BUTTONS_NUM; sub_button_id++) {
- if (analog_map_buttons[analog_id][sub_button_id] &&
- analog_map_buttons[analog_id][sub_button_id]->isEnabled())
- analogs_param[analog_id].Erase(analog_sub_buttons[sub_button_id]);
- }
- }
- updateButtonLabels();
+void ConfigureInput::applyConfiguration() {
+ for (std::size_t i = 0; i < 8; ++i) {
+ Settings::values.players[i].connected = players_enabled[i]->isChecked();
+ Settings::values.players[i].type =
+ static_cast<Settings::ControllerType>(player_controller[i]->currentIndex());
+ }
+
+ Settings::values.use_docked_mode = ui->use_docked_mode->isChecked();
+ Settings::values.players[8].connected = ui->handheld_connected->isChecked();
+ Settings::values.debug_pad_enabled = ui->debug_enabled->isChecked();
+ Settings::values.mouse_enabled = ui->mouse_enabled->isChecked();
+ Settings::values.keyboard_enabled = ui->keyboard_enabled->isChecked();
+ Settings::values.touchscreen.enabled = ui->touchscreen_enabled->isChecked();
}
-void ConfigureInput::updateButtonLabels() {
- for (int button = 0; button < Settings::NativeButton::NumButtons; button++) {
- button_map[button]->setText(ButtonToText(buttons_param[button]));
- }
+void ConfigureInput::updateUIEnabled() {
+ for (std::size_t i = 0; i < 8; ++i) {
+ const auto enabled = players_enabled[i]->checkState() == Qt::Checked;
- for (int analog_id = 0; analog_id < Settings::NativeAnalog::NumAnalogs; analog_id++) {
- for (int sub_button_id = 0; sub_button_id < ANALOG_SUB_BUTTONS_NUM; sub_button_id++) {
- if (analog_map_buttons[analog_id][sub_button_id]) {
- analog_map_buttons[analog_id][sub_button_id]->setText(
- AnalogToText(analogs_param[analog_id], analog_sub_buttons[sub_button_id]));
- }
- }
- analog_map_stick[analog_id]->setText(tr("Set Analog Stick"));
+ player_controller[i]->setEnabled(enabled);
+ player_configure[i]->setEnabled(enabled);
}
-}
-
-void ConfigureInput::handleClick(QPushButton* button,
- std::function<void(const Common::ParamPackage&)> new_input_setter,
- InputCommon::Polling::DeviceType type) {
- button->setText(tr("[press key]"));
- button->setFocus();
-
- input_setter = new_input_setter;
-
- device_pollers = InputCommon::Polling::GetPollers(type);
-
- // Keyboard keys can only be used as button devices
- want_keyboard_keys = type == InputCommon::Polling::DeviceType::Button;
- for (auto& poller : device_pollers) {
- poller->Start();
+ bool hit_disabled = false;
+ for (auto* player : players_enabled) {
+ if (hit_disabled)
+ player->setDisabled(true);
+ else
+ player->setEnabled(true);
+ if (!player->isChecked())
+ hit_disabled = true;
}
- grabKeyboard();
- grabMouse();
- timeout_timer->start(5000); // Cancel after 5 seconds
- poll_timer->start(200); // Check for new inputs every 200ms
+ ui->handheld_connected->setEnabled(!ui->use_docked_mode->isChecked());
+ ui->handheld_configure->setEnabled(ui->handheld_connected->isChecked() &&
+ !ui->use_docked_mode->isChecked());
+ ui->mouse_advanced->setEnabled(ui->mouse_enabled->isChecked());
+ ui->debug_configure->setEnabled(ui->debug_enabled->isChecked());
+ ui->touchscreen_advanced->setEnabled(ui->touchscreen_enabled->isChecked());
}
-void ConfigureInput::setPollingResult(const Common::ParamPackage& params, bool abort) {
- releaseKeyboard();
- releaseMouse();
- timeout_timer->stop();
- poll_timer->stop();
- for (auto& poller : device_pollers) {
- poller->Stop();
- }
+void ConfigureInput::loadConfiguration() {
+ std::stable_partition(Settings::values.players.begin(), Settings::values.players.end(),
+ [](const auto& player) { return player.connected; });
- if (!abort) {
- (*input_setter)(params);
+ for (std::size_t i = 0; i < 8; ++i) {
+ players_enabled[i]->setChecked(Settings::values.players[i].connected);
+ player_controller[i]->setCurrentIndex(static_cast<u8>(Settings::values.players[i].type));
}
- updateButtonLabels();
- input_setter = {};
+ ui->use_docked_mode->setChecked(Settings::values.use_docked_mode);
+ ui->handheld_connected->setChecked(Settings::values.players[8].connected);
+ ui->debug_enabled->setChecked(Settings::values.debug_pad_enabled);
+ ui->mouse_enabled->setChecked(Settings::values.mouse_enabled);
+ ui->keyboard_enabled->setChecked(Settings::values.keyboard_enabled);
+ ui->touchscreen_enabled->setChecked(Settings::values.touchscreen.enabled);
+
+ updateUIEnabled();
}
-void ConfigureInput::keyPressEvent(QKeyEvent* event) {
- if (!input_setter || !event)
- return;
+void ConfigureInput::restoreDefaults() {
+ players_enabled[0]->setCheckState(Qt::Checked);
+ player_controller[0]->setCurrentIndex(1);
- if (event->key() != Qt::Key_Escape) {
- if (want_keyboard_keys) {
- setPollingResult(Common::ParamPackage{InputCommon::GenerateKeyboardParam(event->key())},
- false);
- } else {
- // Escape key wasn't pressed and we don't want any keyboard keys, so don't stop polling
- return;
- }
+ for (std::size_t i = 1; i < 8; ++i) {
+ players_enabled[i]->setCheckState(Qt::Unchecked);
+ player_controller[i]->setCurrentIndex(0);
}
- setPollingResult({}, true);
+
+ ui->use_docked_mode->setCheckState(Qt::Unchecked);
+ ui->handheld_connected->setCheckState(Qt::Unchecked);
+ ui->mouse_enabled->setCheckState(Qt::Unchecked);
+ ui->keyboard_enabled->setCheckState(Qt::Unchecked);
+ ui->debug_enabled->setCheckState(Qt::Unchecked);
+ ui->touchscreen_enabled->setCheckState(Qt::Checked);
+ updateUIEnabled();
}