mirror of https://github.com/mgba-emu/mgba.git
Qt: Restore most functionality in input revamp
This commit is contained in:
parent
b8dd7a7632
commit
f975088c4d
|
@ -54,9 +54,6 @@ InputController::InputController(InputModel* model, int playerId, QWidget* topLe
|
|||
m_gamepadTimer.setInterval(50);
|
||||
m_gamepadTimer.start();
|
||||
|
||||
m_autofireMenu = m_inputModel->root()->addItem(tr("Autofire"), "autofire");
|
||||
m_inputMenu = m_inputModel->root()->addItem(tr("Bindings"), "bindings");
|
||||
|
||||
mInputMapInit(&m_inputMap, &GBAInputInfo);
|
||||
|
||||
#ifdef BUILD_SDL
|
||||
|
@ -632,20 +629,6 @@ void InputController::releaseFocus(QWidget* focus) {
|
|||
}
|
||||
}
|
||||
|
||||
void InputController::setupCallback(GameController* controller) {
|
||||
[this, controller](InputItem* item, int key, bool down) {
|
||||
if (item->parent() == m_autofireMenu) {
|
||||
controller->setAutofire(key, down);
|
||||
} else {
|
||||
if (down) {
|
||||
controller->keyPressed(key);
|
||||
} else {
|
||||
controller->keyReleased(key);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
void InputController::doBindKey(const QModelIndex& index, int key) {
|
||||
int coreKey = m_inputModel->itemAt(index)->key();
|
||||
if (coreKey < 0) {
|
||||
|
@ -699,26 +682,48 @@ bool InputController::eventFilter(QObject*, QEvent* event) {
|
|||
return true;
|
||||
}
|
||||
|
||||
// TODO
|
||||
InputItem* item = m_inputModel->itemForShortcut(key);
|
||||
if (item) {
|
||||
item->trigger(event->type() == QEvent::KeyPress);
|
||||
event->accept();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (event->type() == GamepadButtonEvent::Down() || event->type() == GamepadButtonEvent::Up()) {
|
||||
GamepadButtonEvent* gbe = static_cast<GamepadButtonEvent*>(event);
|
||||
// TODO
|
||||
InputItem* item = m_inputModel->itemForButton(gbe->value());
|
||||
if (item) {
|
||||
item->trigger(event->type() == GamepadButtonEvent::Down());
|
||||
event->accept();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (event->type() == GamepadAxisEvent::Type()) {
|
||||
GamepadAxisEvent* gae = static_cast<GamepadAxisEvent*>(event);
|
||||
// TODO
|
||||
InputItem* item = m_inputModel->itemForAxis(gae->axis(), gae->direction());
|
||||
if (item) {
|
||||
item->trigger(event->type() == gae->isNew());
|
||||
event->accept();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
InputItem* InputController::itemForKey(int key) {
|
||||
if (key < 0 || key >= m_inputMap.info->nKeys) {
|
||||
return nullptr;
|
||||
}
|
||||
return m_inputModel->itemAt(QString("key%0").arg(m_inputMap.info->keyId[key]));
|
||||
}
|
||||
|
||||
void InputController::restoreModel() {
|
||||
bool signalsBlocked = m_inputModel->blockSignals(true);
|
||||
int nKeys = m_inputMap.info->nKeys;
|
||||
/*for (int i = 0; i < nKeys; ++i) {
|
||||
InputItem* item = m_inputModel->itemForKey(i);
|
||||
for (int i = 0; i < nKeys; ++i) {
|
||||
InputItem* item = itemForKey(i);
|
||||
if (item) {
|
||||
int key = mInputQueryBinding(&m_inputMap, KEYBOARD, i);
|
||||
if (key >= 0) {
|
||||
|
@ -737,22 +742,31 @@ void InputController::restoreModel() {
|
|||
}
|
||||
}
|
||||
#ifdef BUILD_SDL
|
||||
struct Context {
|
||||
InputModel* model;
|
||||
InputController* controller;
|
||||
} context {
|
||||
m_inputModel,
|
||||
this
|
||||
};
|
||||
mInputEnumerateAxes(&m_inputMap, SDL_BINDING_BUTTON, [](int axis, const struct mInputAxis* description, void* user) {
|
||||
InputModel* model = static_cast<InputModel*>(user);
|
||||
Context* context = static_cast<Context*>(user);
|
||||
InputModel* model = context->model;
|
||||
InputController* controller = context->controller;
|
||||
InputItem* item;
|
||||
if (description->highDirection >= 0) {
|
||||
item = model->itemForKey(description->highDirection);
|
||||
if (description->highDirection >= 0 && description->highDirection < controller->m_inputMap.info->nKeys) {
|
||||
item = controller->itemForKey(description->highDirection);
|
||||
if (item) {
|
||||
item->setAxis(axis, GamepadAxisEvent::POSITIVE);
|
||||
}
|
||||
}
|
||||
if (description->lowDirection >= 0) {
|
||||
item = model->itemForKey(description->lowDirection);
|
||||
if (description->lowDirection >= 0 && description->lowDirection < controller->m_inputMap.info->nKeys) {
|
||||
item = controller->itemForKey(description->lowDirection);
|
||||
if (item) {
|
||||
item->setAxis(axis, GamepadAxisEvent::NEGATIVE);
|
||||
}
|
||||
}
|
||||
}, m_inputModel);
|
||||
#endif*/
|
||||
}, &context);
|
||||
#endif
|
||||
m_inputModel->blockSignals(signalsBlocked);
|
||||
}
|
||||
|
|
|
@ -89,8 +89,6 @@ public:
|
|||
mRumble* rumble();
|
||||
mRotationSource* rotationSource();
|
||||
|
||||
void setupCallback(GameController* controller);
|
||||
|
||||
signals:
|
||||
void profileLoaded(const QString& profile);
|
||||
|
||||
|
@ -119,6 +117,8 @@ private:
|
|||
void sendGamepadEvent(QEvent*);
|
||||
void restoreModel();
|
||||
|
||||
InputItem* itemForKey(int key);
|
||||
|
||||
InputModel* m_inputModel = nullptr;
|
||||
mInputMap m_inputMap;
|
||||
ConfigController* m_config = nullptr;
|
||||
|
@ -136,9 +136,6 @@ private:
|
|||
|
||||
QVector<int> m_deadzones;
|
||||
|
||||
InputItem* m_inputMenu;
|
||||
InputItem* m_autofireMenu;
|
||||
|
||||
QSet<int> m_activeButtons;
|
||||
QSet<QPair<int, GamepadAxisEvent::Direction>> m_activeAxes;
|
||||
QSet<QPair<int, GamepadHatEvent::Direction>> m_activeHats;
|
||||
|
|
|
@ -43,7 +43,7 @@ InputItem::InputItem(InputItem::Functions functions, const QString& visibleName,
|
|||
|
||||
InputItem::InputItem(int key, const QString& visibleName, const QString& name, InputItem* parent)
|
||||
: QObject(parent)
|
||||
, m_keys(key)
|
||||
, m_key(key)
|
||||
, m_name(name)
|
||||
, m_visibleName(visibleName)
|
||||
, m_parent(parent)
|
||||
|
@ -84,3 +84,15 @@ void InputItem::setAxis(int axis, GamepadAxisEvent::Direction direction) {
|
|||
m_direction = direction;
|
||||
emit axisBound(this, axis, direction);
|
||||
}
|
||||
|
||||
void InputItem::trigger(bool active) {
|
||||
if (active) {
|
||||
if (m_functions.first) {
|
||||
m_functions.first();
|
||||
}
|
||||
} else {
|
||||
if (m_functions.second) {
|
||||
m_functions.second();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ public:
|
|||
const QAction* action() const { return m_action; }
|
||||
const QMenu* menu() const { return m_menu; }
|
||||
Functions functions() const { return m_functions; }
|
||||
int key() const { return m_keys; }
|
||||
int key() const { return m_key; }
|
||||
|
||||
const QString& visibleName() const { return m_visibleName; }
|
||||
const QString& name() const { return m_name; }
|
||||
|
@ -64,6 +64,9 @@ public:
|
|||
return m_name == other.m_name && m_visibleName == other.m_visibleName;
|
||||
}
|
||||
|
||||
public slots:
|
||||
void trigger(bool = true);
|
||||
|
||||
signals:
|
||||
void shortcutBound(InputItem*, int shortcut);
|
||||
void buttonBound(InputItem*, int button);
|
||||
|
@ -80,7 +83,7 @@ private:
|
|||
int m_shortcut = 0;
|
||||
int m_button = -1;
|
||||
int m_axis = -1;
|
||||
int m_keys =-1;
|
||||
int m_key = -1;
|
||||
GamepadAxisEvent::Direction m_direction = GamepadAxisEvent::NEUTRAL;
|
||||
QList<InputItem*> m_items;
|
||||
InputItem* m_parent;
|
||||
|
|
|
@ -136,6 +136,14 @@ const InputItem* InputModel::itemAt(const QModelIndex& index) const {
|
|||
return pmenu->items()[index.row()];
|
||||
}
|
||||
|
||||
InputItem* InputModel::itemAt(const QString& name) {
|
||||
return m_names[name];
|
||||
}
|
||||
|
||||
const InputItem* InputModel::itemAt(const QString& name) const {
|
||||
return m_names[name];
|
||||
}
|
||||
|
||||
InputItem* InputModel::itemForMenu(const QMenu* menu) {
|
||||
InputItem* item = m_menus[menu];
|
||||
if (!item) {
|
||||
|
@ -143,6 +151,7 @@ InputItem* InputModel::itemForMenu(const QMenu* menu) {
|
|||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
const InputItem* InputModel::itemForMenu(const QMenu* menu) const {
|
||||
const InputItem* item = m_menus[menu];
|
||||
if (!item) {
|
||||
|
@ -151,6 +160,18 @@ const InputItem* InputModel::itemForMenu(const QMenu* menu) const {
|
|||
return item;
|
||||
}
|
||||
|
||||
InputItem* InputModel::itemForShortcut(int shortcut) {
|
||||
return m_shortcuts[shortcut];
|
||||
}
|
||||
|
||||
InputItem* InputModel::itemForButton(int button) {
|
||||
return m_buttons[button];
|
||||
}
|
||||
|
||||
InputItem* InputModel::itemForAxis(int axis, GamepadAxisEvent::Direction direction) {
|
||||
return m_axes[qMakePair(axis, direction)];
|
||||
}
|
||||
|
||||
bool InputModel::loadShortcuts(InputItem* item) {
|
||||
if (item->name().isNull()) {
|
||||
return false;
|
||||
|
@ -293,6 +314,36 @@ void InputModel::itemAdded(InputItem* parent, InputItem* child) {
|
|||
if (menu) {
|
||||
m_menus[menu] = child;
|
||||
}
|
||||
if (child->shortcut()) {
|
||||
m_shortcuts[child->shortcut()] = child;
|
||||
}
|
||||
if (child->button() >= 0) {
|
||||
m_buttons[child->button()] = child;
|
||||
}
|
||||
if (child->direction() != GamepadAxisEvent::NEUTRAL) {
|
||||
m_axes[qMakePair(child->axis(), child->direction())] = child;
|
||||
}
|
||||
m_names[child->name()] = child;
|
||||
connect(child, &InputItem::childAdded, this, &InputModel::itemAdded);
|
||||
connect(child, &InputItem::shortcutBound, this, &InputModel::rebindShortcut);
|
||||
connect(child, &InputItem::buttonBound, this, &InputModel::rebindButton);
|
||||
connect(child, &InputItem::axisBound, this, &InputModel::rebindAxis);
|
||||
}
|
||||
|
||||
void InputModel::rebindShortcut(InputItem* item, int shortcut) {
|
||||
if (shortcut) {
|
||||
m_shortcuts[shortcut] = item;
|
||||
}
|
||||
}
|
||||
|
||||
void InputModel::rebindButton(InputItem* item, int button) {
|
||||
if (button >= 0) {
|
||||
m_buttons[button] = item;
|
||||
}
|
||||
}
|
||||
|
||||
void InputModel::rebindAxis(InputItem* item, int axis, GamepadAxisEvent::Direction direction) {
|
||||
if (axis != GamepadAxisEvent::NEUTRAL) {
|
||||
m_axes[qMakePair(axis, direction)] = item;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,6 +37,9 @@ private:
|
|||
|
||||
private slots:
|
||||
void itemAdded(InputItem* parent, InputItem* child);
|
||||
void rebindShortcut(InputItem*, int shortcut);
|
||||
void rebindButton(InputItem*, int button);
|
||||
void rebindAxis(InputItem*, int axis, GamepadAxisEvent::Direction);
|
||||
|
||||
public:
|
||||
InputModel(QObject* parent = nullptr);
|
||||
|
@ -60,12 +63,13 @@ public:
|
|||
InputItem* itemAt(const QModelIndex& index);
|
||||
const InputItem* itemAt(const QModelIndex& index) const;
|
||||
|
||||
InputItem* itemForKey(int key);
|
||||
const InputItem* itemForKey(int key) const;
|
||||
|
||||
InputItem* itemForMenu(const QMenu* menu);
|
||||
const InputItem* itemForMenu(const QMenu* menu) const;
|
||||
|
||||
InputItem* itemForShortcut(int shortcut);
|
||||
InputItem* itemForButton(int button);
|
||||
InputItem* itemForAxis(int axis, GamepadAxisEvent::Direction);
|
||||
|
||||
static int toModifierShortcut(const QString& shortcut);
|
||||
static bool isModifierKey(int key);
|
||||
static int toModifierKey(int key);
|
||||
|
@ -84,6 +88,9 @@ private:
|
|||
InputItem m_rootMenu;
|
||||
QMap<QString, InputItem*> m_names;
|
||||
QMap<const QMenu*, InputItem*> m_menus;
|
||||
QMap<int, InputItem*> m_shortcuts;
|
||||
QMap<int, InputItem*> m_buttons;
|
||||
QMap<QPair<int, GamepadAxisEvent::Direction>, InputItem*> m_axes;
|
||||
ConfigController* m_config;
|
||||
QString m_profileName;
|
||||
const InputProfile* m_profile;
|
||||
|
|
|
@ -193,8 +193,6 @@ Window::Window(ConfigController* config, int playerId, QWidget* parent)
|
|||
|
||||
m_inputModel->setConfigController(m_config);
|
||||
setupMenu(menuBar());
|
||||
|
||||
m_inputController.setupCallback(m_controller);
|
||||
}
|
||||
|
||||
Window::~Window() {
|
||||
|
@ -1543,6 +1541,69 @@ void Window::setupMenu(QMenuBar* menubar) {
|
|||
m_controller->setAutofire(GBA_KEY_LEFT, false);
|
||||
}), tr("Autofire Left"), "autofireLeft");
|
||||
|
||||
QMenu* bindingsMenu = new QMenu(tr("Bindings"), this);
|
||||
InputItem* bindingsMenuItem = m_inputModel->addItem(bindingsMenu, "bindings");
|
||||
|
||||
bindingsMenuItem->addItem(qMakePair([this]() {
|
||||
m_controller->keyPressed(GBA_KEY_A);
|
||||
}, [this]() {
|
||||
m_controller->keyReleased(GBA_KEY_A);
|
||||
}), tr("A"), "keyA");
|
||||
|
||||
bindingsMenuItem->addItem(qMakePair([this]() {
|
||||
m_controller->keyPressed(GBA_KEY_B);
|
||||
}, [this]() {
|
||||
m_controller->keyReleased(GBA_KEY_B);
|
||||
}), tr("B"), "keyB");
|
||||
|
||||
bindingsMenuItem->addItem(qMakePair([this]() {
|
||||
m_controller->keyPressed(GBA_KEY_START);
|
||||
}, [this]() {
|
||||
m_controller->keyReleased(GBA_KEY_START);
|
||||
}), tr("Start"), "keyStart");
|
||||
|
||||
bindingsMenuItem->addItem(qMakePair([this]() {
|
||||
m_controller->keyPressed(GBA_KEY_SELECT);
|
||||
}, [this]() {
|
||||
m_controller->keyReleased(GBA_KEY_SELECT);
|
||||
}), tr("Select"), "keySelect");
|
||||
|
||||
bindingsMenuItem->addItem(qMakePair([this]() {
|
||||
m_controller->keyPressed(GBA_KEY_L);
|
||||
}, [this]() {
|
||||
m_controller->keyReleased(GBA_KEY_L);
|
||||
}), tr("L"), "keyL");
|
||||
|
||||
bindingsMenuItem->addItem(qMakePair([this]() {
|
||||
m_controller->keyPressed(GBA_KEY_R);
|
||||
}, [this]() {
|
||||
m_controller->keyReleased(GBA_KEY_R);
|
||||
}), tr("R"), "keyR");
|
||||
|
||||
bindingsMenuItem->addItem(qMakePair([this]() {
|
||||
m_controller->keyPressed(GBA_KEY_UP);
|
||||
}, [this]() {
|
||||
m_controller->keyReleased(GBA_KEY_UP);
|
||||
}), tr("Up"), "keyUp");
|
||||
|
||||
bindingsMenuItem->addItem(qMakePair([this]() {
|
||||
m_controller->keyPressed(GBA_KEY_DOWN);
|
||||
}, [this]() {
|
||||
m_controller->keyReleased(GBA_KEY_DOWN);
|
||||
}), tr("Down"), "keyDown");
|
||||
|
||||
bindingsMenuItem->addItem(qMakePair([this]() {
|
||||
m_controller->keyPressed(GBA_KEY_LEFT);
|
||||
}, [this]() {
|
||||
m_controller->keyReleased(GBA_KEY_LEFT);
|
||||
}), tr("Left"), "keyLeft");
|
||||
|
||||
bindingsMenuItem->addItem(qMakePair([this]() {
|
||||
m_controller->keyPressed(GBA_KEY_RIGHT);
|
||||
}, [this]() {
|
||||
m_controller->keyReleased(GBA_KEY_RIGHT);
|
||||
}), tr("Right"), "keyRight");
|
||||
|
||||
for (QAction* action : m_gameActions) {
|
||||
action->setDisabled(true);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue