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#ifndef QGBA_INPUT_CONTROLLER_H
7#define QGBA_INPUT_CONTROLLER_H
8
9#include "GamepadAxisEvent.h"
10#include "GamepadHatEvent.h"
11#include "InputIndex.h"
12
13#include <memory>
14
15#include <QMap>
16#include <QObject>
17#include <QSet>
18#include <QTimer>
19#include <QVector>
20
21#include <mgba/core/core.h>
22#include <mgba/core/input.h>
23
24#ifdef BUILD_SDL
25#include "platform/sdl/sdl-events.h"
26#endif
27
28class QMenu;
29
30struct mRotationSource;
31struct mRumble;
32
33namespace QGBA {
34
35class ConfigController;
36class GameController;
37class InputItem;
38
39class InputController : public QObject {
40Q_OBJECT
41
42public:
43 static const uint32_t KEYBOARD = 0x51545F4B;
44
45 InputController(int playerId = 0, QWidget* topLevel = nullptr, QObject* parent = nullptr);
46 ~InputController();
47
48 InputIndex* inputIndex() { return &m_inputIndex; }
49 InputIndex* keyIndex() { return &m_keyIndex; }
50 void rebuildIndex(const InputIndex* = nullptr);
51 void rebuildKeyIndex(const InputIndex* = nullptr);
52
53 void addPlatform(mPlatform, const mInputPlatformInfo*);
54 void setPlatform(mPlatform);
55 void addKey(const QString& name);
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 bool allowOpposing() const { return m_allowOpposing; }
66 void setAllowOpposing(bool allowOpposing) { m_allowOpposing = allowOpposing; }
67
68 const mInputMap* map();
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 bindKey(uint32_t type, int key, const QString&);
79 void bindAxis(uint32_t type, int axis, GamepadAxisEvent::Direction, const QString&);
80 void bindHat(uint32_t type, int hat, GamepadHatEvent::Direction, const QString&);
81
82 QStringList connectedGamepads(uint32_t type) const;
83 int gamepad(uint32_t type) const;
84 void setGamepad(uint32_t type, int index);
85 void setPreferredGamepad(uint32_t type, const QString& device);
86
87 void registerTiltAxisX(int axis);
88 void registerTiltAxisY(int axis);
89 void registerGyroAxisX(int axis);
90 void registerGyroAxisY(int axis);
91
92 float gyroSensitivity() const;
93 void setGyroSensitivity(float sensitivity);
94
95 void stealFocus(QWidget* focus);
96 void releaseFocus(QWidget* focus);
97
98 mRumble* rumble();
99 mRotationSource* rotationSource();
100
101signals:
102 void profileLoaded(const QString& profile);
103 void keyPressed(int);
104 void keyReleased(int);
105 void keyAutofire(int, bool enabled);
106
107public slots:
108 void testGamepad(int type);
109 void updateJoysticks();
110
111 // TODO: Move these to somewhere that makes sense
112 void suspendScreensaver();
113 void resumeScreensaver();
114 void setScreensaverSuspendable(bool);
115
116protected:
117 bool eventFilter(QObject*, QEvent*) override;
118
119private:
120 void postPendingEvent(int key);
121 void clearPendingEvent(int key);
122 bool hasPendingEvent(int key) const;
123 void sendGamepadEvent(QEvent*);
124 void restoreModel();
125 void rebindKey(const QString& key);
126
127 InputItem* itemForKey(const QString& key);
128 int keyId(const QString& key);
129
130 InputIndex m_inputIndex;
131 InputIndex m_keyIndex;
132 mInputMap m_inputMap;
133 ConfigController* m_config = nullptr;
134 int m_playerId;
135 bool m_allowOpposing = false;
136 QWidget* m_topLevel;
137 QWidget* m_focusParent;
138 QMap<mPlatform, const mInputPlatformInfo*> m_keyInfo;
139 const mInputPlatformInfo* m_activeKeyInfo = nullptr;
140
141 std::unique_ptr<QMenu> m_bindings;
142 std::unique_ptr<QMenu> m_autofire;
143
144#ifdef BUILD_SDL
145 static int s_sdlInited;
146 static mSDLEvents s_sdlEvents;
147 mSDLPlayer m_sdlPlayer{};
148 bool m_playerAttached = false;
149#endif
150
151 QVector<int> m_deadzones;
152
153 QSet<int> m_activeButtons;
154 QSet<QPair<int, GamepadAxisEvent::Direction>> m_activeAxes;
155 QSet<QPair<int, GamepadHatEvent::Direction>> m_activeHats;
156 QTimer m_gamepadTimer{nullptr};
157
158 QSet<int> m_pendingEvents;
159};
160
161}
162
163#endif