diff --git a/src/input_common/main.cpp b/src/input_common/main.cpp
index 5573537408dd53aa23100c69c6df956b7180267e..95d40f09fe6664c764138e1c44560fca821c7674 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 5604f0fa88011ded93a9fc21a4ffaf1f43e1e4c6..77a0ce90b28869d90a3f97c0ac4015cb193affbc 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 d404afa89f7db7c70397309718809b140b79bab5..88b557c5dc64969a0bc2f622aa4e6d514f5dca10 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 3e72debcceeb7ed44ab2b9cba69a3f8502b37aaf..7934099d4b52bee4be54387f3fd5d89be52df144 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 d92a1fed9f2b8decdce82f45ad204572744589b2..cd7520f2904d9a64c1c79243b719f57885810605 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 c950fbcb433b55c2c225eae1ff005c0406c0d755..a0bef86d56b048e38be42230edfeba995e9c6ac0 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 5143c9d725b1fa2b6a37fc6a4a4defcac45998f2..c162ca02c8e6e9a36795aab54a804436210ad8db 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>