summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbunnei <bunneidev@gmail.com>2018-01-16 16:13:39 +0100
committerGitHub <noreply@github.com>2018-01-16 16:13:39 +0100
commitd81879186674ed3732ff3539937a9ac0fb45b585 (patch)
tree4ced33464372737e8a98ee37432f1e389f8d325f
parentMerge pull request #38 from goaaats/citra_merges (diff)
parentAdding meumart's Citra SDL Joystick support. Citra PR #3116 (diff)
downloadyuzu-d81879186674ed3732ff3539937a9ac0fb45b585.tar
yuzu-d81879186674ed3732ff3539937a9ac0fb45b585.tar.gz
yuzu-d81879186674ed3732ff3539937a9ac0fb45b585.tar.bz2
yuzu-d81879186674ed3732ff3539937a9ac0fb45b585.tar.lz
yuzu-d81879186674ed3732ff3539937a9ac0fb45b585.tar.xz
yuzu-d81879186674ed3732ff3539937a9ac0fb45b585.tar.zst
yuzu-d81879186674ed3732ff3539937a9ac0fb45b585.zip
-rw-r--r--src/input_common/main.cpp11
-rw-r--r--src/input_common/main.h32
-rw-r--r--src/input_common/sdl/sdl.cpp183
-rw-r--r--src/input_common/sdl/sdl.h23
-rw-r--r--src/yuzu/configuration/configure_input.cpp139
-rw-r--r--src/yuzu/configuration/configure_input.h31
-rw-r--r--src/yuzu/configuration/configure_input.ui296
7 files changed, 524 insertions, 191 deletions
diff --git a/src/input_common/main.cpp b/src/input_common/main.cpp
index 557353740..95d40f09f 100644
--- a/src/input_common/main.cpp
+++ b/src/input_common/main.cpp
@@ -71,4 +71,15 @@ std::string GenerateAnalogParamFromKeys(int key_up, int key_down, int key_left,
return circle_pad_param.Serialize();
}
+namespace Polling {
+
+std::vector<std::unique_ptr<DevicePoller>> GetPollers(DeviceType type) {
+#ifdef HAVE_SDL2
+ return SDL::Polling::GetPollers(type);
+#else
+ return {};
+#endif
+}
+
+} // namespace Polling
} // namespace InputCommon
diff --git a/src/input_common/main.h b/src/input_common/main.h
index 5604f0fa8..77a0ce90b 100644
--- a/src/input_common/main.h
+++ b/src/input_common/main.h
@@ -4,7 +4,13 @@
#pragma once
+#include <memory>
#include <string>
+#include <vector>
+
+namespace Common {
+class ParamPackage;
+}
namespace InputCommon {
@@ -31,4 +37,30 @@ std::string GenerateKeyboardParam(int key_code);
std::string GenerateAnalogParamFromKeys(int key_up, int key_down, int key_left, int key_right,
int key_modifier, float modifier_scale);
+namespace Polling {
+
+enum class DeviceType { Button, Analog };
+
+/**
+ * A class that can be used to get inputs from an input device like controllers without having to
+ * poll the device's status yourself
+ */
+class DevicePoller {
+public:
+ virtual ~DevicePoller() = default;
+ /// Setup and start polling for inputs, should be called before GetNextInput
+ virtual void Start() = 0;
+ /// Stop polling
+ virtual void Stop() = 0;
+ /**
+ * Every call to this function returns the next input recorded since calling Start
+ * @return A ParamPackage of the recorded input, which can be used to create an InputDevice.
+ * If there has been no input, the package is empty
+ */
+ virtual Common::ParamPackage GetNextInput() = 0;
+};
+
+// Get all DevicePoller from all backends for a specific device type
+std::vector<std::unique_ptr<DevicePoller>> GetPollers(DeviceType type);
+} // namespace Polling
} // namespace InputCommon
diff --git a/src/input_common/sdl/sdl.cpp b/src/input_common/sdl/sdl.cpp
index d404afa89..88b557c5d 100644
--- a/src/input_common/sdl/sdl.cpp
+++ b/src/input_common/sdl/sdl.cpp
@@ -3,13 +3,15 @@
// Refer to the license.txt file included.
#include <cmath>
-#include <memory>
#include <string>
#include <tuple>
#include <unordered_map>
+#include <utility>
#include <SDL.h>
#include "common/logging/log.h"
#include "common/math_util.h"
+#include "common/param_package.h"
+#include "input_common/main.h"
#include "input_common/sdl/sdl.h"
namespace InputCommon {
@@ -69,6 +71,10 @@ public:
return (SDL_JoystickGetHat(joystick.get(), hat) & direction) != 0;
}
+ SDL_JoystickID GetJoystickID() const {
+ return SDL_JoystickInstanceID(joystick.get());
+ }
+
private:
std::unique_ptr<SDL_Joystick, decltype(&SDL_JoystickClose)> joystick;
};
@@ -247,5 +253,180 @@ void Shutdown() {
}
}
+/**
+ * This function converts a joystick ID used in SDL events to the device index. This is necessary
+ * because Citra opens joysticks using their indices, not their IDs.
+ */
+static int JoystickIDToDeviceIndex(SDL_JoystickID id) {
+ int num_joysticks = SDL_NumJoysticks();
+ for (int i = 0; i < num_joysticks; i++) {
+ auto joystick = GetJoystick(i);
+ if (joystick->GetJoystickID() == id) {
+ return i;
+ }
+ }
+ return -1;
+}
+
+Common::ParamPackage SDLEventToButtonParamPackage(const SDL_Event& event) {
+ Common::ParamPackage params({{"engine", "sdl"}});
+ switch (event.type) {
+ case SDL_JOYAXISMOTION:
+ params.Set("joystick", JoystickIDToDeviceIndex(event.jaxis.which));
+ params.Set("axis", event.jaxis.axis);
+ if (event.jaxis.value > 0) {
+ params.Set("direction", "+");
+ params.Set("threshold", "0.5");
+ } else {
+ params.Set("direction", "-");
+ params.Set("threshold", "-0.5");
+ }
+ break;
+ case SDL_JOYBUTTONUP:
+ params.Set("joystick", JoystickIDToDeviceIndex(event.jbutton.which));
+ params.Set("button", event.jbutton.button);
+ break;
+ case SDL_JOYHATMOTION:
+ params.Set("joystick", JoystickIDToDeviceIndex(event.jhat.which));
+ params.Set("hat", event.jhat.hat);
+ switch (event.jhat.value) {
+ case SDL_HAT_UP:
+ params.Set("direction", "up");
+ break;
+ case SDL_HAT_DOWN:
+ params.Set("direction", "down");
+ break;
+ case SDL_HAT_LEFT:
+ params.Set("direction", "left");
+ break;
+ case SDL_HAT_RIGHT:
+ params.Set("direction", "right");
+ break;
+ default:
+ return {};
+ }
+ break;
+ }
+ return params;
+}
+
+namespace Polling {
+
+class SDLPoller : public InputCommon::Polling::DevicePoller {
+public:
+ SDLPoller() = default;
+
+ ~SDLPoller() = default;
+
+ void Start() override {
+ // SDL joysticks must be opened, otherwise they don't generate events
+ SDL_JoystickUpdate();
+ int num_joysticks = SDL_NumJoysticks();
+ for (int i = 0; i < num_joysticks; i++) {
+ joysticks_opened.emplace_back(GetJoystick(i));
+ }
+ // Empty event queue to get rid of old events. citra-qt doesn't use the queue
+ SDL_Event dummy;
+ while (SDL_PollEvent(&dummy)) {
+ }
+ }
+
+ void Stop() override {
+ joysticks_opened.clear();
+ }
+
+private:
+ std::vector<std::shared_ptr<SDLJoystick>> joysticks_opened;
+};
+
+class SDLButtonPoller final : public SDLPoller {
+public:
+ SDLButtonPoller() = default;
+
+ ~SDLButtonPoller() = default;
+
+ Common::ParamPackage GetNextInput() override {
+ SDL_Event event;
+ while (SDL_PollEvent(&event)) {
+ switch (event.type) {
+ case SDL_JOYAXISMOTION:
+ if (std::abs(event.jaxis.value / 32767.0) < 0.5) {
+ break;
+ }
+ case SDL_JOYBUTTONUP:
+ case SDL_JOYHATMOTION:
+ return SDLEventToButtonParamPackage(event);
+ }
+ }
+ return {};
+ }
+};
+
+class SDLAnalogPoller final : public SDLPoller {
+public:
+ SDLAnalogPoller() = default;
+
+ ~SDLAnalogPoller() = default;
+
+ void Start() override {
+ SDLPoller::Start();
+
+ // Reset stored axes
+ analog_xaxis = -1;
+ analog_yaxis = -1;
+ analog_axes_joystick = -1;
+ }
+
+ Common::ParamPackage GetNextInput() override {
+ SDL_Event event;
+ while (SDL_PollEvent(&event)) {
+ if (event.type != SDL_JOYAXISMOTION || std::abs(event.jaxis.value / 32767.0) < 0.5) {
+ continue;
+ }
+ // An analog device needs two axes, so we need to store the axis for later and wait for
+ // a second SDL event. The axes also must be from the same joystick.
+ int axis = event.jaxis.axis;
+ if (analog_xaxis == -1) {
+ analog_xaxis = axis;
+ analog_axes_joystick = event.jaxis.which;
+ } else if (analog_yaxis == -1 && analog_xaxis != axis &&
+ analog_axes_joystick == event.jaxis.which) {
+ analog_yaxis = axis;
+ }
+ }
+ Common::ParamPackage params;
+ if (analog_xaxis != -1 && analog_yaxis != -1) {
+ params.Set("engine", "sdl");
+ params.Set("joystick", JoystickIDToDeviceIndex(analog_axes_joystick));
+ params.Set("axis_x", analog_xaxis);
+ params.Set("axis_y", analog_yaxis);
+ analog_xaxis = -1;
+ analog_yaxis = -1;
+ analog_axes_joystick = -1;
+ return params;
+ }
+ return params;
+ }
+
+private:
+ int analog_xaxis = -1;
+ int analog_yaxis = -1;
+ SDL_JoystickID analog_axes_joystick = -1;
+};
+
+std::vector<std::unique_ptr<InputCommon::Polling::DevicePoller>> GetPollers(
+ InputCommon::Polling::DeviceType type) {
+ std::vector<std::unique_ptr<InputCommon::Polling::DevicePoller>> pollers;
+ switch (type) {
+ case InputCommon::Polling::DeviceType::Analog:
+ pollers.push_back(std::make_unique<SDLAnalogPoller>());
+ break;
+ case InputCommon::Polling::DeviceType::Button:
+ pollers.push_back(std::make_unique<SDLButtonPoller>());
+ break;
+ }
+ return std::move(pollers);
+}
+} // namespace Polling
} // namespace SDL
} // namespace InputCommon
diff --git a/src/input_common/sdl/sdl.h b/src/input_common/sdl/sdl.h
index 3e72debcc..7934099d4 100644
--- a/src/input_common/sdl/sdl.h
+++ b/src/input_common/sdl/sdl.h
@@ -4,8 +4,21 @@
#pragma once
+#include <memory>
+#include <vector>
#include "core/frontend/input.h"
+union SDL_Event;
+namespace Common {
+class ParamPackage;
+}
+namespace InputCommon {
+namespace Polling {
+class DevicePoller;
+enum class DeviceType;
+} // namespace Polling
+} // namespace InputCommon
+
namespace InputCommon {
namespace SDL {
@@ -15,5 +28,15 @@ void Init();
/// Unresisters SDL device factories and shut them down.
void Shutdown();
+/// Creates a ParamPackage from an SDL_Event that can directly be used to create a ButtonDevice
+Common::ParamPackage SDLEventToButtonParamPackage(const SDL_Event& event);
+
+namespace Polling {
+
+/// Get all DevicePoller that use the SDL backend for a specific device type
+std::vector<std::unique_ptr<InputCommon::Polling::DevicePoller>> GetPollers(
+ InputCommon::Polling::DeviceType type);
+
+} // namespace Polling
} // namespace SDL
} // namespace InputCommon
diff --git a/src/yuzu/configuration/configure_input.cpp b/src/yuzu/configuration/configure_input.cpp
index d92a1fed9..cd7520f29 100644
--- a/src/yuzu/configuration/configure_input.cpp
+++ b/src/yuzu/configuration/configure_input.cpp
@@ -5,13 +5,13 @@
#include <algorithm>
#include <memory>
#include <utility>
+#include <QMessageBox>
#include <QTimer>
#include "common/param_package.h"
#include "input_common/main.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",
@@ -32,23 +32,19 @@ static QString getKeyName(int key_code) {
}
}
-static void SetButtonKey(int key, Common::ParamPackage& button_param) {
- button_param = Common::ParamPackage{InputCommon::GenerateKeyboardParam(key)};
-}
-
-static void SetAnalogKey(int key, Common::ParamPackage& analog_param,
- const std::string& button_name) {
+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, InputCommon::GenerateKeyboardParam(key));
+ analog_param.Set(button_name, input_param.Serialize());
}
ConfigureInput::ConfigureInput(QWidget* parent)
: QWidget(parent), ui(std::make_unique<Ui::ConfigureInput>()),
- timer(std::make_unique<QTimer>()) {
+ timeout_timer(std::make_unique<QTimer>()), poll_timer(std::make_unique<QTimer>()) {
ui->setupUi(this);
setFocusPolicy(Qt::ClickFocus);
@@ -63,7 +59,7 @@ ConfigureInput::ConfigureInput(QWidget* parent)
ui->buttonSL, ui->buttonSR, ui->buttonHome, ui->buttonScreenshot,
};
- analog_map = {{
+ analog_map_buttons = {{
{
ui->buttonLStickUp, ui->buttonLStickDown, ui->buttonLStickLeft, ui->buttonLStickRight,
ui->buttonLStickMod,
@@ -74,35 +70,57 @@ ConfigureInput::ConfigureInput(QWidget* parent)
},
}};
+ analog_map_stick = {ui->buttonLStickAnalog, ui->buttonRStickAnalog};
+
for (int button_id = 0; button_id < Settings::NativeButton::NumButtons; button_id++) {
if (button_map[button_id])
connect(button_map[button_id], &QPushButton::released, [=]() {
- handleClick(button_map[button_id],
- [=](int key) { SetButtonKey(key, buttons_param[button_id]); });
+ handleClick(
+ button_map[button_id],
+ [=](const Common::ParamPackage& params) { buttons_param[button_id] = params; },
+ InputCommon::Polling::DeviceType::Button);
});
}
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[analog_id][sub_button_id] != nullptr) {
- connect(analog_map[analog_id][sub_button_id], &QPushButton::released, [=]() {
- handleClick(analog_map[analog_id][sub_button_id], [=](int key) {
- SetAnalogKey(key, analogs_param[analog_id],
- analog_sub_buttons[sub_button_id]);
- });
- });
+ if (analog_map_buttons[analog_id][sub_button_id] != nullptr) {
+ 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_stick[analog_id], &QPushButton::released, [=]() {
+ QMessageBox::information(
+ this, "Information",
+ "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);
+ });
}
connect(ui->buttonRestoreDefaults, &QPushButton::released, [this]() { restoreDefaults(); });
- timer->setSingleShot(true);
- connect(timer.get(), &QTimer::timeout, [this]() {
- releaseKeyboard();
- releaseMouse();
- key_setter = boost::none;
- updateButtonLabels();
+ timeout_timer->setSingleShot(true);
+ connect(timeout_timer.get(), &QTimer::timeout, [this]() { setPollingResult({}, true); });
+
+ 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;
+ }
+ }
});
this->loadConfiguration();
@@ -132,13 +150,15 @@ void ConfigureInput::loadConfiguration() {
void ConfigureInput::restoreDefaults() {
for (int button_id = 0; button_id < Settings::NativeButton::NumButtons; button_id++) {
- SetButtonKey(Config::default_buttons[button_id], buttons_param[button_id]);
+ buttons_param[button_id] = Common::ParamPackage{
+ InputCommon::GenerateKeyboardParam(Config::default_buttons[button_id])};
}
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++) {
- SetAnalogKey(Config::default_analogs[analog_id][sub_button_id],
- analogs_param[analog_id], analog_sub_buttons[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]);
}
}
updateButtonLabels();
@@ -149,7 +169,9 @@ void ConfigureInput::updateButtonLabels() {
QString non_keyboard(tr("[non-keyboard]"));
auto KeyToText = [&non_keyboard](const Common::ParamPackage& param) {
- if (param.Get("engine", "") != "keyboard") {
+ if (!param.Has("engine")) {
+ return QString("[not set]");
+ } else if (param.Get("engine", "") != "keyboard") {
return non_keyboard;
} else {
return getKeyName(param.Get("code", 0));
@@ -162,7 +184,7 @@ void ConfigureInput::updateButtonLabels() {
for (int analog_id = 0; analog_id < Settings::NativeAnalog::NumAnalogs; analog_id++) {
if (analogs_param[analog_id].Get("engine", "") != "analog_from_button") {
- for (QPushButton* button : analog_map[analog_id]) {
+ for (QPushButton* button : analog_map_buttons[analog_id]) {
if (button)
button->setText(non_keyboard);
}
@@ -170,35 +192,66 @@ void ConfigureInput::updateButtonLabels() {
for (int sub_button_id = 0; sub_button_id < ANALOG_SUB_BUTTONS_NUM; sub_button_id++) {
Common::ParamPackage param(
analogs_param[analog_id].Get(analog_sub_buttons[sub_button_id], ""));
- if (analog_map[analog_id][sub_button_id])
- analog_map[analog_id][sub_button_id]->setText(KeyToText(param));
+ if (analog_map_buttons[analog_id][sub_button_id])
+ analog_map_buttons[analog_id][sub_button_id]->setText(KeyToText(param));
}
}
+ analog_map_stick[analog_id]->setText("Set Analog Stick");
}
}
-void ConfigureInput::handleClick(QPushButton* button, std::function<void(int)> new_key_setter) {
+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();
- key_setter = new_key_setter;
+ 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();
+ }
grabKeyboard();
grabMouse();
- timer->start(5000); // Cancel after 5 seconds
+ timeout_timer->start(5000); // Cancel after 5 seconds
+ poll_timer->start(200); // Check for new inputs every 200ms
}
-void ConfigureInput::keyPressEvent(QKeyEvent* event) {
+void ConfigureInput::setPollingResult(const Common::ParamPackage& params, bool abort) {
releaseKeyboard();
releaseMouse();
+ timeout_timer->stop();
+ poll_timer->stop();
+ for (auto& poller : device_pollers) {
+ poller->Stop();
+ }
- if (!key_setter || !event)
- return;
-
- if (event->key() != Qt::Key_Escape)
- (*key_setter)(event->key());
+ if (!abort) {
+ (*input_setter)(params);
+ }
updateButtonLabels();
- key_setter = boost::none;
- timer->stop();
+ input_setter = boost::none;
+}
+
+void ConfigureInput::keyPressEvent(QKeyEvent* event) {
+ if (!input_setter || !event)
+ return;
+
+ 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;
+ }
+ }
+ setPollingResult({}, true);
}
diff --git a/src/yuzu/configuration/configure_input.h b/src/yuzu/configuration/configure_input.h
index c950fbcb4..a0bef86d5 100644
--- a/src/yuzu/configuration/configure_input.h
+++ b/src/yuzu/configuration/configure_input.h
@@ -8,11 +8,13 @@
#include <functional>
#include <memory>
#include <string>
+#include <unordered_map>
#include <QKeyEvent>
#include <QWidget>
#include <boost/optional.hpp>
#include "common/param_package.h"
#include "core/settings.h"
+#include "input_common/main.h"
#include "ui_configure_input.h"
class QPushButton;
@@ -35,10 +37,11 @@ public:
private:
std::unique_ptr<Ui::ConfigureInput> ui;
- std::unique_ptr<QTimer> timer;
+ std::unique_ptr<QTimer> timeout_timer;
+ std::unique_ptr<QTimer> poll_timer;
/// This will be the the setting function when an input is awaiting configuration.
- boost::optional<std::function<void(int)>> key_setter;
+ boost::optional<std::function<void(const Common::ParamPackage&)>> input_setter;
std::array<Common::ParamPackage, Settings::NativeButton::NumButtons> buttons_param;
std::array<Common::ParamPackage, Settings::NativeAnalog::NumAnalogs> analogs_param;
@@ -48,13 +51,23 @@ private:
/// Each button input is represented by a QPushButton.
std::array<QPushButton*, Settings::NativeButton::NumButtons> button_map;
- /// Each analog input is represented by five QPushButtons which represents up, down, left, right
- /// and modifier
+ /// A group of five QPushButtons represent one analog input. The buttons each represent up,
+ /// down, left, right, and modifier, respectively.
std::array<std::array<QPushButton*, ANALOG_SUB_BUTTONS_NUM>, Settings::NativeAnalog::NumAnalogs>
- analog_map;
+ analog_map_buttons;
+
+ /// Analog inputs are also represented each with a single button, used to configure with an
+ /// actual analog stick
+ std::array<QPushButton*, Settings::NativeAnalog::NumAnalogs> analog_map_stick;
static const std::array<std::string, ANALOG_SUB_BUTTONS_NUM> analog_sub_buttons;
+ std::vector<std::unique_ptr<InputCommon::Polling::DevicePoller>> device_pollers;
+
+ /// A flag to indicate if keyboard keys are okay when configuring an input. If this is false,
+ /// keyboard events are ignored.
+ bool want_keyboard_keys = false;
+
/// Load configuration settings.
void loadConfiguration();
/// Restore all buttons to their default values.
@@ -63,7 +76,13 @@ private:
void updateButtonLabels();
/// Called when the button was pressed.
- void handleClick(QPushButton* button, std::function<void(int)> new_key_setter);
+ void handleClick(QPushButton* button,
+ std::function<void(const Common::ParamPackage&)> new_input_setter,
+ InputCommon::Polling::DeviceType type);
+
+ /// Finish polling and configure input using the input_setter
+ void setPollingResult(const Common::ParamPackage& params, bool abort);
+
/// Handle key press events.
void keyPressEvent(QKeyEvent* event) override;
};
diff --git a/src/yuzu/configuration/configure_input.ui b/src/yuzu/configuration/configure_input.ui
index 5143c9d72..c162ca02c 100644
--- a/src/yuzu/configuration/configure_input.ui
+++ b/src/yuzu/configuration/configure_input.ui
@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>343</width>
- <height>665</height>
+ <height>677</height>
</rect>
</property>
<property name="windowTitle">
@@ -16,10 +16,10 @@
<layout class="QVBoxLayout" name="verticalLayout_5">
<item>
<layout class="QGridLayout" name="gridLayout_7">
- <item row="0" column="0">
- <widget class="QGroupBox" name="faceButtons">
+ <item row="3" column="1">
+ <widget class="QGroupBox" name="faceButtons_6">
<property name="title">
- <string>Face Buttons</string>
+ <string>Misc.</string>
</property>
<property name="flat">
<bool>false</bool>
@@ -27,18 +27,18 @@
<property name="checkable">
<bool>false</bool>
</property>
- <layout class="QGridLayout" name="gridLayout">
+ <layout class="QGridLayout" name="gridLayout_6">
<item row="0" column="0">
- <layout class="QVBoxLayout" name="verticalLayout">
+ <layout class="QVBoxLayout" name="verticalLayout_25">
<item>
- <widget class="QLabel" name="label">
+ <widget class="QLabel" name="label_29">
<property name="text">
- <string>A:</string>
+ <string>Plus:</string>
</property>
</widget>
</item>
<item>
- <widget class="QPushButton" name="buttonA">
+ <widget class="QPushButton" name="buttonPlus">
<property name="text">
<string/>
</property>
@@ -47,16 +47,16 @@
</layout>
</item>
<item row="0" column="1">
- <layout class="QVBoxLayout" name="verticalLayout_2">
+ <layout class="QVBoxLayout" name="verticalLayout_26">
<item>
- <widget class="QLabel" name="label_2">
+ <widget class="QLabel" name="label_30">
<property name="text">
- <string>B:</string>
+ <string>Minus:</string>
</property>
</widget>
</item>
<item>
- <widget class="QPushButton" name="buttonB">
+ <widget class="QPushButton" name="buttonMinus">
<property name="text">
<string/>
</property>
@@ -65,16 +65,16 @@
</layout>
</item>
<item row="1" column="0">
- <layout class="QVBoxLayout" name="verticalLayout_3">
+ <layout class="QVBoxLayout" name="verticalLayout_27">
<item>
- <widget class="QLabel" name="label_3">
+ <widget class="QLabel" name="label_31">
<property name="text">
- <string>X:</string>
+ <string>Home:</string>
</property>
</widget>
</item>
<item>
- <widget class="QPushButton" name="buttonX">
+ <widget class="QPushButton" name="buttonHome">
<property name="text">
<string/>
</property>
@@ -83,16 +83,17 @@
</layout>
</item>
<item row="1" column="1">
- <layout class="QVBoxLayout" name="verticalLayout_4">
+ <layout class="QVBoxLayout" name="verticalLayout_28">
<item>
- <widget class="QLabel" name="label_4">
+ <widget class="QLabel" name="label_11">
<property name="text">
- <string>Y:</string>
+ <string>Screen
+Capture:</string>
</property>
</widget>
</item>
<item>
- <widget class="QPushButton" name="buttonY">
+ <widget class="QPushButton" name="buttonScreenshot">
<property name="text">
<string/>
</property>
@@ -100,13 +101,26 @@
</item>
</layout>
</item>
+ <item row="2" column="1">
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
</layout>
</widget>
</item>
- <item row="0" column="1">
- <widget class="QGroupBox" name="faceButtons_2">
+ <item row="0" column="0">
+ <widget class="QGroupBox" name="faceButtons">
<property name="title">
- <string>Directional Pad</string>
+ <string>Face Buttons</string>
</property>
<property name="flat">
<bool>false</bool>
@@ -114,18 +128,18 @@
<property name="checkable">
<bool>false</bool>
</property>
- <layout class="QGridLayout" name="gridLayout_2">
- <item row="1" column="0">
- <layout class="QVBoxLayout" name="verticalLayout_12">
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0">
+ <layout class="QVBoxLayout" name="verticalLayout">
<item>
- <widget class="QLabel" name="label_34">
+ <widget class="QLabel" name="label">
<property name="text">
- <string>Up:</string>
+ <string>A:</string>
</property>
</widget>
</item>
<item>
- <widget class="QPushButton" name="buttonDpadUp">
+ <widget class="QPushButton" name="buttonA">
<property name="text">
<string/>
</property>
@@ -133,17 +147,17 @@
</item>
</layout>
</item>
- <item row="1" column="1">
- <layout class="QVBoxLayout" name="verticalLayout_9">
+ <item row="0" column="1">
+ <layout class="QVBoxLayout" name="verticalLayout_2">
<item>
- <widget class="QLabel" name="label_35">
+ <widget class="QLabel" name="label_2">
<property name="text">
- <string>Down:</string>
+ <string>B:</string>
</property>
</widget>
</item>
<item>
- <widget class="QPushButton" name="buttonDpadDown">
+ <widget class="QPushButton" name="buttonB">
<property name="text">
<string/>
</property>
@@ -151,17 +165,17 @@
</item>
</layout>
</item>
- <item row="0" column="0">
- <layout class="QVBoxLayout" name="verticalLayout_10">
+ <item row="1" column="0">
+ <layout class="QVBoxLayout" name="verticalLayout_3">
<item>
- <widget class="QLabel" name="label_32">
+ <widget class="QLabel" name="label_3">
<property name="text">
- <string>Left:</string>
+ <string>X:</string>
</property>
</widget>
</item>
<item>
- <widget class="QPushButton" name="buttonDpadLeft">
+ <widget class="QPushButton" name="buttonX">
<property name="text">
<string/>
</property>
@@ -169,17 +183,17 @@
</item>
</layout>
</item>
- <item row="0" column="1">
- <layout class="QVBoxLayout" name="verticalLayout_11">
+ <item row="1" column="1">
+ <layout class="QVBoxLayout" name="verticalLayout_4">
<item>
- <widget class="QLabel" name="label_33">
+ <widget class="QLabel" name="label_4">
<property name="text">
- <string>Right:</string>
+ <string>Y:</string>
</property>
</widget>
</item>
<item>
- <widget class="QPushButton" name="buttonDpadRight">
+ <widget class="QPushButton" name="buttonY">
<property name="text">
<string/>
</property>
@@ -190,10 +204,10 @@
</layout>
</widget>
</item>
- <item row="3" column="1">
- <widget class="QGroupBox" name="faceButtons_6">
+ <item row="0" column="1">
+ <widget class="QGroupBox" name="faceButtons_2">
<property name="title">
- <string>Misc.</string>
+ <string>Directional Pad</string>
</property>
<property name="flat">
<bool>false</bool>
@@ -201,18 +215,18 @@
<property name="checkable">
<bool>false</bool>
</property>
- <layout class="QGridLayout" name="gridLayout_6">
- <item row="0" column="0">
- <layout class="QVBoxLayout" name="verticalLayout_25">
+ <layout class="QGridLayout" name="gridLayout_2">
+ <item row="1" column="0">
+ <layout class="QVBoxLayout" name="verticalLayout_12">
<item>
- <widget class="QLabel" name="label_29">
+ <widget class="QLabel" name="label_34">
<property name="text">
- <string>Plus:</string>
+ <string>Up:</string>
</property>
</widget>
</item>
<item>
- <widget class="QPushButton" name="buttonPlus">
+ <widget class="QPushButton" name="buttonDpadUp">
<property name="text">
<string/>
</property>
@@ -220,17 +234,17 @@
</item>
</layout>
</item>
- <item row="0" column="1">
- <layout class="QVBoxLayout" name="verticalLayout_26">
+ <item row="1" column="1">
+ <layout class="QVBoxLayout" name="verticalLayout_9">
<item>
- <widget class="QLabel" name="label_30">
+ <widget class="QLabel" name="label_35">
<property name="text">
- <string>Minus:</string>
+ <string>Down:</string>
</property>
</widget>
</item>
<item>
- <widget class="QPushButton" name="buttonMinus">
+ <widget class="QPushButton" name="buttonDpadDown">
<property name="text">
<string/>
</property>
@@ -238,17 +252,17 @@
</item>
</layout>
</item>
- <item row="1" column="0">
- <layout class="QVBoxLayout" name="verticalLayout_27">
+ <item row="0" column="0">
+ <layout class="QVBoxLayout" name="verticalLayout_10">
<item>
- <widget class="QLabel" name="label_31">
+ <widget class="QLabel" name="label_32">
<property name="text">
- <string>Home:</string>
+ <string>Left:</string>
</property>
</widget>
</item>
<item>
- <widget class="QPushButton" name="buttonHome">
+ <widget class="QPushButton" name="buttonDpadLeft">
<property name="text">
<string/>
</property>
@@ -256,18 +270,17 @@
</item>
</layout>
</item>
- <item row="1" column="1">
- <layout class="QVBoxLayout" name="verticalLayout_28">
+ <item row="0" column="1">
+ <layout class="QVBoxLayout" name="verticalLayout_11">
<item>
- <widget class="QLabel" name="label_11">
+ <widget class="QLabel" name="label_33">
<property name="text">
- <string>Screen
-Capture:</string>
+ <string>Right:</string>
</property>
</widget>
</item>
<item>
- <widget class="QPushButton" name="buttonScreenshot">
+ <widget class="QPushButton" name="buttonDpadRight">
<property name="text">
<string/>
</property>
@@ -275,19 +288,6 @@ Capture:</string>
</item>
</layout>
</item>
- <item row="2" column="1">
- <spacer name="verticalSpacer">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>40</height>
- </size>
- </property>
- </spacer>
- </item>
</layout>
</widget>
</item>
@@ -414,10 +414,13 @@ Capture:</string>
</layout>
</widget>
</item>
- <item row="1" column="0">
- <widget class="QGroupBox" name="faceButtons_4">
+ <item row="1" column="1">
+ <widget class="QGroupBox" name="faceButtons_5">
<property name="title">
- <string>Left Stick</string>
+ <string>Right Stick</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
<property name="flat">
<bool>false</bool>
@@ -425,18 +428,18 @@ Capture:</string>
<property name="checkable">
<bool>false</bool>
</property>
- <layout class="QGridLayout" name="gridLayout_4">
- <item row="0" column="0">
- <layout class="QVBoxLayout" name="verticalLayout_17">
+ <layout class="QGridLayout" name="gridLayout_5">
+ <item row="1" column="1">
+ <layout class="QVBoxLayout" name="verticalLayout_24">
<item>
- <widget class="QLabel" name="label_21">
+ <widget class="QLabel" name="label_26">
<property name="text">
- <string>Left:</string>
+ <string>Down:</string>
</property>
</widget>
</item>
<item>
- <widget class="QPushButton" name="buttonLStickLeft">
+ <widget class="QPushButton" name="buttonRStickDown">
<property name="text">
<string/>
</property>
@@ -445,16 +448,16 @@ Capture:</string>
</layout>
</item>
<item row="0" column="1">
- <layout class="QVBoxLayout" name="verticalLayout_18">
+ <layout class="QVBoxLayout" name="verticalLayout_22">
<item>
- <widget class="QLabel" name="label_23">
+ <widget class="QLabel" name="label_27">
<property name="text">
<string>Right:</string>
</property>
</widget>
</item>
<item>
- <widget class="QPushButton" name="buttonLStickRight">
+ <widget class="QPushButton" name="buttonRStickRight">
<property name="text">
<string/>
</property>
@@ -462,17 +465,24 @@ Capture:</string>
</item>
</layout>
</item>
+ <item row="3" column="0" colspan="2">
+ <widget class="QPushButton" name="buttonRStickAnalog">
+ <property name="text">
+ <string>Set Analog Stick</string>
+ </property>
+ </widget>
+ </item>
<item row="1" column="0">
- <layout class="QVBoxLayout" name="verticalLayout_19">
+ <layout class="QVBoxLayout" name="verticalLayout_21">
<item>
- <widget class="QLabel" name="label_24">
+ <widget class="QLabel" name="label_25">
<property name="text">
- <string>Up:</string>
+ <string>Left:</string>
</property>
</widget>
</item>
<item>
- <widget class="QPushButton" name="buttonLStickUp">
+ <widget class="QPushButton" name="buttonRStickLeft">
<property name="text">
<string/>
</property>
@@ -480,17 +490,17 @@ Capture:</string>
</item>
</layout>
</item>
- <item row="1" column="1">
- <layout class="QVBoxLayout" name="verticalLayout_20">
+ <item row="0" column="0">
+ <layout class="QVBoxLayout" name="verticalLayout_25">
<item>
- <widget class="QLabel" name="label_22">
+ <widget class="QLabel" name="label_28">
<property name="text">
- <string>Down:</string>
+ <string>Up:</string>
</property>
</widget>
</item>
<item>
- <widget class="QPushButton" name="buttonLStickDown">
+ <widget class="QPushButton" name="buttonRStickUp">
<property name="text">
<string/>
</property>
@@ -499,16 +509,16 @@ Capture:</string>
</layout>
</item>
<item row="2" column="0">
- <layout class="QVBoxLayout" name="verticalLayout_7" stretch="0,0">
+ <layout class="QVBoxLayout" name="verticalLayout_6">
<item>
- <widget class="QLabel" name="label_6">
+ <widget class="QLabel" name="label_5">
<property name="text">
<string>Pressed:</string>
</property>
</widget>
</item>
<item>
- <widget class="QPushButton" name="buttonLStick">
+ <widget class="QPushButton" name="buttonRStick">
<property name="text">
<string/>
</property>
@@ -517,16 +527,16 @@ Capture:</string>
</layout>
</item>
<item row="2" column="1">
- <layout class="QVBoxLayout" name="verticalLayout_31">
+ <layout class="QVBoxLayout" name="verticalLayout_32">
<item>
- <widget class="QLabel" name="label_9">
+ <widget class="QLabel" name="label_10">
<property name="text">
<string>Modifier:</string>
</property>
</widget>
</item>
<item>
- <widget class="QPushButton" name="buttonLStickMod">
+ <widget class="QPushButton" name="buttonRStickMod">
<property name="text">
<string/>
</property>
@@ -537,13 +547,10 @@ Capture:</string>
</layout>
</widget>
</item>
- <item row="1" column="1">
- <widget class="QGroupBox" name="faceButtons_5">
+ <item row="1" column="0">
+ <widget class="QGroupBox" name="faceButtons_4">
<property name="title">
- <string>Right Stick</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
+ <string>Left Stick</string>
</property>
<property name="flat">
<bool>false</bool>
@@ -551,18 +558,18 @@ Capture:</string>
<property name="checkable">
<bool>false</bool>
</property>
- <layout class="QGridLayout" name="gridLayout_5">
+ <layout class="QGridLayout" name="gridLayout_4">
<item row="1" column="1">
- <layout class="QVBoxLayout" name="verticalLayout_24">
+ <layout class="QVBoxLayout" name="verticalLayout_20">
<item>
- <widget class="QLabel" name="label_26">
+ <widget class="QLabel" name="label_22">
<property name="text">
<string>Down:</string>
</property>
</widget>
</item>
<item>
- <widget class="QPushButton" name="buttonRStickDown">
+ <widget class="QPushButton" name="buttonLStickDown">
<property name="text">
<string/>
</property>
@@ -570,17 +577,24 @@ Capture:</string>
</item>
</layout>
</item>
+ <item row="4" column="0" colspan="2">
+ <widget class="QPushButton" name="buttonLStickAnalog">
+ <property name="text">
+ <string>Set Analog Stick</string>
+ </property>
+ </widget>
+ </item>
<item row="0" column="1">
- <layout class="QVBoxLayout" name="verticalLayout_22">
+ <layout class="QVBoxLayout" name="verticalLayout_18">
<item>
- <widget class="QLabel" name="label_27">
+ <widget class="QLabel" name="label_23">
<property name="text">
<string>Right:</string>
</property>
</widget>
</item>
<item>
- <widget class="QPushButton" name="buttonRStickRight">
+ <widget class="QPushButton" name="buttonLStickRight">
<property name="text">
<string/>
</property>
@@ -588,17 +602,17 @@ Capture:</string>
</item>
</layout>
</item>
- <item row="1" column="0">
- <layout class="QVBoxLayout" name="verticalLayout_23">
+ <item row="0" column="0">
+ <layout class="QVBoxLayout" name="verticalLayout_17">
<item>
- <widget class="QLabel" name="label_28">
+ <widget class="QLabel" name="label_21">
<property name="text">
- <string>Up:</string>
+ <string>Left:</string>
</property>
</widget>
</item>
<item>
- <widget class="QPushButton" name="buttonRStickUp">
+ <widget class="QPushButton" name="buttonLStickLeft">
<property name="text">
<string/>
</property>
@@ -606,17 +620,17 @@ Capture:</string>
</item>
</layout>
</item>
- <item row="0" column="0">
- <layout class="QVBoxLayout" name="verticalLayout_21">
+ <item row="1" column="0">
+ <layout class="QVBoxLayout" name="verticalLayout_19">
<item>
- <widget class="QLabel" name="label_25">
+ <widget class="QLabel" name="label_24">
<property name="text">
- <string>Left:</string>
+ <string>Up:</string>
</property>
</widget>
</item>
<item>
- <widget class="QPushButton" name="buttonRStickLeft">
+ <widget class="QPushButton" name="buttonLStickUp">
<property name="text">
<string/>
</property>
@@ -624,17 +638,17 @@ Capture:</string>
</item>
</layout>
</item>
- <item row="2" column="1">
- <layout class="QVBoxLayout" name="verticalLayout_32">
+ <item row="3" column="0">
+ <layout class="QVBoxLayout" name="verticalLayout_31">
<item>
- <widget class="QLabel" name="label_10">
+ <widget class="QLabel" name="label_9">
<property name="text">
<string>Modifier:</string>
</property>
</widget>
</item>
<item>
- <widget class="QPushButton" name="buttonRStickMod">
+ <widget class="QPushButton" name="buttonLStickMod">
<property name="text">
<string/>
</property>
@@ -642,17 +656,17 @@ Capture:</string>
</item>
</layout>
</item>
- <item row="2" column="0">
- <layout class="QVBoxLayout" name="verticalLayout_6">
+ <item row="3" column="1">
+ <layout class="QVBoxLayout" name="verticalLayout_7" stretch="0,0">
<item>
- <widget class="QLabel" name="label_5">
+ <widget class="QLabel" name="label_6">
<property name="text">
<string>Pressed:</string>
</property>
</widget>
</item>
<item>
- <widget class="QPushButton" name="buttonRStick">
+ <widget class="QPushButton" name="buttonLStick">
<property name="text">
<string/>
</property>