all repos — mgba @ e81ed20a144be7e9952abc0b91d235cf0d11ad39

mGBA Game Boy Advance Emulator

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

  1/* Copyright (c) 2013-2015 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 "ConfigController.h"
  7
  8#include "GameController.h"
  9
 10#include <QAction>
 11#include <QDir>
 12#include <QMenu>
 13
 14extern "C" {
 15#include "feature/commandline.h"
 16}
 17
 18using namespace QGBA;
 19
 20ConfigOption::ConfigOption(QObject* parent)
 21	: QObject(parent)
 22{
 23}
 24
 25void ConfigOption::connect(std::function<void(const QVariant&)> slot, QObject* parent) {
 26	m_slots[parent] = slot;
 27	QObject::connect(parent, &QAction::destroyed, [this, slot, parent]() {
 28		m_slots.remove(parent);
 29	});
 30}
 31
 32QAction* ConfigOption::addValue(const QString& text, const QVariant& value, QMenu* parent) {
 33	QAction* action = new QAction(text, parent);
 34	action->setCheckable(true);
 35	QObject::connect(action, &QAction::triggered, [this, value]() {
 36		emit valueChanged(value);
 37	});
 38	QObject::connect(parent, &QAction::destroyed, [this, action, value]() {
 39		m_actions.removeAll(qMakePair(action, value));
 40	});
 41	parent->addAction(action);
 42	m_actions.append(qMakePair(action, value));
 43	return action;
 44}
 45
 46QAction* ConfigOption::addValue(const QString& text, const char* value, QMenu* parent) {
 47	return addValue(text, QString(value), parent);
 48}
 49
 50QAction* ConfigOption::addBoolean(const QString& text, QMenu* parent) {
 51	QAction* action = new QAction(text, parent);
 52	action->setCheckable(true);
 53	QObject::connect(action, &QAction::triggered, [this, action]() {
 54		emit valueChanged(action->isChecked());
 55	});
 56	QObject::connect(parent, &QAction::destroyed, [this, action]() {
 57		m_actions.removeAll(qMakePair(action, 1));
 58	});
 59	parent->addAction(action);
 60	m_actions.append(qMakePair(action, 1));
 61	return action;
 62}
 63
 64void ConfigOption::setValue(bool value) {
 65	setValue(QVariant(value));
 66}
 67
 68void ConfigOption::setValue(int value) {
 69	setValue(QVariant(value));
 70}
 71
 72void ConfigOption::setValue(unsigned value) {
 73	setValue(QVariant(value));
 74}
 75
 76void ConfigOption::setValue(const char* value) {
 77	setValue(QVariant(QString(value)));
 78}
 79
 80void ConfigOption::setValue(const QVariant& value) {
 81	QPair<QAction*, QVariant> action;
 82	foreach (action, m_actions) {
 83		bool signalsEnabled = action.first->blockSignals(true);
 84		action.first->setChecked(value == action.second);
 85		action.first->blockSignals(signalsEnabled);
 86	}
 87	std::function<void(const QVariant&)> slot;
 88	foreach(slot, m_slots.values()) {
 89		slot(value);
 90	}
 91}
 92
 93ConfigController::ConfigController(QObject* parent)
 94	: QObject(parent)
 95	, m_opts()
 96{
 97	char path[PATH_MAX];
 98	mCoreConfigDirectory(path, sizeof(path));
 99	QString fileName(path);
100	fileName.append(QDir::separator());
101	fileName.append("qt.ini");
102	m_settings = new QSettings(fileName, QSettings::IniFormat, this);
103
104	mCoreConfigInit(&m_config, PORT);
105
106	m_opts.audioSync = GameController::AUDIO_SYNC;
107	m_opts.videoSync = GameController::VIDEO_SYNC;
108	m_opts.fpsTarget = 60;
109	m_opts.audioBuffers = 1536;
110	m_opts.sampleRate = 44100;
111	m_opts.volume = 0x100;
112	m_opts.logLevel = mLOG_WARN | mLOG_ERROR | mLOG_FATAL;
113	m_opts.rewindEnable = false;
114	m_opts.rewindBufferCapacity = 300;
115	m_opts.useBios = true;
116	m_opts.suspendScreensaver = true;
117	mCoreConfigLoad(&m_config);
118	mCoreConfigLoadDefaults(&m_config, &m_opts);
119	mCoreConfigMap(&m_config, &m_opts);
120}
121
122ConfigController::~ConfigController() {
123	mCoreConfigDeinit(&m_config);
124	mCoreConfigFreeOpts(&m_opts);
125}
126
127bool ConfigController::parseArguments(mArguments* args, int argc, char* argv[], mSubParser* subparser) {
128	if (::parseArguments(args, argc, argv, subparser)) {
129		mCoreConfigFreeOpts(&m_opts);
130		applyArguments(args, subparser, &m_config);
131		mCoreConfigMap(&m_config, &m_opts);
132		return true;
133	}
134	return false;
135}
136
137ConfigOption* ConfigController::addOption(const char* key) {
138	QString optionName(key);
139
140	if (m_optionSet.contains(optionName)) {
141		return m_optionSet[optionName];
142	}
143	ConfigOption* newOption = new ConfigOption(this);
144	m_optionSet[optionName] = newOption;
145	connect(newOption, &ConfigOption::valueChanged, [this, key](const QVariant& value) {
146		setOption(key, value);
147	});
148	return newOption;
149}
150
151void ConfigController::updateOption(const char* key) {
152	if (!key) {
153		return;
154	}
155
156	QString optionName(key);
157
158	if (!m_optionSet.contains(optionName)) {
159		return;
160	}
161	m_optionSet[optionName]->setValue(mCoreConfigGetValue(&m_config, key));
162}
163
164QString ConfigController::getOption(const char* key) const {
165	return QString(mCoreConfigGetValue(&m_config, key));
166}
167
168QVariant ConfigController::getQtOption(const QString& key, const QString& group) const {
169	if (!group.isNull()) {
170		m_settings->beginGroup(group);
171	}
172	QVariant value = m_settings->value(key);
173	if (!group.isNull()) {
174		m_settings->endGroup();
175	}
176	return value;
177}
178
179void ConfigController::saveOverride(const Override& override) {
180	override.save(overrides());
181	write();
182}
183
184void ConfigController::setOption(const char* key, bool value) {
185	mCoreConfigSetIntValue(&m_config, key, value);
186	QString optionName(key);
187	if (m_optionSet.contains(optionName)) {
188		m_optionSet[optionName]->setValue(value);
189	}
190}
191
192void ConfigController::setOption(const char* key, int value) {
193	mCoreConfigSetIntValue(&m_config, key, value);
194	QString optionName(key);
195	if (m_optionSet.contains(optionName)) {
196		m_optionSet[optionName]->setValue(value);
197	}
198}
199
200void ConfigController::setOption(const char* key, unsigned value) {
201	mCoreConfigSetUIntValue(&m_config, key, value);
202	QString optionName(key);
203	if (m_optionSet.contains(optionName)) {
204		m_optionSet[optionName]->setValue(value);
205	}
206}
207
208void ConfigController::setOption(const char* key, const char* value) {
209	mCoreConfigSetValue(&m_config, key, value);
210	QString optionName(key);
211	if (m_optionSet.contains(optionName)) {
212		m_optionSet[optionName]->setValue(value);
213	}
214}
215
216void ConfigController::setOption(const char* key, const QVariant& value) {
217	if (value.type() == QVariant::Bool) {
218		setOption(key, value.toBool());
219		return;
220	}
221	QString stringValue(value.toString());
222	setOption(key, stringValue.toUtf8().constData());
223}
224
225void ConfigController::setQtOption(const QString& key, const QVariant& value, const QString& group) {
226	if (!group.isNull()) {
227		m_settings->beginGroup(group);
228	}
229	m_settings->setValue(key, value);
230	if (!group.isNull()) {
231		m_settings->endGroup();
232	}
233}
234
235QList<QString> ConfigController::getMRU() const {
236	QList<QString> mru;
237	m_settings->beginGroup("mru");
238	for (int i = 0; i < MRU_LIST_SIZE; ++i) {
239		QString item = m_settings->value(QString::number(i)).toString();
240		if (item.isNull()) {
241			continue;
242		}
243		mru.append(item);
244	}
245	m_settings->endGroup();
246	return mru;
247}
248
249void ConfigController::setMRU(const QList<QString>& mru) {
250	int i = 0;
251	m_settings->beginGroup("mru");
252	for (const QString& item : mru) {
253		m_settings->setValue(QString::number(i), item);
254		++i;
255		if (i >= MRU_LIST_SIZE) {
256			break;
257		}
258	}
259	m_settings->endGroup();
260}
261
262void ConfigController::write() {
263	mCoreConfigSave(&m_config);
264	m_settings->sync();
265
266	mCoreConfigFreeOpts(&m_opts);
267	mCoreConfigMap(&m_config, &m_opts);
268}
269
270void ConfigController::makePortable() {
271	mCoreConfigMakePortable(&m_config);
272
273	char path[PATH_MAX];
274	mCoreConfigDirectory(path, sizeof(path));
275	QString fileName(path);
276	fileName.append(QDir::separator());
277	fileName.append("qt.ini");
278	QSettings* settings2 = new QSettings(fileName, QSettings::IniFormat, this);
279	for (const auto& key : m_settings->allKeys()) {
280		settings2->setValue(key, m_settings->value(key));
281	}
282	delete m_settings;
283	m_settings = settings2;
284}