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