aboutsummaryrefslogtreecommitdiff
path: root/src/citra_qt
diff options
context:
space:
mode:
Diffstat (limited to 'src/citra_qt')
-rw-r--r--src/citra_qt/CMakeLists.txt6
-rw-r--r--src/citra_qt/Info.plist2
-rw-r--r--src/citra_qt/config.cpp11
-rw-r--r--src/citra_qt/config.h6
-rw-r--r--src/citra_qt/configure.ui19
-rw-r--r--src/citra_qt/configure_dialog.cpp10
-rw-r--r--src/citra_qt/configure_dialog.h3
-rw-r--r--src/citra_qt/configure_input.cpp149
-rw-r--r--src/citra_qt/configure_input.h63
-rw-r--r--src/citra_qt/configure_input.ui593
-rw-r--r--src/citra_qt/configure_system.cpp136
-rw-r--r--src/citra_qt/configure_system.h38
-rw-r--r--src/citra_qt/configure_system.ui252
-rw-r--r--src/citra_qt/main.cpp3
14 files changed, 1277 insertions, 14 deletions
diff --git a/src/citra_qt/CMakeLists.txt b/src/citra_qt/CMakeLists.txt
index 43a766053..4402ad995 100644
--- a/src/citra_qt/CMakeLists.txt
+++ b/src/citra_qt/CMakeLists.txt
@@ -22,6 +22,8 @@ set(SRCS
configure_debug.cpp
configure_dialog.cpp
configure_general.cpp
+ configure_system.cpp
+ configure_input.cpp
game_list.cpp
hotkeys.cpp
main.cpp
@@ -52,6 +54,8 @@ set(HEADERS
configure_debug.h
configure_dialog.h
configure_general.h
+ configure_system.h
+ configure_input.h
game_list.h
game_list_p.h
hotkeys.h
@@ -69,6 +73,8 @@ set(UIS
configure_audio.ui
configure_debug.ui
configure_general.ui
+ configure_system.ui
+ configure_input.ui
hotkeys.ui
main.ui
)
diff --git a/src/citra_qt/Info.plist b/src/citra_qt/Info.plist
index 4c89e128b..7d46b39d1 100644
--- a/src/citra_qt/Info.plist
+++ b/src/citra_qt/Info.plist
@@ -5,7 +5,7 @@
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
- <string>$(EXECUTABLE_NAME)</string>
+ <string>${EXECUTABLE_NAME}</string>
<key>CFBundleGetInfoString</key>
<string></string>
<key>CFBundleIconFile</key>
diff --git a/src/citra_qt/config.cpp b/src/citra_qt/config.cpp
index ba7edaff9..93c6a6e41 100644
--- a/src/citra_qt/config.cpp
+++ b/src/citra_qt/config.cpp
@@ -3,14 +3,11 @@
// Refer to the license.txt file included.
#include <QSettings>
-#include <QString>
-#include <QStringList>
#include "citra_qt/config.h"
#include "citra_qt/ui_settings.h"
#include "common/file_util.h"
-#include "core/settings.h"
Config::Config() {
// TODO: Don't hardcode the path; let the frontend decide where to put the config files.
@@ -21,7 +18,7 @@ Config::Config() {
Reload();
}
-static const std::array<QVariant, Settings::NativeInput::NUM_INPUTS> defaults = {
+const std::array<QVariant, Settings::NativeInput::NUM_INPUTS> Config::defaults = {
// directly mapped keys
Qt::Key_A, Qt::Key_S, Qt::Key_Z, Qt::Key_X,
Qt::Key_Q, Qt::Key_W, Qt::Key_1, Qt::Key_2,
@@ -48,7 +45,7 @@ void Config::ReadValues() {
qt_config->endGroup();
qt_config->beginGroup("Renderer");
- Settings::values.use_hw_renderer = qt_config->value("use_hw_renderer", false).toBool();
+ Settings::values.use_hw_renderer = qt_config->value("use_hw_renderer", true).toBool();
Settings::values.use_shader_jit = qt_config->value("use_shader_jit", true).toBool();
Settings::values.use_scaled_resolution = qt_config->value("use_scaled_resolution", false).toBool();
@@ -109,7 +106,7 @@ void Config::ReadValues() {
UISettings::values.shortcuts.emplace_back(
UISettings::Shortcut(group + "/" + hotkey,
UISettings::ContextualShortcut(qt_config->value("KeySeq").toString(),
- qt_config->value("Context").toInt())));
+ qt_config->value("Context").toInt())));
qt_config->endGroup();
}
@@ -191,7 +188,7 @@ void Config::SaveValues() {
qt_config->endGroup();
qt_config->beginGroup("Shortcuts");
- for (auto shortcut : UISettings::values.shortcuts ) {
+ for (auto shortcut : UISettings::values.shortcuts) {
qt_config->setValue(shortcut.first + "/KeySeq", shortcut.second.first);
qt_config->setValue(shortcut.first + "/Context", shortcut.second.second);
}
diff --git a/src/citra_qt/config.h b/src/citra_qt/config.h
index dd0b2ef0b..0cbdb707f 100644
--- a/src/citra_qt/config.h
+++ b/src/citra_qt/config.h
@@ -1,10 +1,13 @@
-// Copyright 2014 Citra Emulator Project
+// Copyright 2014 Citra Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include <string>
+#include <QVariant>
+
+#include "core/settings.h"
class QSettings;
@@ -20,4 +23,5 @@ public:
void Reload();
void Save();
+ static const std::array<QVariant, Settings::NativeInput::NUM_INPUTS> defaults;
};
diff --git a/src/citra_qt/configure.ui b/src/citra_qt/configure.ui
index e1624bbef..15fe17323 100644
--- a/src/citra_qt/configure.ui
+++ b/src/citra_qt/configure.ui
@@ -24,7 +24,12 @@
<string>General</string>
</attribute>
</widget>
- <widget class="QWidget" name="inputTab">
+ <widget class="ConfigureSystem" name="systemTab">
+ <attribute name="title">
+ <string>System</string>
+ </attribute>
+ </widget>
+ <widget class="ConfigureInput" name="inputTab">
<attribute name="title">
<string>Input</string>
</attribute>
@@ -58,6 +63,12 @@
<container>1</container>
</customwidget>
<customwidget>
+ <class>ConfigureSystem</class>
+ <extends>QWidget</extends>
+ <header>configure_system.h</header>
+ <container>1</container>
+ </customwidget>
+ <customwidget>
<class>ConfigureAudio</class>
<extends>QWidget</extends>
<header>configure_audio.h</header>
@@ -69,6 +80,12 @@
<header>configure_debug.h</header>
<container>1</container>
</customwidget>
+ <customwidget>
+ <class>ConfigureInput</class>
+ <extends>QWidget</extends>
+ <header>configure_input.h</header>
+ <container>1</container>
+ </customwidget>
</customwidgets>
<resources/>
<connections>
diff --git a/src/citra_qt/configure_dialog.cpp b/src/citra_qt/configure_dialog.cpp
index 2f0317fe0..459fac4bb 100644
--- a/src/citra_qt/configure_dialog.cpp
+++ b/src/citra_qt/configure_dialog.cpp
@@ -9,9 +9,10 @@
#include "core/settings.h"
-ConfigureDialog::ConfigureDialog(QWidget *parent) :
+ConfigureDialog::ConfigureDialog(QWidget *parent, bool running) :
QDialog(parent),
- ui(new Ui::ConfigureDialog)
+ ui(new Ui::ConfigureDialog),
+ emulation_running(running)
{
ui->setupUi(this);
this->setConfiguration();
@@ -21,10 +22,15 @@ ConfigureDialog::~ConfigureDialog() {
}
void ConfigureDialog::setConfiguration() {
+ // System tab needs set manually
+ // depending on whether emulation is running
+ ui->systemTab->setConfiguration(emulation_running);
}
void ConfigureDialog::applyConfiguration() {
ui->generalTab->applyConfiguration();
+ ui->systemTab->applyConfiguration();
+ ui->inputTab->applyConfiguration();
ui->audioTab->applyConfiguration();
ui->debugTab->applyConfiguration();
}
diff --git a/src/citra_qt/configure_dialog.h b/src/citra_qt/configure_dialog.h
index 89020eeb4..305b33bdf 100644
--- a/src/citra_qt/configure_dialog.h
+++ b/src/citra_qt/configure_dialog.h
@@ -16,7 +16,7 @@ class ConfigureDialog : public QDialog
Q_OBJECT
public:
- explicit ConfigureDialog(QWidget *parent = nullptr);
+ explicit ConfigureDialog(QWidget *parent, bool emulation_running);
~ConfigureDialog();
void applyConfiguration();
@@ -26,4 +26,5 @@ private:
private:
std::unique_ptr<Ui::ConfigureDialog> ui;
+ bool emulation_running;
};
diff --git a/src/citra_qt/configure_input.cpp b/src/citra_qt/configure_input.cpp
new file mode 100644
index 000000000..9c7a67174
--- /dev/null
+++ b/src/citra_qt/configure_input.cpp
@@ -0,0 +1,149 @@
+// Copyright 2016 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include <memory>
+#include <utility>
+#include <QTimer>
+
+#include "citra_qt/configure_input.h"
+
+ConfigureInput::ConfigureInput(QWidget* parent) : QWidget(parent), ui(std::make_unique<Ui::ConfigureInput>()) {
+ ui->setupUi(this);
+
+ // Initialize mapping of input enum to UI button.
+ input_mapping = {
+ { std::make_pair(Settings::NativeInput::Values::A, ui->buttonA) },
+ { std::make_pair(Settings::NativeInput::Values::B, ui->buttonB) },
+ { std::make_pair(Settings::NativeInput::Values::X, ui->buttonX) },
+ { std::make_pair(Settings::NativeInput::Values::Y, ui->buttonY) },
+ { std::make_pair(Settings::NativeInput::Values::L, ui->buttonL) },
+ { std::make_pair(Settings::NativeInput::Values::R, ui->buttonR) },
+ { std::make_pair(Settings::NativeInput::Values::ZL, ui->buttonZL) },
+ { std::make_pair(Settings::NativeInput::Values::ZR, ui->buttonZR) },
+ { std::make_pair(Settings::NativeInput::Values::START, ui->buttonStart) },
+ { std::make_pair(Settings::NativeInput::Values::SELECT, ui->buttonSelect) },
+ { std::make_pair(Settings::NativeInput::Values::HOME, ui->buttonHome) },
+ { std::make_pair(Settings::NativeInput::Values::DUP, ui->buttonDpadUp) },
+ { std::make_pair(Settings::NativeInput::Values::DDOWN, ui->buttonDpadDown) },
+ { std::make_pair(Settings::NativeInput::Values::DLEFT, ui->buttonDpadLeft) },
+ { std::make_pair(Settings::NativeInput::Values::DRIGHT, ui->buttonDpadRight) },
+ { std::make_pair(Settings::NativeInput::Values::CUP, ui->buttonCStickUp) },
+ { std::make_pair(Settings::NativeInput::Values::CDOWN, ui->buttonCStickDown) },
+ { std::make_pair(Settings::NativeInput::Values::CLEFT, ui->buttonCStickLeft) },
+ { std::make_pair(Settings::NativeInput::Values::CRIGHT, ui->buttonCStickRight) },
+ { std::make_pair(Settings::NativeInput::Values::CIRCLE_UP, ui->buttonCircleUp) },
+ { std::make_pair(Settings::NativeInput::Values::CIRCLE_DOWN, ui->buttonCircleDown) },
+ { std::make_pair(Settings::NativeInput::Values::CIRCLE_LEFT, ui->buttonCircleLeft) },
+ { std::make_pair(Settings::NativeInput::Values::CIRCLE_RIGHT, ui->buttonCircleRight) },
+ { std::make_pair(Settings::NativeInput::Values::CIRCLE_MODIFIER, ui->buttonCircleMod) },
+ };
+
+ // Attach handle click method to each button click.
+ for (const auto& entry : input_mapping) {
+ connect(entry.second, SIGNAL(released()), this, SLOT(handleClick()));
+ }
+ connect(ui->buttonRestoreDefaults, SIGNAL(released()), this, SLOT(restoreDefaults()));
+ setFocusPolicy(Qt::ClickFocus);
+ timer = new QTimer(this);
+ timer->setSingleShot(true);
+ connect(timer, &QTimer::timeout, this, [&]() { key_pressed = Qt::Key_Escape; setKey(); });
+ this->setConfiguration();
+}
+
+void ConfigureInput::handleClick() {
+ QPushButton* sender = qobject_cast<QPushButton*>(QObject::sender());
+ previous_mapping = sender->text();
+ sender->setText(tr("[waiting]"));
+ sender->setFocus();
+ grabKeyboard();
+ grabMouse();
+ changing_button = sender;
+ timer->start(5000); //Cancel after 5 seconds
+}
+
+void ConfigureInput::applyConfiguration() {
+ for (int i = 0; i < Settings::NativeInput::NUM_INPUTS; ++i) {
+ int value = getKeyValue(input_mapping[Settings::NativeInput::Values(i)]->text());
+ Settings::values.input_mappings[Settings::NativeInput::All[i]] = value;
+ }
+ Settings::Apply();
+}
+
+void ConfigureInput::setConfiguration() {
+ for (int i = 0; i < Settings::NativeInput::NUM_INPUTS; ++i) {
+ QString keyValue = getKeyName(Settings::values.input_mappings[i]);
+ input_mapping[Settings::NativeInput::Values(i)]->setText(keyValue);
+ }
+}
+
+void ConfigureInput::keyPressEvent(QKeyEvent* event) {
+ if (!changing_button)
+ return;
+ if (!event || event->key() == Qt::Key_unknown)
+ return;
+ key_pressed = event->key();
+ timer->stop();
+ setKey();
+}
+
+void ConfigureInput::setKey() {
+ const QString key_value = getKeyName(key_pressed);
+ if (key_pressed == Qt::Key_Escape)
+ changing_button->setText(previous_mapping);
+ else
+ changing_button->setText(key_value);
+ removeDuplicates(key_value);
+ key_pressed = Qt::Key_unknown;
+ releaseKeyboard();
+ releaseMouse();
+ changing_button = nullptr;
+ previous_mapping = nullptr;
+}
+
+QString ConfigureInput::getKeyName(int key_code) const {
+ if (key_code == Qt::Key_Shift)
+ return tr("Shift");
+ if (key_code == Qt::Key_Control)
+ return tr("Ctrl");
+ if (key_code == Qt::Key_Alt)
+ return tr("Alt");
+ if (key_code == Qt::Key_Meta)
+ return "";
+ if (key_code == -1)
+ return "";
+
+ return QKeySequence(key_code).toString();
+}
+
+Qt::Key ConfigureInput::getKeyValue(const QString& text) const {
+ if (text == "Shift")
+ return Qt::Key_Shift;
+ if (text == "Ctrl")
+ return Qt::Key_Control;
+ if (text == "Alt")
+ return Qt::Key_Alt;
+ if (text == "Meta")
+ return Qt::Key_unknown;
+ if (text == "")
+ return Qt::Key_unknown;
+
+ return Qt::Key(QKeySequence(text)[0]);
+}
+
+void ConfigureInput::removeDuplicates(const QString& newValue) {
+ for (int i = 0; i < Settings::NativeInput::NUM_INPUTS; ++i) {
+ if (changing_button != input_mapping[Settings::NativeInput::Values(i)]) {
+ const QString oldValue = input_mapping[Settings::NativeInput::Values(i)]->text();
+ if (newValue == oldValue)
+ input_mapping[Settings::NativeInput::Values(i)]->setText("");
+ }
+ }
+}
+
+void ConfigureInput::restoreDefaults() {
+ for (int i = 0; i < Settings::NativeInput::NUM_INPUTS; ++i) {
+ const QString keyValue = getKeyName(Config::defaults[i].toInt());
+ input_mapping[Settings::NativeInput::Values(i)]->setText(keyValue);
+ }
+}
diff --git a/src/citra_qt/configure_input.h b/src/citra_qt/configure_input.h
new file mode 100644
index 000000000..fe8ea5580
--- /dev/null
+++ b/src/citra_qt/configure_input.h
@@ -0,0 +1,63 @@
+// Copyright 2016 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include <QWidget>
+#include <QKeyEvent>
+
+#include "citra_qt/config.h"
+#include "core/settings.h"
+#include "ui_configure_input.h"
+
+class QPushButton;
+class QString;
+class QTimer;
+
+namespace Ui {
+ class ConfigureInput;
+}
+
+class ConfigureInput : public QWidget {
+ Q_OBJECT
+
+public:
+ explicit ConfigureInput(QWidget* parent = nullptr);
+
+ /// Save all button configurations to settings file
+ void applyConfiguration();
+
+private:
+ std::unique_ptr<Ui::ConfigureInput> ui;
+ std::map<Settings::NativeInput::Values, QPushButton*> input_mapping;
+ int key_pressed;
+ QPushButton* changing_button = nullptr; ///< button currently waiting for key press.
+ QString previous_mapping;
+ QTimer* timer;
+
+ /// Load configuration settings into button text
+ void setConfiguration();
+
+ /// Check all inputs for duplicate keys. Clears out any other button with the same value as this button's new value.
+ void removeDuplicates(const QString& newValue);
+
+ /// Handle key press event for input tab when a button is 'waiting'.
+ void keyPressEvent(QKeyEvent* event) override;
+
+ /// Convert key ASCII value to its' letter/name
+ QString getKeyName(int key_code) const;
+
+ /// Convert letter/name of key to its ASCII value.
+ Qt::Key getKeyValue(const QString& text) const;
+
+ /// Set button text to name of key pressed.
+ void setKey();
+
+private slots:
+ /// Event handler for all button released() event.
+ void handleClick();
+
+ /// Restore all buttons to their default values.
+ void restoreDefaults();
+};
diff --git a/src/citra_qt/configure_input.ui b/src/citra_qt/configure_input.ui
new file mode 100644
index 000000000..a040d4df4
--- /dev/null
+++ b/src/citra_qt/configure_input.ui
@@ -0,0 +1,593 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>ConfigureInput</class>
+ <widget class="QWidget" name="ConfigureInput">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>370</width>
+ <height>534</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>ConfigureInput</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_5">
+ <item>
+ <layout class="QGridLayout" name="gridLayout_7">
+ <item row="0" column="0">
+ <widget class="QGroupBox" name="faceButtons">
+ <property name="title">
+ <string>Face Buttons</string>
+ </property>
+ <property name="flat">
+ <bool>false</bool>
+ </property>
+ <property name="checkable">
+ <bool>false</bool>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0">
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>A:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="buttonA">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="0" column="1">
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>B:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="buttonB">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="1" column="0">
+ <layout class="QVBoxLayout" name="verticalLayout_3">
+ <item>
+ <widget class="QLabel" name="label_3">
+ <property name="text">
+ <string>X:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="buttonX">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="1" column="1">
+ <layout class="QVBoxLayout" name="verticalLayout_4">
+ <item>
+ <widget class="QLabel" name="label_4">
+ <property name="text">
+ <string>Y:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="buttonY">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QGroupBox" name="faceButtons_2">
+ <property name="title">
+ <string>Directional Pad</string>
+ </property>
+ <property name="flat">
+ <bool>false</bool>
+ </property>
+ <property name="checkable">
+ <bool>false</bool>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_2">
+ <item row="1" column="0">
+ <layout class="QVBoxLayout" name="verticalLayout_12">
+ <item>
+ <widget class="QLabel" name="label_34">
+ <property name="text">
+ <string>Up:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="buttonDpadUp">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="1" column="1">
+ <layout class="QVBoxLayout" name="verticalLayout_9">
+ <item>
+ <widget class="QLabel" name="label_35">
+ <property name="text">
+ <string>Down:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="buttonDpadDown">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="0" column="0">
+ <layout class="QVBoxLayout" name="verticalLayout_10">
+ <item>
+ <widget class="QLabel" name="label_32">
+ <property name="text">
+ <string>Left:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="buttonDpadLeft">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="0" column="1">
+ <layout class="QVBoxLayout" name="verticalLayout_11">
+ <item>
+ <widget class="QLabel" name="label_33">
+ <property name="text">
+ <string>Right:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="buttonDpadRight">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QGroupBox" name="faceButtons_3">
+ <property name="title">
+ <string>Shoulder Buttons</string>
+ </property>
+ <property name="flat">
+ <bool>false</bool>
+ </property>
+ <property name="checkable">
+ <bool>false</bool>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_3">
+ <item row="0" column="0">
+ <layout class="QVBoxLayout" name="verticalLayout_13">
+ <item>
+ <widget class="QLabel" name="label_17">
+ <property name="text">
+ <string>L:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="buttonL">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="0" column="1">
+ <layout class="QVBoxLayout" name="verticalLayout_14">
+ <item>
+ <widget class="QLabel" name="label_19">
+ <property name="text">
+ <string>R:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="buttonR">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="1" column="0">
+ <layout class="QVBoxLayout" name="verticalLayout_15">
+ <item>
+ <widget class="QLabel" name="label_20">
+ <property name="text">
+ <string>ZL:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="buttonZL">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="1" column="1">
+ <layout class="QVBoxLayout" name="verticalLayout_16">
+ <item>
+ <widget class="QLabel" name="label_18">
+ <property name="text">
+ <string>ZR:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="buttonZR">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ <zorder></zorder>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QGroupBox" name="faceButtons_4">
+ <property name="title">
+ <string>Circle Pad</string>
+ </property>
+ <property name="flat">
+ <bool>false</bool>
+ </property>
+ <property name="checkable">
+ <bool>false</bool>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_4">
+ <item row="0" column="0">
+ <layout class="QVBoxLayout" name="verticalLayout_17">
+ <item>
+ <widget class="QLabel" name="label_21">
+ <property name="text">
+ <string>Left:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="buttonCircleLeft">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="0" column="1">
+ <layout class="QVBoxLayout" name="verticalLayout_18">
+ <item>
+ <widget class="QLabel" name="label_23">
+ <property name="text">
+ <string>Right:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="buttonCircleRight">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="1" column="0">
+ <layout class="QVBoxLayout" name="verticalLayout_19">
+ <item>
+ <widget class="QLabel" name="label_24">
+ <property name="text">
+ <string>Up:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="buttonCircleUp">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="1" column="1">
+ <layout class="QVBoxLayout" name="verticalLayout_20">
+ <item>
+ <widget class="QLabel" name="label_22">
+ <property name="text">
+ <string>Down:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="buttonCircleDown">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QGroupBox" name="faceButtons_5">
+ <property name="title">
+ <string>C-Stick</string>
+ </property>
+ <property name="flat">
+ <bool>false</bool>
+ </property>
+ <property name="checkable">
+ <bool>false</bool>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_5">
+ <item row="0" column="0">
+ <layout class="QVBoxLayout" name="verticalLayout_21">
+ <item>
+ <widget class="QLabel" name="label_25">
+ <property name="text">
+ <string>Left:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="buttonCStickLeft">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="0" column="1">
+ <layout class="QVBoxLayout" name="verticalLayout_22">
+ <item>
+ <widget class="QLabel" name="label_27">
+ <property name="text">
+ <string>Right:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="buttonCStickRight">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="1" column="0">
+ <layout class="QVBoxLayout" name="verticalLayout_23">
+ <item>
+ <widget class="QLabel" name="label_28">
+ <property name="text">
+ <string>Up:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="buttonCStickUp">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="1" column="1">
+ <layout class="QVBoxLayout" name="verticalLayout_24">
+ <item>
+ <widget class="QLabel" name="label_26">
+ <property name="text">
+ <string>Down:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="buttonCStickDown">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QGroupBox" name="faceButtons_6">
+ <property name="title">
+ <string>Misc.</string>
+ </property>
+ <property name="flat">
+ <bool>false</bool>
+ </property>
+ <property name="checkable">
+ <bool>false</bool>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_6">
+ <item row="0" column="0">
+ <layout class="QVBoxLayout" name="verticalLayout_25">
+ <item>
+ <widget class="QLabel" name="label_29">
+ <property name="text">
+ <string>Start:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="buttonStart">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="0" column="1">
+ <layout class="QVBoxLayout" name="verticalLayout_26">
+ <item>
+ <widget class="QLabel" name="label_30">
+ <property name="text">
+ <string>Select:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="buttonSelect">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="1" column="0">
+ <layout class="QVBoxLayout" name="verticalLayout_27">
+ <item>
+ <widget class="QLabel" name="label_31">
+ <property name="text">
+ <string>Home:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="buttonHome">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="1" column="1">
+ <layout class="QVBoxLayout" name="verticalLayout_28">
+ <item>
+ <widget class="QLabel" name="label_34">
+ <property name="text">
+ <string>Circle Mod:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="buttonCircleMod">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="buttonRestoreDefaults">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="sizeIncrement">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="baseSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="layoutDirection">
+ <enum>Qt::LeftToRight</enum>
+ </property>
+ <property name="text">
+ <string>Restore Defaults</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/citra_qt/configure_system.cpp b/src/citra_qt/configure_system.cpp
new file mode 100644
index 000000000..4f0d4dbfe
--- /dev/null
+++ b/src/citra_qt/configure_system.cpp
@@ -0,0 +1,136 @@
+// Copyright 2016 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include "citra_qt/configure_system.h"
+#include "citra_qt/ui_settings.h"
+#include "ui_configure_system.h"
+
+#include "core/hle/service/fs/archive.h"
+#include "core/hle/service/cfg/cfg.h"
+
+static const std::array<int, 12> days_in_month = {{
+ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
+}};
+
+ConfigureSystem::ConfigureSystem(QWidget *parent) :
+ QWidget(parent),
+ ui(new Ui::ConfigureSystem) {
+ ui->setupUi(this);
+
+ connect(ui->combo_birthmonth, SIGNAL(currentIndexChanged(int)), SLOT(updateBirthdayComboBox(int)));
+}
+
+ConfigureSystem::~ConfigureSystem() {
+}
+
+void ConfigureSystem::setConfiguration(bool emulation_running) {
+ enabled = !emulation_running;
+
+ if (!enabled) {
+ ReadSystemSettings();
+ ui->group_system_settings->setEnabled(false);
+ } else {
+ // This tab is enabled only when game is not running (i.e. all service are not initialized).
+ // Temporarily register archive types and load the config savegame file to memory.
+ Service::FS::RegisterArchiveTypes();
+ ResultCode result = Service::CFG::LoadConfigNANDSaveFile();
+ Service::FS::UnregisterArchiveTypes();
+
+ if (result.IsError()) {
+ ui->label_disable_info->setText(tr("Failed to load system settings data."));
+ ui->group_system_settings->setEnabled(false);
+ enabled = false;
+ return;
+ }
+
+ ReadSystemSettings();
+ ui->label_disable_info->hide();
+ }
+}
+
+void ConfigureSystem::ReadSystemSettings() {
+ // set username
+ username = Service::CFG::GetUsername();
+ // ui->edit_username->setText(QString::fromStdU16String(username)); // TODO(wwylele): Use this when we move to Qt 5.5
+ ui->edit_username->setText(QString::fromUtf16(reinterpret_cast<const ushort*>(username.data())));
+
+ // set birthday
+ std::tie(birthmonth, birthday) = Service::CFG::GetBirthday();
+ ui->combo_birthmonth->setCurrentIndex(birthmonth - 1);
+ ui->combo_birthday->setCurrentIndex(birthday - 1);
+
+ // set system language
+ language_index = Service::CFG::GetSystemLanguage();
+ ui->combo_language->setCurrentIndex(language_index);
+
+ // set sound output mode
+ sound_index = Service::CFG::GetSoundOutputMode();
+ ui->combo_sound->setCurrentIndex(sound_index);
+}
+
+void ConfigureSystem::applyConfiguration() {
+ if (!enabled)
+ return;
+
+ bool modified = false;
+
+ // apply username
+ // std::u16string new_username = ui->edit_username->text().toStdU16String(); // TODO(wwylele): Use this when we move to Qt 5.5
+ std::u16string new_username(reinterpret_cast<const char16_t*>(ui->edit_username->text().utf16()));
+ if (new_username != username) {
+ Service::CFG::SetUsername(new_username);
+ modified = true;
+ }
+
+ // apply birthday
+ int new_birthmonth = ui->combo_birthmonth->currentIndex() + 1;
+ int new_birthday = ui->combo_birthday->currentIndex() + 1;
+ if (birthmonth != new_birthmonth || birthday != new_birthday) {
+ Service::CFG::SetBirthday(new_birthmonth, new_birthday);
+ modified = true;
+ }
+
+ // apply language
+ int new_language = ui->combo_language->currentIndex();
+ if (language_index != new_language) {
+ Service::CFG::SetSystemLanguage(static_cast<Service::CFG::SystemLanguage>(new_language));
+ modified = true;
+ }
+
+ // apply sound
+ int new_sound = ui->combo_sound->currentIndex();
+ if (sound_index != new_sound) {
+ Service::CFG::SetSoundOutputMode(static_cast<Service::CFG::SoundOutputMode>(new_sound));
+ modified = true;
+ }
+
+ // update the config savegame if any item is modified.
+ if (modified)
+ Service::CFG::UpdateConfigNANDSavegame();
+}
+
+void ConfigureSystem::updateBirthdayComboBox(int birthmonth_index) {
+ if (birthmonth_index < 0 || birthmonth_index >= 12)
+ return;
+
+ // store current day selection
+ int birthday_index = ui->combo_birthday->currentIndex();
+
+ // get number of days in the new selected month
+ int days = days_in_month[birthmonth_index];
+
+ // if the selected day is out of range,
+ // reset it to 1st
+ if (birthday_index < 0 || birthday_index >= days)
+ birthday_index = 0;
+
+ // update the day combo box
+ ui->combo_birthday->clear();
+ for (int i = 1; i <= days; ++i) {
+ ui->combo_birthday->addItem(QString::number(i));
+ }
+
+ // restore the day selection
+ ui->combo_birthday->setCurrentIndex(birthday_index);
+}
diff --git a/src/citra_qt/configure_system.h b/src/citra_qt/configure_system.h
new file mode 100644
index 000000000..1f5577070
--- /dev/null
+++ b/src/citra_qt/configure_system.h
@@ -0,0 +1,38 @@
+// Copyright 2016 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include <memory>
+#include <QWidget>
+
+namespace Ui {
+class ConfigureSystem;
+}
+
+class ConfigureSystem : public QWidget
+{
+ Q_OBJECT
+
+public:
+ explicit ConfigureSystem(QWidget *parent = nullptr);
+ ~ConfigureSystem();
+
+ void applyConfiguration();
+ void setConfiguration(bool emulation_running);
+
+public slots:
+ void updateBirthdayComboBox(int birthmonth_index);
+
+private:
+ void ReadSystemSettings();
+
+ std::unique_ptr<Ui::ConfigureSystem> ui;
+ bool enabled;
+
+ std::u16string username;
+ int birthmonth, birthday;
+ int language_index;
+ int sound_index;
+};
diff --git a/src/citra_qt/configure_system.ui b/src/citra_qt/configure_system.ui
new file mode 100644
index 000000000..6a906b61b
--- /dev/null
+++ b/src/citra_qt/configure_system.ui
@@ -0,0 +1,252 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>ConfigureSystem</class>
+ <widget class="QWidget" name="ConfigureSystem">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>360</width>
+ <height>377</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QGroupBox" name="group_system_settings">
+ <property name="title">
+ <string>System Settings</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0">
+ <widget class="QLabel" name="label_username">
+ <property name="text">
+ <string>Username</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLineEdit" name="edit_username">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maxLength">
+ <number>10</number>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_birthday">
+ <property name="text">
+ <string>Birthday</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <layout class="QHBoxLayout" name="horizontalLayout_birthday2">
+ <item>
+ <widget class="QComboBox" name="combo_birthmonth">
+ <item>
+ <property name="text">
+ <string>January</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>February</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>March</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>April</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>May</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>June</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>July</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>August</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>September</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>October</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>November</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>December</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="combo_birthday"/>
+ </item>
+ </layout>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="label_language">
+ <property name="text">
+ <string>Language</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QComboBox" name="combo_language">
+ <item>
+ <property name="text">
+ <string>Japanese (日本語)</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>English</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>French (français)</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>German (Deutsch)</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Italian (italiano)</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Spanish (español)</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Simplified Chinese (简体中文)</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Korean (한국어)</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Dutch (Nederlands)</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Portuguese (português)</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Russian (Русский)</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Traditional Chinese (正體中文)</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="3" column="0">
+ <widget class="QLabel" name="label_sound">
+ <property name="text">
+ <string>Sound output mode</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1">
+ <widget class="QComboBox" name="combo_sound">
+ <item>
+ <property name="text">
+ <string>Mono</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Stereo</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Surround</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_disable_info">
+ <property name="text">
+ <string>System settings are available only when game is not running.</string>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/citra_qt/main.cpp b/src/citra_qt/main.cpp
index 0ed1ffa5a..68a936087 100644
--- a/src/citra_qt/main.cpp
+++ b/src/citra_qt/main.cpp
@@ -508,11 +508,12 @@ void GMainWindow::ToggleWindowMode() {
}
void GMainWindow::OnConfigure() {
- ConfigureDialog configureDialog(this);
+ ConfigureDialog configureDialog(this, emulation_running);
auto result = configureDialog.exec();
if (result == QDialog::Accepted)
{
configureDialog.applyConfiguration();
+ render_window->ReloadSetKeymaps();
config->Save();
}
}