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