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}