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}