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