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(256, 256, QImage::Format_RGB32)
13 , m_audioContext(0)
14{
15 m_renderer = new GBAVideoSoftwareRenderer;
16 GBAVideoSoftwareRendererCreate(m_renderer);
17 m_renderer->outputBuffer = (color_t*) m_drawContext.bits();
18 m_renderer->outputBufferStride = m_drawContext.bytesPerLine() / 4;
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 GBAThreadEnd(&m_threadContext);
47 GBAThreadJoin(&m_threadContext);
48 delete m_renderer;
49}
50
51void GameController::loadGame(const QString& path) {
52 m_rom = new QFile(path);
53 if (!m_rom->open(QIODevice::ReadOnly)) {
54 delete m_rom;
55 m_rom = 0;
56 }
57
58 m_pauseAfterFrame = false;
59
60 m_threadContext.fd = m_rom->handle();
61 m_threadContext.fname = path.toLocal8Bit().constData();
62 GBAThreadStart(&m_threadContext);
63 emit gameStarted();
64}
65
66void GameController::setPaused(bool paused) {
67 if (paused == GBAThreadIsPaused(&m_threadContext)) {
68 return;
69 }
70 if (paused) {
71 GBAThreadPause(&m_threadContext);
72 } else {
73 GBAThreadUnpause(&m_threadContext);
74 }
75}
76
77void GameController::frameAdvance() {
78 m_pauseMutex.lock();
79 m_pauseAfterFrame = true;
80 setPaused(false);
81 m_pauseMutex.unlock();
82}
83
84void GameController::keyPressed(int key) {
85 int mappedKey = 1 << key;
86 m_threadContext.activeKeys |= mappedKey;
87}
88
89void GameController::keyReleased(int key) {
90 int mappedKey = 1 << key;
91 m_threadContext.activeKeys &= ~mappedKey;
92}