all repos — mgba @ aec8ef45ef1105b5784aeb8e9a6e73f498f02d0f

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