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