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