src/platform/qt/GBAApp.cpp (view raw)
1/* Copyright (c) 2013-2014 Jeffrey Pfau
2 *
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6#include "GBAApp.h"
7
8#include "AudioProcessor.h"
9#include "Display.h"
10#include "GameController.h"
11#include "Window.h"
12
13#include <QFileInfo>
14#include <QFileOpenEvent>
15#include <QIcon>
16
17extern "C" {
18#include "platform/commandline.h"
19#include "util/socket.h"
20}
21
22using namespace QGBA;
23
24static GBAApp* g_app = nullptr;
25
26GBAApp::GBAApp(int& argc, char* argv[])
27 : QApplication(argc, argv)
28 , m_windows{}
29{
30 g_app = this;
31
32#ifdef BUILD_SDL
33 SDL_Init(SDL_INIT_NOPARACHUTE);
34#endif
35
36 setWindowIcon(QIcon(":/res/mgba-1024.png"));
37
38 SocketSubsystemInit();
39 qRegisterMetaType<const uint32_t*>("const uint32_t*");
40
41 QApplication::setApplicationName(projectName);
42 QApplication::setApplicationVersion(projectVersion);
43
44 Window* w = new Window(&m_configController);
45 connect(w, &Window::destroyed, [this]() {
46 m_windows[0] = nullptr;
47 });
48 m_windows[0] = w;
49
50#ifndef Q_OS_MAC
51 w->show();
52#endif
53
54 GBAArguments args;
55 if (m_configController.parseArguments(&args, argc, argv)) {
56 w->argumentsPassed(&args);
57 } else {
58 w->loadConfig();
59 }
60 freeArguments(&args);
61
62 Display::setDriver(static_cast<Display::Driver>(m_configController.getQtOption("videoDriver").toInt()));
63 AudioProcessor::setDriver(static_cast<AudioProcessor::Driver>(m_configController.getQtOption("audioDriver").toInt()));
64 w->controller()->reloadAudioDriver();
65
66 w->controller()->setMultiplayerController(&m_multiplayer);
67#ifdef Q_OS_MAC
68 w->show();
69#endif
70}
71
72bool GBAApp::event(QEvent* event) {
73 if (event->type() == QEvent::FileOpen) {
74 m_windows[0]->controller()->loadGame(static_cast<QFileOpenEvent*>(event)->file());
75 return true;
76 }
77 return QApplication::event(event);
78}
79
80Window* GBAApp::newWindow() {
81 if (m_multiplayer.attached() >= MAX_GBAS) {
82 return nullptr;
83 }
84 Window* w = new Window(&m_configController, m_multiplayer.attached());
85 int windowId = m_multiplayer.attached();
86 connect(w, &Window::destroyed, [this, windowId]() {
87 m_windows[windowId] = nullptr;
88 });
89 m_windows[windowId] = w;
90 w->setAttribute(Qt::WA_DeleteOnClose);
91#ifndef Q_OS_MAC
92 w->show();
93#endif
94 w->loadConfig();
95 w->controller()->setMultiplayerController(&m_multiplayer);
96#ifdef Q_OS_MAC
97 w->show();
98#endif
99 return w;
100}
101
102GBAApp* GBAApp::app() {
103 return g_app;
104}
105
106void GBAApp::interruptAll() {
107 for (int i = 0; i < MAX_GBAS; ++i) {
108 if (!m_windows[i] || !m_windows[i]->controller()->isLoaded()) {
109 continue;
110 }
111 m_windows[i]->controller()->threadInterrupt();
112 }
113}
114
115void GBAApp::continueAll() {
116 for (int i = 0; i < MAX_GBAS; ++i) {
117 if (!m_windows[i] || !m_windows[i]->controller()->isLoaded()) {
118 continue;
119 }
120 m_windows[i]->controller()->threadContinue();
121 }
122}
123
124QString GBAApp::getOpenFileName(QWidget* owner, const QString& title, const QString& filter) {
125 interruptAll();
126 QString filename = QFileDialog::getOpenFileName(owner, title, m_configController.getQtOption("lastDirectory").toString(), filter);
127 continueAll();
128 if (!filename.isEmpty()) {
129 m_configController.setQtOption("lastDirectory", QFileInfo(filename).dir().path());
130 }
131 return filename;
132}
133
134QString GBAApp::getSaveFileName(QWidget* owner, const QString& title, const QString& filter) {
135 interruptAll();
136 QString filename = QFileDialog::getSaveFileName(owner, title, m_configController.getQtOption("lastDirectory").toString(), filter);
137 continueAll();
138 if (!filename.isEmpty()) {
139 m_configController.setQtOption("lastDirectory", QFileInfo(filename).dir().path());
140 }
141 return filename;
142}
143
144QFileDialog* GBAApp::getOpenFileDialog(QWidget* owner, const QString& title, const QString& filter) {
145 FileDialog* dialog = new FileDialog(this, owner, title, filter);
146 dialog->setAcceptMode(QFileDialog::AcceptOpen);
147 return dialog;
148}
149
150QFileDialog* GBAApp::getSaveFileDialog(QWidget* owner, const QString& title, const QString& filter) {
151 FileDialog* dialog = new FileDialog(this, owner, title, filter);
152 dialog->setAcceptMode(QFileDialog::AcceptSave);
153 return dialog;
154}
155
156GBAApp::FileDialog::FileDialog(GBAApp* app, QWidget* parent, const QString& caption, const QString& filter)
157 : QFileDialog(parent, caption, app->m_configController.getQtOption("lastDirectory").toString(), filter)
158 , m_app(app)
159{
160}
161
162int GBAApp::FileDialog::exec() {
163 m_app->interruptAll();
164 bool didAccept = QFileDialog::exec() == QDialog::Accepted;
165 QStringList filenames = selectedFiles();
166 if (!filenames.isEmpty()) {
167 m_app->m_configController.setQtOption("lastDirectory", QFileInfo(filenames[0]).dir().path());
168 }
169 m_app->continueAll();
170 return didAccept;
171}