mirror of https://github.com/mgba-emu/mgba.git
Qt: Begin revamping profiles
This commit is contained in:
parent
53690f7a83
commit
ac2e7b6447
|
@ -185,18 +185,11 @@ void InputController::loadConfiguration(uint32_t type) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void InputController::loadProfile(uint32_t type, const QString& profile) {
|
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);
|
const InputProfile* ip = InputProfile::findProfile(profile);
|
||||||
if (ip) {
|
if (ip) {
|
||||||
ip->apply(this);
|
ip->apply(this);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
recalibrateAxes();
|
recalibrateAxes();
|
||||||
m_inputIndex.loadProfile(profile);
|
|
||||||
m_keyIndex.loadProfile(profile);
|
|
||||||
emit profileLoaded(profile);
|
emit profileLoaded(profile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
#include "InputIndex.h"
|
#include "InputIndex.h"
|
||||||
|
|
||||||
#include "ConfigController.h"
|
#include "ConfigController.h"
|
||||||
#include "InputProfile.h"
|
|
||||||
|
|
||||||
using namespace QGBA;
|
using namespace QGBA;
|
||||||
|
|
||||||
|
@ -62,6 +61,9 @@ void InputIndex::rebuild(const InputIndex* root) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!newItem) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
newItem->setShortcut(item->shortcut());
|
newItem->setShortcut(item->shortcut());
|
||||||
newItem->setButton(item->button());
|
newItem->setButton(item->button());
|
||||||
newItem->setAxis(item->axis(), item->direction());
|
newItem->setAxis(item->axis(), item->direction());
|
||||||
|
@ -121,29 +123,16 @@ void InputIndex::loadGamepadShortcuts(InputItem* item) {
|
||||||
if (item->name().isNull()) {
|
if (item->name().isNull()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
QVariant button = m_config->getQtOption(item->name(), !m_profileName.isNull() ? BUTTON_PROFILE_SECTION + m_profileName : BUTTON_SECTION);
|
QVariant button = m_config->getQtOption(item->name(), BUTTON_SECTION);
|
||||||
if (button.isNull() && m_profile) {
|
|
||||||
int buttonInt;
|
|
||||||
if (m_profile->lookupShortcutButton(item->name(), &buttonInt)) {
|
|
||||||
button = buttonInt;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!button.isNull()) {
|
if (!button.isNull()) {
|
||||||
item->setButton(button.toInt());
|
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();
|
int oldAxis = item->axis();
|
||||||
if (oldAxis >= 0) {
|
if (oldAxis >= 0) {
|
||||||
item->setAxis(-1, GamepadAxisEvent::NEUTRAL);
|
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()) {
|
if (!axis.isNull()) {
|
||||||
QString axisDesc = axis.toString();
|
QString axisDesc = axis.toString();
|
||||||
if (axisDesc.size() >= 2) {
|
if (axisDesc.size() >= 2) {
|
||||||
|
@ -240,14 +229,6 @@ int InputIndex::toModifierKey(int key) {
|
||||||
return modifiers;
|
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() {
|
void InputIndex::saveConfig() {
|
||||||
for (auto& item : m_items) {
|
for (auto& item : m_items) {
|
||||||
m_config->setQtOption(item->name(), QKeySequence(item->shortcut()).toString(), KEY_SECTION);
|
m_config->setQtOption(item->name(), QKeySequence(item->shortcut()).toString(), KEY_SECTION);
|
||||||
|
|
|
@ -17,7 +17,6 @@ class QMenu;
|
||||||
namespace QGBA {
|
namespace QGBA {
|
||||||
|
|
||||||
class ConfigController;
|
class ConfigController;
|
||||||
class InputProfile;
|
|
||||||
|
|
||||||
class InputIndex {
|
class InputIndex {
|
||||||
private:
|
private:
|
||||||
|
@ -25,10 +24,6 @@ private:
|
||||||
constexpr static const char* const BUTTON_SECTION = "shortcutButton";
|
constexpr static const char* const BUTTON_SECTION = "shortcutButton";
|
||||||
constexpr static const char* const AXIS_SECTION = "shortcutAxis";
|
constexpr static const char* const AXIS_SECTION = "shortcutAxis";
|
||||||
constexpr static const char* const HAT_SECTION = "shortcutHat";
|
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:
|
public:
|
||||||
void setConfigController(ConfigController* controller);
|
void setConfigController(ConfigController* controller);
|
||||||
|
@ -60,8 +55,6 @@ public:
|
||||||
static bool isModifierKey(int key);
|
static bool isModifierKey(int key);
|
||||||
static int toModifierKey(int key);
|
static int toModifierKey(int key);
|
||||||
|
|
||||||
void loadProfile(const QString& profile);
|
|
||||||
|
|
||||||
void saveConfig();
|
void saveConfig();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -79,8 +72,6 @@ private:
|
||||||
QMap<QPair<int, GamepadAxisEvent::Direction>, InputItem*> m_axes;
|
QMap<QPair<int, GamepadAxisEvent::Direction>, InputItem*> m_axes;
|
||||||
|
|
||||||
ConfigController* m_config = nullptr;
|
ConfigController* m_config = nullptr;
|
||||||
QString m_profileName;
|
|
||||||
const InputProfile* m_profile = nullptr;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,262 +7,93 @@
|
||||||
|
|
||||||
#include "InputController.h"
|
#include "InputController.h"
|
||||||
|
|
||||||
#include <QRegExp>
|
#include <QSettings>
|
||||||
|
|
||||||
using namespace QGBA;
|
using namespace QGBA;
|
||||||
|
|
||||||
const InputProfile InputProfile::s_defaultMaps[] = {
|
QList<InputProfile> InputProfile::s_profiles;
|
||||||
{
|
|
||||||
"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,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
constexpr InputProfile::InputProfile(const char* name,
|
InputProfile::InputProfile(const QString& 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)
|
|
||||||
: m_profileName(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,
|
|
||||||
}
|
|
||||||
, m_axes {
|
|
||||||
axes.keyA,
|
|
||||||
axes.keyB,
|
|
||||||
axes.keySelect,
|
|
||||||
axes.keyStart,
|
|
||||||
axes.keyRight,
|
|
||||||
axes.keyLeft,
|
|
||||||
axes.keyUp,
|
|
||||||
axes.keyDown,
|
|
||||||
axes.keyR,
|
|
||||||
axes.keyL,
|
|
||||||
}
|
|
||||||
, m_shortcutButtons(shortcutButtons)
|
|
||||||
, m_shortcutAxes(shortcutAxes)
|
|
||||||
, m_tiltAxis(tiltAxis)
|
|
||||||
, m_gyroAxis(gyroAxis)
|
|
||||||
, m_gyroSensitivity(gyroSensitivity)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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()) {
|
||||||
|
}
|
||||||
|
profileIni.beginGroup(PROFILE_SECTION);
|
||||||
|
for (const auto& group : profileIni.childGroups()) {
|
||||||
|
loadProfile(profileIni, group);
|
||||||
|
}
|
||||||
|
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) {
|
const InputProfile* InputProfile::findProfile(const QString& name) {
|
||||||
for (size_t i = 0; i < sizeof(s_defaultMaps) / sizeof(*s_defaultMaps); ++i) {
|
if (s_profiles.isEmpty()) {
|
||||||
QRegExp re(s_defaultMaps[i].m_profileName);
|
loadDefaultProfiles();
|
||||||
if (re.exactMatch(name)) {
|
}
|
||||||
return &s_defaultMaps[i];
|
for (const InputProfile& profile : s_profiles) {
|
||||||
|
for (const auto& match : profile.m_match) {
|
||||||
|
if (match.exactMatch(name)) {
|
||||||
|
return &profile;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void InputProfile::apply(InputController* controller) const {
|
void InputProfile::apply(InputController* controller) const {
|
||||||
for (size_t i = 0; i < GBA_KEY_MAX; ++i) {
|
controller->rebuildIndex(&m_inputIndex);
|
||||||
#ifdef BUILD_SDL
|
controller->rebuildKeyIndex(&m_inputIndex);
|
||||||
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->registerTiltAxisX(m_tiltAxis.x);
|
controller->registerTiltAxisX(m_tiltAxis.x);
|
||||||
controller->registerTiltAxisY(m_tiltAxis.y);
|
controller->registerTiltAxisY(m_tiltAxis.y);
|
||||||
controller->registerGyroAxisX(m_gyroAxis.x);
|
controller->registerGyroAxisX(m_gyroAxis.x);
|
||||||
controller->registerGyroAxisY(m_gyroAxis.y);
|
controller->registerGyroAxisY(m_gyroAxis.y);
|
||||||
controller->setGyroSensitivity(m_gyroSensitivity);
|
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;
|
|
||||||
}
|
|
||||||
|
|
|
@ -7,91 +7,52 @@
|
||||||
#define QGBA_INPUT_PROFILE
|
#define QGBA_INPUT_PROFILE
|
||||||
|
|
||||||
#include "GamepadAxisEvent.h"
|
#include "GamepadAxisEvent.h"
|
||||||
|
#include "InputIndex.h"
|
||||||
|
|
||||||
#include <mgba/core/core.h>
|
#include <mgba/core/core.h>
|
||||||
#include <mgba/gba/interface.h>
|
#include <mgba/gba/interface.h>
|
||||||
|
|
||||||
|
#include <QRegExp>
|
||||||
|
|
||||||
|
class QSettings;
|
||||||
|
|
||||||
namespace QGBA {
|
namespace QGBA {
|
||||||
|
|
||||||
class InputController;
|
class InputController;
|
||||||
|
|
||||||
class InputProfile {
|
class InputProfile {
|
||||||
public:
|
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 const InputProfile* findProfile(const QString& name);
|
||||||
|
static void loadProfiles(const QString& path);
|
||||||
|
|
||||||
void apply(InputController*) const;
|
void apply(InputController*) const;
|
||||||
bool lookupShortcutButton(const QString& shortcut, int* button) const;
|
|
||||||
bool lookupShortcutAxis(const QString& shortcut, int* axis, GamepadAxisEvent::Direction* direction) const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
InputProfile(const QString&);
|
||||||
|
|
||||||
struct Coord {
|
struct Coord {
|
||||||
int x;
|
int x;
|
||||||
int y;
|
int y;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AxisValue {
|
static void loadDefaultProfiles();
|
||||||
GamepadAxisEvent::Direction direction;
|
static void loadProfile(QSettings&, const QString& name);
|
||||||
int axis;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T> struct Shortcuts {
|
static QList<InputProfile> s_profiles;
|
||||||
T loadState;
|
|
||||||
T saveState;
|
|
||||||
T holdFastForward;
|
|
||||||
T holdRewind;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Axis {
|
QString m_profileName;
|
||||||
GamepadAxisEvent::Direction direction;
|
QList<QRegExp> m_match;
|
||||||
int axis;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T> struct KeyList {
|
Coord m_tiltAxis = { 2, 3 };
|
||||||
T keyA;
|
Coord m_gyroAxis = { 0, 1 };
|
||||||
T keyB;
|
float m_gyroSensitivity = 2e+09f;
|
||||||
T keySelect;
|
InputIndex m_inputIndex;
|
||||||
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;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
|
@ -3,5 +3,6 @@
|
||||||
<file>../../../res/mgba-1024.png</file>
|
<file>../../../res/mgba-1024.png</file>
|
||||||
<file>../../../res/keymap.qpic</file>
|
<file>../../../res/keymap.qpic</file>
|
||||||
<file>../../../res/patrons.txt</file>
|
<file>../../../res/patrons.txt</file>
|
||||||
|
<file>input/default-profiles.ini</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
|
|
@ -350,7 +350,7 @@ void mSDLUpdateJoysticks(struct mSDLEvents* events, const struct Configuration*
|
||||||
}
|
}
|
||||||
if (events->preferredJoysticks[i] && strcmp(events->preferredJoysticks[i], joystickName) == 0) {
|
if (events->preferredJoysticks[i] && strcmp(events->preferredJoysticks[i], joystickName) == 0) {
|
||||||
events->players[i]->joystick = joystick;
|
events->players[i]->joystick = joystick;
|
||||||
if (config) {
|
if (config && events->players[i]->bindings) {
|
||||||
mInputProfileLoad(events->players[i]->bindings, SDL_BINDING_BUTTON, config, joystickName);
|
mInputProfileLoad(events->players[i]->bindings, SDL_BINDING_BUTTON, config, joystickName);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
@ -361,7 +361,7 @@ void mSDLUpdateJoysticks(struct mSDLEvents* events, const struct Configuration*
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
events->players[i]->joystick = joystick;
|
events->players[i]->joystick = joystick;
|
||||||
if (config) {
|
if (config && events->players[i]->bindings) {
|
||||||
mInputProfileLoad(events->players[i]->bindings, SDL_BINDING_BUTTON, config, joystickName);
|
mInputProfileLoad(events->players[i]->bindings, SDL_BINDING_BUTTON, config, joystickName);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in New Issue