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