Qt: Migrate axis bindings to GamepadAxisEvent
jump to
@@ -44,6 +44,7 @@ GBAKeyEditor.cpp
GIFView.cpp GameController.cpp GamePakView.cpp + GamepadAxisEvent.cpp GamepadButtonEvent.cpp InputController.cpp KeyEditor.cpp
@@ -109,12 +109,6 @@
m_background.load(":/res/keymap.qpic"); setAll->setFocus(); - -#ifdef BUILD_SDL - if (type == SDL_BINDING_BUTTON) { - connect(m_controller, SIGNAL(axisChanged(int, int32_t)), this, SLOT(setAxisValue(int, int32_t))); - } -#endif } void GBAKeyEditor::setAll() {@@ -205,7 +199,7 @@ }
#endif void GBAKeyEditor::bindKey(const KeyEditor* keyEditor, GBAKey key) { - if (keyEditor->direction() != InputController::NEUTRAL) { + if (keyEditor->direction() != GamepadAxisEvent::NEUTRAL) { m_controller->bindAxis(m_type, keyEditor->value(), keyEditor->direction(), key); } else { m_controller->bindKey(m_type, keyEditor->value(), key);
@@ -0,0 +1,35 @@
+/* Copyright (c) 2013-2015 Jeffrey Pfau + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include "GamepadAxisEvent.h" + +#include "InputController.h" + +using namespace QGBA; + +QEvent::Type GamepadAxisEvent::s_type = QEvent::None; + +GamepadAxisEvent::GamepadAxisEvent(int axis, Direction direction, bool isNew, InputController* controller) + : QEvent(Type()) + , m_axis(axis) + , m_direction(direction) + , m_isNew(isNew) + , m_controller(controller) + , m_key(GBA_KEY_NONE) +{ + ignore(); +#ifdef BUILD_SDL + if (controller) { + m_key = GBAInputMapAxis(controller->map(), SDL_BINDING_BUTTON, axis, direction * INT_MAX); + } +#endif +} + +QEvent::Type GamepadAxisEvent::Type() { + if (s_type == None) { + s_type = static_cast<enum Type>(registerEventType()); + } + return s_type; +}
@@ -0,0 +1,48 @@
+/* Copyright (c) 2013-2015 Jeffrey Pfau + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#ifndef QGBA_GAMEPAD_AXIS_EVENT +#define QGBA_GAMEPAD_AXIS_EVENT + +#include <QEvent> + +extern "C" { +#include "gba-input.h" +} + +namespace QGBA { + +class InputController; + +class GamepadAxisEvent : public QEvent { +public: + enum Direction { + NEUTRAL = 0, + POSITIVE = 1, + NEGATIVE = -1 + }; + + GamepadAxisEvent(int axis, Direction direction, bool isNew, InputController* controller = nullptr); + + int axis() const { return m_axis; } + Direction direction() const { return m_direction; } + bool isNew() const { return m_isNew; } + GBAKey gbaKey() const { return m_key; } + + static enum Type Type(); + +private: + static enum Type s_type; + + int m_axis; + Direction m_direction; + bool m_isNew; + InputController* m_controller; + GBAKey m_key; +}; + +} + +#endif
@@ -6,6 +6,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "InputController.h" #include "ConfigController.h" +#include "GamepadAxisEvent.h" #include "GamepadButtonEvent.h" #include <QApplication>@@ -144,33 +145,33 @@ }
return activeButtons; } -QSet<QPair<int, int32_t>> InputController::activeGamepadAxes() { +QSet<QPair<int, GamepadAxisEvent::Direction>> InputController::activeGamepadAxes() { SDL_Joystick* joystick = m_sdlEvents.joystick; SDL_JoystickUpdate(); int numButtons = SDL_JoystickNumAxes(joystick); - QSet<QPair<int, int32_t>> activeAxes; + QSet<QPair<int, GamepadAxisEvent::Direction>> activeAxes; int i; for (i = 0; i < numButtons; ++i) { int32_t axis = SDL_JoystickGetAxis(joystick, i); if (axis >= AXIS_THRESHOLD || axis <= -AXIS_THRESHOLD) { - activeAxes.insert(qMakePair(i, axis > 0 ? 1 : -1)); + activeAxes.insert(qMakePair(i, axis > 0 ? GamepadAxisEvent::POSITIVE : GamepadAxisEvent::NEGATIVE)); } } return activeAxes; } -void InputController::bindAxis(uint32_t type, int axis, Direction direction, GBAKey key) { +void InputController::bindAxis(uint32_t type, int axis, GamepadAxisEvent::Direction direction, GBAKey key) { const GBAAxis* old = GBAInputQueryAxis(&m_inputMap, SDL_BINDING_BUTTON, axis); GBAAxis description = { GBA_KEY_NONE, GBA_KEY_NONE, -AXIS_THRESHOLD, AXIS_THRESHOLD }; if (old) { description = *old; } switch (direction) { - case NEGATIVE: + case GamepadAxisEvent::NEGATIVE: description.lowDirection = key; description.deadLow = -AXIS_THRESHOLD; break; - case POSITIVE: + case GamepadAxisEvent::POSITIVE: description.highDirection = key; description.deadHigh = AXIS_THRESHOLD; break;@@ -186,19 +187,35 @@ #ifdef BUILD_SDL
auto activeAxes = activeGamepadAxes(); auto oldAxes = m_activeAxes; m_activeAxes = activeAxes; - activeAxes.subtract(oldAxes); - if (!activeAxes.empty()) { - emit axisChanged(activeAxes.begin()->first, activeAxes.begin()->second); - } auto activeButtons = activeGamepadButtons(); auto oldButtons = m_activeButtons; m_activeButtons = activeButtons; + if (!QApplication::focusWidget()) { return; } + + activeAxes.subtract(oldAxes); + oldAxes.subtract(m_activeAxes); + + for (auto& axis : m_activeAxes) { + bool newlyAboveThreshold = activeAxes.contains(axis); + GamepadAxisEvent* event = new GamepadAxisEvent(axis.first, axis.second, newlyAboveThreshold, this); + if (newlyAboveThreshold) { + postPendingEvent(event->gbaKey()); + if (!event->isAccepted()) { + clearPendingEvent(event->gbaKey()); + } + } else if (oldAxes.contains(axis)) { + clearPendingEvent(event->gbaKey()); + } + QApplication::sendEvent(QApplication::focusWidget(), event); + } + activeButtons.subtract(oldButtons); oldButtons.subtract(m_activeButtons); + for (int button : activeButtons) { GamepadButtonEvent* event = new GamepadButtonEvent(GamepadButtonEvent::Down(), button, this); postPendingEvent(event->gbaKey());
@@ -6,6 +6,8 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef QGBA_INPUT_CONTROLLER_H #define QGBA_INPUT_CONTROLLER_H +#include "GamepadAxisEvent.h" + #include <QObject> #include <QSet>@@ -44,21 +46,13 @@ const GBAInputMap* map() const { return &m_inputMap; }
#ifdef BUILD_SDL static const int32_t AXIS_THRESHOLD = 0x3000; - enum Direction { - NEUTRAL = 0, - POSITIVE = 1, - NEGATIVE = -1 - }; int testSDLEvents(); QSet<int> activeGamepadButtons(); - QSet<QPair<int, int32_t>> activeGamepadAxes(); + QSet<QPair<int, GamepadAxisEvent::Direction>> activeGamepadAxes(); - void bindAxis(uint32_t type, int axis, Direction, GBAKey); + void bindAxis(uint32_t type, int axis, GamepadAxisEvent::Direction, GBAKey); #endif - -signals: - void axisChanged(int axis, int32_t value); public slots: void testGamepad();@@ -76,7 +70,7 @@ GBASDLEvents m_sdlEvents;
#endif QSet<int> m_activeButtons; - QSet<QPair<int, int32_t>> m_activeAxes; + QSet<QPair<int, GamepadAxisEvent::Direction>> m_activeAxes; QTimer* m_gamepadTimer; QSet<GBAKey> m_pendingEvents;
@@ -5,6 +5,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "KeyEditor.h" +#include "GamepadAxisEvent.h" #include "GamepadButtonEvent.h" #include <QKeyEvent>@@ -13,7 +14,7 @@ using namespace QGBA;
KeyEditor::KeyEditor(QWidget* parent) : QLineEdit(parent) - , m_direction(InputController::NEUTRAL) + , m_direction(GamepadAxisEvent::NEUTRAL) { setAlignment(Qt::AlignCenter); }@@ -39,14 +40,14 @@ }
void KeyEditor::setValueButton(int button) { m_button = true; - m_direction = InputController::NEUTRAL; + m_direction = GamepadAxisEvent::NEUTRAL; setValue(button); } void KeyEditor::setValueAxis(int axis, int32_t value) { m_button = true; m_key = axis; - m_direction = value < 0 ? InputController::NEGATIVE : InputController::POSITIVE; + m_direction = value < 0 ? GamepadAxisEvent::NEGATIVE : GamepadAxisEvent::POSITIVE; setText((value < 0 ? "-" : "+") + QString::number(axis)); emit axisChanged(axis, m_direction); }@@ -70,6 +71,14 @@ return QWidget::event(event);
} if (event->type() == GamepadButtonEvent::Down()) { setValueButton(static_cast<GamepadButtonEvent*>(event)->value()); + event->accept(); + return true; + } + if (event->type() == GamepadAxisEvent::Type()) { + GamepadAxisEvent* gae = static_cast<GamepadAxisEvent*>(event); + if (gae->isNew()) { + setValueAxis(gae->axis(), gae->direction()); + } event->accept(); return true; }
@@ -6,7 +6,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef QGBA_KEY_EDITOR #define QGBA_KEY_EDITOR -#include "InputController.h" +#include "GamepadAxisEvent.h" #include <QLineEdit> namespace QGBA {@@ -19,7 +19,7 @@ KeyEditor(QWidget* parent = nullptr);
int value() const { return m_key; } - InputController::Direction direction() const { return m_direction; } + GamepadAxisEvent::Direction direction() const { return m_direction; } virtual QSize sizeHint() const override;@@ -40,7 +40,7 @@
private: int m_key; bool m_button; - InputController::Direction m_direction; + GamepadAxisEvent::Direction m_direction; }; }
@@ -6,6 +6,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "LoadSaveState.h" #include "GameController.h" +#include "GamepadAxisEvent.h" #include "GamepadButtonEvent.h" #include "VFileDevice.h"@@ -105,10 +106,21 @@ return true;
} } } - if (event->type() == GamepadButtonEvent::Down()) { + if (event->type() == GamepadButtonEvent::Down() || event->type() == GamepadAxisEvent::Type()) { int column = m_currentFocus % 3; int row = m_currentFocus - column; - switch (static_cast<GamepadButtonEvent*>(event)->gbaKey()) { + GBAKey key = GBA_KEY_NONE; + if (event->type() == GamepadButtonEvent::Down()) { + key = static_cast<GamepadButtonEvent*>(event)->gbaKey(); + } else if (event->type() == GamepadAxisEvent::Type()) { + GamepadAxisEvent* gae = static_cast<GamepadAxisEvent*>(event); + if (gae->isNew()) { + key = gae->gbaKey(); + } else { + return false; + } + } + switch (key) { case GBA_KEY_UP: row += 6; break;
@@ -15,7 +15,6 @@
ShortcutView::ShortcutView(QWidget* parent) : QWidget(parent) , m_controller(nullptr) - , m_inputController(nullptr) { m_ui.setupUi(this); m_ui.keyEdit->setValueButton(-1);@@ -30,11 +29,6 @@
void ShortcutView::setController(ShortcutController* controller) { m_controller = controller; m_ui.shortcutTable->setModel(controller); -} - -void ShortcutView::setInputController(InputController* controller) { - m_inputController = controller; - connect(controller, SIGNAL(axisChanged(int, int32_t)), m_ui.keyEdit, SLOT(setValueAxis(int, int32_t))); } bool ShortcutView::event(QEvent* event) {
@@ -12,7 +12,6 @@ #include "ui_ShortcutView.h"
namespace QGBA { -class InputController; class ShortcutController; class ShortcutView : public QWidget {@@ -22,7 +21,6 @@ public:
ShortcutView(QWidget* parent = nullptr); void setController(ShortcutController* controller); - void setInputController(InputController* controller); protected: virtual bool event(QEvent* event) override;@@ -38,7 +36,6 @@ private:
Ui::ShortcutView m_ui; ShortcutController* m_controller; - InputController* m_inputController; }; }
@@ -215,7 +215,6 @@
void Window::openShortcutWindow() { ShortcutView* shortcutView = new ShortcutView(); shortcutView->setController(m_shortcutController); - shortcutView->setInputController(&m_inputController); connect(this, SIGNAL(shutdown()), shortcutView, SLOT(close())); shortcutView->setAttribute(Qt::WA_DeleteOnClose); shortcutView->show();