src/platform/qt/input/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#pragma once
7
8#include "GamepadAxisEvent.h"
9#include "GamepadHatEvent.h"
10#include "InputIndex.h"
11
12#include <memory>
13
14#include <QImage>
15#include <QMap>
16#include <QMutex>
17#include <QObject>
18#include <QSet>
19#include <QTimer>
20#include <QVector>
21
22#include <mgba/core/core.h>
23#include <mgba/core/input.h>
24
25#include <mgba/gba/interface.h>
26
27#ifdef BUILD_SDL
28#include "platform/sdl/sdl-events.h"
29#endif
30
31#ifdef BUILD_QT_MULTIMEDIA
32#include "VideoDumper.h"
33#endif
34
35struct mRotationSource;
36struct mRumble;
37
38class QCamera;
39class QMenu;
40
41namespace QGBA {
42
43class ConfigController;
44class GameController;
45class InputItem;
46
47class InputController : public QObject {
48Q_OBJECT
49
50public:
51 enum class CameraDriver : int {
52 NONE = 0,
53#ifdef BUILD_QT_MULTIMEDIA
54 QT_MULTIMEDIA = 1,
55#endif
56 };
57
58 static const uint32_t KEYBOARD = 0x51545F4B;
59
60 InputController(int playerId = 0, QWidget* topLevel = nullptr, QObject* parent = nullptr);
61 ~InputController();
62
63 InputIndex* inputIndex() { return &m_inputIndex; }
64 InputIndex* keyIndex() { return &m_keyIndex; }
65 void rebuildIndex(const InputIndex* = nullptr);
66 void rebuildKeyIndex(const InputIndex* = nullptr);
67
68 void addPlatform(mPlatform, const mInputPlatformInfo*);
69 void setPlatform(mPlatform);
70 void addKey(const QString& name);
71
72 void setConfiguration(ConfigController* config);
73 void saveConfiguration();
74 void loadConfiguration(uint32_t type);
75 void loadProfile(uint32_t type, const QString& profile);
76 void saveConfiguration(uint32_t type);
77 void saveProfile(uint32_t type, const QString& profile);
78 const char* profileForType(uint32_t type);
79
80 GBAKey mapKeyboard(int key) const;
81
82 void bindKey(uint32_t type, int key, GBAKey);
83
84 const mInputMap* map();
85
86 int pollEvents();
87
88 static const int32_t AXIS_THRESHOLD = 0x3000;
89 QSet<int> activeGamepadButtons(int type);
90 QSet<QPair<int, GamepadAxisEvent::Direction>> activeGamepadAxes(int type);
91 QSet<QPair<int, GamepadHatEvent::Direction>> activeGamepadHats(int type);
92 void recalibrateAxes();
93
94 void bindKey(uint32_t type, int key, const QString&);
95 void bindAxis(uint32_t type, int axis, GamepadAxisEvent::Direction, const QString&);
96 void bindHat(uint32_t type, int hat, GamepadHatEvent::Direction, const QString&);
97
98 QStringList connectedGamepads(uint32_t type) const;
99 int gamepad(uint32_t type) const;
100 void setGamepad(uint32_t type, int index);
101 void setPreferredGamepad(uint32_t type, const QString& device);
102
103 void registerTiltAxisX(int axis);
104 void registerTiltAxisY(int axis);
105 void registerGyroAxisX(int axis);
106 void registerGyroAxisY(int axis);
107
108 float gyroSensitivity() const;
109 void setGyroSensitivity(float sensitivity);
110
111 void stealFocus(QWidget* focus);
112 void releaseFocus(QWidget* focus);
113
114 mRumble* rumble();
115 mRotationSource* rotationSource();
116 mImageSource* imageSource() { return &m_image; }
117 GBALuminanceSource* luminance() { return &m_lux; }
118
119signals:
120 void profileLoaded(const QString& profile);
121 void luminanceValueChanged(int value);
122
123public slots:
124 void testGamepad(int type);
125 void updateJoysticks();
126 int updateAutofire();
127
128 void setAutofire(int key, bool enable);
129
130 // TODO: Move these to somewhere that makes sense
131 void suspendScreensaver();
132 void resumeScreensaver();
133 void setScreensaverSuspendable(bool);
134
135 void increaseLuminanceLevel();
136 void decreaseLuminanceLevel();
137 void setLuminanceLevel(int level);
138 void setLuminanceValue(uint8_t value);
139
140 void loadCamImage(const QString& path);
141 void setCamImage(const QImage& image);
142
143protected:
144 bool eventFilter(QObject*, QEvent*) override;
145
146private slots:
147 void setupCam();
148 void teardownCam();
149
150private:
151 void postPendingEvent(int key);
152 void clearPendingEvent(int key);
153 bool hasPendingEvent(int key) const;
154 void sendGamepadEvent(QEvent*);
155 void restoreModel();
156 void rebindKey(const QString& key);
157
158 InputItem* itemForKey(const QString& key);
159 int keyId(const QString& key);
160
161 InputIndex m_inputIndex;
162 InputIndex m_keyIndex;
163
164 struct InputControllerLux : GBALuminanceSource {
165 InputController* p;
166 uint8_t value;
167 } m_lux;
168 uint8_t m_luxValue;
169 int m_luxLevel;
170
171 struct InputControllerImage : mImageSource {
172 InputController* p;
173 QImage image;
174 QImage resizedImage;
175 bool outOfDate;
176 QMutex mutex;
177 unsigned w, h;
178 } m_image;
179
180#ifdef BUILD_QT_MULTIMEDIA
181 std::unique_ptr<QCamera> m_camera;
182 VideoDumper m_videoDumper;
183#endif
184
185 mInputMap m_inputMap;
186 int m_activeKeys;
187 bool m_autofireEnabled[32] = {};
188 int m_autofireStatus[32] = {};
189
190 ConfigController* m_config = nullptr;
191 int m_playerId;
192 QWidget* m_topLevel;
193 QWidget* m_focusParent;
194 QMap<mPlatform, const mInputPlatformInfo*> m_keyInfo;
195 const mInputPlatformInfo* m_activeKeyInfo = nullptr;
196
197 std::unique_ptr<QMenu> m_bindings;
198 std::unique_ptr<QMenu> m_autofire;
199
200#ifdef BUILD_SDL
201 static int s_sdlInited;
202 static mSDLEvents s_sdlEvents;
203 mSDLPlayer m_sdlPlayer{};
204 bool m_playerAttached = false;
205#endif
206
207 QVector<int> m_deadzones;
208
209 QSet<int> m_activeButtons;
210 QSet<QPair<int, GamepadAxisEvent::Direction>> m_activeAxes;
211 QSet<QPair<int, GamepadHatEvent::Direction>> m_activeHats;
212 QTimer m_gamepadTimer{nullptr};
213
214 QSet<int> m_pendingEvents;
215};
216
217}