From 281b64daf46ca5a27c29a14cf31f1b8b6f985d46 Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Thu, 22 Nov 2018 15:25:12 -0500 Subject: [PATCH 1/5] ui_settings: Add UI setting for input profile index --- src/yuzu/configuration/config.cpp | 2 ++ src/yuzu/ui_settings.h | 3 +++ 2 files changed, 5 insertions(+) diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp index 83ebbd1fe7..ef028cca34 100644 --- a/src/yuzu/configuration/config.cpp +++ b/src/yuzu/configuration/config.cpp @@ -506,6 +506,7 @@ void Config::ReadValues() { UISettings::values.first_start = qt_config->value("firstStart", true).toBool(); UISettings::values.callout_flags = qt_config->value("calloutFlags", 0).toUInt(); UISettings::values.show_console = qt_config->value("showConsole", false).toBool(); + UISettings::values.profile_index = qt_config->value("profileIndex", 0).toUInt(); qt_config->endGroup(); } @@ -695,6 +696,7 @@ void Config::SaveValues() { qt_config->setValue("firstStart", UISettings::values.first_start); qt_config->setValue("calloutFlags", UISettings::values.callout_flags); qt_config->setValue("showConsole", UISettings::values.show_console); + qt_config->setValue("profileIndex", UISettings::values.profile_index); qt_config->endGroup(); } diff --git a/src/yuzu/ui_settings.h b/src/yuzu/ui_settings.h index e80aebc0a2..035192aeb5 100644 --- a/src/yuzu/ui_settings.h +++ b/src/yuzu/ui_settings.h @@ -58,6 +58,9 @@ struct Values { // logging bool show_console; + // Controllers + uint32_t profile_index; + // Game List bool show_unknown; bool show_add_ons; From 20dffc22a2f706d4a7420457f22137c794efeecc Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Thu, 22 Nov 2018 15:26:29 -0500 Subject: [PATCH 2/5] configure: Use ConfigureInputSimple for Input tab --- src/yuzu/configuration/configure.ui | 52 ++++++++++++++--------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/src/yuzu/configuration/configure.ui b/src/yuzu/configuration/configure.ui index 9b297df283..8706b80d21 100644 --- a/src/yuzu/configuration/configure.ui +++ b/src/yuzu/configuration/configure.ui @@ -7,7 +7,7 @@ 0 0 461 - 500 + 659 @@ -24,17 +24,17 @@ General - - - Game List - - + + + Game List + + System - + Input @@ -54,11 +54,11 @@ Debug - - - Web - - + + + Web + + @@ -77,12 +77,12 @@
configuration/configure_general.h
1 - - ConfigureGameList - QWidget -
configuration/configure_gamelist.h
- 1 -
+ + ConfigureGameList + QWidget +
configuration/configure_gamelist.h
+ 1 +
ConfigureSystem QWidget @@ -102,9 +102,9 @@ 1 - ConfigureInput + ConfigureInputSimple QWidget -
configuration/configure_input.h
+
configuration/configure_input_simple.h
1
@@ -113,12 +113,12 @@
configuration/configure_graphics.h
1
- - ConfigureWeb - QWidget -
configuration/configure_web.h
- 1 -
+ + ConfigureWeb + QWidget +
configuration/configure_web.h
+ 1 +
From 59ca8d458d36f6780b17e7d29e97c6084c23b542 Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Thu, 22 Nov 2018 15:27:07 -0500 Subject: [PATCH 3/5] configure_input: Convert into QDialog --- src/yuzu/configuration/configure_input.cpp | 2 +- src/yuzu/configuration/configure_input.h | 4 +- src/yuzu/configuration/configure_input.ui | 48 ++++++++++++++++++++-- 3 files changed, 47 insertions(+), 7 deletions(-) diff --git a/src/yuzu/configuration/configure_input.cpp b/src/yuzu/configuration/configure_input.cpp index 830d261153..3e78802ce3 100644 --- a/src/yuzu/configuration/configure_input.cpp +++ b/src/yuzu/configuration/configure_input.cpp @@ -34,7 +34,7 @@ void CallConfigureDialog(ConfigureInput& parent, Args&&... args) { } // Anonymous namespace ConfigureInput::ConfigureInput(QWidget* parent) - : QWidget(parent), ui(std::make_unique()) { + : QDialog(parent), ui(std::make_unique()) { ui->setupUi(this); players_controller = { diff --git a/src/yuzu/configuration/configure_input.h b/src/yuzu/configuration/configure_input.h index 1649e4c0b0..b5005e3ea6 100644 --- a/src/yuzu/configuration/configure_input.h +++ b/src/yuzu/configuration/configure_input.h @@ -7,8 +7,8 @@ #include #include +#include #include -#include #include "ui_configure_input.h" @@ -20,7 +20,7 @@ namespace Ui { class ConfigureInput; } -class ConfigureInput : public QWidget { +class ConfigureInput : public QDialog { Q_OBJECT public: diff --git a/src/yuzu/configuration/configure_input.ui b/src/yuzu/configuration/configure_input.ui index dae8277bcd..0a2d9f0246 100644 --- a/src/yuzu/configuration/configure_input.ui +++ b/src/yuzu/configuration/configure_input.ui @@ -1,13 +1,13 @@ ConfigureInput - + 0 0 - 473 - 685 + 384 + 576 @@ -478,6 +478,13 @@
+ + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + @@ -485,5 +492,38 @@ - + + + buttonBox + accepted() + ConfigureInput + accept() + + + 294 + 553 + + + 191 + 287 + + + + + buttonBox + rejected() + ConfigureInput + reject() + + + 294 + 553 + + + 191 + 287 + + + + From 233a80419633db70f7b9e26be69fe62d6040cecf Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Sat, 1 Dec 2018 11:11:11 -0500 Subject: [PATCH 4/5] configure_input: Add ConfigureInputSimple as default input UI config Greatly simplifies the current input UI, while still allowing power users to tweak advanced settings. Adds 'input profiles', which are easy autoconfigurations to make getting started easy and fast. Also has a custom option which brings up the current, full UI. --- src/yuzu/CMakeLists.txt | 3 + src/yuzu/configuration/config.cpp | 10 ++ src/yuzu/configuration/config.h | 1 + .../configuration/configure_input_player.cpp | 1 + .../configuration/configure_input_simple.cpp | 140 ++++++++++++++++++ .../configuration/configure_input_simple.h | 40 +++++ .../configuration/configure_input_simple.ui | 97 ++++++++++++ src/yuzu/ui_settings.h | 2 +- 8 files changed, 293 insertions(+), 1 deletion(-) create mode 100644 src/yuzu/configuration/configure_input_simple.cpp create mode 100644 src/yuzu/configuration/configure_input_simple.h create mode 100644 src/yuzu/configuration/configure_input_simple.ui diff --git a/src/yuzu/CMakeLists.txt b/src/yuzu/CMakeLists.txt index cfca8f4a8d..68448e5649 100644 --- a/src/yuzu/CMakeLists.txt +++ b/src/yuzu/CMakeLists.txt @@ -31,6 +31,8 @@ add_executable(yuzu configuration/configure_input.h configuration/configure_input_player.cpp configuration/configure_input_player.h + configuration/configure_input_simple.cpp + configuration/configure_input_simple.h configuration/configure_mouse_advanced.cpp configuration/configure_mouse_advanced.h configuration/configure_system.cpp @@ -85,6 +87,7 @@ set(UIS configuration/configure_graphics.ui configuration/configure_input.ui configuration/configure_input_player.ui + configuration/configure_input_simple.ui configuration/configure_mouse_advanced.ui configuration/configure_system.ui configuration/configure_touchscreen_advanced.ui diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp index ef028cca34..5e0d149cd9 100644 --- a/src/yuzu/configuration/config.cpp +++ b/src/yuzu/configuration/config.cpp @@ -4,6 +4,7 @@ #include #include "common/file_util.h" +#include "configure_input_simple.h" #include "core/hle/service/acc/profile_manager.h" #include "core/hle/service/hid/controllers/npad.h" #include "input_common/main.h" @@ -342,6 +343,13 @@ void Config::ReadTouchscreenValues() { qt_config->endGroup(); } +void Config::ApplyDefaultProfileIfInputInvalid() { + if (!std::any_of(Settings::values.players.begin(), Settings::values.players.end(), + [](const Settings::PlayerInput& in) { return in.connected; })) { + ApplyInputProfileConfiguration(UISettings::values.profile_index); + } +} + void Config::ReadValues() { qt_config->beginGroup("Controls"); @@ -508,6 +516,8 @@ void Config::ReadValues() { UISettings::values.show_console = qt_config->value("showConsole", false).toBool(); UISettings::values.profile_index = qt_config->value("profileIndex", 0).toUInt(); + ApplyDefaultProfileIfInputInvalid(); + qt_config->endGroup(); } diff --git a/src/yuzu/configuration/config.h b/src/yuzu/configuration/config.h index a1c27bbf9c..e73ad19bbc 100644 --- a/src/yuzu/configuration/config.h +++ b/src/yuzu/configuration/config.h @@ -34,6 +34,7 @@ private: void ReadKeyboardValues(); void ReadMouseValues(); void ReadTouchscreenValues(); + void ApplyDefaultProfileIfInputInvalid(); void SaveValues(); void SavePlayerValues(); diff --git a/src/yuzu/configuration/configure_input_player.cpp b/src/yuzu/configuration/configure_input_player.cpp index 7dadd83c1a..ba2b32c4f2 100644 --- a/src/yuzu/configuration/configure_input_player.cpp +++ b/src/yuzu/configuration/configure_input_player.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include diff --git a/src/yuzu/configuration/configure_input_simple.cpp b/src/yuzu/configuration/configure_input_simple.cpp new file mode 100644 index 0000000000..10c804388f --- /dev/null +++ b/src/yuzu/configuration/configure_input_simple.cpp @@ -0,0 +1,140 @@ +// Copyright 2016 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include +#include +#include +#include + +#include + +#include "ui_configure_input_simple.h" +#include "yuzu/configuration/configure_input.h" +#include "yuzu/configuration/configure_input_player.h" +#include "yuzu/configuration/configure_input_simple.h" +#include "yuzu/ui_settings.h" + +namespace { + +template +void CallConfigureDialog(ConfigureInputSimple* caller, Args&&... args) { + caller->applyConfiguration(); + Dialog dialog(caller, std::forward(args)...); + + const auto res = dialog.exec(); + if (res == QDialog::Accepted) { + dialog.applyConfiguration(); + } +} + +// OnProfileSelect functions should (when applicable): +// - Set controller types +// - Set controller enabled +// - Set docked mode +// - Set advanced controller config/enabled (i.e. debug, kbd, mouse, touch) +// +// OnProfileSelect function should NOT however: +// - Reset any button mappings +// - Open any dialogs +// - Block in any way + +constexpr std::size_t HANDHELD_INDEX = 8; + +void HandheldOnProfileSelect() { + Settings::values.players[HANDHELD_INDEX].connected = true; + Settings::values.players[HANDHELD_INDEX].type = Settings::ControllerType::DualJoycon; + + for (std::size_t player = 0; player < HANDHELD_INDEX; ++player) { + Settings::values.players[player].connected = false; + } + + Settings::values.use_docked_mode = false; + Settings::values.keyboard_enabled = false; + Settings::values.mouse_enabled = false; + Settings::values.debug_pad_enabled = false; + Settings::values.touchscreen.enabled = true; +} + +void DualJoyconsDockedOnProfileSelect() { + Settings::values.players[0].connected = true; + Settings::values.players[0].type = Settings::ControllerType::DualJoycon; + + for (std::size_t player = 1; player <= HANDHELD_INDEX; ++player) { + Settings::values.players[player].connected = false; + } + + Settings::values.use_docked_mode = true; + Settings::values.keyboard_enabled = false; + Settings::values.mouse_enabled = false; + Settings::values.debug_pad_enabled = false; + Settings::values.touchscreen.enabled = false; +} + +// Name, OnProfileSelect (called when selected in drop down), OnConfigure (called when configure +// is clicked) +using InputProfile = + std::tuple, std::function>; + +const std::array INPUT_PROFILES{{ + {ConfigureInputSimple::tr("Single Player - Handheld - Undocked"), HandheldOnProfileSelect, + [](ConfigureInputSimple* caller) { + CallConfigureDialog(caller, HANDHELD_INDEX, false); + }}, + {ConfigureInputSimple::tr("Single Player - Dual Joycons - Docked"), + DualJoyconsDockedOnProfileSelect, + [](ConfigureInputSimple* caller) { + CallConfigureDialog(caller, 1, false); + }}, + {ConfigureInputSimple::tr("Custom"), [] {}, CallConfigureDialog}, +}}; + +} // namespace + +void ApplyInputProfileConfiguration(int profile_index) { + std::get<1>( + INPUT_PROFILES.at(std::min(profile_index, static_cast(INPUT_PROFILES.size() - 1))))(); +} + +ConfigureInputSimple::ConfigureInputSimple(QWidget* parent) + : QWidget(parent), ui(std::make_unique()) { + ui->setupUi(this); + + for (const auto& profile : INPUT_PROFILES) { + ui->profile_combobox->addItem(std::get<0>(profile), std::get<0>(profile)); + } + + connect(ui->profile_combobox, QOverload::of(&QComboBox::currentIndexChanged), this, + &ConfigureInputSimple::OnSelectProfile); + connect(ui->profile_configure, &QPushButton::pressed, this, &ConfigureInputSimple::OnConfigure); + + this->loadConfiguration(); +} + +ConfigureInputSimple::~ConfigureInputSimple() = default; + +void ConfigureInputSimple::applyConfiguration() { + auto index = ui->profile_combobox->currentIndex(); + // Make the stored index for "Custom" very large so that if new profiles are added it + // doesn't change. + if (index >= static_cast(INPUT_PROFILES.size() - 1)) + index = std::numeric_limits::max(); + + UISettings::values.profile_index = index; +} + +void ConfigureInputSimple::loadConfiguration() { + const auto index = UISettings::values.profile_index; + if (index >= static_cast(INPUT_PROFILES.size()) || index < 0) + ui->profile_combobox->setCurrentIndex(static_cast(INPUT_PROFILES.size() - 1)); + else + ui->profile_combobox->setCurrentIndex(index); +} + +void ConfigureInputSimple::OnSelectProfile(int index) { + ApplyInputProfileConfiguration(index); +} + +void ConfigureInputSimple::OnConfigure() { + std::get<2>(INPUT_PROFILES.at(ui->profile_combobox->currentIndex()))(this); +} diff --git a/src/yuzu/configuration/configure_input_simple.h b/src/yuzu/configuration/configure_input_simple.h new file mode 100644 index 0000000000..5b6b699948 --- /dev/null +++ b/src/yuzu/configuration/configure_input_simple.h @@ -0,0 +1,40 @@ +// Copyright 2016 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include + +#include + +class QPushButton; +class QString; +class QTimer; + +namespace Ui { +class ConfigureInputSimple; +} + +// Used by configuration loader to apply a profile if the input is invalid. +void ApplyInputProfileConfiguration(int profile_index); + +class ConfigureInputSimple : public QWidget { + Q_OBJECT + +public: + explicit ConfigureInputSimple(QWidget* parent = nullptr); + ~ConfigureInputSimple() override; + + /// Save all button configurations to settings file + void applyConfiguration(); + +private: + /// Load configuration settings. + void loadConfiguration(); + + void OnSelectProfile(int index); + void OnConfigure(); + + std::unique_ptr ui; +}; diff --git a/src/yuzu/configuration/configure_input_simple.ui b/src/yuzu/configuration/configure_input_simple.ui new file mode 100644 index 0000000000..c4889caa99 --- /dev/null +++ b/src/yuzu/configuration/configure_input_simple.ui @@ -0,0 +1,97 @@ + + + ConfigureInputSimple + + + + 0 + 0 + 473 + 685 + + + + ConfigureInputSimple + + + + + + + + Profile + + + + + + Configure + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 250 + 0 + + + + + + + + Choose a controller configuration: + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + diff --git a/src/yuzu/ui_settings.h b/src/yuzu/ui_settings.h index 035192aeb5..2f434eab0e 100644 --- a/src/yuzu/ui_settings.h +++ b/src/yuzu/ui_settings.h @@ -59,7 +59,7 @@ struct Values { bool show_console; // Controllers - uint32_t profile_index; + int profile_index; // Game List bool show_unknown; From c07059e7fdead17b47acea02ab1a6ac13c8f4d9c Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Tue, 4 Dec 2018 22:01:01 -0500 Subject: [PATCH 5/5] configure_input_simple: Properly signal docked mode change --- src/yuzu/configuration/configure_input.cpp | 58 +++++++++---------- src/yuzu/configuration/configure_input.h | 4 +- .../configuration/configure_input_simple.cpp | 2 + 3 files changed, 31 insertions(+), 33 deletions(-) diff --git a/src/yuzu/configuration/configure_input.cpp b/src/yuzu/configuration/configure_input.cpp index 3e78802ce3..f39d57998a 100644 --- a/src/yuzu/configuration/configure_input.cpp +++ b/src/yuzu/configuration/configure_input.cpp @@ -20,6 +20,33 @@ #include "yuzu/configuration/configure_input_player.h" #include "yuzu/configuration/configure_mouse_advanced.h" +void OnDockedModeChanged(bool last_state, bool new_state) { + if (last_state == new_state) { + return; + } + + Core::System& system{Core::System::GetInstance()}; + if (!system.IsPoweredOn()) { + return; + } + Service::SM::ServiceManager& sm = system.ServiceManager(); + + // Message queue is shared between these services, we just need to signal an operation + // change to one and it will handle both automatically + auto applet_oe = sm.GetService("appletOE"); + auto applet_ae = sm.GetService("appletAE"); + bool has_signalled = false; + + if (applet_oe != nullptr) { + applet_oe->GetMessageQueue()->OperationModeChanged(); + has_signalled = true; + } + + if (applet_ae != nullptr && !has_signalled) { + applet_ae->GetMessageQueue()->OperationModeChanged(); + } +} + namespace { template void CallConfigureDialog(ConfigureInput& parent, Args&&... args) { @@ -90,37 +117,6 @@ ConfigureInput::ConfigureInput(QWidget* parent) ConfigureInput::~ConfigureInput() = default; -void ConfigureInput::OnDockedModeChanged(bool last_state, bool new_state) { - if (ui->use_docked_mode->isChecked() && ui->handheld_connected->isChecked()) { - ui->handheld_connected->setChecked(false); - } - - if (last_state == new_state) { - return; - } - - Core::System& system{Core::System::GetInstance()}; - if (!system.IsPoweredOn()) { - return; - } - Service::SM::ServiceManager& sm = system.ServiceManager(); - - // Message queue is shared between these services, we just need to signal an operation - // change to one and it will handle both automatically - auto applet_oe = sm.GetService("appletOE"); - auto applet_ae = sm.GetService("appletAE"); - bool has_signalled = false; - - if (applet_oe != nullptr) { - applet_oe->GetMessageQueue()->OperationModeChanged(); - has_signalled = true; - } - - if (applet_ae != nullptr && !has_signalled) { - applet_ae->GetMessageQueue()->OperationModeChanged(); - } -} - void ConfigureInput::applyConfiguration() { for (std::size_t i = 0; i < players_controller.size(); ++i) { const auto controller_type_index = players_controller[i]->currentIndex(); diff --git a/src/yuzu/configuration/configure_input.h b/src/yuzu/configuration/configure_input.h index b5005e3ea6..b8e62cc2b6 100644 --- a/src/yuzu/configuration/configure_input.h +++ b/src/yuzu/configuration/configure_input.h @@ -20,6 +20,8 @@ namespace Ui { class ConfigureInput; } +void OnDockedModeChanged(bool last_state, bool new_state); + class ConfigureInput : public QDialog { Q_OBJECT @@ -33,8 +35,6 @@ public: private: void updateUIEnabled(); - void OnDockedModeChanged(bool last_state, bool new_state); - /// Load configuration settings. void loadConfiguration(); /// Restore all buttons to their default values. diff --git a/src/yuzu/configuration/configure_input_simple.cpp b/src/yuzu/configuration/configure_input_simple.cpp index 10c804388f..b4f3724bd6 100644 --- a/src/yuzu/configuration/configure_input_simple.cpp +++ b/src/yuzu/configuration/configure_input_simple.cpp @@ -132,7 +132,9 @@ void ConfigureInputSimple::loadConfiguration() { } void ConfigureInputSimple::OnSelectProfile(int index) { + const auto old_docked = Settings::values.use_docked_mode; ApplyInputProfileConfiguration(index); + OnDockedModeChanged(old_docked, Settings::values.use_docked_mode); } void ConfigureInputSimple::OnConfigure() {