all repos — mgba @ 12fce1fba0adf92d61d95a279324e31e27fef03b

mGBA Game Boy Advance Emulator

Qt: Migrate axis bindings to GamepadAxisEvent
Jeffrey Pfau jeffrey@endrift.com
Thu, 08 Jan 2015 00:24:43 -0800
commit

12fce1fba0adf92d61d95a279324e31e27fef03b

parent

a9f0fabdd278ea847af78822023cd8651aa34af8

M src/platform/qt/CMakeLists.txtsrc/platform/qt/CMakeLists.txt

@@ -44,6 +44,7 @@ GBAKeyEditor.cpp

GIFView.cpp GameController.cpp GamePakView.cpp + GamepadAxisEvent.cpp GamepadButtonEvent.cpp InputController.cpp KeyEditor.cpp
M src/platform/qt/GBAKeyEditor.cppsrc/platform/qt/GBAKeyEditor.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);
A src/platform/qt/GamepadAxisEvent.cpp

@@ -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; +}
A src/platform/qt/GamepadAxisEvent.h

@@ -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
M src/platform/qt/InputController.cppsrc/platform/qt/InputController.cpp

@@ -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());
M src/platform/qt/InputController.hsrc/platform/qt/InputController.h

@@ -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;
M src/platform/qt/KeyEditor.cppsrc/platform/qt/KeyEditor.cpp

@@ -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; }
M src/platform/qt/KeyEditor.hsrc/platform/qt/KeyEditor.h

@@ -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; }; }
M src/platform/qt/LoadSaveState.cppsrc/platform/qt/LoadSaveState.cpp

@@ -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;
M src/platform/qt/ShortcutView.cppsrc/platform/qt/ShortcutView.cpp

@@ -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) {
M src/platform/qt/ShortcutView.hsrc/platform/qt/ShortcutView.h

@@ -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; }; }
M src/platform/qt/Window.cppsrc/platform/qt/Window.cpp

@@ -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();