diff options
Diffstat (limited to 'src/citra_qt')
| -rw-r--r-- | src/citra_qt/CMakeLists.txt | 6 | ||||
| -rw-r--r-- | src/citra_qt/Info.plist | 2 | ||||
| -rw-r--r-- | src/citra_qt/config.cpp | 11 | ||||
| -rw-r--r-- | src/citra_qt/config.h | 6 | ||||
| -rw-r--r-- | src/citra_qt/configure.ui | 19 | ||||
| -rw-r--r-- | src/citra_qt/configure_dialog.cpp | 10 | ||||
| -rw-r--r-- | src/citra_qt/configure_dialog.h | 3 | ||||
| -rw-r--r-- | src/citra_qt/configure_input.cpp | 149 | ||||
| -rw-r--r-- | src/citra_qt/configure_input.h | 63 | ||||
| -rw-r--r-- | src/citra_qt/configure_input.ui | 593 | ||||
| -rw-r--r-- | src/citra_qt/configure_system.cpp | 136 | ||||
| -rw-r--r-- | src/citra_qt/configure_system.h | 38 | ||||
| -rw-r--r-- | src/citra_qt/configure_system.ui | 252 | ||||
| -rw-r--r-- | src/citra_qt/main.cpp | 3 |
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(); } } |
