all repos — mgba @ 6d8a34a6dcb5c819a978933bf47f3396ab6a7d3a

mGBA Game Boy Advance Emulator

src/platform/qt/SettingsView.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 "SettingsView.h"
  7
  8#include "AudioProcessor.h"
  9#include "ConfigController.h"
 10#include "Display.h"
 11#include "GBAApp.h"
 12#include "GBAKeyEditor.h"
 13#include "InputController.h"
 14#include "ShortcutView.h"
 15
 16using namespace QGBA;
 17
 18SettingsView::SettingsView(ConfigController* controller, InputController* inputController, ShortcutController* shortcutController, QWidget* parent)
 19	: QDialog(parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint)
 20	, m_controller(controller)
 21{
 22	m_ui.setupUi(this);
 23
 24	loadSetting("bios", m_ui.bios);
 25	loadSetting("useBios", m_ui.useBios);
 26	loadSetting("skipBios", m_ui.skipBios);
 27	loadSetting("audioBuffers", m_ui.audioBufferSize);
 28	loadSetting("sampleRate", m_ui.sampleRate);
 29	loadSetting("videoSync", m_ui.videoSync);
 30	loadSetting("audioSync", m_ui.audioSync);
 31	loadSetting("frameskip", m_ui.frameskip);
 32	loadSetting("fpsTarget", m_ui.fpsTarget);
 33	loadSetting("lockAspectRatio", m_ui.lockAspectRatio);
 34	loadSetting("volume", m_ui.volume);
 35	loadSetting("mute", m_ui.mute);
 36	loadSetting("rewindEnable", m_ui.rewind);
 37	loadSetting("rewindBufferInterval", m_ui.rewindInterval);
 38	loadSetting("rewindBufferCapacity", m_ui.rewindCapacity);
 39	loadSetting("resampleVideo", m_ui.resampleVideo);
 40	loadSetting("allowOpposingDirections", m_ui.allowOpposingDirections);
 41	loadSetting("suspendScreensaver", m_ui.suspendScreensaver);
 42	loadSetting("pauseOnFocusLost", m_ui.pauseOnFocusLost);
 43	loadSetting("savegamePath", m_ui.savegamePath);
 44	loadSetting("savestatePath", m_ui.savestatePath);
 45	loadSetting("screenshotPath", m_ui.screenshotPath);
 46	loadSetting("patchPath", m_ui.patchPath);
 47
 48	if (m_ui.savegamePath->text().isEmpty()) {
 49		m_ui.savegameSameDir->setChecked(true);
 50	}
 51	connect(m_ui.savegameSameDir, &QAbstractButton::toggled, [this] (bool e) {
 52		if (e) {
 53			m_ui.savegamePath->clear();
 54		}
 55	});
 56	connect(m_ui.savegameBrowse, &QAbstractButton::pressed, [this] () {
 57		QString path = GBAApp::app()->getOpenDirectoryName(this, "Select directory");
 58		if (!path.isNull()) {
 59			m_ui.savegameSameDir->setChecked(false);
 60			m_ui.savegamePath->setText(path);
 61		}
 62	});
 63
 64	if (m_ui.savestatePath->text().isEmpty()) {
 65		m_ui.savestateSameDir->setChecked(true);
 66	}
 67	connect(m_ui.savestateSameDir, &QAbstractButton::toggled, [this] (bool e) {
 68		if (e) {
 69			m_ui.savestatePath->clear();
 70		}
 71	});
 72	connect(m_ui.savestateBrowse, &QAbstractButton::pressed, [this] () {
 73		QString path = GBAApp::app()->getOpenDirectoryName(this, "Select directory");
 74		if (!path.isNull()) {
 75			m_ui.savestateSameDir->setChecked(false);
 76			m_ui.savestatePath->setText(path);
 77		}
 78	});
 79
 80	if (m_ui.screenshotPath->text().isEmpty()) {
 81		m_ui.screenshotSameDir->setChecked(true);
 82	}
 83	connect(m_ui.screenshotSameDir, &QAbstractButton::toggled, [this] (bool e) {
 84		if (e) {
 85			m_ui.screenshotPath->clear();
 86		}
 87	});
 88	connect(m_ui.screenshotBrowse, &QAbstractButton::pressed, [this] () {
 89		QString path = GBAApp::app()->getOpenDirectoryName(this, "Select directory");
 90		if (!path.isNull()) {
 91			m_ui.screenshotSameDir->setChecked(false);
 92			m_ui.screenshotPath->setText(path);
 93		}
 94	});
 95
 96	if (m_ui.patchPath->text().isEmpty()) {
 97		m_ui.patchSameDir->setChecked(true);
 98	}
 99	connect(m_ui.patchSameDir, &QAbstractButton::toggled, [this] (bool e) {
100		if (e) {
101			m_ui.patchPath->clear();
102		}
103	});
104	connect(m_ui.patchBrowse, &QAbstractButton::pressed, [this] () {
105		QString path = GBAApp::app()->getOpenDirectoryName(this, "Select directory");
106		if (!path.isNull()) {
107			m_ui.patchSameDir->setChecked(false);
108			m_ui.patchPath->setText(path);
109		}
110	});
111
112	double fastForwardRatio = loadSetting("fastForwardRatio").toDouble();
113	if (fastForwardRatio <= 0) {
114		m_ui.fastForwardUnbounded->setChecked(true);
115		m_ui.fastForwardRatio->setEnabled(false);
116	} else {
117		m_ui.fastForwardUnbounded->setChecked(false);
118		m_ui.fastForwardRatio->setEnabled(true);
119		m_ui.fastForwardRatio->setValue(fastForwardRatio);
120	}
121	connect(m_ui.fastForwardUnbounded, &QAbstractButton::toggled, [this](bool checked) {
122		m_ui.fastForwardRatio->setEnabled(!checked);
123	});
124
125	QString idleOptimization = loadSetting("idleOptimization");
126	if (idleOptimization == "ignore") {
127		m_ui.idleOptimization->setCurrentIndex(0);
128	} else if (idleOptimization == "remove") {
129		m_ui.idleOptimization->setCurrentIndex(1);
130	} else if (idleOptimization == "detect") {
131		m_ui.idleOptimization->setCurrentIndex(2);
132	}
133
134	QVariant audioDriver = m_controller->getQtOption("audioDriver");
135#ifdef BUILD_QT_MULTIMEDIA
136	m_ui.audioDriver->addItem(tr("Qt Multimedia"), static_cast<int>(AudioProcessor::Driver::QT_MULTIMEDIA));
137	if (!audioDriver.isNull() && audioDriver.toInt() == static_cast<int>(AudioProcessor::Driver::QT_MULTIMEDIA)) {
138		m_ui.audioDriver->setCurrentIndex(m_ui.audioDriver->count() - 1);
139	}
140#endif
141
142#ifdef BUILD_SDL
143	m_ui.audioDriver->addItem(tr("SDL"), static_cast<int>(AudioProcessor::Driver::SDL));
144	if (audioDriver.isNull() || audioDriver.toInt() == static_cast<int>(AudioProcessor::Driver::SDL)) {
145		m_ui.audioDriver->setCurrentIndex(m_ui.audioDriver->count() - 1);
146	}
147#endif
148
149	QVariant displayDriver = m_controller->getQtOption("displayDriver");
150	m_ui.displayDriver->addItem(tr("Software (Qt)"), static_cast<int>(Display::Driver::QT));
151	if (!displayDriver.isNull() && displayDriver.toInt() == static_cast<int>(Display::Driver::QT)) {
152		m_ui.displayDriver->setCurrentIndex(m_ui.displayDriver->count() - 1);
153	}
154
155#ifdef BUILD_GL
156	m_ui.displayDriver->addItem(tr("OpenGL"), static_cast<int>(Display::Driver::OPENGL));
157	if (displayDriver.isNull() || displayDriver.toInt() == static_cast<int>(Display::Driver::OPENGL)) {
158		m_ui.displayDriver->setCurrentIndex(m_ui.displayDriver->count() - 1);
159	}
160#endif
161
162	connect(m_ui.biosBrowse, SIGNAL(clicked()), this, SLOT(selectBios()));
163	connect(m_ui.buttonBox, SIGNAL(accepted()), this, SLOT(updateConfig()));
164	connect(m_ui.buttonBox, &QDialogButtonBox::clicked, [this](QAbstractButton* button) {
165		if (m_ui.buttonBox->buttonRole(button) == QDialogButtonBox::ApplyRole) {
166			updateConfig();
167		}
168	});
169
170	GBAKeyEditor* editor = new GBAKeyEditor(inputController, InputController::KEYBOARD, QString(), this);
171	m_ui.stackedWidget->addWidget(editor);
172	m_ui.tabs->addItem("Keyboard");
173	connect(m_ui.buttonBox, SIGNAL(accepted()), editor, SLOT(save()));
174
175#ifdef BUILD_SDL
176	inputController->recalibrateAxes();
177	const char* profile = inputController->profileForType(SDL_BINDING_BUTTON);
178	editor = new GBAKeyEditor(inputController, SDL_BINDING_BUTTON, profile);
179	m_ui.stackedWidget->addWidget(editor);
180	m_ui.tabs->addItem("Controllers");
181	connect(m_ui.buttonBox, SIGNAL(accepted()), editor, SLOT(save()));
182#endif
183
184	ShortcutView* shortcutView = new ShortcutView();
185	shortcutView->setController(shortcutController);
186	shortcutView->setInputController(inputController);
187	m_ui.stackedWidget->addWidget(shortcutView);
188	m_ui.tabs->addItem("Shortcuts");
189}
190
191void SettingsView::selectBios() {
192	QString filename = GBAApp::app()->getOpenFileName(this, tr("Select BIOS"));
193	if (!filename.isEmpty()) {
194		m_ui.bios->setText(filename);
195	}
196}
197
198void SettingsView::updateConfig() {
199	saveSetting("bios", m_ui.bios);
200	saveSetting("useBios", m_ui.useBios);
201	saveSetting("skipBios", m_ui.skipBios);
202	saveSetting("audioBuffers", m_ui.audioBufferSize);
203	saveSetting("sampleRate", m_ui.sampleRate);
204	saveSetting("videoSync", m_ui.videoSync);
205	saveSetting("audioSync", m_ui.audioSync);
206	saveSetting("frameskip", m_ui.frameskip);
207	saveSetting("fpsTarget", m_ui.fpsTarget);
208	saveSetting("lockAspectRatio", m_ui.lockAspectRatio);
209	saveSetting("volume", m_ui.volume);
210	saveSetting("mute", m_ui.mute);
211	saveSetting("rewindEnable", m_ui.rewind);
212	saveSetting("rewindBufferInterval", m_ui.rewindInterval);
213	saveSetting("rewindBufferCapacity", m_ui.rewindCapacity);
214	saveSetting("resampleVideo", m_ui.resampleVideo);
215	saveSetting("allowOpposingDirections", m_ui.allowOpposingDirections);
216	saveSetting("suspendScreensaver", m_ui.suspendScreensaver);
217	saveSetting("pauseOnFocusLost", m_ui.pauseOnFocusLost);
218	saveSetting("savegamePath", m_ui.savegamePath);
219	saveSetting("savestatePath", m_ui.savestatePath);
220	saveSetting("screenshotPath", m_ui.screenshotPath);
221	saveSetting("patchPath", m_ui.patchPath);
222
223	if (m_ui.fastForwardUnbounded->isChecked()) {
224		saveSetting("fastForwardRatio", "-1");
225	} else {
226		saveSetting("fastForwardRatio", m_ui.fastForwardRatio);
227	}
228
229	switch (m_ui.idleOptimization->currentIndex() + IDLE_LOOP_IGNORE) {
230	case IDLE_LOOP_IGNORE:
231		saveSetting("idleOptimization", "ignore");
232		break;
233	case IDLE_LOOP_REMOVE:
234		saveSetting("idleOptimization", "remove");
235		break;
236	case IDLE_LOOP_DETECT:
237		saveSetting("idleOptimization", "detect");
238		break;
239	}
240
241	QVariant audioDriver = m_ui.audioDriver->itemData(m_ui.audioDriver->currentIndex());
242	if (audioDriver != m_controller->getQtOption("audioDriver")) {
243		m_controller->setQtOption("audioDriver", audioDriver);
244		AudioProcessor::setDriver(static_cast<AudioProcessor::Driver>(audioDriver.toInt()));
245		emit audioDriverChanged();
246	}
247
248	QVariant displayDriver = m_ui.displayDriver->itemData(m_ui.displayDriver->currentIndex());
249	if (displayDriver != m_controller->getQtOption("displayDriver")) {
250		m_controller->setQtOption("displayDriver", displayDriver);
251		Display::setDriver(static_cast<Display::Driver>(displayDriver.toInt()));
252		emit displayDriverChanged();
253	}
254
255	m_controller->write();
256
257	emit pathsChanged();
258	emit biosLoaded(m_ui.bios->text());
259}
260
261void SettingsView::saveSetting(const char* key, const QAbstractButton* field) {
262	m_controller->setOption(key, field->isChecked());
263	m_controller->updateOption(key);
264}
265
266void SettingsView::saveSetting(const char* key, const QComboBox* field) {
267	saveSetting(key, field->lineEdit());
268}
269
270void SettingsView::saveSetting(const char* key, const QDoubleSpinBox* field) {
271	saveSetting(key, field->value());
272}
273
274void SettingsView::saveSetting(const char* key, const QLineEdit* field) {
275	saveSetting(key, field->text());
276}
277
278void SettingsView::saveSetting(const char* key, const QSlider* field) {
279	saveSetting(key, field->value());
280}
281
282void SettingsView::saveSetting(const char* key, const QSpinBox* field) {
283	saveSetting(key, field->value());
284}
285
286void SettingsView::saveSetting(const char* key, const QVariant& field) {
287	m_controller->setOption(key, field);
288	m_controller->updateOption(key);
289}
290
291void SettingsView::loadSetting(const char* key, QAbstractButton* field) {
292	QString option = loadSetting(key);
293	field->setChecked(!option.isNull() && option != "0");
294}
295
296void SettingsView::loadSetting(const char* key, QComboBox* field) {
297	loadSetting(key, field->lineEdit());
298}
299
300void SettingsView::loadSetting(const char* key, QDoubleSpinBox* field) {
301	QString option = loadSetting(key);
302	field->setValue(option.toDouble());
303}
304
305void SettingsView::loadSetting(const char* key, QLineEdit* field) {
306	QString option = loadSetting(key);
307	field->setText(option);
308}
309
310void SettingsView::loadSetting(const char* key, QSlider* field) {
311	QString option = loadSetting(key);
312	field->setValue(option.toInt());
313}
314
315void SettingsView::loadSetting(const char* key, QSpinBox* field) {
316	QString option = loadSetting(key);
317	field->setValue(option.toInt());
318}
319
320QString SettingsView::loadSetting(const char* key) {
321	return m_controller->getOption(key);
322}