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
76 void setInputController(InputController* controller) { m_inputController = controller; }
77
78 void setMultiplayerController(MultiplayerController* controller);
79 MultiplayerController* multiplayerController() { return m_multiplayer; }
80 void clearMultiplayerController();
81
82 void setOverride(Override* override);
83 Override* override() { return m_override; }
84 void clearOverride();
85
86 void setConfig(const mCoreConfig*);
87
88 int stateSlot() const { return m_stateSlot; }
89
90#ifdef USE_DEBUGGERS
91 mDebugger* debugger();
92 void setDebugger(mDebugger*);
93#endif
94
95 std::shared_ptr<mTileCache> tileCache();
96
97signals:
98 void frameAvailable(const uint32_t*);
99 void gameStarted(mCoreThread*, const QString& fname);
100 void gameStopped(mCoreThread*);
101 void gamePaused(mCoreThread*);
102 void gameUnpaused(mCoreThread*);
103 void gameCrashed(const QString& errorMessage);
104 void gameFailed();
105 void stateLoaded(mCoreThread*);
106 void rewound(mCoreThread*);
107 void unimplementedBiosCall(int);
108
109 void luminanceValueChanged(int);
110
111 void statusPosted(const QString& message);
112 void postLog(int level, int category, const QString& log);
113
114public slots:
115 void loadGame(const QString& path);
116 void loadGame(VFile* vf, const QString& path, const QString& base);
117 void loadBIOS(int platform, const QString& path);
118 void loadSave(const QString& path, bool temporary = true);
119 void yankPak();
120 void replaceGame(const QString& path);
121 void setUseBIOS(bool);
122 void loadPatch(const QString& path);
123 void importSharkport(const QString& path);
124 void exportSharkport(const QString& path);
125 void bootBIOS();
126 void closeGame();
127 void setPaused(bool paused);
128 void reset();
129 void frameAdvance();
130 void setRewind(bool enable, int capacity, bool rewindSave);
131 void rewind(int states = 0);
132 void startRewinding();
133 void stopRewinding();
134 void keyPressed(int key);
135 void keyReleased(int key);
136 void clearKeys();
137 void setAutofire(int key, bool enable);
138 void setAudioBufferSamples(int samples);
139 void setAudioSampleRate(unsigned rate);
140 void setAudioChannelEnabled(int channel, bool enable = true);
141 void startAudio();
142 void setVideoLayerEnabled(int layer, bool enable = true);
143 void setFPSTarget(float fps);
144 void loadState(int slot = 0);
145 void saveState(int slot = 0);
146 void loadBackupState();
147 void saveBackupState();
148 void setTurbo(bool, bool forced = true);
149 void setTurboSpeed(float ratio);
150 void setSync(bool);
151 void setAudioSync(bool);
152 void setVideoSync(bool);
153 void setAVStream(mAVStream*);
154 void clearAVStream();
155 void reloadAudioDriver();
156 void setSaveStateExtdata(int flags);
157 void setLoadStateExtdata(int flags);
158 void setPreload(bool);
159
160#ifdef USE_PNG
161 void screenshot();
162#endif
163
164 void setLuminanceValue(uint8_t value);
165 uint8_t luminanceValue() const { return m_luxValue; }
166 void setLuminanceLevel(int level);
167 void increaseLuminanceLevel() { setLuminanceLevel(m_luxLevel + 1); }
168 void decreaseLuminanceLevel() { setLuminanceLevel(m_luxLevel - 1); }
169
170 void setRealTime();
171 void setFixedTime(const QDateTime& time);
172 void setFakeEpoch(const QDateTime& time);
173
174 void setLogLevel(int);
175 void enableLogLevel(int);
176 void disableLogLevel(int);
177
178 void startVideoLog(const QString& path);
179 void endVideoLog();
180
181private slots:
182 void openGame(bool bios = false);
183 void crashGame(const QString& crashMessage);
184 void cleanGame();
185
186 void pollEvents();
187 void updateAutofire();
188
189private:
190 void updateKeys();
191 void redoSamples(int samples);
192 void enableTurbo();
193
194 uint32_t* m_drawContext = nullptr;
195 uint32_t* m_frontBuffer = nullptr;
196 mCoreThread m_threadContext{};
197 const mCoreConfig* m_config;
198 mCheatDevice* m_cheatDevice;
199 int m_activeKeys = 0;
200 int m_activeButtons = 0;
201 int m_inactiveKeys = 0;
202 int m_logLevels = 0;
203
204 bool m_gameOpen = false;
205
206 QString m_fname;
207 QString m_fsub;
208 VFile* m_vf = nullptr;
209 QString m_bios;
210 bool m_useBios = false;
211 QString m_patch;
212 Override* m_override = nullptr;
213
214 AudioProcessor* m_audioProcessor;
215
216 QAtomicInt m_pauseAfterFrame{false};
217 QList<std::function<void ()>> m_resetActions;
218
219 bool m_sync = true;
220 bool m_videoSync = VIDEO_SYNC;
221 bool m_audioSync = AUDIO_SYNC;
222 float m_fpsTarget = -1;
223 bool m_turbo = false;
224 bool m_turboForced = false;
225 float m_turboSpeed = -1;
226 bool m_wasPaused = false;
227
228 std::shared_ptr<mTileCache> m_tileCache;
229
230 QList<bool> m_audioChannels;
231 QList<bool> m_videoLayers;
232
233 bool m_autofire[GBA_KEY_MAX] = {};
234 int m_autofireStatus[GBA_KEY_MAX] = {};
235
236 int m_stateSlot = 1;
237 struct VFile* m_backupLoadState = nullptr;
238 QByteArray m_backupSaveState{nullptr};
239 int m_saveStateFlags;
240 int m_loadStateFlags;
241
242 bool m_preload = false;
243
244 InputController* m_inputController = nullptr;
245 MultiplayerController* m_multiplayer = nullptr;
246
247 mAVStream* m_stream = nullptr;
248
249 mVideoLogContext* m_vl = nullptr;
250 VFile* m_vlVf = nullptr;
251
252 struct GameControllerLux : GBALuminanceSource {
253 GameController* p;
254 uint8_t value;
255 } m_lux;
256 uint8_t m_luxValue;
257 int m_luxLevel;
258};
259
260}
261
262#endif