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