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 <QImage>
13#include <QMutex>
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#endif
32
33struct mRotationSource;
34struct mRumble;
35
36class QCamera;
37
38namespace QGBA {
39
40class ConfigController;
41
42class InputController : public QObject {
43Q_OBJECT
44
45public:
46 enum class CameraDriver : int {
47 NONE = 0,
48#ifdef BUILD_QT_MULTIMEDIA
49 QT_MULTIMEDIA = 1,
50#endif
51 };
52
53 static const uint32_t KEYBOARD = 0x51545F4B;
54
55 InputController(int playerId = 0, QWidget* topLevel = nullptr, QObject* parent = nullptr);
56 ~InputController();
57
58 void setConfiguration(ConfigController* config);
59 void saveConfiguration();
60 void loadConfiguration(uint32_t type);
61 void loadProfile(uint32_t type, const QString& profile);
62 void saveConfiguration(uint32_t type);
63 void saveProfile(uint32_t type, const QString& profile);
64 const char* profileForType(uint32_t type);
65
66 GBAKey mapKeyboard(int key) const;
67
68 void bindKey(uint32_t type, int key, GBAKey);
69
70 const mInputMap* map() const { return &m_inputMap; }
71
72 int pollEvents();
73
74 static const int32_t AXIS_THRESHOLD = 0x3000;
75 QSet<int> activeGamepadButtons(int type);
76 QSet<QPair<int, GamepadAxisEvent::Direction>> activeGamepadAxes(int type);
77 QSet<QPair<int, GamepadHatEvent::Direction>> activeGamepadHats(int type);
78 void recalibrateAxes();
79
80 void bindAxis(uint32_t type, int axis, GamepadAxisEvent::Direction, GBAKey);
81 void unbindAllAxes(uint32_t type);
82
83 void bindHat(uint32_t type, int hat, GamepadHatEvent::Direction, GBAKey);
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, const QString& device);
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 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
127private slots:
128 void setupCam();
129 void teardownCam();
130
131private:
132 void postPendingEvent(GBAKey);
133 void clearPendingEvent(GBAKey);
134 bool hasPendingEvent(GBAKey) const;
135 void sendGamepadEvent(QEvent*);
136
137 struct InputControllerLux : GBALuminanceSource {
138 InputController* p;
139 uint8_t value;
140 } m_lux;
141 uint8_t m_luxValue;
142 int m_luxLevel;
143
144 struct InputControllerImage : mImageSource {
145 InputController* p;
146 QImage image;
147 QImage resizedImage;
148 bool outOfDate;
149 QMutex mutex;
150 unsigned w, h;
151 } m_image;
152
153#ifdef BUILD_QT_MULTIMEDIA
154 std::unique_ptr<QCamera> m_camera;
155 VideoDumper m_videoDumper;
156#endif
157
158 mInputMap m_inputMap;
159 ConfigController* m_config = nullptr;
160 int m_playerId;
161 QWidget* m_topLevel;
162 QWidget* m_focusParent;
163
164#ifdef BUILD_SDL
165 static int s_sdlInited;
166 static mSDLEvents s_sdlEvents;
167 mSDLPlayer m_sdlPlayer{};
168 bool m_playerAttached = false;
169#endif
170
171 QVector<int> m_deadzones;
172
173 QSet<int> m_activeButtons;
174 QSet<QPair<int, GamepadAxisEvent::Direction>> m_activeAxes;
175 QSet<QPair<int, GamepadHatEvent::Direction>> m_activeHats;
176 QTimer m_gamepadTimer{nullptr};
177
178 QSet<GBAKey> m_pendingEvents;
179};
180
181}
182
183#endif