src/platform/qt/GameController.h (view raw)
1/* Copyright (c) 2013-2015 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#ifndef QGBA_GAME_CONTROLLER
7#define QGBA_GAME_CONTROLLER
8
9#include <QAtomicInt>
10#include <QFile>
11#include <QImage>
12#include <QObject>
13#include <QString>
14#include <QTimer>
15
16#include <memory>
17#include <functional>
18
19#include <mgba/core/core.h>
20#include <mgba/core/thread.h>
21#include <mgba/gba/interface.h>
22#include <mgba/internal/gba/input.h>
23#ifdef BUILD_SDL
24#include "platform/sdl/sdl-events.h"
25#endif
26
27struct Configuration;
28struct GBAAudio;
29struct mCoreConfig;
30struct mDebugger;
31struct mTileCache;
32struct mVideoLogContext;
33
34namespace QGBA {
35
36class AudioProcessor;
37class InputController;
38class MultiplayerController;
39class Override;
40
41class GameController : public QObject {
42Q_OBJECT
43
44public:
45 static const bool VIDEO_SYNC = false;
46 static const bool AUDIO_SYNC = true;
47
48 class Interrupter {
49 public:
50 Interrupter(GameController*, bool fromThread = false);
51 ~Interrupter();
52
53 private:
54 GameController* m_parent;
55 bool m_fromThread;
56 };
57
58 GameController(QObject* parent = nullptr);
59 ~GameController();
60
61 const uint32_t* drawContext() const { return m_drawContext; }
62 mCoreThread* thread() { return &m_threadContext; }
63 mCheatDevice* cheatDevice() { return m_threadContext.core ? m_threadContext.core->cheatDevice(m_threadContext.core) : nullptr; }
64
65 void threadInterrupt();
66 void threadContinue();
67
68 bool isPaused();
69 bool isLoaded() { return m_gameOpen && mCoreThreadIsActive(&m_threadContext); }
70 mPlatform platform() const;
71
72 bool audioSync() const { return m_audioSync; }
73 bool videoSync() const { return m_videoSync; }
74 QSize screenDimensions() const;
75 QPair<unsigned, unsigned> frameRate() const;
76
77 void setInputController(InputController* controller) { m_inputController = controller; }
78
79 void setMultiplayerController(MultiplayerController* controller);
80 MultiplayerController* multiplayerController() { return m_multiplayer; }
81 void clearMultiplayerController();
82
83 void setOverride(Override* override);
84 Override* override() { return m_override; }
85 void clearOverride();
86
87 void setConfig(const mCoreConfig*);
88
89 int stateSlot() const { return m_stateSlot; }
90
91#ifdef USE_DEBUGGERS
92 mDebugger* debugger();
93 void setDebugger(mDebugger*);
94#endif
95
96 std::shared_ptr<mTileCache> tileCache();
97
98signals:
99 void frameAvailable(const uint32_t*);
100 void gameStarted(mCoreThread*, const QString& fname);
101 void gameStopped(mCoreThread*);
102 void gamePaused(mCoreThread*);
103 void gameUnpaused(mCoreThread*);
104 void gameCrashed(const QString& errorMessage);
105 void gameFailed();
106 void stateLoaded(mCoreThread*);
107 void rewound(mCoreThread*);
108 void unimplementedBiosCall(int);
109
110 void luminanceValueChanged(int);
111
112 void statusPosted(const QString& message);
113 void postLog(int level, int category, const QString& log);
114
115public slots:
116 void loadGame(const QString& path);
117 void loadGame(VFile* vf, const QString& path, const QString& base);
118 void loadBIOS(int platform, const QString& path);
119 void loadSave(const QString& path, bool temporary = true);
120 void yankPak();
121 void replaceGame(const QString& path);
122 void setUseBIOS(bool);
123 void loadPatch(const QString& path);
124 void importSharkport(const QString& path);
125 void exportSharkport(const QString& path);
126 void bootBIOS();
127 void closeGame();
128 void setPaused(bool paused);
129 void reset();
130 void frameAdvance();
131 void setRewind(bool enable, int capacity, bool rewindSave);
132 void rewind(int states = 0);
133 void startRewinding();
134 void stopRewinding();
135 void keyPressed(int key);
136 void keyReleased(int key);
137 void cursorLocation(int x, int y);
138 void cursorDown(bool);
139 void clearKeys();
140 void setAutofire(int key, bool enable);
141 void setAudioBufferSamples(int samples);
142 void setAudioSampleRate(unsigned rate);
143 void setAudioChannelEnabled(int channel, bool enable = true);
144 void startAudio();
145 void setVideoLayerEnabled(int layer, bool enable = true);
146 void setFPSTarget(float fps);
147 void loadState(int slot = 0);
148 void saveState(int slot = 0);
149 void loadBackupState();
150 void saveBackupState();
151 void setTurbo(bool, bool forced = true);
152 void setTurboSpeed(float ratio);
153 void setSync(bool);
154 void setAudioSync(bool);
155 void setVideoSync(bool);
156 void setAVStream(mAVStream*);
157 void clearAVStream();
158 void reloadAudioDriver();
159 void setSaveStateExtdata(int flags);
160 void setLoadStateExtdata(int flags);
161 void setPreload(bool);
162
163#ifdef USE_PNG
164 void screenshot();
165#endif
166
167 void setLuminanceValue(uint8_t value);
168 uint8_t luminanceValue() const { return m_luxValue; }
169 void setLuminanceLevel(int level);
170 void increaseLuminanceLevel() { setLuminanceLevel(m_luxLevel + 1); }
171 void decreaseLuminanceLevel() { setLuminanceLevel(m_luxLevel - 1); }
172
173 void setRealTime();
174 void setFixedTime(const QDateTime& time);
175 void setFakeEpoch(const QDateTime& time);
176
177 void setLogLevel(int);
178 void enableLogLevel(int);
179 void disableLogLevel(int);
180
181 void startVideoLog(const QString& path);
182 void endVideoLog();
183
184private slots:
185 void openGame(bool bios = false);
186 void crashGame(const QString& crashMessage);
187 void cleanGame();
188
189 void pollEvents();
190 void updateAutofire();
191
192private:
193 void updateKeys();
194 void redoSamples(int samples);
195 void enableTurbo();
196
197 uint32_t* m_drawContext = nullptr;
198 uint32_t* m_frontBuffer = nullptr;
199 mCoreThread m_threadContext{};
200 const mCoreConfig* m_config;
201 mCheatDevice* m_cheatDevice;
202 int m_activeKeys = 0;
203 int m_activeButtons = 0;
204 int m_inactiveKeys = 0;
205 int m_logLevels = 0;
206
207 bool m_gameOpen = false;
208
209 QString m_fname;
210 QString m_fsub;
211 VFile* m_vf = nullptr;
212 QString m_bios;
213 bool m_useBios = false;
214 QString m_patch;
215 Override* m_override = nullptr;
216
217 AudioProcessor* m_audioProcessor;
218
219 QAtomicInt m_pauseAfterFrame{false};
220 QList<std::function<void ()>> m_resetActions;
221
222 bool m_sync = true;
223 bool m_videoSync = VIDEO_SYNC;
224 bool m_audioSync = AUDIO_SYNC;
225 float m_fpsTarget = -1;
226 bool m_turbo = false;
227 bool m_turboForced = false;
228 float m_turboSpeed = -1;
229 bool m_wasPaused = false;
230
231 std::shared_ptr<mTileCache> m_tileCache;
232
233 QList<bool> m_audioChannels;
234 QList<bool> m_videoLayers;
235
236 bool m_autofire[GBA_KEY_MAX] = {};
237 int m_autofireStatus[GBA_KEY_MAX] = {};
238
239 int m_stateSlot = 1;
240 struct VFile* m_backupLoadState = nullptr;
241 QByteArray m_backupSaveState{nullptr};
242 int m_saveStateFlags;
243 int m_loadStateFlags;
244
245 bool m_preload = false;
246
247 InputController* m_inputController = nullptr;
248 MultiplayerController* m_multiplayer = nullptr;
249
250 mAVStream* m_stream = nullptr;
251
252 mVideoLogContext* m_vl = nullptr;
253 VFile* m_vlVf = nullptr;
254
255 struct GameControllerLux : GBALuminanceSource {
256 GameController* p;
257 uint8_t value;
258 } m_lux;
259 uint8_t m_luxValue;
260 int m_luxLevel;
261};
262
263}
264
265#endif