all repos — mgba @ 2f98f542e5cb5b2018eb9961e62b41b96912c6e7

mGBA Game Boy Advance Emulator

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}