all repos — mgba @ 2aac9da42b7514ddb3105becf46de8dee5c797f2

mGBA Game Boy Advance Emulator

src/platform/qt/CoreController.h (view raw)

  1/* Copyright (c) 2013-2017 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 <QByteArray>
  9#include <QFile>
 10#include <QList>
 11#include <QMutex>
 12#include <QObject>
 13#include <QSize>
 14
 15#include "VFileDevice.h"
 16
 17#include <functional>
 18#include <memory>
 19
 20#include <mgba/core/core.h>
 21#include <mgba/core/interface.h>
 22#include <mgba/core/thread.h>
 23#include <mgba/core/cache-set.h>
 24
 25#ifdef M_CORE_GB
 26#include <mgba/internal/gb/sio/printer.h>
 27#endif
 28#ifdef M_CORE_GBA
 29#include <mgba/internal/gba/sio/dolphin.h>
 30#endif
 31
 32#ifdef M_CORE_GBA
 33#include <mgba/gba/interface.h>
 34#endif
 35
 36struct mCore;
 37
 38namespace QGBA {
 39
 40class ConfigController;
 41class InputController;
 42class LogController;
 43class MultiplayerController;
 44class Override;
 45
 46class CoreController : public QObject {
 47Q_OBJECT
 48
 49public:
 50	static const bool VIDEO_SYNC = false;
 51	static const bool AUDIO_SYNC = true;
 52
 53	enum class Feature {
 54		OPENGL = mCORE_FEATURE_OPENGL,
 55	};
 56
 57	class Interrupter {
 58	public:
 59		Interrupter();
 60		Interrupter(CoreController*);
 61		Interrupter(std::shared_ptr<CoreController>);
 62		Interrupter(const Interrupter&);
 63		~Interrupter();
 64
 65		Interrupter& operator=(const Interrupter&);
 66
 67		void interrupt(CoreController*);
 68		void interrupt(std::shared_ptr<CoreController>);
 69		void resume();
 70
 71	private:
 72		void interrupt();
 73		void resume(CoreController*);
 74
 75		CoreController* m_parent;
 76	};
 77
 78	CoreController(mCore* core, QObject* parent = nullptr);
 79	~CoreController();
 80
 81	mCoreThread* thread() { return &m_threadContext; }
 82
 83	const color_t* drawContext();
 84	QImage getPixels();
 85
 86	bool isPaused();
 87	bool hasStarted();
 88
 89	QString title() { return m_dbTitle.isNull() ? m_internalTitle : m_dbTitle; }
 90	QString intenralTitle() { return m_internalTitle; }
 91	QString dbTitle() { return m_dbTitle; }
 92
 93	mPlatform platform() const;
 94	QSize screenDimensions() const;
 95	bool supportsFeature(Feature feature) const { return m_threadContext.core->supportsFeature(m_threadContext.core, static_cast<mCoreFeature>(feature)); }
 96	bool hardwareAccelerated() const { return m_hwaccel; }
 97
 98	void loadConfig(ConfigController*);
 99
100	mCheatDevice* cheatDevice() { return m_threadContext.core->cheatDevice(m_threadContext.core); }
101
102#ifdef USE_DEBUGGERS
103	mDebugger* debugger() { return m_threadContext.core->debugger; }
104	void setDebugger(mDebugger*);
105#endif
106
107	void setMultiplayerController(MultiplayerController*);
108	void clearMultiplayerController();
109	MultiplayerController* multiplayerController() { return m_multiplayer; }
110
111#ifdef M_CORE_GBA
112	bool isDolphinConnected() const { return !SOCKET_FAILED(m_dolphin.data); }
113#endif
114
115	mCacheSet* graphicCaches();
116	int stateSlot() const { return m_stateSlot; }
117
118	void setOverride(std::unique_ptr<Override> override);
119	Override* override() { return m_override.get(); }
120
121	void setInputController(InputController*);
122	void setLogger(LogController*);
123
124	bool audioSync() const { return m_audioSync; }
125	bool videoSync() const { return m_videoSync; }
126
127	void addFrameAction(std::function<void ()> callback);
128
129public slots:
130	void start();
131	void stop();
132	void reset();
133	void setPaused(bool paused);
134	void frameAdvance();
135	void setSync(bool enable);
136
137	void setRewinding(bool);
138	void rewind(int count = 0);
139
140	void setFastForward(bool);
141	void forceFastForward(bool);
142
143	void loadState(int slot = 0);
144	void loadState(const QString& path, int flags = -1);
145	void loadState(QIODevice* iodev, int flags = -1);
146	void saveState(int slot = 0);
147	void saveState(const QString& path, int flags = -1);
148	void saveState(QIODevice* iodev, int flags = -1);
149	void loadBackupState();
150	void saveBackupState();
151
152	void loadSave(const QString&, bool temporary);
153	void loadPatch(const QString&);
154	void scanCard(const QString&);
155	void replaceGame(const QString&);
156	void yankPak();
157
158	void addKey(int key);
159	void clearKey(int key);
160	void setAutofire(int key, bool enable);
161
162#ifdef USE_PNG
163	void screenshot();
164#endif
165
166	void setRealTime();
167	void setFixedTime(const QDateTime& time);
168	void setFakeEpoch(const QDateTime& time);
169
170	void importSharkport(const QString& path);
171	void exportSharkport(const QString& path);
172
173#ifdef M_CORE_GB
174	void attachPrinter();
175	void detachPrinter();
176	void endPrint();
177#endif
178
179#ifdef M_CORE_GBA
180	void attachBattleChipGate();
181	void detachBattleChipGate();
182	void setBattleChipId(uint16_t id);
183	void setBattleChipFlavor(int flavor);
184
185	bool attachDolphin(const Address& address);
186	void detachDolphin();
187#endif
188
189	void setAVStream(mAVStream*);
190	void clearAVStream();
191
192	void clearOverride();
193
194	void startVideoLog(const QString& path, bool compression = true);
195	void startVideoLog(VFile* vf, bool compression = true);
196	void endVideoLog(bool closeVf = true);
197
198	void setFramebufferHandle(int fb);
199
200signals:
201	void started();
202	void paused();
203	void unpaused();
204	void stopping();
205	void crashed(const QString& errorMessage);
206	void failed();
207	void frameAvailable();
208	void didReset();
209	void stateLoaded();
210	void rewound();
211
212	void rewindChanged(bool);
213	void fastForwardChanged(bool);
214
215	void unimplementedBiosCall(int);
216	void statusPosted(const QString& message);
217	void logPosted(int level, int category, const QString& log);
218
219	void imagePrinted(const QImage&);
220
221private:
222	void updateKeys();
223	int updateAutofire();
224	void finishFrame();
225
226	void updateFastForward();
227
228	void updateROMInfo();
229
230	mCoreThread m_threadContext{};
231
232	bool m_patched = false;
233
234	uint32_t m_crc32;
235	QString m_internalTitle;
236	QString m_dbTitle;
237
238	QByteArray m_activeBuffer;
239	QByteArray m_completeBuffer;
240	bool m_hwaccel = false;
241
242	std::unique_ptr<mCacheSet> m_cacheSet;
243	std::unique_ptr<Override> m_override;
244
245	QList<std::function<void()>> m_resetActions;
246	QList<std::function<void()>> m_frameActions;
247	QMutex m_actionMutex{QMutex::Recursive};
248	int m_moreFrames = -1;
249	QMutex m_bufferMutex;
250
251	int m_activeKeys = 0;
252	bool m_autofire[32] = {};
253	int m_autofireStatus[32] = {};
254	int m_autofireThreshold = 1;
255
256	VFileDevice m_backupLoadState;
257	QByteArray m_backupSaveState{nullptr};
258	int m_stateSlot = 1;
259	QString m_statePath;
260	VFile* m_stateVf;
261	int m_loadStateFlags;
262	int m_saveStateFlags;
263
264	bool m_audioSync = AUDIO_SYNC;
265	bool m_videoSync = VIDEO_SYNC;
266
267	bool m_autosave;
268	bool m_autoload;
269	int m_autosaveCounter = 0;
270
271	int m_fastForward = false;
272	int m_fastForwardForced = false;
273	int m_fastForwardVolume = -1;
274	int m_fastForwardMute = -1;
275	float m_fastForwardRatio = -1.f;
276	float m_fastForwardHeldRatio = -1.f;
277	float m_fpsTarget;
278
279	InputController* m_inputController = nullptr;
280	LogController* m_log = nullptr;
281	MultiplayerController* m_multiplayer = nullptr;
282#ifdef M_CORE_GBA
283	GBASIODolphin m_dolphin;
284#endif
285
286	mVideoLogContext* m_vl = nullptr;
287	VFile* m_vlVf = nullptr;
288
289#ifdef M_CORE_GB
290	struct QGBPrinter {
291		GBPrinter d;
292		CoreController* parent;
293	} m_printer;
294#endif
295
296#ifdef M_CORE_GBA
297	GBASIOBattlechipGate m_battlechip;
298	QByteArray m_eReaderData;
299#endif
300};
301
302}