Qt: Migrate axis bindings to GamepadAxisEvent

This commit is contained in:
Jeffrey Pfau 2015-01-08 00:24:43 -08:00
parent a9f0fabdd2
commit 12fce1fba0
12 changed files with 146 additions and 46 deletions

View File

@ -44,6 +44,7 @@ set(SOURCE_FILES
GIFView.cpp
GameController.cpp
GamePakView.cpp
GamepadAxisEvent.cpp
GamepadButtonEvent.cpp
InputController.cpp
KeyEditor.cpp

View File

@ -109,12 +109,6 @@ GBAKeyEditor::GBAKeyEditor(InputController* controller, int type, QWidget* paren
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 @@ void GBAKeyEditor::lookupAxes(const GBAInputMap* map) {
#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);

View File

@ -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;
}

View File

@ -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

View File

@ -6,6 +6,7 @@
#include "InputController.h"
#include "ConfigController.h"
#include "GamepadAxisEvent.h"
#include "GamepadButtonEvent.h"
#include <QApplication>
@ -144,33 +145,33 @@ QSet<int> InputController::activeGamepadButtons() {
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 @@ void InputController::testGamepad() {
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());

View File

@ -6,6 +6,8 @@
#ifndef QGBA_INPUT_CONTROLLER_H
#define QGBA_INPUT_CONTROLLER_H
#include "GamepadAxisEvent.h"
#include <QObject>
#include <QSet>
@ -44,22 +46,14 @@ public:
#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 @@ private:
#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;

View File

@ -5,6 +5,7 @@
* 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::setValueKey(int key) {
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);
}
@ -73,5 +74,13 @@ bool KeyEditor::event(QEvent* event) {
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;
}
return QWidget::event(event);
}

View File

@ -6,7 +6,7 @@
#ifndef QGBA_KEY_EDITOR
#define QGBA_KEY_EDITOR
#include "InputController.h"
#include "GamepadAxisEvent.h"
#include <QLineEdit>
namespace QGBA {
@ -19,7 +19,7 @@ public:
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 @@ protected:
private:
int m_key;
bool m_button;
InputController::Direction m_direction;
GamepadAxisEvent::Direction m_direction;
};
}

View File

@ -6,6 +6,7 @@
#include "LoadSaveState.h"
#include "GameController.h"
#include "GamepadAxisEvent.h"
#include "GamepadButtonEvent.h"
#include "VFileDevice.h"
@ -105,10 +106,21 @@ bool LoadSaveState::eventFilter(QObject* object, QEvent* event) {
}
}
}
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;

View File

@ -15,7 +15,6 @@ using namespace QGBA;
ShortcutView::ShortcutView(QWidget* parent)
: QWidget(parent)
, m_controller(nullptr)
, m_inputController(nullptr)
{
m_ui.setupUi(this);
m_ui.keyEdit->setValueButton(-1);
@ -32,11 +31,6 @@ void ShortcutView::setController(ShortcutController* 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) {
if (event->type() == GamepadButtonEvent::Down()) {
updateButton(static_cast<GamepadButtonEvent*>(event)->value());

View File

@ -12,7 +12,6 @@
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;
};
}

View File

@ -215,7 +215,6 @@ void Window::openSettingsWindow() {
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();