src/platform/qt/InputController.h (view raw)
1/* Copyright (c) 2013-2015 Jeffrey Pfau
2 *
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6#ifndef QGBA_INPUT_CONTROLLER_H
7#define QGBA_INPUT_CONTROLLER_H
8
9#include "GamepadAxisEvent.h"
10#include "GamepadHatEvent.h"
11
12#include <memory>
13
14#include <QMap>
15#include <QObject>
16#include <QSet>
17#include <QTimer>
18#include <QVector>
19
20#include <mgba/core/core.h>
21#include <mgba/core/input.h>
22
23#ifdef BUILD_SDL
24#include "platform/sdl/sdl-events.h"
25#endif
26
27class QMenu;
28
29struct mRotationSource;
30struct mRumble;
31
32namespace QGBA {
33
34class ConfigController;
35class GameController;
36class InputModel;
37
38class InputController : public QObject {
39Q_OBJECT
40
41public:
42 static const uint32_t KEYBOARD = 0x51545F4B;
43
44 InputController(InputModel* model, int playerId = 0, QWidget* topLevel = nullptr, QObject* parent = nullptr);
45 ~InputController();
46
47 void addPlatform(mPlatform, const QString& visibleName, const mInputPlatformInfo*);
48 void setPlatform(mPlatform);
49
50 void setConfiguration(ConfigController* config);
51 void saveConfiguration();
52 void loadConfiguration(uint32_t type);
53 void loadProfile(uint32_t type, const QString& profile);
54 void saveConfiguration(uint32_t type);
55 void saveProfile(uint32_t type, const QString& profile);
56 const char* profileForType(uint32_t type);
57
58 bool allowOpposing() const { return m_allowOpposing; }
59 void setAllowOpposing(bool allowOpposing) { m_allowOpposing = allowOpposing; }
60
61 const mInputMap* map();
62
63 int pollEvents();
64
65 static const int32_t AXIS_THRESHOLD = 0x3000;
66 QSet<int> activeGamepadButtons(int type);
67 QSet<QPair<int, GamepadAxisEvent::Direction>> activeGamepadAxes(int type);
68 QSet<QPair<int, GamepadHatEvent::Direction>> activeGamepadHats(int type);
69 void recalibrateAxes();
70
71 void bindKey(mPlatform platform, uint32_t type, int key, int);
72 void bindAxis(mPlatform platform, uint32_t type, int axis, GamepadAxisEvent::Direction, int);
73 void bindHat(mPlatform platform, uint32_t type, int hat, GamepadHatEvent::Direction, int);
74
75 QStringList connectedGamepads(uint32_t type) const;
76 int gamepad(uint32_t type) const;
77 void setGamepad(uint32_t type, int index);
78 void setPreferredGamepad(uint32_t type, const QString& device);
79
80 void registerTiltAxisX(int axis);
81 void registerTiltAxisY(int axis);
82 void registerGyroAxisX(int axis);
83 void registerGyroAxisY(int axis);
84
85 float gyroSensitivity() const;
86 void setGyroSensitivity(float sensitivity);
87
88 void stealFocus(QWidget* focus);
89 void releaseFocus(QWidget* focus);
90
91 mRumble* rumble();
92 mRotationSource* rotationSource();
93
94 void setupCallback(GameController* controller);
95
96signals:
97 void profileLoaded(const QString& profile);
98
99public slots:
100 void testGamepad(int type);
101 void updateJoysticks();
102
103 // TODO: Move these to somewhere that makes sense
104 void suspendScreensaver();
105 void resumeScreensaver();
106 void setScreensaverSuspendable(bool);
107
108private slots:
109 void bindKey(const QModelIndex&, int key);
110 void bindButton(const QModelIndex&, int key);
111 void bindAxis(const QModelIndex&, int axis, GamepadAxisEvent::Direction);
112 void bindHat(const QModelIndex&, int hat, GamepadHatEvent::Direction);
113
114protected:
115 bool eventFilter(QObject*, QEvent*) override;
116
117private:
118 void postPendingEvent(int key);
119 void clearPendingEvent(int key);
120 bool hasPendingEvent(int key) const;
121 void sendGamepadEvent(QEvent*);
122 void restoreModel();
123
124 InputModel* m_inputModel;
125 mPlatform m_platform;
126 QMap<mPlatform, mInputMap> m_inputMaps;
127 ConfigController* m_config;
128 int m_playerId;
129 bool m_allowOpposing;
130 QWidget* m_topLevel;
131 QWidget* m_focusParent;
132
133#ifdef BUILD_SDL
134 static int s_sdlInited;
135 static mSDLEvents s_sdlEvents;
136 mSDLPlayer m_sdlPlayer;
137 bool m_playerAttached;
138#endif
139
140 QVector<int> m_deadzones;
141
142 std::unique_ptr<QMenu> m_inputMenu;
143 std::unique_ptr<QMenu> m_autofireMenu;
144 QMap<mPlatform, QModelIndex> m_inputMenuIndices;
145
146 QSet<int> m_activeButtons;
147 QSet<QPair<int, GamepadAxisEvent::Direction>> m_activeAxes;
148 QSet<QPair<int, GamepadHatEvent::Direction>> m_activeHats;
149 QTimer m_gamepadTimer;
150
151 QSet<int> m_pendingEvents;
152};
153
154}
155
156#endif