Qt: Begin revamping profiles
Vicki Pfau vi@endrift.com
Sun, 02 Jul 2017 22:05:03 -0700
8 files changed,
217 insertions(+),
345 deletions(-)
jump to
M
src/platform/qt/input/InputController.cpp
→
src/platform/qt/input/InputController.cpp
@@ -185,18 +185,11 @@ #endif
} void InputController::loadProfile(uint32_t type, const QString& profile) { - if (m_activeKeyInfo) { - bool loaded = mInputProfileLoad(&m_inputMap, type, m_config->input(), profile.toUtf8().constData()); - if (!loaded) { - const InputProfile* ip = InputProfile::findProfile(profile); - if (ip) { - ip->apply(this); - } - } + const InputProfile* ip = InputProfile::findProfile(profile); + if (ip) { + ip->apply(this); } recalibrateAxes(); - m_inputIndex.loadProfile(profile); - m_keyIndex.loadProfile(profile); emit profileLoaded(profile); }
M
src/platform/qt/input/InputIndex.cpp
→
src/platform/qt/input/InputIndex.cpp
@@ -6,7 +6,6 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "InputIndex.h" #include "ConfigController.h" -#include "InputProfile.h" using namespace QGBA;@@ -61,6 +60,9 @@ if (*iter == *item) {
newItem = iter; break; } + } + if (!newItem) { + continue; } newItem->setShortcut(item->shortcut()); newItem->setButton(item->button());@@ -121,29 +123,16 @@ void InputIndex::loadGamepadShortcuts(InputItem* item) {
if (item->name().isNull()) { return; } - QVariant button = m_config->getQtOption(item->name(), !m_profileName.isNull() ? BUTTON_PROFILE_SECTION + m_profileName : BUTTON_SECTION); - if (button.isNull() && m_profile) { - int buttonInt; - if (m_profile->lookupShortcutButton(item->name(), &buttonInt)) { - button = buttonInt; - } - } + QVariant button = m_config->getQtOption(item->name(), BUTTON_SECTION); if (!button.isNull()) { item->setButton(button.toInt()); } - QVariant axis = m_config->getQtOption(item->name(), !m_profileName.isNull() ? AXIS_PROFILE_SECTION + m_profileName : AXIS_SECTION); + QVariant axis = m_config->getQtOption(item->name(), AXIS_SECTION); int oldAxis = item->axis(); if (oldAxis >= 0) { item->setAxis(-1, GamepadAxisEvent::NEUTRAL); } - if (axis.isNull() && m_profile) { - int axisInt; - GamepadAxisEvent::Direction direction; - if (m_profile->lookupShortcutAxis(item->name(), &axisInt, &direction)) { - axis = QLatin1String(direction == GamepadAxisEvent::Direction::NEGATIVE ? "-" : "+") + QString::number(axisInt); - } - } if (!axis.isNull()) { QString axisDesc = axis.toString(); if (axisDesc.size() >= 2) {@@ -238,14 +227,6 @@ default:
break; } return modifiers; -} - -void InputIndex::loadProfile(const QString& profile) { - m_profileName = profile; - m_profile = InputProfile::findProfile(profile); - for (auto& item : m_items) { - loadShortcuts(item); - } } void InputIndex::saveConfig() {
M
src/platform/qt/input/InputIndex.h
→
src/platform/qt/input/InputIndex.h
@@ -17,7 +17,6 @@
namespace QGBA { class ConfigController; -class InputProfile; class InputIndex { private:@@ -25,10 +24,6 @@ constexpr static const char* const KEY_SECTION = "shortcutKey";
constexpr static const char* const BUTTON_SECTION = "shortcutButton"; constexpr static const char* const AXIS_SECTION = "shortcutAxis"; constexpr static const char* const HAT_SECTION = "shortcutHat"; - constexpr static const char* const KEY_PROFILE_SECTION = "shortcutProfileKey."; - constexpr static const char* const BUTTON_PROFILE_SECTION = "shortcutProfileButton."; - constexpr static const char* const AXIS_PROFILE_SECTION = "shortcutProfileAxis."; - constexpr static const char* const HAT_PROFILE_SECTION = "shortcutProfileHat."; public: void setConfigController(ConfigController* controller);@@ -60,8 +55,6 @@ static int toModifierShortcut(const QString& shortcut);
static bool isModifierKey(int key); static int toModifierKey(int key); - void loadProfile(const QString& profile); - void saveConfig(); private:@@ -79,8 +72,6 @@ QMap<int, InputItem*> m_buttons;
QMap<QPair<int, GamepadAxisEvent::Direction>, InputItem*> m_axes; ConfigController* m_config = nullptr; - QString m_profileName; - const InputProfile* m_profile = nullptr; }; }
M
src/platform/qt/input/InputProfile.cpp
→
src/platform/qt/input/InputProfile.cpp
@@ -7,262 +7,93 @@ #include "InputProfile.h"
#include "InputController.h" -#include <QRegExp> +#include <QSettings> using namespace QGBA; -const InputProfile InputProfile::s_defaultMaps[] = { - { - "XInput Controller #\\d+", // XInput (Windows) - { - /*keyA */ 11, - /*keyB */ 10, - /*keySelect */ 5, - /*keyStart */ 4, - /*keyRight */ 3, - /*keyLeft */ 2, - /*keyUp */ 0, - /*keyDown */ 1, - /*keyR */ 9, - /*keyL */ 8 - }, - { - /*loadState */ 12, - /*saveState */ 13, - /*holdFastForward */ -1, - /*holdRewind */ -1, - }, - { - /*loadState */ {GamepadAxisEvent::Direction::NEUTRAL, -1}, - /*saveState */ {GamepadAxisEvent::Direction::NEUTRAL, -1}, - /*holdFastForward */ {GamepadAxisEvent::Direction::POSITIVE, 5}, - /*holdRewind */ {GamepadAxisEvent::Direction::POSITIVE, 4}, - } - }, - { - "(Microsoft X-Box 360 pad|Xbox Gamepad \\(userspace driver\\))", // Linux - { - /*keyA */ 1, - /*keyB */ 0, - /*keySelect */ 6, - /*keyStart */ 7, - /*keyRight */ -1, - /*keyLeft */ -1, - /*keyUp */ -1, - /*keyDown */ -1, - /*keyR */ 5, - /*keyL */ 4 - }, - { - /*loadState */ 2, - /*saveState */ 3, - /*holdFastForward */ -1, - /*holdRewind */ -1, - }, - { - /*loadState */ {GamepadAxisEvent::Direction::NEUTRAL, -1}, - /*saveState */ {GamepadAxisEvent::Direction::NEUTRAL, -1}, - /*holdFastForward */ {GamepadAxisEvent::Direction::POSITIVE, 5}, - /*holdRewind */ {GamepadAxisEvent::Direction::POSITIVE, 2}, - } - }, - { - "Xbox 360 Wired Controller", // OS X - { - /*keyA */ 1, - /*keyB */ 0, - /*keySelect */ 9, - /*keyStart */ 8, - /*keyRight */ 14, - /*keyLeft */ 13, - /*keyUp */ 11, - /*keyDown */ 12, - /*keyR */ 5, - /*keyL */ 4 - }, - { - /*loadState */ 2, - /*saveState */ 3, - /*holdFastForward */ -1, - /*holdRewind */ -1, - }, - { - /*loadState */ {GamepadAxisEvent::Direction::NEUTRAL, -1}, - /*saveState */ {GamepadAxisEvent::Direction::NEUTRAL, -1}, - /*holdFastForward */ {GamepadAxisEvent::Direction::POSITIVE, 5}, - /*holdRewind */ {GamepadAxisEvent::Direction::POSITIVE, 2}, - } - }, - { - "(Sony Computer Entertainment )?Wireless Controller", // The DualShock 4 device ID is cut off on Windows - { - /*keyA */ 1, - /*keyB */ 2, - /*keySelect */ 8, - /*keyStart */ 9, - /*keyRight */ -1, - /*keyLeft */ -1, - /*keyUp */ -1, - /*keyDown */ -1, - /*keyR */ 5, - /*keyL */ 4 - }, - { - /*loadState */ 0, - /*saveState */ 3, - /*holdFastForward */ 7, - /*holdRewind */ 6, - }, - }, - { - "PLAYSTATION\\(R\\)3 Controller", // DualShock 3 (OS X) - { - /*keyA */ 13, - /*keyB */ 14, - /*keySelect */ 0, - /*keyStart */ 3, - /*keyRight */ 5, - /*keyLeft */ 7, - /*keyUp */ 4, - /*keyDown */ 6, - /*keyR */ 11, - /*keyL */ 10 - }, - { - /*loadState */ 15, - /*saveState */ 12, - /*holdFastForward */ 9, - /*holdRewind */ 8, - }, - }, - { - "Wiimote \\(..-..-..-..-..-..\\)", // WJoy (OS X) - { - /*keyA */ 15, - /*keyB */ 16, - /*keySelect */ 7, - /*keyStart */ 6, - /*keyRight */ 14, - /*keyLeft */ 13, - /*keyUp */ 11, - /*keyDown */ 12, - /*keyR */ 20, - /*keyL */ 19 - }, - { - /*loadState */ 18, - /*saveState */ 17, - /*holdFastForward */ 22, - /*holdRewind */ 21, - }, - }, -}; +QList<InputProfile> InputProfile::s_profiles; -constexpr InputProfile::InputProfile(const char* name, - const KeyList<int> keys, - const Shortcuts<int> shortcutButtons, - const Shortcuts<Axis> shortcutAxes, - const KeyList<AxisValue> axes, - const struct Coord& tiltAxis, - const struct Coord& gyroAxis, - float gyroSensitivity) +InputProfile::InputProfile(const QString& name) : m_profileName(name) - , m_keys { - keys.keyA, - keys.keyB, - keys.keySelect, - keys.keyStart, - keys.keyRight, - keys.keyLeft, - keys.keyUp, - keys.keyDown, - keys.keyR, - keys.keyL, +{ +} + +void InputProfile::loadDefaultProfiles() { + loadProfiles(":/input/default-profiles.ini"); +} + +void InputProfile::loadProfiles(const QString& path) { + QSettings profileIni(path, QSettings::IniFormat); + + for (const auto& group : profileIni.childGroups()) { } - , m_axes { - axes.keyA, - axes.keyB, - axes.keySelect, - axes.keyStart, - axes.keyRight, - axes.keyLeft, - axes.keyUp, - axes.keyDown, - axes.keyR, - axes.keyL, + profileIni.beginGroup(PROFILE_SECTION); + for (const auto& group : profileIni.childGroups()) { + loadProfile(profileIni, group); } - , m_shortcutButtons(shortcutButtons) - , m_shortcutAxes(shortcutAxes) - , m_tiltAxis(tiltAxis) - , m_gyroAxis(gyroAxis) - , m_gyroSensitivity(gyroSensitivity) -{ + profileIni.endGroup(); +} + +void InputProfile::loadProfile(QSettings& profileIni, const QString& name) { + profileIni.beginGroup(name); + s_profiles.append(name); + InputProfile& profile = s_profiles.last(); + for (const auto& group : profileIni.childGroups()) { + profileIni.beginGroup(group); + if (group == MATCH_SECTION) { + for (const auto& key : profileIni.childKeys()) { + profile.m_match.append(QRegExp(profileIni.value(key).toString())); + } + } + for (const auto& key : profileIni.childKeys()) { + InputItem* item = profile.m_inputIndex.itemAt(key); + if (!item) { + item = profile.m_inputIndex.addItem(QString(), key); + } + if (group == BUTTON_SECTION) { + item->setButton(profileIni.value(key).toInt()); + } + if (group == AXIS_SECTION) { + QString axisDescription = profileIni.value(key).toString(); + GamepadAxisEvent::Direction direction = GamepadAxisEvent::POSITIVE; + int axis = profileIni.value(key).toInt(); + if (axisDescription[0] == '-') { + direction = GamepadAxisEvent::NEGATIVE; + axis = -axis; + } + + item->setAxis(axis, direction); + } + if (group == KEY_SECTION) { + item->setShortcut(profileIni.value(key).toInt()); + } + } + profileIni.endGroup(); + } + profile.m_inputIndex.rebuild(); + profileIni.endGroup(); } const InputProfile* InputProfile::findProfile(const QString& name) { - for (size_t i = 0; i < sizeof(s_defaultMaps) / sizeof(*s_defaultMaps); ++i) { - QRegExp re(s_defaultMaps[i].m_profileName); - if (re.exactMatch(name)) { - return &s_defaultMaps[i]; + if (s_profiles.isEmpty()) { + loadDefaultProfiles(); + } + for (const InputProfile& profile : s_profiles) { + for (const auto& match : profile.m_match) { + if (match.exactMatch(name)) { + return &profile; + } } } return nullptr; } void InputProfile::apply(InputController* controller) const { - for (size_t i = 0; i < GBA_KEY_MAX; ++i) { -#ifdef BUILD_SDL - controller->bindKey(SDL_BINDING_BUTTON, m_keys[i], GBAInputInfo.keyId[i]); - controller->bindAxis(SDL_BINDING_BUTTON, m_axes[i].axis, m_axes[i].direction, GBAInputInfo.keyId[i]); -#endif - } + controller->rebuildIndex(&m_inputIndex); + controller->rebuildKeyIndex(&m_inputIndex); controller->registerTiltAxisX(m_tiltAxis.x); controller->registerTiltAxisY(m_tiltAxis.y); controller->registerGyroAxisX(m_gyroAxis.x); controller->registerGyroAxisY(m_gyroAxis.y); controller->setGyroSensitivity(m_gyroSensitivity); } - -bool InputProfile::lookupShortcutButton(const QString& shortcutName, int* button) const { - if (shortcutName == QLatin1String("loadState")) { - *button = m_shortcutButtons.loadState; - return true; - } - if (shortcutName == QLatin1String("saveState")) { - *button = m_shortcutButtons.saveState; - return true; - } - if (shortcutName == QLatin1String("holdFastForward")) { - *button = m_shortcutButtons.holdFastForward; - return true; - } - if (shortcutName == QLatin1String("holdRewind")) { - *button = m_shortcutButtons.holdRewind; - return true; - } - return false; -} - -bool InputProfile::lookupShortcutAxis(const QString& shortcutName, int* axis, GamepadAxisEvent::Direction* direction) const { - if (shortcutName == QLatin1String("loadState")) { - *axis = m_shortcutAxes.loadState.axis; - *direction = m_shortcutAxes.loadState.direction; - return true; - } - if (shortcutName == QLatin1String("saveState")) { - *axis = m_shortcutAxes.saveState.axis; - *direction = m_shortcutAxes.saveState.direction; - return true; - } - if (shortcutName == QLatin1String("holdFastForward")) { - *axis = m_shortcutAxes.holdFastForward.axis; - *direction = m_shortcutAxes.holdFastForward.direction; - return true; - } - if (shortcutName == QLatin1String("holdRewind")) { - *axis = m_shortcutAxes.holdRewind.axis; - *direction = m_shortcutAxes.holdRewind.direction; - return true; - } - return false; -}
M
src/platform/qt/input/InputProfile.h
→
src/platform/qt/input/InputProfile.h
@@ -7,91 +7,52 @@ #ifndef QGBA_INPUT_PROFILE
#define QGBA_INPUT_PROFILE #include "GamepadAxisEvent.h" +#include "InputIndex.h" #include <mgba/core/core.h> #include <mgba/gba/interface.h> +#include <QRegExp> + +class QSettings; + namespace QGBA { class InputController; class InputProfile { public: + constexpr static const char* const PROFILE_SECTION = "profiles"; + constexpr static const char* const MATCH_SECTION = "match"; + constexpr static const char* const KEY_SECTION = "keys"; + constexpr static const char* const BUTTON_SECTION = "buttons"; + constexpr static const char* const AXIS_SECTION = "axes"; + constexpr static const char* const HAT_SECTION = "hats"; + static const InputProfile* findProfile(const QString& name); + static void loadProfiles(const QString& path); void apply(InputController*) const; - bool lookupShortcutButton(const QString& shortcut, int* button) const; - bool lookupShortcutAxis(const QString& shortcut, int* axis, GamepadAxisEvent::Direction* direction) const; +private: + InputProfile(const QString&); -private: struct Coord { int x; int y; }; - struct AxisValue { - GamepadAxisEvent::Direction direction; - int axis; - }; + static void loadDefaultProfiles(); + static void loadProfile(QSettings&, const QString& name); - template <typename T> struct Shortcuts { - T loadState; - T saveState; - T holdFastForward; - T holdRewind; - }; + static QList<InputProfile> s_profiles; - struct Axis { - GamepadAxisEvent::Direction direction; - int axis; - }; + QString m_profileName; + QList<QRegExp> m_match; - template <typename T> struct KeyList { - T keyA; - T keyB; - T keySelect; - T keyStart; - T keyRight; - T keyLeft; - T keyUp; - T keyDown; - T keyR; - T keyL; - }; - - constexpr InputProfile(const char* name, - const KeyList<int> keys, - const Shortcuts<int> shortcutButtons = { -1, -1, -1, -1}, - const Shortcuts<Axis> shortcutAxes = { - {GamepadAxisEvent::Direction::NEUTRAL, -1}, - {GamepadAxisEvent::Direction::NEUTRAL, -1}, - {GamepadAxisEvent::Direction::NEUTRAL, -1}, - {GamepadAxisEvent::Direction::NEUTRAL, -1}}, - const KeyList<AxisValue> axes = { - { GamepadAxisEvent::Direction::NEUTRAL, -1 }, - { GamepadAxisEvent::Direction::NEUTRAL, -1 }, - { GamepadAxisEvent::Direction::NEUTRAL, -1 }, - { GamepadAxisEvent::Direction::NEUTRAL, -1 }, - { GamepadAxisEvent::Direction::POSITIVE, 0 }, - { GamepadAxisEvent::Direction::NEGATIVE, 0 }, - { GamepadAxisEvent::Direction::NEGATIVE, 1 }, - { GamepadAxisEvent::Direction::POSITIVE, 1 }, - { GamepadAxisEvent::Direction::NEUTRAL, -1 }, - { GamepadAxisEvent::Direction::NEUTRAL, -1 }}, - const struct Coord& tiltAxis = { 2, 3 }, - const struct Coord& gyroAxis = { 0, 1 }, - float gyroSensitivity = 2e+09f); - - static const InputProfile s_defaultMaps[]; - - const char* m_profileName; - const int m_keys[GBA_KEY_MAX]; - const AxisValue m_axes[GBA_KEY_MAX]; - const Shortcuts<int> m_shortcutButtons; - const Shortcuts<Axis> m_shortcutAxes; - Coord m_tiltAxis; - Coord m_gyroAxis; - float m_gyroSensitivity; + Coord m_tiltAxis = { 2, 3 }; + Coord m_gyroAxis = { 0, 1 }; + float m_gyroSensitivity = 2e+09f; + InputIndex m_inputIndex; }; }
A
src/platform/qt/input/default-profiles.ini
@@ -0,0 +1,114 @@
+[profiles/XInput (Windows)/match] +0=XInput Controller #\\d+ + +[profiles/XInput (Windows)/buttons] +keyA=11 +keyB=10 +keySelect=5 +keyStart=4 +keyRight=3 +keyLeft=2 +keyUp=0 +keyDown=1 +keyR=9 +keyL=8 +loadState=12 +saveState=13 + +[profiles/XInput (Windows)/axes] +holdFastForward=+5 +holdRewind=+4 + +[profiles/XInput (Linux)/match] +0=Microsoft X-Box 360 pad +1=Xbox Gamepad \\(userspace driver\\) + +[profiles/XInput (Linux)/buttons] +keyA=1 +keyB=0 +keySelect=6 +keyStart=7 +keyR=5 +keyL=4 +loadState=2 +saveState=3 + +[profiles/XInput (Linux)/axes] +holdFastForward=+5 +holdRewind=+2 + +[profiles/XInput (macOS)/match] +0=Xbox 360 Wired Controller + +[profiles/XInput (macOS)/buttons] +keyA=1 +keyB=0 +keySelect=9 +keyStart=8 +keyRight=14 +keyLeft=13 +keyUp=11 +keyDown=12 +keyR=5 +keyL=4 +loadState=2 +saveState=3 + +[profiles/XInput (macOS)/axes] +holdFastForward=+5 +holdRewind=+2 + + +[profiles/DualShock 4/match] +0=Sony Computer Entertainment Wireless Controller +1=Wireless Controller + +[profiles/DualShock 4/buttons] +keyA=1 +keyB=2 +keySelect=8 +keyStart=9 +keyR=5 +keyL=4 +loadState=0 +saveState=3 +holdFastForward=7 +holdRewind=6 + +[profiles/DualShock 3/match] +0=PLAYSTATION\\(R\\)3 Controller + +[profiles/DualShock 3/buttons] +keyA=13 +keyB=14 +keySelect=0 +keyStart=3 +keyRight=5 +keyLeft=7 +keyUp=4 +keyDown=6 +keyR=11 +keyL=10 +loadState=15 +saveState=12 +holdFastForward=9 +holdRewind=8 + +[profiles/Wii Remote/match] +0=Wiimote \\(..-..-..-..-..-..\\) + +[profiles/Wii Remote/buttons] +keyA=15 +keyB=16 +keySelect=7 +keyStart=6 +keyRight=14 +keyLeft=13 +keyUp=11 +keyDown=12 +keyR=20 +keyL=19 +loadState=18 +saveState=17 +holdFastForward=22 +holdRewind=21
M
src/platform/qt/resources.qrc
→
src/platform/qt/resources.qrc
@@ -3,5 +3,6 @@ <qresource>
<file>../../../res/mgba-1024.png</file> <file>../../../res/keymap.qpic</file> <file>../../../res/patrons.txt</file> + <file>input/default-profiles.ini</file> </qresource> </RCC>
M
src/platform/sdl/sdl-events.c
→
src/platform/sdl/sdl-events.c
@@ -350,7 +350,7 @@ continue;
} if (events->preferredJoysticks[i] && strcmp(events->preferredJoysticks[i], joystickName) == 0) { events->players[i]->joystick = joystick; - if (config) { + if (config && events->players[i]->bindings) { mInputProfileLoad(events->players[i]->bindings, SDL_BINDING_BUTTON, config, joystickName); } return;@@ -361,7 +361,7 @@ if (events->players[i]->joystick) {
continue; } events->players[i]->joystick = joystick; - if (config) { + if (config && events->players[i]->bindings) { mInputProfileLoad(events->players[i]->bindings, SDL_BINDING_BUTTON, config, joystickName); } break;