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}