all repos — mgba @ 000b49e45b30ec9c856b7b2e8cf8baee21daa56d

mGBA Game Boy Advance Emulator

src/platform/qt/GameController.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_GAME_CONTROLLER
  7#define QGBA_GAME_CONTROLLER
  8
  9#include <QAtomicInt>
 10#include <QFile>
 11#include <QImage>
 12#include <QObject>
 13#include <QString>
 14#include <QTimer>
 15
 16#include <memory>
 17#include <functional>
 18
 19#include <mgba/core/core.h>
 20#include <mgba/core/thread.h>
 21#include <mgba/gba/interface.h>
 22#include <mgba/internal/gba/input.h>
 23#ifdef BUILD_SDL
 24#include "platform/sdl/sdl-events.h"
 25#endif
 26
 27struct Configuration;
 28struct GBAAudio;
 29struct mCoreConfig;
 30struct mDebugger;
 31struct mTileCache;
 32struct mVideoLogContext;
 33
 34namespace QGBA {
 35
 36class AudioProcessor;
 37class InputController;
 38class MultiplayerController;
 39class Override;
 40
 41class GameController : public QObject {
 42Q_OBJECT
 43
 44public:
 45	static const bool VIDEO_SYNC = false;
 46	static const bool AUDIO_SYNC = true;
 47
 48	class Interrupter {
 49	public:
 50		Interrupter(GameController*, bool fromThread = false);
 51		~Interrupter();
 52
 53	private:
 54		GameController* m_parent;
 55		bool m_fromThread;
 56	};
 57
 58	GameController(QObject* parent = nullptr);
 59	~GameController();
 60
 61	const uint32_t* drawContext() const { return m_drawContext; }
 62	mCoreThread* thread() { return &m_threadContext; }
 63	mCheatDevice* cheatDevice() { return m_threadContext.core ? m_threadContext.core->cheatDevice(m_threadContext.core) : nullptr; }
 64
 65	void threadInterrupt();
 66	void threadContinue();
 67
 68	bool isPaused();
 69	bool isLoaded() { return m_gameOpen && mCoreThreadIsActive(&m_threadContext); }
 70	mPlatform platform() const;
 71
 72	bool audioSync() const { return m_audioSync; }
 73	bool videoSync() const { return m_videoSync; }
 74	QSize screenDimensions() const;
 75	QPair<unsigned, unsigned> frameRate() const;
 76
 77	void setInputController(InputController* controller) { m_inputController = controller; }
 78
 79	void setMultiplayerController(MultiplayerController* controller);
 80	MultiplayerController* multiplayerController() { return m_multiplayer; }
 81	void clearMultiplayerController();
 82
 83	void setOverride(Override* override);
 84	Override* override() { return m_override; }
 85	void clearOverride();
 86
 87	void setConfig(const mCoreConfig*);
 88
 89	int stateSlot() const { return m_stateSlot; }
 90
 91#ifdef USE_DEBUGGERS
 92	mDebugger* debugger();
 93	void setDebugger(mDebugger*);
 94#endif
 95
 96	std::shared_ptr<mTileCache> tileCache();
 97
 98signals:
 99	void frameAvailable(const uint32_t*);
100	void gameStarted(mCoreThread*, const QString& fname);
101	void gameStopped(mCoreThread*);
102	void gamePaused(mCoreThread*);
103	void gameUnpaused(mCoreThread*);
104	void gameCrashed(const QString& errorMessage);
105	void gameFailed();
106	void stateLoaded(mCoreThread*);
107	void rewound(mCoreThread*);
108	void unimplementedBiosCall(int);
109
110	void luminanceValueChanged(int);
111
112	void statusPosted(const QString& message);
113	void postLog(int level, int category, const QString& log);
114
115public slots:
116	void loadGame(const QString& path);
117	void loadGame(VFile* vf, const QString& path, const QString& base);
118	void loadBIOS(int platform, const QString& path);
119	void loadSave(const QString& path, bool temporary = true);
120	void yankPak();
121	void replaceGame(const QString& path);
122	void setUseBIOS(bool);
123	void loadPatch(const QString& path);
124	void importSharkport(const QString& path);
125	void exportSharkport(const QString& path);
126	void bootBIOS();
127	void closeGame();
128	void setPaused(bool paused);
129	void reset();
130	void frameAdvance();
131	void setRewind(bool enable, int capacity, bool rewindSave);
132	void rewind(int states = 0);
133	void startRewinding();
134	void stopRewinding();
135	void keyPressed(int key);
136	void keyReleased(int key);
137	void cursorLocation(int x, int y);
138	void cursorDown(bool);
139	void clearKeys();
140	void setAutofire(int key, bool enable);
141	void setAudioBufferSamples(int samples);
142	void setAudioSampleRate(unsigned rate);
143	void setAudioChannelEnabled(int channel, bool enable = true);
144	void startAudio();
145	void setVideoLayerEnabled(int layer, bool enable = true);
146	void setFPSTarget(float fps);
147	void loadState(int slot = 0);
148	void saveState(int slot = 0);
149	void loadBackupState();
150	void saveBackupState();
151	void setTurbo(bool, bool forced = true);
152	void setTurboSpeed(float ratio);
153	void setSync(bool);
154	void setAudioSync(bool);
155	void setVideoSync(bool);
156	void setAVStream(mAVStream*);
157	void clearAVStream();
158	void reloadAudioDriver();
159	void setSaveStateExtdata(int flags);
160	void setLoadStateExtdata(int flags);
161	void setPreload(bool);
162
163#ifdef USE_PNG
164	void screenshot();
165#endif
166
167	void setLuminanceValue(uint8_t value);
168	uint8_t luminanceValue() const { return m_luxValue; }
169	void setLuminanceLevel(int level);
170	void increaseLuminanceLevel() { setLuminanceLevel(m_luxLevel + 1); }
171	void decreaseLuminanceLevel() { setLuminanceLevel(m_luxLevel - 1); }
172
173	void setRealTime();
174	void setFixedTime(const QDateTime& time);
175	void setFakeEpoch(const QDateTime& time);
176
177	void setLogLevel(int);
178	void enableLogLevel(int);
179	void disableLogLevel(int);
180
181	void startVideoLog(const QString& path);
182	void endVideoLog();
183
184private slots:
185	void openGame(bool bios = false);
186	void crashGame(const QString& crashMessage);
187	void cleanGame();
188
189	void pollEvents();
190	void updateAutofire();
191
192private:
193	void updateKeys();
194	void redoSamples(int samples);
195	void enableTurbo();
196
197	uint32_t* m_drawContext = nullptr;
198	uint32_t* m_frontBuffer = nullptr;
199	mCoreThread m_threadContext{};
200	const mCoreConfig* m_config;
201	mCheatDevice* m_cheatDevice;
202	int m_activeKeys = 0;
203	int m_activeButtons = 0;
204	int m_inactiveKeys = 0;
205	int m_logLevels = 0;
206
207	bool m_gameOpen = false;
208
209	QString m_fname;
210	QString m_fsub;
211	VFile* m_vf = nullptr;
212	QString m_bios;
213	bool m_useBios = false;
214	QString m_patch;
215	Override* m_override = nullptr;
216
217	AudioProcessor* m_audioProcessor;
218
219	QAtomicInt m_pauseAfterFrame{false};
220	QList<std::function<void ()>> m_resetActions;
221
222	bool m_sync = true;
223	bool m_videoSync = VIDEO_SYNC;
224	bool m_audioSync = AUDIO_SYNC;
225	float m_fpsTarget = -1;
226	bool m_turbo = false;
227	bool m_turboForced = false;
228	float m_turboSpeed = -1;
229	bool m_wasPaused = false;
230
231	std::shared_ptr<mTileCache> m_tileCache;
232
233	QList<bool> m_audioChannels;
234	QList<bool> m_videoLayers;
235
236	bool m_autofire[GBA_KEY_MAX] = {};
237	int m_autofireStatus[GBA_KEY_MAX] = {};
238
239	int m_stateSlot = 1;
240	struct VFile* m_backupLoadState = nullptr;
241	QByteArray m_backupSaveState{nullptr};
242	int m_saveStateFlags;
243	int m_loadStateFlags;
244
245	bool m_preload = false;
246
247	InputController* m_inputController = nullptr;
248	MultiplayerController* m_multiplayer = nullptr;
249
250	mAVStream* m_stream = nullptr;
251
252	mVideoLogContext* m_vl = nullptr;
253	VFile* m_vlVf = nullptr;
254
255	struct GameControllerLux : GBALuminanceSource {
256		GameController* p;
257		uint8_t value;
258	} m_lux;
259	uint8_t m_luxValue;
260	int m_luxLevel;
261};
262
263}
264
265#endif