all repos — mgba @ a6ce525da1ed0f7e14e8db927871d2127681fc95

mGBA Game Boy Advance Emulator

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