all repos — mgba @ c4b38790f211b65cb15af26cebe9fc25e3c19914

mGBA Game Boy Advance Emulator

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#pragma once
  7
  8#include "GamepadAxisEvent.h"
  9#include "GamepadHatEvent.h"
 10
 11#include <QImage>
 12#include <QMutex>
 13#include <QReadWriteLock>
 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#include <QCamera>
 32#endif
 33
 34struct mRotationSource;
 35struct mRumble;
 36
 37namespace QGBA {
 38
 39class ConfigController;
 40
 41class InputController : public QObject {
 42Q_OBJECT
 43
 44public:
 45	enum class CameraDriver : int {
 46		NONE = 0,
 47#ifdef BUILD_QT_MULTIMEDIA
 48		QT_MULTIMEDIA = 1,
 49#endif
 50	};
 51
 52	static const uint32_t KEYBOARD = 0x51545F4B;
 53
 54	InputController(int playerId = 0, QWidget* topLevel = nullptr, QObject* parent = nullptr);
 55	~InputController();
 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	GBAKey mapKeyboard(int key) const;
 66
 67	void bindKey(uint32_t type, int key, GBAKey);
 68
 69	const mInputMap* map() const { return &m_inputMap; }
 70
 71	int pollEvents();
 72
 73	static const int32_t AXIS_THRESHOLD = 0x3000;
 74	QSet<int> activeGamepadButtons(int type);
 75	QSet<QPair<int, GamepadAxisEvent::Direction>> activeGamepadAxes(int type);
 76	QSet<QPair<int, GamepadHatEvent::Direction>> activeGamepadHats(int type);
 77	void recalibrateAxes();
 78
 79	void bindAxis(uint32_t type, int axis, GamepadAxisEvent::Direction, GBAKey);
 80	void unbindAllAxes(uint32_t type);
 81
 82	void bindHat(uint32_t type, int hat, GamepadHatEvent::Direction, GBAKey);
 83	void unbindAllHats(uint32_t type);
 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, int index);
 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	QList<QPair<QByteArray, QString>> listCameras() const;
102
103	mRumble* rumble();
104	mRotationSource* rotationSource();
105	mImageSource* imageSource() { return &m_image; }
106	GBALuminanceSource* luminance() { return &m_lux; }
107
108signals:
109	void profileLoaded(const QString& profile);
110	void luminanceValueChanged(int value);
111
112public slots:
113	void testGamepad(int type);
114	void updateJoysticks();
115
116	// TODO: Move these to somewhere that makes sense
117	void suspendScreensaver();
118	void resumeScreensaver();
119	void setScreensaverSuspendable(bool);
120
121	void increaseLuminanceLevel();
122	void decreaseLuminanceLevel();
123	void setLuminanceLevel(int level);
124	void setLuminanceValue(uint8_t value);
125
126	void loadCamImage(const QString& path);
127	void setCamImage(const QImage& image);
128
129	void setCamera(const QByteArray& id);
130
131private slots:
132#ifdef BUILD_QT_MULTIMEDIA
133	void prepareCamSettings(QCamera::Status);
134#endif
135	void setupCam();
136	void teardownCam();
137
138private:
139	void postPendingEvent(GBAKey);
140	void clearPendingEvent(GBAKey);
141	bool hasPendingEvent(GBAKey) const;
142	void sendGamepadEvent(QEvent*);
143
144	struct InputControllerLux : GBALuminanceSource {
145		InputController* p;
146		uint8_t value;
147	} m_lux;
148	uint8_t m_luxValue;
149	int m_luxLevel;
150
151	struct InputControllerImage : mImageSource {
152		InputController* p;
153		QImage image;
154		QImage resizedImage;
155		bool outOfDate;
156		QMutex mutex;
157		int w, h;
158	} m_image;
159
160#ifdef BUILD_QT_MULTIMEDIA
161	std::unique_ptr<QCamera> m_camera;
162	VideoDumper m_videoDumper;
163#endif
164
165	mInputMap m_inputMap;
166	ConfigController* m_config = nullptr;
167	int m_playerId;
168	QWidget* m_topLevel;
169	QWidget* m_focusParent;
170
171#ifdef BUILD_SDL
172	static int s_sdlInited;
173	static mSDLEvents s_sdlEvents;
174	mSDLPlayer m_sdlPlayer{};
175	bool m_playerAttached = false;
176#endif
177
178	QVector<int> m_deadzones;
179
180	QSet<int> m_activeButtons;
181	QSet<QPair<int, GamepadAxisEvent::Direction>> m_activeAxes;
182	QSet<QPair<int, GamepadHatEvent::Direction>> m_activeHats;
183	QTimer m_gamepadTimer{nullptr};
184
185	QSet<GBAKey> m_pendingEvents;
186	QReadWriteLock m_eventsLock;
187};
188
189}