mirror of
https://github.com/vanilla-wiiu/vanilla.git
synced 2025-01-22 08:11:47 -05:00
started implementing controller remapping functionality
Currently axes don't work, will need to find a good solution for this
This commit is contained in:
parent
a5ef5fca7c
commit
cb0a2afaa1
8 changed files with 549 additions and 119 deletions
|
@ -1,12 +1,15 @@
|
|||
#include "gamepadhandler.h"
|
||||
|
||||
#include <QDateTime>
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QStandardPaths>
|
||||
#include <QXmlStreamWriter>
|
||||
#include <vanilla.h>
|
||||
|
||||
#include "keymap.h"
|
||||
|
||||
static int g_buttonMap[SDL_CONTROLLER_BUTTON_MAX] = {-1};
|
||||
static int g_axisMap[SDL_CONTROLLER_AXIS_MAX] = {-1};
|
||||
static bool g_defaultMapsInitialized = false;
|
||||
static int g_defaultButtonMap[SDL_CONTROLLER_BUTTON_MAX] = {-1};
|
||||
static int g_defaultAxisMap[SDL_CONTROLLER_AXIS_MAX] = {-1};
|
||||
|
||||
GamepadHandler::GamepadHandler(QObject *parent) : QObject(parent)
|
||||
{
|
||||
|
@ -14,29 +17,44 @@ GamepadHandler::GamepadHandler(QObject *parent) : QObject(parent)
|
|||
m_controller = nullptr;
|
||||
m_nextGamepad = -2;
|
||||
m_vibrate = false;
|
||||
m_keyMap = nullptr;
|
||||
m_signalNext = false;
|
||||
|
||||
g_buttonMap[SDL_CONTROLLER_BUTTON_A] = VANILLA_BTN_A;
|
||||
g_buttonMap[SDL_CONTROLLER_BUTTON_B] = VANILLA_BTN_B;
|
||||
g_buttonMap[SDL_CONTROLLER_BUTTON_X] = VANILLA_BTN_X;
|
||||
g_buttonMap[SDL_CONTROLLER_BUTTON_Y] = VANILLA_BTN_Y;
|
||||
g_buttonMap[SDL_CONTROLLER_BUTTON_BACK] = VANILLA_BTN_MINUS;
|
||||
g_buttonMap[SDL_CONTROLLER_BUTTON_GUIDE] = VANILLA_BTN_HOME;
|
||||
g_buttonMap[SDL_CONTROLLER_BUTTON_MISC1] = VANILLA_BTN_TV;
|
||||
g_buttonMap[SDL_CONTROLLER_BUTTON_START] = VANILLA_BTN_PLUS;
|
||||
g_buttonMap[SDL_CONTROLLER_BUTTON_LEFTSTICK] = VANILLA_BTN_L3;
|
||||
g_buttonMap[SDL_CONTROLLER_BUTTON_RIGHTSTICK] = VANILLA_BTN_R3;
|
||||
g_buttonMap[SDL_CONTROLLER_BUTTON_LEFTSHOULDER] = VANILLA_BTN_L;
|
||||
g_buttonMap[SDL_CONTROLLER_BUTTON_RIGHTSHOULDER] = VANILLA_BTN_R;
|
||||
g_buttonMap[SDL_CONTROLLER_BUTTON_DPAD_UP] = VANILLA_BTN_UP;
|
||||
g_buttonMap[SDL_CONTROLLER_BUTTON_DPAD_DOWN] = VANILLA_BTN_DOWN;
|
||||
g_buttonMap[SDL_CONTROLLER_BUTTON_DPAD_LEFT] = VANILLA_BTN_LEFT;
|
||||
g_buttonMap[SDL_CONTROLLER_BUTTON_DPAD_RIGHT] = VANILLA_BTN_RIGHT;
|
||||
g_axisMap[SDL_CONTROLLER_AXIS_LEFTX] = VANILLA_AXIS_L_X;
|
||||
g_axisMap[SDL_CONTROLLER_AXIS_LEFTY] = VANILLA_AXIS_L_Y;
|
||||
g_axisMap[SDL_CONTROLLER_AXIS_RIGHTX] = VANILLA_AXIS_R_X;
|
||||
g_axisMap[SDL_CONTROLLER_AXIS_RIGHTY] = VANILLA_AXIS_R_Y;
|
||||
g_axisMap[SDL_CONTROLLER_AXIS_TRIGGERLEFT] = VANILLA_BTN_ZL;
|
||||
g_axisMap[SDL_CONTROLLER_AXIS_TRIGGERRIGHT] = VANILLA_BTN_ZR;
|
||||
if (!g_defaultMapsInitialized) {
|
||||
g_defaultButtonMap[SDL_CONTROLLER_BUTTON_A] = VANILLA_BTN_A;
|
||||
g_defaultButtonMap[SDL_CONTROLLER_BUTTON_B] = VANILLA_BTN_B;
|
||||
g_defaultButtonMap[SDL_CONTROLLER_BUTTON_X] = VANILLA_BTN_X;
|
||||
g_defaultButtonMap[SDL_CONTROLLER_BUTTON_Y] = VANILLA_BTN_Y;
|
||||
g_defaultButtonMap[SDL_CONTROLLER_BUTTON_BACK] = VANILLA_BTN_MINUS;
|
||||
g_defaultButtonMap[SDL_CONTROLLER_BUTTON_GUIDE] = VANILLA_BTN_HOME;
|
||||
g_defaultButtonMap[SDL_CONTROLLER_BUTTON_MISC1] = VANILLA_BTN_TV;
|
||||
g_defaultButtonMap[SDL_CONTROLLER_BUTTON_START] = VANILLA_BTN_PLUS;
|
||||
g_defaultButtonMap[SDL_CONTROLLER_BUTTON_LEFTSTICK] = VANILLA_BTN_L3;
|
||||
g_defaultButtonMap[SDL_CONTROLLER_BUTTON_RIGHTSTICK] = VANILLA_BTN_R3;
|
||||
g_defaultButtonMap[SDL_CONTROLLER_BUTTON_LEFTSHOULDER] = VANILLA_BTN_L;
|
||||
g_defaultButtonMap[SDL_CONTROLLER_BUTTON_RIGHTSHOULDER] = VANILLA_BTN_R;
|
||||
g_defaultButtonMap[SDL_CONTROLLER_BUTTON_DPAD_UP] = VANILLA_BTN_UP;
|
||||
g_defaultButtonMap[SDL_CONTROLLER_BUTTON_DPAD_DOWN] = VANILLA_BTN_DOWN;
|
||||
g_defaultButtonMap[SDL_CONTROLLER_BUTTON_DPAD_LEFT] = VANILLA_BTN_LEFT;
|
||||
g_defaultButtonMap[SDL_CONTROLLER_BUTTON_DPAD_RIGHT] = VANILLA_BTN_RIGHT;
|
||||
g_defaultAxisMap[SDL_CONTROLLER_AXIS_LEFTX] = VANILLA_AXIS_L_X;
|
||||
g_defaultAxisMap[SDL_CONTROLLER_AXIS_LEFTY] = VANILLA_AXIS_L_Y;
|
||||
g_defaultAxisMap[SDL_CONTROLLER_AXIS_RIGHTX] = VANILLA_AXIS_R_X;
|
||||
g_defaultAxisMap[SDL_CONTROLLER_AXIS_RIGHTY] = VANILLA_AXIS_R_Y;
|
||||
g_defaultAxisMap[SDL_CONTROLLER_AXIS_TRIGGERLEFT] = VANILLA_BTN_ZL;
|
||||
g_defaultAxisMap[SDL_CONTROLLER_AXIS_TRIGGERRIGHT] = VANILLA_BTN_ZR;
|
||||
g_defaultMapsInitialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
void GamepadHandler::setKeyMap(KeyMap *keyMap)
|
||||
{
|
||||
m_keyMap = keyMap;
|
||||
}
|
||||
|
||||
void GamepadHandler::signalNextButtonOrAxis(bool e)
|
||||
{
|
||||
m_signalNext = e;
|
||||
}
|
||||
|
||||
void GamepadHandler::close()
|
||||
|
@ -53,7 +71,98 @@ void GamepadHandler::setController(int index)
|
|||
m_mutex.unlock();
|
||||
}
|
||||
|
||||
void EnableSensorIfAvailable(SDL_GameController *controller, SDL_SensorType sensor)
|
||||
void GamepadHandler::clear()
|
||||
{
|
||||
for (int i = 0; i < SDL_CONTROLLER_BUTTON_MAX; i++) {
|
||||
m_buttonMap[i] = -1;
|
||||
}
|
||||
for (int i = 0; i < SDL_CONTROLLER_AXIS_MAX; i++) {
|
||||
m_axisMap[i] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
void GamepadHandler::setButton(SDL_GameControllerButton sdl_btn, int vanilla_btn)
|
||||
{
|
||||
m_mapMutex.lock();
|
||||
m_buttonMap[sdl_btn] = vanilla_btn;
|
||||
m_mapMutex.unlock();
|
||||
}
|
||||
|
||||
void GamepadHandler::setAxis(SDL_GameControllerAxis sdl_axis, int vanilla_axis)
|
||||
{
|
||||
m_mapMutex.lock();
|
||||
m_axisMap[sdl_axis] = vanilla_axis;
|
||||
m_mapMutex.unlock();
|
||||
}
|
||||
|
||||
void GamepadHandler::save()
|
||||
{
|
||||
saveCustomProfile();
|
||||
}
|
||||
|
||||
QString GamepadHandler::getConfigFilename(SDL_JoystickGUID guid)
|
||||
{
|
||||
QDir dir(QStandardPaths::writableLocation(QStandardPaths::ConfigLocation));
|
||||
dir = dir.filePath("vanilla");
|
||||
dir.mkpath(".");
|
||||
|
||||
char buf[33];
|
||||
SDL_JoystickGetGUIDString(guid, buf, sizeof(buf));
|
||||
|
||||
return dir.filePath(QStringLiteral("controller-%1.xml").arg(buf));
|
||||
}
|
||||
|
||||
static int g_serializationVersion = 1;
|
||||
|
||||
void GamepadHandler::saveCustomProfile()
|
||||
{
|
||||
m_mutex.lock();
|
||||
if (m_controller) {
|
||||
SDL_JoystickGUID guid = SDL_JoystickGetGUID(SDL_GameControllerGetJoystick(m_controller));
|
||||
QFile file(getConfigFilename(guid));
|
||||
if (file.open(QFile::WriteOnly)) {
|
||||
QXmlStreamWriter writer(&file);
|
||||
writer.setAutoFormatting(true);
|
||||
|
||||
writer.writeStartDocument();
|
||||
|
||||
writer.writeStartElement(QStringLiteral("VanillaControllerMap"));
|
||||
|
||||
writer.writeAttribute(QStringLiteral("Version"), QString::number(g_serializationVersion));
|
||||
|
||||
writer.writeStartElement(QStringLiteral("Buttons"));
|
||||
for (int i = 0; i < SDL_CONTROLLER_BUTTON_MAX; i++) {
|
||||
if (m_buttonMap[i] != g_defaultButtonMap[i]) {
|
||||
writer.writeStartElement(QStringLiteral("Button"));
|
||||
writer.writeAttribute(QStringLiteral("Id"), QString::number(i));
|
||||
writer.writeCharacters(QString::number(m_buttonMap[i]));
|
||||
writer.writeEndElement(); // Button
|
||||
}
|
||||
}
|
||||
writer.writeEndElement(); // Buttons
|
||||
|
||||
writer.writeStartElement(QStringLiteral("Axes"));
|
||||
for (int i = 0; i < SDL_CONTROLLER_AXIS_MAX; i++) {
|
||||
if (m_axisMap[i] != g_defaultAxisMap[i]) {
|
||||
writer.writeStartElement(QStringLiteral("Axis"));
|
||||
writer.writeAttribute(QStringLiteral("Id"), QString::number(i));
|
||||
writer.writeCharacters(QString::number(m_axisMap[i]));
|
||||
writer.writeEndElement(); // Axis
|
||||
}
|
||||
}
|
||||
writer.writeEndElement(); // Axes
|
||||
|
||||
writer.writeEndElement(); // VanillaControllerMap
|
||||
|
||||
writer.writeEndDocument();
|
||||
|
||||
file.close();
|
||||
}
|
||||
}
|
||||
m_mutex.unlock();
|
||||
}
|
||||
|
||||
void enableSensorIfAvailable(SDL_GameController *controller, SDL_SensorType sensor)
|
||||
{
|
||||
if (SDL_GameControllerHasSensor(controller, sensor)) {
|
||||
SDL_GameControllerSetSensorEnabled(controller, sensor, SDL_TRUE);
|
||||
|
@ -78,8 +187,28 @@ void GamepadHandler::run()
|
|||
}
|
||||
if (m_nextGamepad != -1) {
|
||||
m_controller = SDL_GameControllerOpen(m_nextGamepad);
|
||||
EnableSensorIfAvailable(m_controller, SDL_SENSOR_ACCEL);
|
||||
EnableSensorIfAvailable(m_controller, SDL_SENSOR_GYRO);
|
||||
enableSensorIfAvailable(m_controller, SDL_SENSOR_ACCEL);
|
||||
enableSensorIfAvailable(m_controller, SDL_SENSOR_GYRO);
|
||||
|
||||
SDL_JoystickGUID guid = SDL_JoystickGetGUID(SDL_GameControllerGetJoystick(m_controller));
|
||||
QFile f(getConfigFilename(guid));
|
||||
clear();
|
||||
bool loaded = false;
|
||||
if (f.open(QFile::ReadOnly)) {
|
||||
// TODO: Load custom profile if available
|
||||
|
||||
f.close();
|
||||
}
|
||||
|
||||
if (!loaded) {
|
||||
// Set defaults
|
||||
for (int i = 0; i < SDL_CONTROLLER_BUTTON_MAX; i++) {
|
||||
m_buttonMap[i] = g_defaultButtonMap[i];
|
||||
}
|
||||
for (int i = 0; i < SDL_CONTROLLER_AXIS_MAX; i++) {
|
||||
m_axisMap[i] = g_defaultAxisMap[i];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
m_controller = nullptr;
|
||||
}
|
||||
|
@ -91,8 +220,6 @@ void GamepadHandler::run()
|
|||
SDL_GameControllerRumble(m_controller, amount, amount, 0);
|
||||
}
|
||||
|
||||
m_mutex.unlock();
|
||||
|
||||
SDL_Event event;
|
||||
while (SDL_PollEvent(&event)) {
|
||||
switch (event.type) {
|
||||
|
@ -112,18 +239,32 @@ void GamepadHandler::run()
|
|||
case SDL_CONTROLLERBUTTONDOWN:
|
||||
case SDL_CONTROLLERBUTTONUP:
|
||||
if (m_controller && event.cdevice.which == SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(m_controller))) {
|
||||
int vanilla_btn = g_buttonMap[event.cbutton.button];
|
||||
int vanilla_btn = m_buttonMap[event.cbutton.button];
|
||||
if (vanilla_btn != -1) {
|
||||
emit buttonStateChanged(vanilla_btn, event.type == SDL_CONTROLLERBUTTONDOWN ? INT16_MAX : 0);
|
||||
}
|
||||
if (m_signalNext && event.type == SDL_CONTROLLERBUTTONDOWN) {
|
||||
emit buttonPressed(static_cast<SDL_GameControllerButton>(event.cbutton.button));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SDL_CONTROLLERAXISMOTION:
|
||||
if (m_controller && event.cdevice.which == SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(m_controller))) {
|
||||
int vanilla_axis = g_axisMap[event.caxis.axis];
|
||||
Sint16 axis_value = event.caxis.value;
|
||||
if (vanilla_axis != -1) {
|
||||
emit buttonStateChanged(vanilla_axis, axis_value);
|
||||
static Sint16 cached_axes[SDL_CONTROLLER_AXIS_MAX] = {0};
|
||||
|
||||
if (event.caxis.value != cached_axes[event.caxis.axis]) {
|
||||
int vanilla_axis = m_axisMap[event.caxis.axis];
|
||||
Sint16 axis_value = event.caxis.value;
|
||||
if (vanilla_axis != -1) {
|
||||
emit buttonStateChanged(vanilla_axis, axis_value);
|
||||
}
|
||||
if (m_signalNext) {
|
||||
static const int threshold = 1024;
|
||||
if (abs(event.caxis.value - cached_axes[event.caxis.axis]) > threshold) {
|
||||
emit axisMoved(static_cast<SDL_GameControllerAxis>(event.caxis.axis));
|
||||
}
|
||||
}
|
||||
cached_axes[event.caxis.axis] = event.caxis.value;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -141,6 +282,8 @@ void GamepadHandler::run()
|
|||
}
|
||||
}
|
||||
|
||||
m_mutex.unlock();
|
||||
|
||||
// Don't spam CPU cycles, still allow for up to 200Hz polling (for reference, Wii U gamepad is 180Hz)
|
||||
SDL_Delay(5);
|
||||
|
||||
|
@ -159,9 +302,9 @@ void GamepadHandler::vibrate(bool on)
|
|||
|
||||
void GamepadHandler::keyPressed(Qt::Key key)
|
||||
{
|
||||
if (!m_controller) {
|
||||
auto it = KeyMap::instance.find(key);
|
||||
if (it != KeyMap::instance.end()) {
|
||||
if (!m_controller && m_keyMap) {
|
||||
auto it = m_keyMap->find(key);
|
||||
if (it != m_keyMap->end()) {
|
||||
emit buttonStateChanged(it->second, INT16_MAX);
|
||||
}
|
||||
}
|
||||
|
@ -169,10 +312,28 @@ void GamepadHandler::keyPressed(Qt::Key key)
|
|||
|
||||
void GamepadHandler::keyReleased(Qt::Key key)
|
||||
{
|
||||
if (!m_controller) {
|
||||
auto it = KeyMap::instance.find(key);
|
||||
if (it != KeyMap::instance.end()) {
|
||||
if (!m_controller && m_keyMap) {
|
||||
auto it = m_keyMap->find(key);
|
||||
if (it != m_keyMap->end()) {
|
||||
emit buttonStateChanged(it->second, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int GamepadHandler::button(SDL_GameControllerButton sdl_btn)
|
||||
{
|
||||
int b;
|
||||
m_mapMutex.lock();
|
||||
b = m_buttonMap[sdl_btn];
|
||||
m_mapMutex.unlock();
|
||||
return b;
|
||||
}
|
||||
|
||||
int GamepadHandler::axis(SDL_GameControllerAxis sdl_axis)
|
||||
{
|
||||
int b;
|
||||
m_mapMutex.lock();
|
||||
b = m_axisMap[sdl_axis];
|
||||
m_mapMutex.unlock();
|
||||
return b;
|
||||
}
|
|
@ -1,10 +1,13 @@
|
|||
#ifndef GAMEPAD_HANDLER_H
|
||||
#define GAMEPAD_HANDLER_H
|
||||
|
||||
#include <QMap>
|
||||
#include <QMutex>
|
||||
#include <QObject>
|
||||
#include <SDL2/SDL.h>
|
||||
|
||||
#include "keymap.h"
|
||||
|
||||
class GamepadHandler : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
@ -15,11 +18,26 @@ public:
|
|||
|
||||
void setController(int index);
|
||||
|
||||
void setButton(SDL_GameControllerButton sdl_btn, int vanilla_btn);
|
||||
void setAxis(SDL_GameControllerAxis sdl_axis, int vanilla_axis);
|
||||
void clear();
|
||||
void save();
|
||||
|
||||
int button(SDL_GameControllerButton sdl_btn);
|
||||
int axis(SDL_GameControllerAxis sdl_axis);
|
||||
|
||||
void setKeyMap(KeyMap *keyMap);
|
||||
|
||||
void signalNextButtonOrAxis(bool e);
|
||||
|
||||
signals:
|
||||
void gamepadsChanged();
|
||||
|
||||
void buttonStateChanged(int button, int32_t value);
|
||||
|
||||
void buttonPressed(SDL_GameControllerButton button);
|
||||
void axisMoved(SDL_GameControllerAxis axis);
|
||||
|
||||
public slots:
|
||||
void run();
|
||||
|
||||
|
@ -29,14 +47,24 @@ public slots:
|
|||
void keyReleased(Qt::Key key);
|
||||
|
||||
private:
|
||||
void saveCustomProfile();
|
||||
static QString getConfigFilename(SDL_JoystickGUID guid);
|
||||
|
||||
QMutex m_mutex;
|
||||
|
||||
bool m_closed;
|
||||
int m_nextGamepad;
|
||||
bool m_vibrate;
|
||||
bool m_signalNext;
|
||||
|
||||
SDL_GameController *m_controller;
|
||||
|
||||
QMutex m_mapMutex;
|
||||
int m_buttonMap[SDL_CONTROLLER_BUTTON_MAX];
|
||||
int m_axisMap[SDL_CONTROLLER_AXIS_MAX];
|
||||
|
||||
KeyMap *m_keyMap;
|
||||
|
||||
};
|
||||
|
||||
#endif // GAMEPAD_HANDLER_H
|
|
@ -7,45 +7,107 @@
|
|||
|
||||
#include <vanilla.h>
|
||||
|
||||
#include "keymap.h"
|
||||
|
||||
InputConfigDialog::InputConfigDialog(QWidget *parent) : QDialog(parent)
|
||||
{
|
||||
}
|
||||
|
||||
InputConfigDialog::InputConfigDialog(KeyMap *keyMap, QWidget *parent) : InputConfigDialog(parent)
|
||||
{
|
||||
m_keyMap = keyMap;
|
||||
m_gamepadHandler = nullptr;
|
||||
|
||||
createLayout<InputConfigKeyButton>();
|
||||
|
||||
for (auto it = m_keyMap->cbegin(); it != m_keyMap->cend(); it++) {
|
||||
InputConfigKeyButton *btn = static_cast<InputConfigKeyButton *>(m_buttons[it->second]);
|
||||
if (btn) {
|
||||
btn->setKey(it->first);
|
||||
}
|
||||
}
|
||||
|
||||
connectSoloSignals();
|
||||
}
|
||||
|
||||
InputConfigDialog::InputConfigDialog(GamepadHandler *gamepadHandler, QWidget *parent) : InputConfigDialog(parent)
|
||||
{
|
||||
m_keyMap = nullptr;
|
||||
m_gamepadHandler = gamepadHandler;
|
||||
|
||||
m_gamepadHandler->signalNextButtonOrAxis(true);
|
||||
|
||||
connect(m_gamepadHandler, &GamepadHandler::axisMoved, this, &InputConfigDialog::setControllerAxis);
|
||||
connect(m_gamepadHandler, &GamepadHandler::buttonPressed, this, &InputConfigDialog::setControllerButton);
|
||||
|
||||
createLayout<InputConfigControllerButton>();
|
||||
|
||||
for (int i = 0; i < SDL_CONTROLLER_BUTTON_MAX; i++) {
|
||||
SDL_GameControllerButton b = static_cast<SDL_GameControllerButton>(i);
|
||||
int id = m_gamepadHandler->button(b);
|
||||
if (id != -1) {
|
||||
if (InputConfigControllerButton *btn = static_cast<InputConfigControllerButton *>(m_buttons[id])) {
|
||||
btn->setButton(b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < SDL_CONTROLLER_AXIS_MAX; i++) {
|
||||
SDL_GameControllerAxis a = static_cast<SDL_GameControllerAxis>(i);
|
||||
int id = m_gamepadHandler->axis(a);
|
||||
if (id != -1) {
|
||||
if (InputConfigControllerButton *btn = static_cast<InputConfigControllerButton *>(m_buttons[id])) {
|
||||
btn->setAxis(a);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
connectSoloSignals();
|
||||
}
|
||||
|
||||
InputConfigDialog::~InputConfigDialog()
|
||||
{
|
||||
if (m_gamepadHandler) {
|
||||
m_gamepadHandler->signalNextButtonOrAxis(false);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void InputConfigDialog::createLayout()
|
||||
{
|
||||
QGridLayout *layout = new QGridLayout(this);
|
||||
|
||||
layout->addWidget(createButton(tr("L"), VANILLA_BTN_L), 2, 1);
|
||||
layout->addWidget(createButton(tr("ZL"), VANILLA_BTN_ZL), 3, 1);
|
||||
layout->addWidget(createButton<T>(tr("L"), VANILLA_BTN_L), 2, 1);
|
||||
layout->addWidget(createButton<T>(tr("ZL"), VANILLA_BTN_ZL), 3, 1);
|
||||
|
||||
layout->addWidget(createButton(tr("R"), VANILLA_BTN_R), 2, 3);
|
||||
layout->addWidget(createButton(tr("ZR"), VANILLA_BTN_ZR), 3, 3);
|
||||
layout->addWidget(createButton<T>(tr("R"), VANILLA_BTN_R), 2, 3);
|
||||
layout->addWidget(createButton<T>(tr("ZR"), VANILLA_BTN_ZR), 3, 3);
|
||||
|
||||
layout->addWidget(createButton(tr("Left Stick Up"), VANILLA_AXIS_L_UP), 4, 0);
|
||||
layout->addWidget(createButton(tr("Left Stick Down"), VANILLA_AXIS_L_DOWN), 5, 0);
|
||||
layout->addWidget(createButton(tr("Left Stick Left"), VANILLA_AXIS_L_LEFT), 6, 0);
|
||||
layout->addWidget(createButton(tr("Left Stick Right"), VANILLA_AXIS_L_RIGHT), 7, 0);
|
||||
layout->addWidget(createButton(tr("Left Stick Click"), VANILLA_BTN_L3), 8, 0);
|
||||
layout->addWidget(createButton<T>(tr("Left Stick Up"), VANILLA_AXIS_L_UP), 4, 0);
|
||||
layout->addWidget(createButton<T>(tr("Left Stick Down"), VANILLA_AXIS_L_DOWN), 5, 0);
|
||||
layout->addWidget(createButton<T>(tr("Left Stick Left"), VANILLA_AXIS_L_LEFT), 6, 0);
|
||||
layout->addWidget(createButton<T>(tr("Left Stick Right"), VANILLA_AXIS_L_RIGHT), 7, 0);
|
||||
layout->addWidget(createButton<T>(tr("Left Stick Click"), VANILLA_BTN_L3), 8, 0);
|
||||
|
||||
layout->addWidget(createButton(tr("D-Pad Up"), VANILLA_BTN_UP), 10, 0);
|
||||
layout->addWidget(createButton(tr("D-Pad Down"), VANILLA_BTN_DOWN), 11, 0);
|
||||
layout->addWidget(createButton(tr("D-Pad Left"), VANILLA_BTN_LEFT), 12, 0);
|
||||
layout->addWidget(createButton(tr("D-Pad Right"), VANILLA_BTN_RIGHT), 13, 0);
|
||||
layout->addWidget(createButton<T>(tr("D-Pad Up"), VANILLA_BTN_UP), 10, 0);
|
||||
layout->addWidget(createButton<T>(tr("D-Pad Down"), VANILLA_BTN_DOWN), 11, 0);
|
||||
layout->addWidget(createButton<T>(tr("D-Pad Left"), VANILLA_BTN_LEFT), 12, 0);
|
||||
layout->addWidget(createButton<T>(tr("D-Pad Right"), VANILLA_BTN_RIGHT), 13, 0);
|
||||
|
||||
layout->addWidget(createButton(tr("TV"), VANILLA_BTN_TV), 14, 1, 1, 1);
|
||||
layout->addWidget(createButton(tr("Home"), VANILLA_BTN_HOME), 14, 2);
|
||||
layout->addWidget(createButton<T>(tr("TV"), VANILLA_BTN_TV), 14, 1, 1, 1);
|
||||
layout->addWidget(createButton<T>(tr("Home"), VANILLA_BTN_HOME), 14, 2);
|
||||
|
||||
layout->addWidget(createButton(tr("Right Stick Up"), VANILLA_AXIS_R_UP), 2, 4);
|
||||
layout->addWidget(createButton(tr("Right Stick Down"), VANILLA_AXIS_R_DOWN), 3, 4);
|
||||
layout->addWidget(createButton(tr("Right Stick Left"), VANILLA_AXIS_R_LEFT), 4, 4);
|
||||
layout->addWidget(createButton(tr("Right Stick Right"), VANILLA_AXIS_R_RIGHT), 5, 4);
|
||||
layout->addWidget(createButton(tr("Right Stick Click"), VANILLA_BTN_R3), 6, 4);
|
||||
layout->addWidget(createButton<T>(tr("Right Stick Up"), VANILLA_AXIS_R_UP), 2, 4);
|
||||
layout->addWidget(createButton<T>(tr("Right Stick Down"), VANILLA_AXIS_R_DOWN), 3, 4);
|
||||
layout->addWidget(createButton<T>(tr("Right Stick Left"), VANILLA_AXIS_R_LEFT), 4, 4);
|
||||
layout->addWidget(createButton<T>(tr("Right Stick Right"), VANILLA_AXIS_R_RIGHT), 5, 4);
|
||||
layout->addWidget(createButton<T>(tr("Right Stick Click"), VANILLA_BTN_R3), 6, 4);
|
||||
|
||||
layout->addWidget(createButton(tr("A"), VANILLA_BTN_A), 8, 4);
|
||||
layout->addWidget(createButton(tr("B"), VANILLA_BTN_B), 9, 4);
|
||||
layout->addWidget(createButton(tr("X"), VANILLA_BTN_X), 10, 4);
|
||||
layout->addWidget(createButton(tr("Y"), VANILLA_BTN_Y), 11, 4);
|
||||
layout->addWidget(createButton<T>(tr("A"), VANILLA_BTN_A), 8, 4);
|
||||
layout->addWidget(createButton<T>(tr("B"), VANILLA_BTN_B), 9, 4);
|
||||
layout->addWidget(createButton<T>(tr("X"), VANILLA_BTN_X), 10, 4);
|
||||
layout->addWidget(createButton<T>(tr("Y"), VANILLA_BTN_Y), 11, 4);
|
||||
|
||||
layout->addWidget(createButton(tr("Start/Plus"), VANILLA_BTN_PLUS), 13, 4);
|
||||
layout->addWidget(createButton(tr("Select/Minus"), VANILLA_BTN_MINUS), 14, 4);
|
||||
layout->addWidget(createButton<T>(tr("Start/Plus"), VANILLA_BTN_PLUS), 13, 4);
|
||||
layout->addWidget(createButton<T>(tr("Select/Minus"), VANILLA_BTN_MINUS), 14, 4);
|
||||
|
||||
QLabel *imageLbl = new QLabel(this);
|
||||
QPixmap imgPix;
|
||||
|
@ -58,42 +120,49 @@ InputConfigDialog::InputConfigDialog(QWidget *parent) : QDialog(parent)
|
|||
connect(buttons, &QDialogButtonBox::accepted, this, &QDialog::accept);
|
||||
connect(buttons, &QDialogButtonBox::rejected, this, &QDialog::reject);
|
||||
layout->addWidget(buttons, 16, 0, 1, 5);
|
||||
|
||||
for (auto it = KeyMap::instance.cbegin(); it != KeyMap::instance.cend(); it++) {
|
||||
InputConfigButton *btn = m_buttons[it->second];
|
||||
if (btn) {
|
||||
btn->setKey(it->first);
|
||||
}
|
||||
}
|
||||
|
||||
setWindowTitle(tr("Keyboard Configuration"));
|
||||
setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
|
||||
}
|
||||
|
||||
InputConfigButton *InputConfigDialog::createButton(const QString &name, int vanillaBtn)
|
||||
template<typename T>
|
||||
InputConfigButtonBase *InputConfigDialog::createButton(const QString &name, int vanillaBtn)
|
||||
{
|
||||
InputConfigButton *i = new InputConfigButton(name, this);
|
||||
InputConfigButtonBase *i = new T(name, this);
|
||||
m_buttons[vanillaBtn] = i;
|
||||
return i;
|
||||
}
|
||||
|
||||
void InputConfigDialog::accept()
|
||||
{
|
||||
KeyMap::instance.clear();
|
||||
if (m_keyMap) {
|
||||
m_keyMap->clear();
|
||||
|
||||
for (auto it = m_buttons.cbegin(); it != m_buttons.cend(); it++) {
|
||||
Qt::Key key = it->second->key();
|
||||
if (key != Qt::Key_unknown) {
|
||||
KeyMap::instance[key] = it->first;
|
||||
for (auto it = m_buttons.cbegin(); it != m_buttons.cend(); it++) {
|
||||
InputConfigKeyButton *keyBtn = static_cast<InputConfigKeyButton *>(it->second);
|
||||
Qt::Key key = keyBtn->key();
|
||||
if (key != Qt::Key_unknown) {
|
||||
(*m_keyMap)[key] = it->first;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
KeyMap::instance.save(KeyMap::getConfigFilename());
|
||||
m_keyMap->save(KeyMap::getConfigFilename());
|
||||
} else if (m_gamepadHandler) {
|
||||
m_gamepadHandler->clear();
|
||||
|
||||
for (auto it = m_buttons.cbegin(); it != m_buttons.cend(); it++) {
|
||||
InputConfigControllerButton *cBtn = static_cast<InputConfigControllerButton *>(it->second);
|
||||
if (cBtn->button() != SDL_CONTROLLER_BUTTON_INVALID) {
|
||||
m_gamepadHandler->setButton(cBtn->button(), it->first);
|
||||
} else if (cBtn->axis() != SDL_CONTROLLER_AXIS_INVALID) {
|
||||
m_gamepadHandler->setAxis(cBtn->axis(), it->first);
|
||||
}
|
||||
}
|
||||
|
||||
m_gamepadHandler->save();
|
||||
}
|
||||
|
||||
QDialog::accept();
|
||||
}
|
||||
|
||||
InputConfigButton::InputConfigButton(const QString &name, QWidget *parent) : QWidget(parent)
|
||||
InputConfigButtonBase::InputConfigButtonBase(const QString &name, QWidget *parent) : QWidget(parent)
|
||||
{
|
||||
QHBoxLayout *layout = new QHBoxLayout(this);
|
||||
|
||||
|
@ -104,27 +173,32 @@ InputConfigButton::InputConfigButton(const QString &name, QWidget *parent) : QWi
|
|||
|
||||
m_button = new QPushButton(this);
|
||||
m_button->setCheckable(true);
|
||||
connect(m_button, &QPushButton::clicked, this, &InputConfigButton::buttonClicked);
|
||||
m_button->installEventFilter(this);
|
||||
connect(m_button, &QPushButton::clicked, this, &InputConfigButtonBase::buttonClicked);
|
||||
connect(m_button, &QPushButton::toggled, this, &InputConfigButtonBase::toggled);
|
||||
connect(m_button, &QPushButton::clicked, this, &InputConfigButtonBase::checked);
|
||||
layout->addWidget(m_button);
|
||||
|
||||
layout->addStretch();
|
||||
|
||||
m_timer = new QTimer(this);
|
||||
m_timer->setInterval(1000);
|
||||
connect(m_timer, &QTimer::timeout, this, &InputConfigButton::timerTimeout);
|
||||
connect(m_timer, &QTimer::timeout, this, &InputConfigButtonBase::timerTimeout);
|
||||
}
|
||||
|
||||
InputConfigKeyButton::InputConfigKeyButton(const QString &name, QWidget *parent) : InputConfigButtonBase(name, parent)
|
||||
{
|
||||
button()->installEventFilter(this);
|
||||
m_key = Qt::Key_unknown;
|
||||
buttonClicked(false);
|
||||
}
|
||||
|
||||
void InputConfigButton::setKey(Qt::Key key)
|
||||
void InputConfigKeyButton::setKey(Qt::Key key)
|
||||
{
|
||||
m_key = key;
|
||||
buttonClicked(false);
|
||||
}
|
||||
|
||||
void InputConfigButton::buttonClicked(bool e)
|
||||
void InputConfigButtonBase::buttonClicked(bool e)
|
||||
{
|
||||
if (e) {
|
||||
m_timerState = 6;
|
||||
|
@ -132,14 +206,25 @@ void InputConfigButton::buttonClicked(bool e)
|
|||
timerTimeout();
|
||||
} else {
|
||||
m_timer->stop();
|
||||
m_button->setText(m_key == Qt::Key_unknown ? tr("<none>") : QKeySequence(m_key).toString());
|
||||
m_button->setText(text());
|
||||
m_button->setChecked(false);
|
||||
}
|
||||
}
|
||||
|
||||
bool InputConfigButton::eventFilter(QObject *object, QEvent *event)
|
||||
void InputConfigButtonBase::setChecked(bool e)
|
||||
{
|
||||
if (object == m_button && m_button->isChecked() && event->type() == QEvent::KeyPress) {
|
||||
m_button->setChecked(e);
|
||||
buttonClicked(e);
|
||||
}
|
||||
|
||||
QString InputConfigKeyButton::text() const
|
||||
{
|
||||
return m_key == Qt::Key_unknown ? tr("<none>") : QKeySequence(m_key).toString();
|
||||
}
|
||||
|
||||
bool InputConfigKeyButton::eventFilter(QObject *object, QEvent *event)
|
||||
{
|
||||
if (object == button() && button()->isChecked() && event->type() == QEvent::KeyPress) {
|
||||
QKeyEvent *key = dynamic_cast<QKeyEvent *>(event);
|
||||
if (key->key() == Qt::Key_Escape) {
|
||||
// Don't set
|
||||
|
@ -155,7 +240,7 @@ bool InputConfigButton::eventFilter(QObject *object, QEvent *event)
|
|||
return false;
|
||||
}
|
||||
|
||||
void InputConfigButton::timerTimeout()
|
||||
void InputConfigButtonBase::timerTimeout()
|
||||
{
|
||||
m_timerState--;
|
||||
if (m_timerState == 0) {
|
||||
|
@ -163,4 +248,88 @@ void InputConfigButton::timerTimeout()
|
|||
} else {
|
||||
m_button->setText(tr("Waiting for input (%1)\n<Backspace> to clear").arg(m_timerState));
|
||||
}
|
||||
}
|
||||
|
||||
InputConfigControllerButton::InputConfigControllerButton(const QString &name, QWidget *parent) : InputConfigButtonBase(name, parent)
|
||||
{
|
||||
m_button = SDL_CONTROLLER_BUTTON_INVALID;
|
||||
m_axis = SDL_CONTROLLER_AXIS_INVALID;
|
||||
buttonClicked(false);
|
||||
}
|
||||
|
||||
QString InputConfigControllerButton::text() const
|
||||
{
|
||||
if (m_button != SDL_CONTROLLER_BUTTON_INVALID) {
|
||||
return SDL_GameControllerGetStringForButton(m_button);
|
||||
} else if (m_axis != SDL_CONTROLLER_AXIS_INVALID) {
|
||||
return SDL_GameControllerGetStringForAxis(m_axis);
|
||||
}
|
||||
return tr("<none>");
|
||||
}
|
||||
|
||||
void InputConfigControllerButton::setButton(SDL_GameControllerButton button)
|
||||
{
|
||||
m_button = button;
|
||||
m_axis = SDL_CONTROLLER_AXIS_INVALID;
|
||||
buttonClicked(false);
|
||||
}
|
||||
|
||||
void InputConfigControllerButton::setAxis(SDL_GameControllerAxis axis)
|
||||
{
|
||||
m_button = SDL_CONTROLLER_BUTTON_INVALID;
|
||||
m_axis = axis;
|
||||
buttonClicked(false);
|
||||
}
|
||||
|
||||
InputConfigButtonBase *InputConfigDialog::findCheckedButton()
|
||||
{
|
||||
for (auto it = m_buttons.cbegin(); it != m_buttons.cend(); it++) {
|
||||
InputConfigButtonBase *test = it->second;
|
||||
if (test && test->isChecked()) {
|
||||
return test;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void InputConfigDialog::setControllerAxis(SDL_GameControllerAxis axis)
|
||||
{
|
||||
if (InputConfigButtonBase *b = findCheckedButton()) {
|
||||
InputConfigControllerButton *c = static_cast<InputConfigControllerButton *>(b);
|
||||
c->setAxis(axis);
|
||||
}
|
||||
}
|
||||
|
||||
void InputConfigDialog::setControllerButton(SDL_GameControllerButton button)
|
||||
{
|
||||
if (InputConfigButtonBase *b = findCheckedButton()) {
|
||||
InputConfigControllerButton *c = static_cast<InputConfigControllerButton *>(b);
|
||||
c->setButton(button);
|
||||
}
|
||||
}
|
||||
|
||||
void InputConfigDialog::connectSoloSignals()
|
||||
{
|
||||
for (auto it = m_buttons.cbegin(); it != m_buttons.cend(); it++) {
|
||||
InputConfigButtonBase *btn = it->second;
|
||||
if (btn)
|
||||
connect(btn, &InputConfigButtonBase::checked, this, &InputConfigDialog::buttonChecked);
|
||||
}
|
||||
}
|
||||
|
||||
void InputConfigDialog::uncheckAllExcept(InputConfigButtonBase *except)
|
||||
{
|
||||
for (auto it = m_buttons.cbegin(); it != m_buttons.cend(); it++) {
|
||||
InputConfigButtonBase *b = it->second;
|
||||
if (b && b != except) {
|
||||
b->setChecked(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void InputConfigDialog::buttonChecked(bool e)
|
||||
{
|
||||
if (e) {
|
||||
uncheckAllExcept(static_cast<InputConfigButtonBase *>(sender()));
|
||||
}
|
||||
}
|
|
@ -1,18 +1,54 @@
|
|||
#ifndef INPUT_CONFIG_DIALOG_H
|
||||
#define INPUT_CONFIG_DIALOG_H
|
||||
|
||||
#include <SDL2/SDL.h>
|
||||
#include <QDialog>
|
||||
#include <QPushButton>
|
||||
#include <QTimer>
|
||||
|
||||
class InputConfigButton : public QWidget
|
||||
#include "gamepadhandler.h"
|
||||
#include "keymap.h"
|
||||
|
||||
class InputConfigButtonBase : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
InputConfigButton(const QString &name, QWidget *parent = nullptr);
|
||||
InputConfigButtonBase(const QString &name, QWidget *parent = nullptr);
|
||||
|
||||
bool isChecked() const { return m_button->isChecked(); }
|
||||
void setChecked(bool e);
|
||||
|
||||
private:
|
||||
QPushButton *m_button;
|
||||
QTimer *m_timer;
|
||||
int m_timerState;
|
||||
|
||||
protected:
|
||||
QPushButton *button() { return m_button; }
|
||||
virtual QString text() const = 0;
|
||||
|
||||
signals:
|
||||
void checked(bool e);
|
||||
void toggled(bool e);
|
||||
|
||||
protected slots:
|
||||
void buttonClicked(bool e);
|
||||
|
||||
private slots:
|
||||
void timerTimeout();
|
||||
|
||||
};
|
||||
|
||||
class InputConfigKeyButton : public InputConfigButtonBase
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
InputConfigKeyButton(const QString &name, QWidget *parent = nullptr);
|
||||
|
||||
Qt::Key key() const { return m_key; }
|
||||
|
||||
virtual QString text() const override;
|
||||
|
||||
public slots:
|
||||
void setKey(Qt::Key key);
|
||||
|
||||
|
@ -20,15 +56,28 @@ protected:
|
|||
virtual bool eventFilter(QObject *object, QEvent *event) override;
|
||||
|
||||
private:
|
||||
QPushButton *m_button;
|
||||
Qt::Key m_key;
|
||||
QTimer *m_timer;
|
||||
int m_timerState;
|
||||
|
||||
private slots:
|
||||
void buttonClicked(bool e);
|
||||
};
|
||||
|
||||
void timerTimeout();
|
||||
class InputConfigControllerButton : public InputConfigButtonBase
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
InputConfigControllerButton(const QString &name, QWidget *parent = nullptr);
|
||||
|
||||
SDL_GameControllerButton button() const { return m_button; }
|
||||
SDL_GameControllerAxis axis() const { return m_axis; }
|
||||
|
||||
virtual QString text() const override;
|
||||
|
||||
public slots:
|
||||
void setButton(SDL_GameControllerButton btn);
|
||||
void setAxis(SDL_GameControllerAxis axis);
|
||||
|
||||
private:
|
||||
SDL_GameControllerButton m_button;
|
||||
SDL_GameControllerAxis m_axis;
|
||||
|
||||
};
|
||||
|
||||
|
@ -36,15 +85,36 @@ class InputConfigDialog : public QDialog
|
|||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
InputConfigDialog(QWidget *parent = nullptr);
|
||||
InputConfigDialog(KeyMap *keyMap, QWidget *parent = nullptr);
|
||||
InputConfigDialog(GamepadHandler *gamepadHandler, QWidget *parent = nullptr);
|
||||
virtual ~InputConfigDialog() override;
|
||||
|
||||
public slots:
|
||||
virtual void accept() override;
|
||||
|
||||
private:
|
||||
InputConfigButton *createButton(const QString &name, int vanillaBtn);
|
||||
InputConfigDialog(QWidget *parent = nullptr);
|
||||
|
||||
std::map<int, InputConfigButton *> m_buttons;
|
||||
template<typename T>
|
||||
void createLayout();
|
||||
|
||||
template<typename T>
|
||||
InputConfigButtonBase *createButton(const QString &name, int vanillaBtn);
|
||||
|
||||
InputConfigButtonBase *findCheckedButton();
|
||||
|
||||
void connectSoloSignals();
|
||||
void uncheckAllExcept(InputConfigButtonBase *except);
|
||||
|
||||
std::map<int, InputConfigButtonBase *> m_buttons;
|
||||
|
||||
KeyMap *m_keyMap;
|
||||
GamepadHandler *m_gamepadHandler;
|
||||
|
||||
private slots:
|
||||
void setControllerAxis(SDL_GameControllerAxis axis);
|
||||
void setControllerButton(SDL_GameControllerButton button);
|
||||
void buttonChecked(bool e);
|
||||
};
|
||||
|
||||
#endif // INPUT_CONFIG_DIALOG_H
|
|
@ -6,8 +6,6 @@
|
|||
#include <QXmlStreamWriter>
|
||||
#include <vanilla.h>
|
||||
|
||||
KeyMap KeyMap::instance;
|
||||
|
||||
KeyMap::KeyMap()
|
||||
{
|
||||
KeyMap &ref = *this;
|
||||
|
@ -39,7 +37,7 @@ KeyMap::KeyMap()
|
|||
ref[Qt::Key_J] = VANILLA_BTN_ZR;
|
||||
}
|
||||
|
||||
int g_serializationVersion = 1;
|
||||
static int g_serializationVersion = 1;
|
||||
|
||||
bool KeyMap::load(const QString &filename)
|
||||
{
|
||||
|
|
|
@ -14,8 +14,6 @@ public:
|
|||
|
||||
static QString getConfigFilename();
|
||||
|
||||
static KeyMap instance;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
|
@ -27,7 +27,6 @@
|
|||
|
||||
#include "backendinitdialog.h"
|
||||
#include "inputconfigdialog.h"
|
||||
#include "keymap.h"
|
||||
#include "syncdialog.h"
|
||||
#include "udpaddressdialog.h"
|
||||
|
||||
|
@ -218,6 +217,7 @@ MainWindow::MainWindow(QWidget *parent) : QWidget(parent)
|
|||
startObjectOnThread(m_videoDecoder);
|
||||
|
||||
m_gamepadHandler = new GamepadHandler();
|
||||
m_gamepadHandler->setKeyMap(&m_keyMap);
|
||||
startObjectOnThread(m_gamepadHandler);
|
||||
QMetaObject::invokeMethod(m_gamepadHandler, &GamepadHandler::run, Qt::QueuedConnection);
|
||||
|
||||
|
@ -236,7 +236,7 @@ MainWindow::MainWindow(QWidget *parent) : QWidget(parent)
|
|||
populateMicrophones();
|
||||
populateControllers();
|
||||
|
||||
KeyMap::instance.load(KeyMap::getConfigFilename());
|
||||
m_keyMap.load(KeyMap::getConfigFilename());
|
||||
|
||||
setWindowTitle(tr("Vanilla"));
|
||||
}
|
||||
|
@ -422,7 +422,6 @@ void MainWindow::setConnectedState(bool on)
|
|||
|
||||
void MainWindow::setJoystick(int index)
|
||||
{
|
||||
m_controllerMappingButton->setEnabled(index == 0); // Currently we only allow configuring keyboard controls
|
||||
m_gamepadHandler->setController(index - 1);
|
||||
}
|
||||
|
||||
|
@ -453,7 +452,12 @@ void MainWindow::volumeChanged(int v)
|
|||
|
||||
void MainWindow::showInputConfigDialog()
|
||||
{
|
||||
InputConfigDialog *d = new InputConfigDialog(this);
|
||||
InputConfigDialog *d;
|
||||
if (m_controllerComboBox->currentData().toInt() == -1) {
|
||||
d = new InputConfigDialog(&m_keyMap, this);
|
||||
} else {
|
||||
d = new InputConfigDialog(m_gamepadHandler, this);
|
||||
}
|
||||
d->open();
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "audiohandler.h"
|
||||
#include "backend.h"
|
||||
#include "gamepadhandler.h"
|
||||
#include "keymap.h"
|
||||
#include "videodecoder.h"
|
||||
#include "viewer.h"
|
||||
|
||||
|
@ -58,6 +59,7 @@ private:
|
|||
VideoDecoder *m_videoDecoder;
|
||||
GamepadHandler *m_gamepadHandler;
|
||||
AudioHandler *m_audioHandler;
|
||||
KeyMap m_keyMap;
|
||||
|
||||
QMap<QObject *, QThread *> m_threadMap;
|
||||
|
||||
|
|
Loading…
Reference in a new issue