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