all repos — mgba @ 1fd8b1b299e785ee75df6ec45bfb6a8d434af684

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 <QObject>
 14#include <QSet>
 15#include <QTimer>
 16#include <QVector>
 17
 18#include <memory>
 19
 20#include <mgba/gba/interface.h>
 21#include <mgba/internal/gba/input.h>
 22
 23#ifdef BUILD_SDL
 24#include "platform/sdl/sdl-events.h"
 25#endif
 26
 27
 28#ifdef BUILD_QT_MULTIMEDIA
 29#include "VideoDumper.h"
 30#include <QCamera>
 31#endif
 32
 33struct mRotationSource;
 34struct mRumble;
 35
 36namespace QGBA {
 37
 38class ConfigController;
 39
 40class InputController : public QObject {
 41Q_OBJECT
 42
 43public:
 44	enum class CameraDriver : int {
 45		NONE = 0,
 46#ifdef BUILD_QT_MULTIMEDIA
 47		QT_MULTIMEDIA = 1,
 48#endif
 49	};
 50
 51	static const uint32_t KEYBOARD = 0x51545F4B;
 52
 53	InputController(int playerId = 0, QWidget* topLevel = nullptr, QObject* parent = nullptr);
 54	~InputController();
 55
 56	void setConfiguration(ConfigController* config);
 57	void saveConfiguration();
 58	void loadConfiguration(uint32_t type);
 59	void loadProfile(uint32_t type, const QString& profile);
 60	void saveConfiguration(uint32_t type);
 61	void saveProfile(uint32_t type, const QString& profile);
 62	const char* profileForType(uint32_t type);
 63
 64	GBAKey mapKeyboard(int key) const;
 65
 66	void bindKey(uint32_t type, int key, GBAKey);
 67
 68	const mInputMap* map() const { return &m_inputMap; }
 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 bindAxis(uint32_t type, int axis, GamepadAxisEvent::Direction, GBAKey);
 79	void unbindAllAxes(uint32_t type);
 80
 81	void bindHat(uint32_t type, int hat, GamepadHatEvent::Direction, GBAKey);
 82
 83	QStringList connectedGamepads(uint32_t type) const;
 84	int gamepad(uint32_t type) const;
 85	void setGamepad(uint32_t type, int index);
 86	void setPreferredGamepad(uint32_t type, const QString& device);
 87
 88	void registerTiltAxisX(int axis);
 89	void registerTiltAxisY(int axis);
 90	void registerGyroAxisX(int axis);
 91	void registerGyroAxisY(int axis);
 92
 93	float gyroSensitivity() const;
 94	void setGyroSensitivity(float sensitivity);
 95
 96	void stealFocus(QWidget* focus);
 97	void releaseFocus(QWidget* focus);
 98
 99	QList<QPair<QByteArray, QString>> listCameras() const;
100
101	mRumble* rumble();
102	mRotationSource* rotationSource();
103	mImageSource* imageSource() { return &m_image; }
104	GBALuminanceSource* luminance() { return &m_lux; }
105
106signals:
107	void profileLoaded(const QString& profile);
108	void luminanceValueChanged(int value);
109
110public slots:
111	void testGamepad(int type);
112	void updateJoysticks();
113
114	// TODO: Move these to somewhere that makes sense
115	void suspendScreensaver();
116	void resumeScreensaver();
117	void setScreensaverSuspendable(bool);
118
119	void increaseLuminanceLevel();
120	void decreaseLuminanceLevel();
121	void setLuminanceLevel(int level);
122	void setLuminanceValue(uint8_t value);
123
124	void loadCamImage(const QString& path);
125	void setCamImage(const QImage& image);
126
127	void setCamera(const QByteArray& id);
128
129private slots:
130#ifdef BUILD_QT_MULTIMEDIA
131	void prepareCamSettings(QCamera::Status);
132#endif
133	void setupCam();
134	void teardownCam();
135
136private:
137	void postPendingEvent(GBAKey);
138	void clearPendingEvent(GBAKey);
139	bool hasPendingEvent(GBAKey) const;
140	void sendGamepadEvent(QEvent*);
141
142	struct InputControllerLux : GBALuminanceSource {
143		InputController* p;
144		uint8_t value;
145	} m_lux;
146	uint8_t m_luxValue;
147	int m_luxLevel;
148
149	struct InputControllerImage : mImageSource {
150		InputController* p;
151		QImage image;
152		QImage resizedImage;
153		bool outOfDate;
154		QMutex mutex;
155		unsigned w, h;
156	} m_image;
157
158#ifdef BUILD_QT_MULTIMEDIA
159	std::unique_ptr<QCamera> m_camera;
160	VideoDumper m_videoDumper;
161#endif
162
163	mInputMap m_inputMap;
164	ConfigController* m_config = nullptr;
165	int m_playerId;
166	QWidget* m_topLevel;
167	QWidget* m_focusParent;
168
169#ifdef BUILD_SDL
170	static int s_sdlInited;
171	static mSDLEvents s_sdlEvents;
172	mSDLPlayer m_sdlPlayer{};
173	bool m_playerAttached = false;
174#endif
175
176	QVector<int> m_deadzones;
177
178	QSet<int> m_activeButtons;
179	QSet<QPair<int, GamepadAxisEvent::Direction>> m_activeAxes;
180	QSet<QPair<int, GamepadHatEvent::Direction>> m_activeHats;
181	QTimer m_gamepadTimer{nullptr};
182
183	QSet<GBAKey> m_pendingEvents;
184};
185
186}