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