From fa123843506ee748bf4d220253bc52e58cf36fe6 Mon Sep 17 00:00:00 2001 From: Liam Date: Fri, 26 Jan 2024 23:28:24 -0500 Subject: [PATCH] general: add default configurations for applet mode --- src/common/settings.cpp | 3 + src/common/settings.h | 32 +++++++ src/common/settings_common.h | 1 + src/common/settings_enums.h | 2 + .../hle/service/am/library_applet_creator.cpp | 51 +++++++++-- src/frontend_common/config.cpp | 18 ++++ src/frontend_common/config.h | 2 + src/yuzu/CMakeLists.txt | 3 + src/yuzu/configuration/configure_applets.cpp | 86 +++++++++++++++++++ src/yuzu/configuration/configure_applets.h | 48 +++++++++++ src/yuzu/configuration/configure_applets.ui | 65 ++++++++++++++ src/yuzu/configuration/configure_dialog.cpp | 7 +- src/yuzu/configuration/configure_dialog.h | 2 + src/yuzu/configuration/shared_translation.cpp | 22 +++++ 14 files changed, 334 insertions(+), 8 deletions(-) create mode 100644 src/yuzu/configuration/configure_applets.cpp create mode 100644 src/yuzu/configuration/configure_applets.h create mode 100644 src/yuzu/configuration/configure_applets.ui diff --git a/src/common/settings.cpp b/src/common/settings.cpp index 07709d4e5..80d388fe8 100644 --- a/src/common/settings.cpp +++ b/src/common/settings.cpp @@ -30,6 +30,7 @@ namespace Settings { #define SETTING(TYPE, RANGED) template class Setting #define SWITCHABLE(TYPE, RANGED) template class SwitchableSetting +SETTING(AppletMode, false); SETTING(AudioEngine, false); SETTING(bool, false); SETTING(int, false); @@ -215,6 +216,8 @@ const char* TranslateCategory(Category category) { return "Debugging"; case Category::GpuDriver: return "GpuDriver"; + case Category::LibraryApplet: + return "LibraryApplet"; case Category::Miscellaneous: return "Miscellaneous"; case Category::Network: diff --git a/src/common/settings.h b/src/common/settings.h index f1b1add56..aa054dc24 100644 --- a/src/common/settings.h +++ b/src/common/settings.h @@ -133,6 +133,38 @@ struct TouchFromButtonMap { struct Values { Linkage linkage{}; + // Applet + Setting cabinet_applet_mode{linkage, AppletMode::LLE, "cabinet_applet_mode", + Category::LibraryApplet}; + Setting controller_applet_mode{linkage, AppletMode::HLE, "controller_applet_mode", + Category::LibraryApplet}; + Setting data_erase_applet_mode{linkage, AppletMode::HLE, "data_erase_applet_mode", + Category::LibraryApplet}; + Setting error_applet_mode{linkage, AppletMode::HLE, "error_applet_mode", + Category::LibraryApplet}; + Setting net_connect_applet_mode{linkage, AppletMode::HLE, "net_connect_applet_mode", + Category::LibraryApplet}; + Setting player_select_applet_mode{ + linkage, AppletMode::HLE, "player_select_applet_mode", Category::LibraryApplet}; + Setting swkbd_applet_mode{linkage, AppletMode::LLE, "swkbd_applet_mode", + Category::LibraryApplet}; + Setting mii_edit_applet_mode{linkage, AppletMode::LLE, "mii_edit_applet_mode", + Category::LibraryApplet}; + Setting web_applet_mode{linkage, AppletMode::HLE, "web_applet_mode", + Category::LibraryApplet}; + Setting shop_applet_mode{linkage, AppletMode::HLE, "shop_applet_mode", + Category::LibraryApplet}; + Setting photo_viewer_applet_mode{ + linkage, AppletMode::LLE, "photo_viewer_applet_mode", Category::LibraryApplet}; + Setting offline_web_applet_mode{linkage, AppletMode::LLE, "offline_web_applet_mode", + Category::LibraryApplet}; + Setting login_share_applet_mode{linkage, AppletMode::HLE, "login_share_applet_mode", + Category::LibraryApplet}; + Setting wifi_web_auth_applet_mode{ + linkage, AppletMode::HLE, "wifi_web_auth_applet_mode", Category::LibraryApplet}; + Setting my_page_applet_mode{linkage, AppletMode::LLE, "my_page_applet_mode", + Category::LibraryApplet}; + // Audio SwitchableSetting sink_id{linkage, AudioEngine::Auto, "output_engine", Category::Audio, Specialization::RuntimeList}; diff --git a/src/common/settings_common.h b/src/common/settings_common.h index 987489e8a..2df3f0809 100644 --- a/src/common/settings_common.h +++ b/src/common/settings_common.h @@ -44,6 +44,7 @@ enum class Category : u32 { Services, Paths, Linux, + LibraryApplet, MaxEnum, }; diff --git a/src/common/settings_enums.h b/src/common/settings_enums.h index 617036588..f42367e67 100644 --- a/src/common/settings_enums.h +++ b/src/common/settings_enums.h @@ -151,6 +151,8 @@ ENUM(AspectRatio, R16_9, R4_3, R21_9, R16_10, Stretch); ENUM(ConsoleMode, Handheld, Docked); +ENUM(AppletMode, HLE, LLE); + template inline std::string CanonicalizeEnum(Type id) { const auto group = EnumMetadata::Canonicalizations(); diff --git a/src/core/hle/service/am/library_applet_creator.cpp b/src/core/hle/service/am/library_applet_creator.cpp index ee646bea5..a883a021e 100644 --- a/src/core/hle/service/am/library_applet_creator.cpp +++ b/src/core/hle/service/am/library_applet_creator.cpp @@ -1,6 +1,7 @@ // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later +#include "common/settings.h" #include "core/hle/kernel/k_transfer_memory.h" #include "core/hle/service/am/applet_data_broker.h" #include "core/hle/service/am/applet_manager.h" @@ -16,6 +17,34 @@ namespace Service::AM { namespace { +bool ShouldCreateGuestApplet(AppletId applet_id) { +#define X(Name, name) \ + if (applet_id == AppletId::Name && \ + Settings::values.name##_applet_mode.GetValue() != Settings::AppletMode::LLE) { \ + return false; \ + } + + X(Cabinet, cabinet) + X(Controller, controller) + X(DataErase, data_erase) + X(Error, error) + X(NetConnect, net_connect) + X(ProfileSelect, player_select) + X(SoftwareKeyboard, swkbd) + X(MiiEdit, mii_edit) + X(Web, web) + X(Shop, shop) + X(PhotoViewer, photo_viewer) + X(OfflineWeb, offline_web) + X(LoginShare, login_share) + X(WebAuth, wifi_web_auth) + X(MyPage, my_page) + +#undef X + + return true; +} + AppletProgramId AppletIdToProgramId(AppletId applet_id) { switch (applet_id) { case AppletId::OverlayDisplay: @@ -63,9 +92,10 @@ AppletProgramId AppletIdToProgramId(AppletId applet_id) { } } -[[maybe_unused]] std::shared_ptr CreateGuestApplet( - Core::System& system, std::shared_ptr caller_applet, AppletId applet_id, - LibraryAppletMode mode) { +std::shared_ptr CreateGuestApplet(Core::System& system, + std::shared_ptr caller_applet, + AppletId applet_id, + LibraryAppletMode mode) { const auto program_id = static_cast(AppletIdToProgramId(applet_id)); if (program_id == 0) { // Unknown applet @@ -117,9 +147,10 @@ AppletProgramId AppletIdToProgramId(AppletId applet_id) { return std::make_shared(system, broker, applet); } -[[maybe_unused]] std::shared_ptr CreateFrontendApplet( - Core::System& system, std::shared_ptr caller_applet, AppletId applet_id, - LibraryAppletMode mode) { +std::shared_ptr CreateFrontendApplet(Core::System& system, + std::shared_ptr caller_applet, + AppletId applet_id, + LibraryAppletMode mode) { const auto program_id = static_cast(AppletIdToProgramId(applet_id)); auto process = std::make_unique(system); @@ -163,7 +194,13 @@ void ILibraryAppletCreator::CreateLibraryApplet(HLERequestContext& ctx) { LOG_DEBUG(Service_AM, "called with applet_id={:08X}, applet_mode={:08X}", applet_id, applet_mode); - auto library_applet = CreateFrontendApplet(system, applet, applet_id, applet_mode); + std::shared_ptr library_applet; + if (ShouldCreateGuestApplet(applet_id)) { + library_applet = CreateGuestApplet(system, applet, applet_id, applet_mode); + } + if (!library_applet) { + library_applet = CreateFrontendApplet(system, applet, applet_id, applet_mode); + } if (!library_applet) { LOG_ERROR(Service_AM, "Applet doesn't exist! applet_id={}", applet_id); diff --git a/src/frontend_common/config.cpp b/src/frontend_common/config.cpp index d34624d28..cbbb07ac7 100644 --- a/src/frontend_common/config.cpp +++ b/src/frontend_common/config.cpp @@ -401,6 +401,14 @@ void Config::ReadNetworkValues() { EndGroup(); } +void Config::ReadLibraryAppletValues() { + BeginGroup(Settings::TranslateCategory(Settings::Category::LibraryApplet)); + + ReadCategory(Settings::Category::LibraryApplet); + + EndGroup(); +} + void Config::ReadValues() { if (global) { ReadDataStorageValues(); @@ -410,6 +418,7 @@ void Config::ReadValues() { ReadServiceValues(); ReadWebServiceValues(); ReadMiscellaneousValues(); + ReadLibraryAppletValues(); } ReadControlValues(); ReadCoreValues(); @@ -511,6 +520,7 @@ void Config::SaveValues() { SaveNetworkValues(); SaveWebServiceValues(); SaveMiscellaneousValues(); + SaveLibraryAppletValues(); } else { LOG_DEBUG(Config, "Saving only generic configuration values"); } @@ -691,6 +701,14 @@ void Config::SaveWebServiceValues() { EndGroup(); } +void Config::SaveLibraryAppletValues() { + BeginGroup(Settings::TranslateCategory(Settings::Category::LibraryApplet)); + + WriteCategory(Settings::Category::LibraryApplet); + + EndGroup(); +} + bool Config::ReadBooleanSetting(const std::string& key, const std::optional default_value) { std::string full_key = GetFullKey(key, false); if (!default_value.has_value()) { diff --git a/src/frontend_common/config.h b/src/frontend_common/config.h index 4ecb97044..8b0599cc3 100644 --- a/src/frontend_common/config.h +++ b/src/frontend_common/config.h @@ -88,6 +88,7 @@ protected: void ReadSystemValues(); void ReadWebServiceValues(); void ReadNetworkValues(); + void ReadLibraryAppletValues(); // Read platform specific sections virtual void ReadHidbusValues() = 0; @@ -121,6 +122,7 @@ protected: void SaveScreenshotValues(); void SaveSystemValues(); void SaveWebServiceValues(); + void SaveLibraryAppletValues(); // Save platform specific sections virtual void SaveHidbusValues() = 0; diff --git a/src/yuzu/CMakeLists.txt b/src/yuzu/CMakeLists.txt index 76f06da12..0259a8c29 100644 --- a/src/yuzu/CMakeLists.txt +++ b/src/yuzu/CMakeLists.txt @@ -41,6 +41,9 @@ add_executable(yuzu configuration/configuration_shared.cpp configuration/configuration_shared.h configuration/configure.ui + configuration/configure_applets.cpp + configuration/configure_applets.h + configuration/configure_applets.ui configuration/configure_audio.cpp configuration/configure_audio.h configuration/configure_audio.ui diff --git a/src/yuzu/configuration/configure_applets.cpp b/src/yuzu/configuration/configure_applets.cpp new file mode 100644 index 000000000..513ecb548 --- /dev/null +++ b/src/yuzu/configuration/configure_applets.cpp @@ -0,0 +1,86 @@ +// SPDX-FileCopyrightText: 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "common/settings.h" +#include "core/core.h" +#include "ui_configure_applets.h" +#include "yuzu/configuration/configuration_shared.h" +#include "yuzu/configuration/configure_applets.h" +#include "yuzu/configuration/shared_widget.h" + +ConfigureApplets::ConfigureApplets(Core::System& system_, + std::shared_ptr> group_, + const ConfigurationShared::Builder& builder, QWidget* parent) + : Tab(group_, parent), ui{std::make_unique()}, system{system_} { + ui->setupUi(this); + + Setup(builder); + + SetConfiguration(); +} + +ConfigureApplets::~ConfigureApplets() = default; + +void ConfigureApplets::changeEvent(QEvent* event) { + if (event->type() == QEvent::LanguageChange) { + RetranslateUI(); + } + + QWidget::changeEvent(event); +} + +void ConfigureApplets::RetranslateUI() { + ui->retranslateUi(this); +} + +void ConfigureApplets::Setup(const ConfigurationShared::Builder& builder) { + auto& library_applets_layout = *ui->group_library_applet_modes->layout(); + std::map applets_hold{}; + + std::vector settings; + auto push = [&settings](auto& list) { + for (auto setting : list) { + settings.push_back(setting); + } + }; + + push(Settings::values.linkage.by_category[Settings::Category::LibraryApplet]); + + for (auto setting : settings) { + ConfigurationShared::Widget* widget = builder.BuildWidget(setting, apply_funcs); + + if (widget == nullptr) { + continue; + } + if (!widget->Valid()) { + widget->deleteLater(); + continue; + } + + // Untested applets + if (setting->Id() == Settings::values.data_erase_applet_mode.Id() || + setting->Id() == Settings::values.error_applet_mode.Id() || + setting->Id() == Settings::values.net_connect_applet_mode.Id() || + setting->Id() == Settings::values.web_applet_mode.Id() || + setting->Id() == Settings::values.shop_applet_mode.Id() || + setting->Id() == Settings::values.login_share_applet_mode.Id() || + setting->Id() == Settings::values.wifi_web_auth_applet_mode.Id() || + setting->Id() == Settings::values.my_page_applet_mode.Id()) { + widget->setHidden(true); + } + + applets_hold.emplace(setting->Id(), widget); + } + for (const auto& [label, widget] : applets_hold) { + library_applets_layout.addWidget(widget); + } +} + +void ConfigureApplets::SetConfiguration() {} + +void ConfigureApplets::ApplyConfiguration() { + const bool powered_on = system.IsPoweredOn(); + for (const auto& func : apply_funcs) { + func(powered_on); + } +} diff --git a/src/yuzu/configuration/configure_applets.h b/src/yuzu/configuration/configure_applets.h new file mode 100644 index 000000000..54f494d2f --- /dev/null +++ b/src/yuzu/configuration/configure_applets.h @@ -0,0 +1,48 @@ +// SPDX-FileCopyrightText: 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include "yuzu/configuration/configuration_shared.h" + +class QCheckBox; +class QLineEdit; +class QComboBox; +class QDateTimeEdit; +namespace Core { +class System; +} + +namespace Ui { +class ConfigureApplets; +} + +namespace ConfigurationShared { +class Builder; +} + +class ConfigureApplets : public ConfigurationShared::Tab { +public: + explicit ConfigureApplets(Core::System& system_, + std::shared_ptr> group, + const ConfigurationShared::Builder& builder, + QWidget* parent = nullptr); + ~ConfigureApplets() override; + + void ApplyConfiguration() override; + void SetConfiguration() override; + +private: + void changeEvent(QEvent* event) override; + void RetranslateUI(); + + void Setup(const ConfigurationShared::Builder& builder); + + std::vector> apply_funcs{}; + + std::unique_ptr ui; + bool enabled = false; + + Core::System& system; +}; diff --git a/src/yuzu/configuration/configure_applets.ui b/src/yuzu/configuration/configure_applets.ui new file mode 100644 index 000000000..6f2ca66bd --- /dev/null +++ b/src/yuzu/configuration/configure_applets.ui @@ -0,0 +1,65 @@ + + + ConfigureApplets + + + + 0 + 0 + 605 + 300 + + + + Form + + + Applets + + + + + + + + Applet mode preference + + + + + + + 0 + + + 0 + + + 0 + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + diff --git a/src/yuzu/configuration/configure_dialog.cpp b/src/yuzu/configuration/configure_dialog.cpp index aab54a1cc..37f23388e 100644 --- a/src/yuzu/configuration/configure_dialog.cpp +++ b/src/yuzu/configuration/configure_dialog.cpp @@ -8,6 +8,7 @@ #include "core/core.h" #include "ui_configure.h" #include "vk_device_info.h" +#include "yuzu/configuration/configure_applets.h" #include "yuzu/configuration/configure_audio.h" #include "yuzu/configuration/configure_cpu.h" #include "yuzu/configuration/configure_debug_tab.h" @@ -34,6 +35,7 @@ ConfigureDialog::ConfigureDialog(QWidget* parent, HotkeyRegistry& registry_, : QDialog(parent), ui{std::make_unique()}, registry(registry_), system{system_}, builder{std::make_unique( this, !system_.IsPoweredOn())}, + applets_tab{std::make_unique(system_, nullptr, *builder, this)}, audio_tab{std::make_unique(system_, nullptr, *builder, this)}, cpu_tab{std::make_unique(system_, nullptr, *builder, this)}, debug_tab_tab{std::make_unique(system_, this)}, @@ -58,6 +60,7 @@ ConfigureDialog::ConfigureDialog(QWidget* parent, HotkeyRegistry& registry_, ui->setupUi(this); + ui->tabWidget->addTab(applets_tab.get(), tr("Applets")); ui->tabWidget->addTab(audio_tab.get(), tr("Audio")); ui->tabWidget->addTab(cpu_tab.get(), tr("CPU")); ui->tabWidget->addTab(debug_tab_tab.get(), tr("Debug")); @@ -124,6 +127,7 @@ void ConfigureDialog::ApplyConfiguration() { debug_tab_tab->ApplyConfiguration(); web_tab->ApplyConfiguration(); network_tab->ApplyConfiguration(); + applets_tab->ApplyConfiguration(); system.ApplySettings(); Settings::LogSettings(); } @@ -161,7 +165,8 @@ void ConfigureDialog::PopulateSelectionList() { {{tr("General"), {general_tab.get(), hotkeys_tab.get(), ui_tab.get(), web_tab.get(), debug_tab_tab.get()}}, {tr("System"), - {system_tab.get(), profile_tab.get(), network_tab.get(), filesystem_tab.get()}}, + {system_tab.get(), profile_tab.get(), network_tab.get(), filesystem_tab.get(), + applets_tab.get()}}, {tr("CPU"), {cpu_tab.get()}}, {tr("Graphics"), {graphics_tab.get(), graphics_advanced_tab.get()}}, {tr("Audio"), {audio_tab.get()}}, diff --git a/src/yuzu/configuration/configure_dialog.h b/src/yuzu/configuration/configure_dialog.h index b28ce288c..d0a24a07b 100644 --- a/src/yuzu/configuration/configure_dialog.h +++ b/src/yuzu/configuration/configure_dialog.h @@ -15,6 +15,7 @@ namespace Core { class System; } +class ConfigureApplets; class ConfigureAudio; class ConfigureCpu; class ConfigureDebugTab; @@ -75,6 +76,7 @@ private: std::unique_ptr builder; std::vector tab_group; + std::unique_ptr applets_tab; std::unique_ptr audio_tab; std::unique_ptr cpu_tab; std::unique_ptr debug_tab_tab; diff --git a/src/yuzu/configuration/shared_translation.cpp b/src/yuzu/configuration/shared_translation.cpp index ed9c7d859..ce65b2bf1 100644 --- a/src/yuzu/configuration/shared_translation.cpp +++ b/src/yuzu/configuration/shared_translation.cpp @@ -26,6 +26,23 @@ std::unique_ptr InitializeTranslations(QWidget* parent) { // A setting can be ignored by giving it a blank name + // Applets + INSERT(Settings, cabinet_applet_mode, tr("Amiibo editor"), QStringLiteral()); + INSERT(Settings, controller_applet_mode, tr("Controller configuration"), QStringLiteral()); + INSERT(Settings, data_erase_applet_mode, tr("Data erase"), QStringLiteral()); + INSERT(Settings, error_applet_mode, tr("Error"), QStringLiteral()); + INSERT(Settings, net_connect_applet_mode, tr("Net connect"), QStringLiteral()); + INSERT(Settings, player_select_applet_mode, tr("Player select"), QStringLiteral()); + INSERT(Settings, swkbd_applet_mode, tr("Software keyboard"), QStringLiteral()); + INSERT(Settings, mii_edit_applet_mode, tr("Mii Edit"), QStringLiteral()); + INSERT(Settings, web_applet_mode, tr("Online web"), QStringLiteral()); + INSERT(Settings, shop_applet_mode, tr("Shop"), QStringLiteral()); + INSERT(Settings, photo_viewer_applet_mode, tr("Photo viewer"), QStringLiteral()); + INSERT(Settings, offline_web_applet_mode, tr("Offline web"), QStringLiteral()); + INSERT(Settings, login_share_applet_mode, tr("Login share"), QStringLiteral()); + INSERT(Settings, wifi_web_auth_applet_mode, tr("Wifi web auth"), QStringLiteral()); + INSERT(Settings, my_page_applet_mode, tr("My page"), QStringLiteral()); + // Audio INSERT(Settings, sink_id, tr("Output Engine:"), QStringLiteral()); INSERT(Settings, audio_output_device_id, tr("Output Device:"), QStringLiteral()); @@ -203,6 +220,11 @@ std::unique_ptr ComboboxEnumeration(QWidget* parent) { #define PAIR(ENUM, VALUE, TRANSLATION) {static_cast(Settings::ENUM::VALUE), (TRANSLATION)} // Intentionally skipping VSyncMode to let the UI fill that one out + translations->insert({Settings::EnumMetadata::Index(), + { + PAIR(AppletMode, HLE, tr("Custom frontend")), + PAIR(AppletMode, LLE, tr("Real applet")), + }}); translations->insert({Settings::EnumMetadata::Index(), {