all repos — mgba @ e0a6af087e83d79b53ad5352511c7e02c557b93f

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