all repos — mgba @ 22ef0977dc138d57300aa9ea2fbd8ec94c10caa3

mGBA Game Boy Advance Emulator

src/platform/qt/Window.cpp (view raw)

  1#include "Window.h"
  2
  3#include <QFileDialog>
  4#include <QKeyEvent>
  5#include <QKeySequence>
  6#include <QMenuBar>
  7
  8using namespace QGBA;
  9
 10Window::Window(QWidget* parent) : QMainWindow(parent) {
 11	setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
 12	setMinimumSize(240, 160);
 13
 14	m_controller = new GameController(this);
 15	m_display = new Display();
 16	setCentralWidget(m_display);
 17	connect(m_controller, SIGNAL(audioDeviceAvailable(GBAAudio*)), this, SLOT(setupAudio(GBAAudio*)));
 18	connect(m_controller, SIGNAL(gameStarted(GBAThread*)), this, SLOT(gameStarted(GBAThread*)));
 19	connect(this, SIGNAL(startDrawing(const uint32_t*, GBAThread*)), m_display, SLOT(startDrawing(const uint32_t*, GBAThread*)), Qt::QueuedConnection);
 20	connect(this, SIGNAL(shutdown()), m_display, SLOT(stopDrawing()));
 21
 22	setupMenu(menuBar());
 23}
 24
 25GBAKey Window::mapKey(int qtKey) {
 26	switch (qtKey) {
 27	case Qt::Key_Z:
 28		return GBA_KEY_A;
 29		break;
 30	case Qt::Key_X:
 31		return GBA_KEY_B;
 32		break;
 33	case Qt::Key_A:
 34		return GBA_KEY_L;
 35		break;
 36	case Qt::Key_S:
 37		return GBA_KEY_R;
 38		break;
 39	case Qt::Key_Return:
 40		return GBA_KEY_START;
 41		break;
 42	case Qt::Key_Backspace:
 43		return GBA_KEY_SELECT;
 44		break;
 45	case Qt::Key_Up:
 46		return GBA_KEY_UP;
 47		break;
 48	case Qt::Key_Down:
 49		return GBA_KEY_DOWN;
 50		break;
 51	case Qt::Key_Left:
 52		return GBA_KEY_LEFT;
 53		break;
 54	case Qt::Key_Right:
 55		return GBA_KEY_RIGHT;
 56		break;
 57	default:
 58		return GBA_KEY_NONE;
 59	}
 60}
 61
 62void Window::selectROM() {
 63	QString filename = QFileDialog::getOpenFileName(this, tr("Select ROM"));
 64	if (!filename.isEmpty()) {
 65		m_controller->loadGame(filename);
 66	}
 67}
 68
 69void Window::keyPressEvent(QKeyEvent* event) {
 70	if (event->isAutoRepeat()) {
 71		QWidget::keyPressEvent(event);
 72		return;
 73	}
 74	GBAKey key = mapKey(event->key());
 75	if (key == GBA_KEY_NONE) {
 76		QWidget::keyPressEvent(event);
 77		return;
 78	}
 79	m_controller->keyPressed(key);
 80	event->accept();
 81}
 82
 83void Window::keyReleaseEvent(QKeyEvent* event) {
 84	if (event->isAutoRepeat()) {
 85		QWidget::keyReleaseEvent(event);
 86		return;
 87	}
 88	GBAKey key = mapKey(event->key());
 89	if (key == GBA_KEY_NONE) {
 90		QWidget::keyPressEvent(event);
 91		return;
 92	}
 93	m_controller->keyReleased(key);
 94	event->accept();
 95}
 96
 97void Window::closeEvent(QCloseEvent* event) {
 98	emit shutdown();
 99	QMainWindow::closeEvent(event);
100}
101
102void Window::gameStarted(GBAThread* context) {
103	emit startDrawing(m_controller->drawContext(), context);
104	foreach (QAction* action, m_gameActions) {
105		action->setDisabled(false);
106	}
107}
108
109void Window::setupAudio(GBAAudio* audio) {
110	AudioThread* thread = new AudioThread(this);
111	thread->setInput(audio);
112	thread->start(QThread::HighPriority);
113	connect(this, SIGNAL(shutdown()), thread, SLOT(shutdown()));
114}
115
116void Window::setupMenu(QMenuBar* menubar) {
117	menubar->clear();
118	QMenu* fileMenu = menubar->addMenu(tr("&File"));
119	fileMenu->addAction(tr("Load &ROM"), this, SLOT(selectROM()), QKeySequence::Open);
120
121	QMenu* emulationMenu = menubar->addMenu(tr("&Emulation"));
122	QAction* pause = new QAction(tr("&Pause"), 0);
123	pause->setChecked(false);
124	pause->setCheckable(true);
125	pause->setShortcut(tr("Ctrl+P"));
126	pause->setDisabled(true);
127	connect(pause, SIGNAL(triggered(bool)), m_controller, SLOT(setPaused(bool)));
128	m_gameActions.append(pause);
129	emulationMenu->addAction(pause);
130
131	QAction* frameAdvance = new QAction(tr("&Next frame"), 0);
132	frameAdvance->setShortcut(tr("Ctrl+N"));
133	frameAdvance->setDisabled(true);
134	connect(frameAdvance, SIGNAL(triggered()), m_controller, SLOT(frameAdvance()));
135	m_gameActions.append(frameAdvance);
136	emulationMenu->addAction(frameAdvance);
137}