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