src/platform/qt/GameController.cpp (view raw)
1#include "GameController.h"
2
3extern "C" {
4#include "gba.h"
5#include "renderers/video-software.h"
6}
7
8using namespace QGBA;
9
10GameController::GameController(QObject* parent)
11 : QObject(parent)
12 , m_drawContext(new uint32_t[256 * 256])
13 , m_audioContext(0)
14{
15 m_renderer = new GBAVideoSoftwareRenderer;
16 GBAVideoSoftwareRendererCreate(m_renderer);
17 m_renderer->outputBuffer = (color_t*) m_drawContext;
18 m_renderer->outputBufferStride = 256;
19 m_threadContext = {
20 .useDebugger = 0,
21 .frameskip = 0,
22 .biosFd = -1,
23 .renderer = &m_renderer->d,
24 .sync.videoFrameWait = 0,
25 .sync.audioWait = 1,
26 .userData = this,
27 .rewindBufferCapacity = 0
28 };
29 m_threadContext.startCallback = [] (GBAThread* context) {
30 GameController* controller = static_cast<GameController*>(context->userData);
31 controller->audioDeviceAvailable(&context->gba->audio);
32 };
33 m_threadContext.frameCallback = [] (GBAThread* context) {
34 GameController* controller = static_cast<GameController*>(context->userData);
35 controller->m_pauseMutex.lock();
36 if (controller->m_pauseAfterFrame) {
37 GBAThreadPause(context);
38 controller->m_pauseAfterFrame = false;
39 }
40 controller->m_pauseMutex.unlock();
41 controller->frameAvailable(controller->m_drawContext);
42 };
43}
44
45GameController::~GameController() {
46 if (GBAThreadIsPaused(&m_threadContext)) {
47 GBAThreadUnpause(&m_threadContext);
48 }
49 GBAThreadEnd(&m_threadContext);
50 GBAThreadJoin(&m_threadContext);
51 delete m_renderer;
52}
53
54void GameController::loadGame(const QString& path) {
55 m_rom = new QFile(path);
56 if (!m_rom->open(QIODevice::ReadOnly)) {
57 delete m_rom;
58 m_rom = 0;
59 }
60
61 m_pauseAfterFrame = false;
62
63 m_threadContext.fd = m_rom->handle();
64 m_threadContext.fname = path.toLocal8Bit().constData();
65 GBAThreadStart(&m_threadContext);
66 emit gameStarted(&m_threadContext);
67}
68
69void GameController::setPaused(bool paused) {
70 if (paused == GBAThreadIsPaused(&m_threadContext)) {
71 return;
72 }
73 if (paused) {
74 GBAThreadPause(&m_threadContext);
75 } else {
76 GBAThreadUnpause(&m_threadContext);
77 }
78}
79
80void GameController::frameAdvance() {
81 m_pauseMutex.lock();
82 m_pauseAfterFrame = true;
83 setPaused(false);
84 m_pauseMutex.unlock();
85}
86
87void GameController::keyPressed(int key) {
88 int mappedKey = 1 << key;
89 m_threadContext.activeKeys |= mappedKey;
90}
91
92void GameController::keyReleased(int key) {
93 int mappedKey = 1 << key;
94 m_threadContext.activeKeys &= ~mappedKey;
95}