all repos — mgba @ 22ef0977dc138d57300aa9ea2fbd8ec94c10caa3

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(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}