diff options
23 files changed, 673 insertions, 380 deletions
| diff --git a/src/android/app/src/main/AndroidManifest.xml b/src/android/app/src/main/AndroidManifest.xml index f10131b24..f011bd696 100644 --- a/src/android/app/src/main/AndroidManifest.xml +++ b/src/android/app/src/main/AndroidManifest.xml @@ -31,6 +31,9 @@ SPDX-License-Identifier: GPL-3.0-or-later          android:dataExtractionRules="@xml/data_extraction_rules_api_31"          android:enableOnBackInvokedCallback="true"> +        <meta-data android:name="android.game_mode_config" +            android:resource="@xml/game_mode_config" /> +          <activity              android:name="org.yuzu.yuzu_emu.ui.main.MainActivity"              android:exported="true" diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/NativeLibrary.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/NativeLibrary.kt index 010c44951..b7556e353 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/NativeLibrary.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/NativeLibrary.kt @@ -548,6 +548,15 @@ object NativeLibrary {      external fun getSavePath(programId: String): String      /** +     * Gets the root save directory for the default profile as either +     * /user/save/account/<user id raw string> or /user/save/000...000/<user id> +     * +     * @param future If true, returns the /user/save/account/... directory +     * @return Save data path that may not exist yet +     */ +    external fun getDefaultProfileSaveDataRoot(future: Boolean): String + +    /**       * Adds a file to the manual filesystem provider in our EmulationSession instance       * @param path Path to the file we're adding. Can be a string representation of a [Uri] or       * a normal path diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/InstallableFragment.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/InstallableFragment.kt index 569727b90..5b4bf2c9f 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/InstallableFragment.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/InstallableFragment.kt @@ -7,20 +7,39 @@ import android.os.Bundle  import android.view.LayoutInflater  import android.view.View  import android.view.ViewGroup +import android.widget.Toast +import androidx.activity.result.contract.ActivityResultContracts  import androidx.core.view.ViewCompat  import androidx.core.view.WindowInsetsCompat  import androidx.core.view.updatePadding  import androidx.fragment.app.Fragment  import androidx.fragment.app.activityViewModels +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.lifecycleScope +import androidx.lifecycle.repeatOnLifecycle  import androidx.navigation.findNavController  import androidx.recyclerview.widget.GridLayoutManager  import com.google.android.material.transition.MaterialSharedAxis +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext +import org.yuzu.yuzu_emu.NativeLibrary  import org.yuzu.yuzu_emu.R +import org.yuzu.yuzu_emu.YuzuApplication  import org.yuzu.yuzu_emu.adapters.InstallableAdapter  import org.yuzu.yuzu_emu.databinding.FragmentInstallablesBinding  import org.yuzu.yuzu_emu.model.HomeViewModel  import org.yuzu.yuzu_emu.model.Installable +import org.yuzu.yuzu_emu.model.TaskState  import org.yuzu.yuzu_emu.ui.main.MainActivity +import org.yuzu.yuzu_emu.utils.DirectoryInitialization +import org.yuzu.yuzu_emu.utils.FileUtil +import java.io.BufferedInputStream +import java.io.BufferedOutputStream +import java.io.File +import java.math.BigInteger +import java.time.LocalDateTime +import java.time.format.DateTimeFormatter  class InstallableFragment : Fragment() {      private var _binding: FragmentInstallablesBinding? = null @@ -56,6 +75,17 @@ class InstallableFragment : Fragment() {              binding.root.findNavController().popBackStack()          } +        viewLifecycleOwner.lifecycleScope.launch { +            repeatOnLifecycle(Lifecycle.State.CREATED) { +                homeViewModel.openImportSaves.collect { +                    if (it) { +                        importSaves.launch(arrayOf("application/zip")) +                        homeViewModel.setOpenImportSaves(false) +                    } +                } +            } +        } +          val installables = listOf(              Installable(                  R.string.user_data, @@ -64,6 +94,43 @@ class InstallableFragment : Fragment() {                  export = { mainActivity.exportUserData.launch("export.zip") }              ),              Installable( +                R.string.manage_save_data, +                R.string.manage_save_data_description, +                install = { +                    MessageDialogFragment.newInstance( +                        requireActivity(), +                        titleId = R.string.import_save_warning, +                        descriptionId = R.string.import_save_warning_description, +                        positiveAction = { homeViewModel.setOpenImportSaves(true) } +                    ).show(parentFragmentManager, MessageDialogFragment.TAG) +                }, +                export = { +                    val oldSaveDataFolder = File( +                        "${DirectoryInitialization.userDirectory}/nand" + +                            NativeLibrary.getDefaultProfileSaveDataRoot(false) +                    ) +                    val futureSaveDataFolder = File( +                        "${DirectoryInitialization.userDirectory}/nand" + +                            NativeLibrary.getDefaultProfileSaveDataRoot(true) +                    ) +                    if (!oldSaveDataFolder.exists() && !futureSaveDataFolder.exists()) { +                        Toast.makeText( +                            YuzuApplication.appContext, +                            R.string.no_save_data_found, +                            Toast.LENGTH_SHORT +                        ).show() +                        return@Installable +                    } else { +                        exportSaves.launch( +                            "${getString(R.string.save_data)} " + +                                LocalDateTime.now().format( +                                    DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm") +                                ) +                        ) +                    } +                } +            ), +            Installable(                  R.string.install_game_content,                  R.string.install_game_content_description,                  install = { mainActivity.installGameUpdate.launch(arrayOf("*/*")) } @@ -121,4 +188,156 @@ class InstallableFragment : Fragment() {              windowInsets          } + +    private val importSaves = +        registerForActivityResult(ActivityResultContracts.OpenDocument()) { result -> +            if (result == null) { +                return@registerForActivityResult +            } + +            val inputZip = requireContext().contentResolver.openInputStream(result) +            val cacheSaveDir = File("${requireContext().cacheDir.path}/saves/") +            cacheSaveDir.mkdir() + +            if (inputZip == null) { +                Toast.makeText( +                    YuzuApplication.appContext, +                    getString(R.string.fatal_error), +                    Toast.LENGTH_LONG +                ).show() +                return@registerForActivityResult +            } + +            IndeterminateProgressDialogFragment.newInstance( +                requireActivity(), +                R.string.save_files_importing, +                false +            ) { +                try { +                    FileUtil.unzipToInternalStorage(BufferedInputStream(inputZip), cacheSaveDir) +                    val files = cacheSaveDir.listFiles() +                    var successfulImports = 0 +                    var failedImports = 0 +                    if (files != null) { +                        for (file in files) { +                            if (file.isDirectory) { +                                val baseSaveDir = +                                    NativeLibrary.getSavePath(BigInteger(file.name, 16).toString()) +                                if (baseSaveDir.isEmpty()) { +                                    failedImports++ +                                    continue +                                } + +                                val internalSaveFolder = File( +                                    "${DirectoryInitialization.userDirectory}/nand$baseSaveDir" +                                ) +                                internalSaveFolder.deleteRecursively() +                                internalSaveFolder.mkdir() +                                file.copyRecursively(target = internalSaveFolder, overwrite = true) +                                successfulImports++ +                            } +                        } +                    } + +                    withContext(Dispatchers.Main) { +                        if (successfulImports == 0) { +                            MessageDialogFragment.newInstance( +                                requireActivity(), +                                titleId = R.string.save_file_invalid_zip_structure, +                                descriptionId = R.string.save_file_invalid_zip_structure_description +                            ).show(parentFragmentManager, MessageDialogFragment.TAG) +                            return@withContext +                        } +                        val successString = if (failedImports > 0) { +                            """ +                            ${ +                            requireContext().resources.getQuantityString( +                                R.plurals.saves_import_success, +                                successfulImports, +                                successfulImports +                            ) +                            } +                            ${ +                            requireContext().resources.getQuantityString( +                                R.plurals.saves_import_failed, +                                failedImports, +                                failedImports +                            ) +                            } +                            """ +                        } else { +                            requireContext().resources.getQuantityString( +                                R.plurals.saves_import_success, +                                successfulImports, +                                successfulImports +                            ) +                        } +                        MessageDialogFragment.newInstance( +                            requireActivity(), +                            titleId = R.string.import_complete, +                            descriptionString = successString +                        ).show(parentFragmentManager, MessageDialogFragment.TAG) +                    } + +                    cacheSaveDir.deleteRecursively() +                } catch (e: Exception) { +                    Toast.makeText( +                        YuzuApplication.appContext, +                        getString(R.string.fatal_error), +                        Toast.LENGTH_LONG +                    ).show() +                } +            }.show(parentFragmentManager, IndeterminateProgressDialogFragment.TAG) +        } + +    private val exportSaves = registerForActivityResult( +        ActivityResultContracts.CreateDocument("application/zip") +    ) { result -> +        if (result == null) { +            return@registerForActivityResult +        } + +        IndeterminateProgressDialogFragment.newInstance( +            requireActivity(), +            R.string.save_files_exporting, +            false +        ) { +            val cacheSaveDir = File("${requireContext().cacheDir.path}/saves/") +            cacheSaveDir.mkdir() + +            val oldSaveDataFolder = File( +                "${DirectoryInitialization.userDirectory}/nand" + +                    NativeLibrary.getDefaultProfileSaveDataRoot(false) +            ) +            if (oldSaveDataFolder.exists()) { +                oldSaveDataFolder.copyRecursively(cacheSaveDir) +            } + +            val futureSaveDataFolder = File( +                "${DirectoryInitialization.userDirectory}/nand" + +                    NativeLibrary.getDefaultProfileSaveDataRoot(true) +            ) +            if (futureSaveDataFolder.exists()) { +                futureSaveDataFolder.copyRecursively(cacheSaveDir) +            } + +            val saveFilesTotal = cacheSaveDir.listFiles()?.size ?: 0 +            if (saveFilesTotal == 0) { +                cacheSaveDir.deleteRecursively() +                return@newInstance getString(R.string.no_save_data_found) +            } + +            val zipResult = FileUtil.zipFromInternalStorage( +                cacheSaveDir, +                cacheSaveDir.path, +                BufferedOutputStream(requireContext().contentResolver.openOutputStream(result)) +            ) +            cacheSaveDir.deleteRecursively() + +            return@newInstance when (zipResult) { +                TaskState.Completed -> getString(R.string.export_success) +                TaskState.Cancelled, TaskState.Failed -> getString(R.string.export_failed) +            } +        }.show(parentFragmentManager, IndeterminateProgressDialogFragment.TAG) +    }  } diff --git a/src/android/app/src/main/jni/native.cpp b/src/android/app/src/main/jni/native.cpp index 056920a4a..136c8dee6 100644 --- a/src/android/app/src/main/jni/native.cpp +++ b/src/android/app/src/main/jni/native.cpp @@ -862,6 +862,9 @@ jobjectArray Java_org_yuzu_yuzu_1emu_NativeLibrary_getAddonsForFile(JNIEnv* env,  jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_getSavePath(JNIEnv* env, jobject jobj,                                                            jstring jprogramId) {      auto program_id = EmulationSession::GetProgramId(env, jprogramId); +    if (program_id == 0) { +        return ToJString(env, ""); +    }      auto& system = EmulationSession::GetInstance().System(); @@ -880,6 +883,19 @@ jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_getSavePath(JNIEnv* env, jobject j      return ToJString(env, user_save_data_path);  } +jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_getDefaultProfileSaveDataRoot(JNIEnv* env, +                                                                            jobject jobj, +                                                                            jboolean jfuture) { +    Service::Account::ProfileManager manager; +    // TODO: Pass in a selected user once we get the relevant UI working +    const auto user_id = manager.GetUser(static_cast<std::size_t>(0)); +    ASSERT(user_id); + +    const auto user_save_data_root = +        FileSys::SaveDataFactory::GetUserGameSaveDataRoot(user_id->AsU128(), jfuture); +    return ToJString(env, user_save_data_root); +} +  void Java_org_yuzu_yuzu_1emu_NativeLibrary_addFileToFilesystemProvider(JNIEnv* env, jobject jobj,                                                                         jstring jpath) {      EmulationSession::GetInstance().ConfigureFilesystemProvider(GetJString(env, jpath)); diff --git a/src/android/app/src/main/res/values/strings.xml b/src/android/app/src/main/res/values/strings.xml index 83aa1b781..3bb92ad67 100644 --- a/src/android/app/src/main/res/values/strings.xml +++ b/src/android/app/src/main/res/values/strings.xml @@ -133,6 +133,15 @@      <string name="add_game_folder">Add game folder</string>      <string name="folder_already_added">This folder was already added!</string>      <string name="game_folder_properties">Game folder properties</string> +    <plurals name="saves_import_failed"> +        <item quantity="one">Failed to import %d save</item> +        <item quantity="other">Failed to import %d saves</item> +    </plurals> +    <plurals name="saves_import_success"> +        <item quantity="one">Successfully imported %d save</item> +        <item quantity="other">Successfully imported %d saves</item> +    </plurals> +    <string name="no_save_data_found">No save data found</string>      <!-- Applet launcher strings -->      <string name="applets">Applet launcher</string> @@ -276,6 +285,7 @@      <string name="global">Global</string>      <string name="custom">Custom</string>      <string name="notice">Notice</string> +    <string name="import_complete">Import complete</string>      <!-- GPU driver installation -->      <string name="select_gpu_driver">Select GPU driver</string> diff --git a/src/android/app/src/main/res/xml/game_mode_config.xml b/src/android/app/src/main/res/xml/game_mode_config.xml new file mode 100644 index 000000000..b28dd3a11 --- /dev/null +++ b/src/android/app/src/main/res/xml/game_mode_config.xml @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<game-mode-config +    xmlns:android="http://schemas.android.com/apk/res/android" +    android:supportsBatteryGameMode="true" +    android:supportsPerformanceGameMode="true" +    android:allowGameDownscaling="false" +    android:allowGameFpsOverride="false"/> diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index adcc23c18..753f55ebe 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -708,24 +708,24 @@ add_library(core STATIC      hle/service/server_manager.h      hle/service/service.cpp      hle/service/service.h -    hle/service/set/set.cpp -    hle/service/set/set.h      hle/service/set/appln_settings.cpp      hle/service/set/appln_settings.h      hle/service/set/device_settings.cpp      hle/service/set/device_settings.h +    hle/service/set/factory_settings_server.cpp +    hle/service/set/factory_settings_server.h +    hle/service/set/firmware_debug_settings_server.cpp +    hle/service/set/firmware_debug_settings_server.h      hle/service/set/private_settings.cpp      hle/service/set/private_settings.h -    hle/service/set/set_cal.cpp -    hle/service/set/set_cal.h -    hle/service/set/set_fd.cpp -    hle/service/set/set_fd.h -    hle/service/set/set_sys.cpp -    hle/service/set/set_sys.h      hle/service/set/settings.cpp      hle/service/set/settings.h +    hle/service/set/settings_server.cpp +    hle/service/set/settings_server.h      hle/service/set/system_settings.cpp      hle/service/set/system_settings.h +    hle/service/set/system_settings_server.cpp +    hle/service/set/system_settings_server.h      hle/service/sm/sm.cpp      hle/service/sm/sm.h      hle/service/sm/sm_controller.cpp diff --git a/src/core/file_sys/patch_manager.cpp b/src/core/file_sys/patch_manager.cpp index cc7af2ea3..4a3dbc6a3 100644 --- a/src/core/file_sys/patch_manager.cpp +++ b/src/core/file_sys/patch_manager.cpp @@ -26,7 +26,7 @@  #include "core/file_sys/vfs_vector.h"  #include "core/hle/service/filesystem/filesystem.h"  #include "core/hle/service/ns/language.h" -#include "core/hle/service/set/set.h" +#include "core/hle/service/set/settings_server.h"  #include "core/loader/loader.h"  #include "core/loader/nso.h"  #include "core/memory/cheat_engine.h" diff --git a/src/core/file_sys/savedata_factory.cpp b/src/core/file_sys/savedata_factory.cpp index 8d5d593e8..12b3bd797 100644 --- a/src/core/file_sys/savedata_factory.cpp +++ b/src/core/file_sys/savedata_factory.cpp @@ -189,6 +189,15 @@ std::string SaveDataFactory::GetFullPath(Core::System& system, VirtualDir dir,      }  } +std::string SaveDataFactory::GetUserGameSaveDataRoot(u128 user_id, bool future) { +    if (future) { +        Common::UUID uuid; +        std::memcpy(uuid.uuid.data(), user_id.data(), sizeof(Common::UUID)); +        return fmt::format("/user/save/account/{}", uuid.RawString()); +    } +    return fmt::format("/user/save/{:016X}/{:016X}{:016X}", 0, user_id[1], user_id[0]); +} +  SaveDataSize SaveDataFactory::ReadSaveDataSize(SaveDataType type, u64 title_id,                                                 u128 user_id) const {      const auto path = diff --git a/src/core/file_sys/savedata_factory.h b/src/core/file_sys/savedata_factory.h index e3a0f8cef..fd4887e99 100644 --- a/src/core/file_sys/savedata_factory.h +++ b/src/core/file_sys/savedata_factory.h @@ -101,6 +101,7 @@ public:      static std::string GetSaveDataSpaceIdPath(SaveDataSpaceId space);      static std::string GetFullPath(Core::System& system, VirtualDir dir, SaveDataSpaceId space,                                     SaveDataType type, u64 title_id, u128 user_id, u64 save_id); +    static std::string GetUserGameSaveDataRoot(u128 user_id, bool future);      SaveDataSize ReadSaveDataSize(SaveDataType type, u64 title_id, u128 user_id) const;      void WriteSaveDataSize(SaveDataType type, u64 title_id, u128 user_id, diff --git a/src/core/hle/service/ns/language.cpp b/src/core/hle/service/ns/language.cpp index 036a1e9b7..b1a7686ff 100644 --- a/src/core/hle/service/ns/language.cpp +++ b/src/core/hle/service/ns/language.cpp @@ -2,7 +2,7 @@  // SPDX-License-Identifier: GPL-2.0-or-later  #include "core/hle/service/ns/language.h" -#include "core/hle/service/set/set.h" +#include "core/hle/service/set/settings_server.h"  namespace Service::NS { diff --git a/src/core/hle/service/ns/ns.cpp b/src/core/hle/service/ns/ns.cpp index f9e0e272d..a25b79513 100644 --- a/src/core/hle/service/ns/ns.cpp +++ b/src/core/hle/service/ns/ns.cpp @@ -16,7 +16,7 @@  #include "core/hle/service/ns/ns.h"  #include "core/hle/service/ns/pdm_qry.h"  #include "core/hle/service/server_manager.h" -#include "core/hle/service/set/set.h" +#include "core/hle/service/set/settings_server.h"  namespace Service::NS { diff --git a/src/core/hle/service/set/set_cal.cpp b/src/core/hle/service/set/factory_settings_server.cpp index d2c0d536f..a8e307ae2 100644 --- a/src/core/hle/service/set/set_cal.cpp +++ b/src/core/hle/service/set/factory_settings_server.cpp @@ -1,11 +1,12 @@  // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project  // SPDX-License-Identifier: GPL-2.0-or-later -#include "core/hle/service/set/set_cal.h" +#include "core/hle/service/set/factory_settings_server.h"  namespace Service::Set { -SET_CAL::SET_CAL(Core::System& system_) : ServiceFramework{system_, "set:cal"} { +IFactorySettingsServer::IFactorySettingsServer(Core::System& system_) +    : ServiceFramework{system_, "set:cal"} {      // clang-format off      static const FunctionInfo functions[] = {          {0, nullptr, "GetBluetoothBdAddress"}, @@ -57,6 +58,6 @@ SET_CAL::SET_CAL(Core::System& system_) : ServiceFramework{system_, "set:cal"} {      RegisterHandlers(functions);  } -SET_CAL::~SET_CAL() = default; +IFactorySettingsServer::~IFactorySettingsServer() = default;  } // namespace Service::Set diff --git a/src/core/hle/service/set/set_fd.h b/src/core/hle/service/set/factory_settings_server.h index 150a7cbce..e64cd1380 100644 --- a/src/core/hle/service/set/set_fd.h +++ b/src/core/hle/service/set/factory_settings_server.h @@ -11,10 +11,10 @@ class System;  namespace Service::Set { -class SET_FD final : public ServiceFramework<SET_FD> { +class IFactorySettingsServer final : public ServiceFramework<IFactorySettingsServer> {  public: -    explicit SET_FD(Core::System& system_); -    ~SET_FD() override; +    explicit IFactorySettingsServer(Core::System& system_); +    ~IFactorySettingsServer() override;  };  } // namespace Service::Set diff --git a/src/core/hle/service/set/set_fd.cpp b/src/core/hle/service/set/firmware_debug_settings_server.cpp index 278ef32e1..b3a5e623b 100644 --- a/src/core/hle/service/set/set_fd.cpp +++ b/src/core/hle/service/set/firmware_debug_settings_server.cpp @@ -1,11 +1,12 @@  // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project  // SPDX-License-Identifier: GPL-2.0-or-later -#include "core/hle/service/set/set_fd.h" +#include "core/hle/service/set/firmware_debug_settings_server.h"  namespace Service::Set { -SET_FD::SET_FD(Core::System& system_) : ServiceFramework{system_, "set:fd"} { +IFirmwareDebugSettingsServer::IFirmwareDebugSettingsServer(Core::System& system_) +    : ServiceFramework{system_, "set:fd"} {      // clang-format off      static const FunctionInfo functions[] = {          {2, nullptr, "SetSettingsItemValue"}, @@ -23,6 +24,6 @@ SET_FD::SET_FD(Core::System& system_) : ServiceFramework{system_, "set:fd"} {      RegisterHandlers(functions);  } -SET_FD::~SET_FD() = default; +IFirmwareDebugSettingsServer::~IFirmwareDebugSettingsServer() = default;  } // namespace Service::Set diff --git a/src/core/hle/service/set/set_cal.h b/src/core/hle/service/set/firmware_debug_settings_server.h index 8f50278ed..5dae2263e 100644 --- a/src/core/hle/service/set/set_cal.h +++ b/src/core/hle/service/set/firmware_debug_settings_server.h @@ -11,10 +11,10 @@ class System;  namespace Service::Set { -class SET_CAL final : public ServiceFramework<SET_CAL> { +class IFirmwareDebugSettingsServer final : public ServiceFramework<IFirmwareDebugSettingsServer> {  public: -    explicit SET_CAL(Core::System& system_); -    ~SET_CAL() override; +    explicit IFirmwareDebugSettingsServer(Core::System& system_); +    ~IFirmwareDebugSettingsServer() override;  };  } // namespace Service::Set diff --git a/src/core/hle/service/set/settings.cpp b/src/core/hle/service/set/settings.cpp index c48844f77..73d021ff4 100644 --- a/src/core/hle/service/set/settings.cpp +++ b/src/core/hle/service/set/settings.cpp @@ -2,21 +2,24 @@  // SPDX-License-Identifier: GPL-2.0-or-later  #include "core/hle/service/server_manager.h" -#include "core/hle/service/set/set.h" -#include "core/hle/service/set/set_cal.h" -#include "core/hle/service/set/set_fd.h" -#include "core/hle/service/set/set_sys.h" +#include "core/hle/service/set/factory_settings_server.h" +#include "core/hle/service/set/firmware_debug_settings_server.h"  #include "core/hle/service/set/settings.h" +#include "core/hle/service/set/settings_server.h" +#include "core/hle/service/set/system_settings_server.h"  namespace Service::Set {  void LoopProcess(Core::System& system) {      auto server_manager = std::make_unique<ServerManager>(system); -    server_manager->RegisterNamedService("set", std::make_shared<SET>(system)); -    server_manager->RegisterNamedService("set:cal", std::make_shared<SET_CAL>(system)); -    server_manager->RegisterNamedService("set:fd", std::make_shared<SET_FD>(system)); -    server_manager->RegisterNamedService("set:sys", std::make_shared<SET_SYS>(system)); +    server_manager->RegisterNamedService("set", std::make_shared<ISettingsServer>(system)); +    server_manager->RegisterNamedService("set:cal", +                                         std::make_shared<IFactorySettingsServer>(system)); +    server_manager->RegisterNamedService("set:fd", +                                         std::make_shared<IFirmwareDebugSettingsServer>(system)); +    server_manager->RegisterNamedService("set:sys", +                                         std::make_shared<ISystemSettingsServer>(system));      ServerManager::RunServer(std::move(server_manager));  } diff --git a/src/core/hle/service/set/set.cpp b/src/core/hle/service/set/settings_server.cpp index 2082b8ef7..b2caa00ff 100644 --- a/src/core/hle/service/set/set.cpp +++ b/src/core/hle/service/set/settings_server.cpp @@ -7,7 +7,7 @@  #include "common/logging/log.h"  #include "common/settings.h"  #include "core/hle/service/ipc_helpers.h" -#include "core/hle/service/set/set.h" +#include "core/hle/service/set/settings_server.h"  namespace Service::Set {  namespace { @@ -58,13 +58,36 @@ LanguageCode GetLanguageCodeFromIndex(std::size_t index) {      return available_language_codes.at(index);  } -void SET::GetAvailableLanguageCodes(HLERequestContext& ctx) { +ISettingsServer::ISettingsServer(Core::System& system_) : ServiceFramework{system_, "set"} { +    // clang-format off +    static const FunctionInfo functions[] = { +        {0, &ISettingsServer::GetLanguageCode, "GetLanguageCode"}, +        {1, &ISettingsServer::GetAvailableLanguageCodes, "GetAvailableLanguageCodes"}, +        {2, &ISettingsServer::MakeLanguageCode, "MakeLanguageCode"}, +        {3, &ISettingsServer::GetAvailableLanguageCodeCount, "GetAvailableLanguageCodeCount"}, +        {4, &ISettingsServer::GetRegionCode, "GetRegionCode"}, +        {5, &ISettingsServer::GetAvailableLanguageCodes2, "GetAvailableLanguageCodes2"}, +        {6, &ISettingsServer::GetAvailableLanguageCodeCount2, "GetAvailableLanguageCodeCount2"}, +        {7, &ISettingsServer::GetKeyCodeMap, "GetKeyCodeMap"}, +        {8, &ISettingsServer::GetQuestFlag, "GetQuestFlag"}, +        {9, &ISettingsServer::GetKeyCodeMap2, "GetKeyCodeMap2"}, +        {10, nullptr, "GetFirmwareVersionForDebug"}, +        {11, &ISettingsServer::GetDeviceNickName, "GetDeviceNickName"}, +    }; +    // clang-format on + +    RegisterHandlers(functions); +} + +ISettingsServer::~ISettingsServer() = default; + +void ISettingsServer::GetAvailableLanguageCodes(HLERequestContext& ctx) {      LOG_DEBUG(Service_SET, "called");      GetAvailableLanguageCodesImpl(ctx, PRE_4_0_0_MAX_ENTRIES);  } -void SET::MakeLanguageCode(HLERequestContext& ctx) { +void ISettingsServer::MakeLanguageCode(HLERequestContext& ctx) {      IPC::RequestParser rp{ctx};      const auto index = rp.Pop<u32>(); @@ -80,25 +103,25 @@ void SET::MakeLanguageCode(HLERequestContext& ctx) {      rb.PushEnum(available_language_codes[index]);  } -void SET::GetAvailableLanguageCodes2(HLERequestContext& ctx) { +void ISettingsServer::GetAvailableLanguageCodes2(HLERequestContext& ctx) {      LOG_DEBUG(Service_SET, "called");      GetAvailableLanguageCodesImpl(ctx, POST_4_0_0_MAX_ENTRIES);  } -void SET::GetAvailableLanguageCodeCount(HLERequestContext& ctx) { +void ISettingsServer::GetAvailableLanguageCodeCount(HLERequestContext& ctx) {      LOG_DEBUG(Service_SET, "called");      PushResponseLanguageCode(ctx, PRE_4_0_0_MAX_ENTRIES);  } -void SET::GetAvailableLanguageCodeCount2(HLERequestContext& ctx) { +void ISettingsServer::GetAvailableLanguageCodeCount2(HLERequestContext& ctx) {      LOG_DEBUG(Service_SET, "called");      PushResponseLanguageCode(ctx, POST_4_0_0_MAX_ENTRIES);  } -void SET::GetQuestFlag(HLERequestContext& ctx) { +void ISettingsServer::GetQuestFlag(HLERequestContext& ctx) {      LOG_DEBUG(Service_SET, "called");      IPC::ResponseBuilder rb{ctx, 3}; @@ -106,7 +129,7 @@ void SET::GetQuestFlag(HLERequestContext& ctx) {      rb.Push(static_cast<s32>(Settings::values.quest_flag.GetValue()));  } -void SET::GetLanguageCode(HLERequestContext& ctx) { +void ISettingsServer::GetLanguageCode(HLERequestContext& ctx) {      LOG_DEBUG(Service_SET, "called {}", Settings::values.language_index.GetValue());      IPC::ResponseBuilder rb{ctx, 4}; @@ -115,7 +138,7 @@ void SET::GetLanguageCode(HLERequestContext& ctx) {          available_language_codes[static_cast<s32>(Settings::values.language_index.GetValue())]);  } -void SET::GetRegionCode(HLERequestContext& ctx) { +void ISettingsServer::GetRegionCode(HLERequestContext& ctx) {      LOG_DEBUG(Service_SET, "called");      IPC::ResponseBuilder rb{ctx, 3}; @@ -123,44 +146,21 @@ void SET::GetRegionCode(HLERequestContext& ctx) {      rb.Push(static_cast<u32>(Settings::values.region_index.GetValue()));  } -void SET::GetKeyCodeMap(HLERequestContext& ctx) { +void ISettingsServer::GetKeyCodeMap(HLERequestContext& ctx) {      LOG_DEBUG(Service_SET, "Called {}", ctx.Description());      GetKeyCodeMapImpl(ctx);  } -void SET::GetKeyCodeMap2(HLERequestContext& ctx) { +void ISettingsServer::GetKeyCodeMap2(HLERequestContext& ctx) {      LOG_DEBUG(Service_SET, "Called {}", ctx.Description());      GetKeyCodeMapImpl(ctx);  } -void SET::GetDeviceNickName(HLERequestContext& ctx) { +void ISettingsServer::GetDeviceNickName(HLERequestContext& ctx) {      LOG_DEBUG(Service_SET, "called");      IPC::ResponseBuilder rb{ctx, 2};      rb.Push(ResultSuccess);      ctx.WriteBuffer(Settings::values.device_name.GetValue());  } -SET::SET(Core::System& system_) : ServiceFramework{system_, "set"} { -    // clang-format off -    static const FunctionInfo functions[] = { -        {0, &SET::GetLanguageCode, "GetLanguageCode"}, -        {1, &SET::GetAvailableLanguageCodes, "GetAvailableLanguageCodes"}, -        {2, &SET::MakeLanguageCode, "MakeLanguageCode"}, -        {3, &SET::GetAvailableLanguageCodeCount, "GetAvailableLanguageCodeCount"}, -        {4, &SET::GetRegionCode, "GetRegionCode"}, -        {5, &SET::GetAvailableLanguageCodes2, "GetAvailableLanguageCodes2"}, -        {6, &SET::GetAvailableLanguageCodeCount2, "GetAvailableLanguageCodeCount2"}, -        {7, &SET::GetKeyCodeMap, "GetKeyCodeMap"}, -        {8, &SET::GetQuestFlag, "GetQuestFlag"}, -        {9, &SET::GetKeyCodeMap2, "GetKeyCodeMap2"}, -        {10, nullptr, "GetFirmwareVersionForDebug"}, -        {11, &SET::GetDeviceNickName, "GetDeviceNickName"}, -    }; -    // clang-format on - -    RegisterHandlers(functions); -} - -SET::~SET() = default; -  } // namespace Service::Set diff --git a/src/core/hle/service/set/set.h b/src/core/hle/service/set/settings_server.h index 6ef3da410..a4e78db6c 100644 --- a/src/core/hle/service/set/set.h +++ b/src/core/hle/service/set/settings_server.h @@ -73,10 +73,10 @@ static constexpr std::array<std::pair<LanguageCode, KeyboardLayout>, 18> languag  LanguageCode GetLanguageCodeFromIndex(std::size_t idx); -class SET final : public ServiceFramework<SET> { +class ISettingsServer final : public ServiceFramework<ISettingsServer> {  public: -    explicit SET(Core::System& system_); -    ~SET() override; +    explicit ISettingsServer(Core::System& system_); +    ~ISettingsServer() override;  private:      void GetLanguageCode(HLERequestContext& ctx); diff --git a/src/core/hle/service/set/set_sys.cpp b/src/core/hle/service/set/system_settings_server.cpp index 8e637f963..f7ad6193e 100644 --- a/src/core/hle/service/set/set_sys.cpp +++ b/src/core/hle/service/set/system_settings_server.cpp @@ -19,8 +19,8 @@  #include "core/file_sys/system_archive/system_archive.h"  #include "core/hle/service/filesystem/filesystem.h"  #include "core/hle/service/ipc_helpers.h" -#include "core/hle/service/set/set.h" -#include "core/hle/service/set/set_sys.h" +#include "core/hle/service/set/settings_server.h" +#include "core/hle/service/set/system_settings_server.h"  namespace Service::Set { @@ -87,7 +87,234 @@ Result GetFirmwareVersionImpl(FirmwareVersionFormat& out_firmware, Core::System&      return ResultSuccess;  } -bool SET_SYS::LoadSettingsFile(std::filesystem::path& path, auto&& default_func) { +ISystemSettingsServer::ISystemSettingsServer(Core::System& system_) +    : ServiceFramework{system_, "set:sys"}, m_system{system} { +    // clang-format off +    static const FunctionInfo functions[] = { +        {0, &ISystemSettingsServer::SetLanguageCode, "SetLanguageCode"}, +        {1, nullptr, "SetNetworkSettings"}, +        {2, nullptr, "GetNetworkSettings"}, +        {3, &ISystemSettingsServer::GetFirmwareVersion, "GetFirmwareVersion"}, +        {4, &ISystemSettingsServer::GetFirmwareVersion2, "GetFirmwareVersion2"}, +        {5, nullptr, "GetFirmwareVersionDigest"}, +        {7, nullptr, "GetLockScreenFlag"}, +        {8, nullptr, "SetLockScreenFlag"}, +        {9, nullptr, "GetBacklightSettings"}, +        {10, nullptr, "SetBacklightSettings"}, +        {11, nullptr, "SetBluetoothDevicesSettings"}, +        {12, nullptr, "GetBluetoothDevicesSettings"}, +        {13, &ISystemSettingsServer::GetExternalSteadyClockSourceId, "GetExternalSteadyClockSourceId"}, +        {14, &ISystemSettingsServer::SetExternalSteadyClockSourceId, "SetExternalSteadyClockSourceId"}, +        {15, &ISystemSettingsServer::GetUserSystemClockContext, "GetUserSystemClockContext"}, +        {16, &ISystemSettingsServer::SetUserSystemClockContext, "SetUserSystemClockContext"}, +        {17, &ISystemSettingsServer::GetAccountSettings, "GetAccountSettings"}, +        {18, &ISystemSettingsServer::SetAccountSettings, "SetAccountSettings"}, +        {19, nullptr, "GetAudioVolume"}, +        {20, nullptr, "SetAudioVolume"}, +        {21, &ISystemSettingsServer::GetEulaVersions, "GetEulaVersions"}, +        {22, &ISystemSettingsServer::SetEulaVersions, "SetEulaVersions"}, +        {23, &ISystemSettingsServer::GetColorSetId, "GetColorSetId"}, +        {24, &ISystemSettingsServer::SetColorSetId, "SetColorSetId"}, +        {25, nullptr, "GetConsoleInformationUploadFlag"}, +        {26, nullptr, "SetConsoleInformationUploadFlag"}, +        {27, nullptr, "GetAutomaticApplicationDownloadFlag"}, +        {28, nullptr, "SetAutomaticApplicationDownloadFlag"}, +        {29, &ISystemSettingsServer::GetNotificationSettings, "GetNotificationSettings"}, +        {30, &ISystemSettingsServer::SetNotificationSettings, "SetNotificationSettings"}, +        {31, &ISystemSettingsServer::GetAccountNotificationSettings, "GetAccountNotificationSettings"}, +        {32, &ISystemSettingsServer::SetAccountNotificationSettings, "SetAccountNotificationSettings"}, +        {35, nullptr, "GetVibrationMasterVolume"}, +        {36, nullptr, "SetVibrationMasterVolume"}, +        {37, &ISystemSettingsServer::GetSettingsItemValueSize, "GetSettingsItemValueSize"}, +        {38, &ISystemSettingsServer::GetSettingsItemValue, "GetSettingsItemValue"}, +        {39, &ISystemSettingsServer::GetTvSettings, "GetTvSettings"}, +        {40, &ISystemSettingsServer::SetTvSettings, "SetTvSettings"}, +        {41, nullptr, "GetEdid"}, +        {42, nullptr, "SetEdid"}, +        {43, nullptr, "GetAudioOutputMode"}, +        {44, nullptr, "SetAudioOutputMode"}, +        {45, nullptr, "IsForceMuteOnHeadphoneRemoved"}, +        {46, nullptr, "SetForceMuteOnHeadphoneRemoved"}, +        {47, &ISystemSettingsServer::GetQuestFlag, "GetQuestFlag"}, +        {48, nullptr, "SetQuestFlag"}, +        {49, nullptr, "GetDataDeletionSettings"}, +        {50, nullptr, "SetDataDeletionSettings"}, +        {51, nullptr, "GetInitialSystemAppletProgramId"}, +        {52, nullptr, "GetOverlayDispProgramId"}, +        {53, &ISystemSettingsServer::GetDeviceTimeZoneLocationName, "GetDeviceTimeZoneLocationName"}, +        {54, &ISystemSettingsServer::SetDeviceTimeZoneLocationName, "SetDeviceTimeZoneLocationName"}, +        {55, nullptr, "GetWirelessCertificationFileSize"}, +        {56, nullptr, "GetWirelessCertificationFile"}, +        {57, &ISystemSettingsServer::SetRegionCode, "SetRegionCode"}, +        {58, &ISystemSettingsServer::GetNetworkSystemClockContext, "GetNetworkSystemClockContext"}, +        {59, &ISystemSettingsServer::SetNetworkSystemClockContext, "SetNetworkSystemClockContext"}, +        {60, &ISystemSettingsServer::IsUserSystemClockAutomaticCorrectionEnabled, "IsUserSystemClockAutomaticCorrectionEnabled"}, +        {61, &ISystemSettingsServer::SetUserSystemClockAutomaticCorrectionEnabled, "SetUserSystemClockAutomaticCorrectionEnabled"}, +        {62, &ISystemSettingsServer::GetDebugModeFlag, "GetDebugModeFlag"}, +        {63, &ISystemSettingsServer::GetPrimaryAlbumStorage, "GetPrimaryAlbumStorage"}, +        {64, nullptr, "SetPrimaryAlbumStorage"}, +        {65, nullptr, "GetUsb30EnableFlag"}, +        {66, nullptr, "SetUsb30EnableFlag"}, +        {67, nullptr, "GetBatteryLot"}, +        {68, nullptr, "GetSerialNumber"}, +        {69, nullptr, "GetNfcEnableFlag"}, +        {70, nullptr, "SetNfcEnableFlag"}, +        {71, &ISystemSettingsServer::GetSleepSettings, "GetSleepSettings"}, +        {72, &ISystemSettingsServer::SetSleepSettings, "SetSleepSettings"}, +        {73, nullptr, "GetWirelessLanEnableFlag"}, +        {74, nullptr, "SetWirelessLanEnableFlag"}, +        {75, &ISystemSettingsServer::GetInitialLaunchSettings, "GetInitialLaunchSettings"}, +        {76, &ISystemSettingsServer::SetInitialLaunchSettings, "SetInitialLaunchSettings"}, +        {77, &ISystemSettingsServer::GetDeviceNickName, "GetDeviceNickName"}, +        {78, &ISystemSettingsServer::SetDeviceNickName, "SetDeviceNickName"}, +        {79, &ISystemSettingsServer::GetProductModel, "GetProductModel"}, +        {80, nullptr, "GetLdnChannel"}, +        {81, nullptr, "SetLdnChannel"}, +        {82, nullptr, "AcquireTelemetryDirtyFlagEventHandle"}, +        {83, nullptr, "GetTelemetryDirtyFlags"}, +        {84, nullptr, "GetPtmBatteryLot"}, +        {85, nullptr, "SetPtmBatteryLot"}, +        {86, nullptr, "GetPtmFuelGaugeParameter"}, +        {87, nullptr, "SetPtmFuelGaugeParameter"}, +        {88, nullptr, "GetBluetoothEnableFlag"}, +        {89, nullptr, "SetBluetoothEnableFlag"}, +        {90, &ISystemSettingsServer::GetMiiAuthorId, "GetMiiAuthorId"}, +        {91, nullptr, "SetShutdownRtcValue"}, +        {92, nullptr, "GetShutdownRtcValue"}, +        {93, nullptr, "AcquireFatalDirtyFlagEventHandle"}, +        {94, nullptr, "GetFatalDirtyFlags"}, +        {95, &ISystemSettingsServer::GetAutoUpdateEnableFlag, "GetAutoUpdateEnableFlag"}, +        {96, nullptr, "SetAutoUpdateEnableFlag"}, +        {97, nullptr, "GetNxControllerSettings"}, +        {98, nullptr, "SetNxControllerSettings"}, +        {99, &ISystemSettingsServer::GetBatteryPercentageFlag, "GetBatteryPercentageFlag"}, +        {100, nullptr, "SetBatteryPercentageFlag"}, +        {101, nullptr, "GetExternalRtcResetFlag"}, +        {102, nullptr, "SetExternalRtcResetFlag"}, +        {103, nullptr, "GetUsbFullKeyEnableFlag"}, +        {104, nullptr, "SetUsbFullKeyEnableFlag"}, +        {105, &ISystemSettingsServer::SetExternalSteadyClockInternalOffset, "SetExternalSteadyClockInternalOffset"}, +        {106, &ISystemSettingsServer::GetExternalSteadyClockInternalOffset, "GetExternalSteadyClockInternalOffset"}, +        {107, nullptr, "GetBacklightSettingsEx"}, +        {108, nullptr, "SetBacklightSettingsEx"}, +        {109, nullptr, "GetHeadphoneVolumeWarningCount"}, +        {110, nullptr, "SetHeadphoneVolumeWarningCount"}, +        {111, nullptr, "GetBluetoothAfhEnableFlag"}, +        {112, nullptr, "SetBluetoothAfhEnableFlag"}, +        {113, nullptr, "GetBluetoothBoostEnableFlag"}, +        {114, nullptr, "SetBluetoothBoostEnableFlag"}, +        {115, nullptr, "GetInRepairProcessEnableFlag"}, +        {116, nullptr, "SetInRepairProcessEnableFlag"}, +        {117, nullptr, "GetHeadphoneVolumeUpdateFlag"}, +        {118, nullptr, "SetHeadphoneVolumeUpdateFlag"}, +        {119, nullptr, "NeedsToUpdateHeadphoneVolume"}, +        {120, nullptr, "GetPushNotificationActivityModeOnSleep"}, +        {121, nullptr, "SetPushNotificationActivityModeOnSleep"}, +        {122, nullptr, "GetServiceDiscoveryControlSettings"}, +        {123, nullptr, "SetServiceDiscoveryControlSettings"}, +        {124, &ISystemSettingsServer::GetErrorReportSharePermission, "GetErrorReportSharePermission"}, +        {125, nullptr, "SetErrorReportSharePermission"}, +        {126, &ISystemSettingsServer::GetAppletLaunchFlags, "GetAppletLaunchFlags"}, +        {127, &ISystemSettingsServer::SetAppletLaunchFlags, "SetAppletLaunchFlags"}, +        {128, nullptr, "GetConsoleSixAxisSensorAccelerationBias"}, +        {129, nullptr, "SetConsoleSixAxisSensorAccelerationBias"}, +        {130, nullptr, "GetConsoleSixAxisSensorAngularVelocityBias"}, +        {131, nullptr, "SetConsoleSixAxisSensorAngularVelocityBias"}, +        {132, nullptr, "GetConsoleSixAxisSensorAccelerationGain"}, +        {133, nullptr, "SetConsoleSixAxisSensorAccelerationGain"}, +        {134, nullptr, "GetConsoleSixAxisSensorAngularVelocityGain"}, +        {135, nullptr, "SetConsoleSixAxisSensorAngularVelocityGain"}, +        {136, &ISystemSettingsServer::GetKeyboardLayout, "GetKeyboardLayout"}, +        {137, nullptr, "SetKeyboardLayout"}, +        {138, nullptr, "GetWebInspectorFlag"}, +        {139, nullptr, "GetAllowedSslHosts"}, +        {140, nullptr, "GetHostFsMountPoint"}, +        {141, nullptr, "GetRequiresRunRepairTimeReviser"}, +        {142, nullptr, "SetRequiresRunRepairTimeReviser"}, +        {143, nullptr, "SetBlePairingSettings"}, +        {144, nullptr, "GetBlePairingSettings"}, +        {145, nullptr, "GetConsoleSixAxisSensorAngularVelocityTimeBias"}, +        {146, nullptr, "SetConsoleSixAxisSensorAngularVelocityTimeBias"}, +        {147, nullptr, "GetConsoleSixAxisSensorAngularAcceleration"}, +        {148, nullptr, "SetConsoleSixAxisSensorAngularAcceleration"}, +        {149, nullptr, "GetRebootlessSystemUpdateVersion"}, +        {150, &ISystemSettingsServer::GetDeviceTimeZoneLocationUpdatedTime, "GetDeviceTimeZoneLocationUpdatedTime"}, +        {151, &ISystemSettingsServer::SetDeviceTimeZoneLocationUpdatedTime, "SetDeviceTimeZoneLocationUpdatedTime"}, +        {152, &ISystemSettingsServer::GetUserSystemClockAutomaticCorrectionUpdatedTime, "GetUserSystemClockAutomaticCorrectionUpdatedTime"}, +        {153, &ISystemSettingsServer::SetUserSystemClockAutomaticCorrectionUpdatedTime, "SetUserSystemClockAutomaticCorrectionUpdatedTime"}, +        {154, nullptr, "GetAccountOnlineStorageSettings"}, +        {155, nullptr, "SetAccountOnlineStorageSettings"}, +        {156, nullptr, "GetPctlReadyFlag"}, +        {157, nullptr, "SetPctlReadyFlag"}, +        {158, nullptr, "GetAnalogStickUserCalibrationL"}, +        {159, nullptr, "SetAnalogStickUserCalibrationL"}, +        {160, nullptr, "GetAnalogStickUserCalibrationR"}, +        {161, nullptr, "SetAnalogStickUserCalibrationR"}, +        {162, nullptr, "GetPtmBatteryVersion"}, +        {163, nullptr, "SetPtmBatteryVersion"}, +        {164, nullptr, "GetUsb30HostEnableFlag"}, +        {165, nullptr, "SetUsb30HostEnableFlag"}, +        {166, nullptr, "GetUsb30DeviceEnableFlag"}, +        {167, nullptr, "SetUsb30DeviceEnableFlag"}, +        {168, nullptr, "GetThemeId"}, +        {169, nullptr, "SetThemeId"}, +        {170, &ISystemSettingsServer::GetChineseTraditionalInputMethod, "GetChineseTraditionalInputMethod"}, +        {171, nullptr, "SetChineseTraditionalInputMethod"}, +        {172, nullptr, "GetPtmCycleCountReliability"}, +        {173, nullptr, "SetPtmCycleCountReliability"}, +        {174, &ISystemSettingsServer::GetHomeMenuScheme, "GetHomeMenuScheme"}, +        {175, nullptr, "GetThemeSettings"}, +        {176, nullptr, "SetThemeSettings"}, +        {177, nullptr, "GetThemeKey"}, +        {178, nullptr, "SetThemeKey"}, +        {179, nullptr, "GetZoomFlag"}, +        {180, nullptr, "SetZoomFlag"}, +        {181, nullptr, "GetT"}, +        {182, nullptr, "SetT"}, +        {183, nullptr, "GetPlatformRegion"}, +        {184, nullptr, "SetPlatformRegion"}, +        {185, &ISystemSettingsServer::GetHomeMenuSchemeModel, "GetHomeMenuSchemeModel"}, +        {186, nullptr, "GetMemoryUsageRateFlag"}, +        {187, nullptr, "GetTouchScreenMode"}, +        {188, nullptr, "SetTouchScreenMode"}, +        {189, nullptr, "GetButtonConfigSettingsFull"}, +        {190, nullptr, "SetButtonConfigSettingsFull"}, +        {191, nullptr, "GetButtonConfigSettingsEmbedded"}, +        {192, nullptr, "SetButtonConfigSettingsEmbedded"}, +        {193, nullptr, "GetButtonConfigSettingsLeft"}, +        {194, nullptr, "SetButtonConfigSettingsLeft"}, +        {195, nullptr, "GetButtonConfigSettingsRight"}, +        {196, nullptr, "SetButtonConfigSettingsRight"}, +        {197, nullptr, "GetButtonConfigRegisteredSettingsEmbedded"}, +        {198, nullptr, "SetButtonConfigRegisteredSettingsEmbedded"}, +        {199, nullptr, "GetButtonConfigRegisteredSettings"}, +        {200, nullptr, "SetButtonConfigRegisteredSettings"}, +        {201, &ISystemSettingsServer::GetFieldTestingFlag, "GetFieldTestingFlag"}, +        {202, nullptr, "SetFieldTestingFlag"}, +        {203, nullptr, "GetPanelCrcMode"}, +        {204, nullptr, "SetPanelCrcMode"}, +        {205, nullptr, "GetNxControllerSettingsEx"}, +        {206, nullptr, "SetNxControllerSettingsEx"}, +        {207, nullptr, "GetHearingProtectionSafeguardFlag"}, +        {208, nullptr, "SetHearingProtectionSafeguardFlag"}, +        {209, nullptr, "GetHearingProtectionSafeguardRemainingTime"}, +        {210, nullptr, "SetHearingProtectionSafeguardRemainingTime"}, +    }; +    // clang-format on + +    RegisterHandlers(functions); + +    SetupSettings(); +    m_save_thread = +        std::jthread([this](std::stop_token stop_token) { StoreSettingsThreadFunc(stop_token); }); +} + +ISystemSettingsServer::~ISystemSettingsServer() { +    SetSaveNeeded(); +    m_save_thread.request_stop(); +} + +bool ISystemSettingsServer::LoadSettingsFile(std::filesystem::path& path, auto&& default_func) {      using settings_type = decltype(default_func());      if (!Common::FS::CreateDirs(path)) { @@ -155,7 +382,7 @@ bool SET_SYS::LoadSettingsFile(std::filesystem::path& path, auto&& default_func)      return true;  } -bool SET_SYS::StoreSettingsFile(std::filesystem::path& path, auto& settings) { +bool ISystemSettingsServer::StoreSettingsFile(std::filesystem::path& path, auto& settings) {      using settings_type = std::decay_t<decltype(settings)>;      if (!Common::FS::IsDir(path)) { @@ -195,7 +422,7 @@ bool SET_SYS::StoreSettingsFile(std::filesystem::path& path, auto& settings) {      return true;  } -void SET_SYS::SetLanguageCode(HLERequestContext& ctx) { +void ISystemSettingsServer::SetLanguageCode(HLERequestContext& ctx) {      IPC::RequestParser rp{ctx};      m_system_settings.language_code = rp.PopEnum<LanguageCode>();      SetSaveNeeded(); @@ -206,7 +433,7 @@ void SET_SYS::SetLanguageCode(HLERequestContext& ctx) {      rb.Push(ResultSuccess);  } -void SET_SYS::GetFirmwareVersion(HLERequestContext& ctx) { +void ISystemSettingsServer::GetFirmwareVersion(HLERequestContext& ctx) {      LOG_DEBUG(Service_SET, "called");      FirmwareVersionFormat firmware_data{}; @@ -221,7 +448,7 @@ void SET_SYS::GetFirmwareVersion(HLERequestContext& ctx) {      rb.Push(result);  } -void SET_SYS::GetFirmwareVersion2(HLERequestContext& ctx) { +void ISystemSettingsServer::GetFirmwareVersion2(HLERequestContext& ctx) {      LOG_DEBUG(Service_SET, "called");      FirmwareVersionFormat firmware_data{}; @@ -236,7 +463,7 @@ void SET_SYS::GetFirmwareVersion2(HLERequestContext& ctx) {      rb.Push(result);  } -void SET_SYS::GetExternalSteadyClockSourceId(HLERequestContext& ctx) { +void ISystemSettingsServer::GetExternalSteadyClockSourceId(HLERequestContext& ctx) {      LOG_INFO(Service_SET, "called");      Common::UUID id{}; @@ -247,7 +474,7 @@ void SET_SYS::GetExternalSteadyClockSourceId(HLERequestContext& ctx) {      rb.PushRaw(id);  } -void SET_SYS::SetExternalSteadyClockSourceId(HLERequestContext& ctx) { +void ISystemSettingsServer::SetExternalSteadyClockSourceId(HLERequestContext& ctx) {      LOG_INFO(Service_SET, "called");      IPC::RequestParser rp{ctx}; @@ -259,7 +486,7 @@ void SET_SYS::SetExternalSteadyClockSourceId(HLERequestContext& ctx) {      rb.Push(res);  } -void SET_SYS::GetUserSystemClockContext(HLERequestContext& ctx) { +void ISystemSettingsServer::GetUserSystemClockContext(HLERequestContext& ctx) {      LOG_INFO(Service_SET, "called");      Service::Time::Clock::SystemClockContext context{}; @@ -271,7 +498,7 @@ void SET_SYS::GetUserSystemClockContext(HLERequestContext& ctx) {      rb.PushRaw(context);  } -void SET_SYS::SetUserSystemClockContext(HLERequestContext& ctx) { +void ISystemSettingsServer::SetUserSystemClockContext(HLERequestContext& ctx) {      LOG_INFO(Service_SET, "called");      IPC::RequestParser rp{ctx}; @@ -283,7 +510,7 @@ void SET_SYS::SetUserSystemClockContext(HLERequestContext& ctx) {      rb.Push(res);  } -void SET_SYS::GetAccountSettings(HLERequestContext& ctx) { +void ISystemSettingsServer::GetAccountSettings(HLERequestContext& ctx) {      LOG_INFO(Service_SET, "called");      IPC::ResponseBuilder rb{ctx, 3}; @@ -291,7 +518,7 @@ void SET_SYS::GetAccountSettings(HLERequestContext& ctx) {      rb.PushRaw(m_system_settings.account_settings);  } -void SET_SYS::SetAccountSettings(HLERequestContext& ctx) { +void ISystemSettingsServer::SetAccountSettings(HLERequestContext& ctx) {      IPC::RequestParser rp{ctx};      m_system_settings.account_settings = rp.PopRaw<AccountSettings>();      SetSaveNeeded(); @@ -303,7 +530,7 @@ void SET_SYS::SetAccountSettings(HLERequestContext& ctx) {      rb.Push(ResultSuccess);  } -void SET_SYS::GetEulaVersions(HLERequestContext& ctx) { +void ISystemSettingsServer::GetEulaVersions(HLERequestContext& ctx) {      LOG_INFO(Service_SET, "called");      ctx.WriteBuffer(m_system_settings.eula_versions); @@ -313,7 +540,7 @@ void SET_SYS::GetEulaVersions(HLERequestContext& ctx) {      rb.Push(m_system_settings.eula_version_count);  } -void SET_SYS::SetEulaVersions(HLERequestContext& ctx) { +void ISystemSettingsServer::SetEulaVersions(HLERequestContext& ctx) {      const auto elements = ctx.GetReadBufferNumElements<EulaVersion>();      const auto buffer_data = ctx.ReadBuffer(); @@ -329,7 +556,7 @@ void SET_SYS::SetEulaVersions(HLERequestContext& ctx) {      rb.Push(ResultSuccess);  } -void SET_SYS::GetColorSetId(HLERequestContext& ctx) { +void ISystemSettingsServer::GetColorSetId(HLERequestContext& ctx) {      LOG_DEBUG(Service_SET, "called");      IPC::ResponseBuilder rb{ctx, 3}; @@ -337,7 +564,7 @@ void SET_SYS::GetColorSetId(HLERequestContext& ctx) {      rb.PushEnum(m_system_settings.color_set_id);  } -void SET_SYS::SetColorSetId(HLERequestContext& ctx) { +void ISystemSettingsServer::SetColorSetId(HLERequestContext& ctx) {      IPC::RequestParser rp{ctx};      m_system_settings.color_set_id = rp.PopEnum<ColorSet>();      SetSaveNeeded(); @@ -348,7 +575,7 @@ void SET_SYS::SetColorSetId(HLERequestContext& ctx) {      rb.Push(ResultSuccess);  } -void SET_SYS::GetNotificationSettings(HLERequestContext& ctx) { +void ISystemSettingsServer::GetNotificationSettings(HLERequestContext& ctx) {      LOG_INFO(Service_SET, "called");      IPC::ResponseBuilder rb{ctx, 8}; @@ -356,7 +583,7 @@ void SET_SYS::GetNotificationSettings(HLERequestContext& ctx) {      rb.PushRaw(m_system_settings.notification_settings);  } -void SET_SYS::SetNotificationSettings(HLERequestContext& ctx) { +void ISystemSettingsServer::SetNotificationSettings(HLERequestContext& ctx) {      IPC::RequestParser rp{ctx};      m_system_settings.notification_settings = rp.PopRaw<NotificationSettings>();      SetSaveNeeded(); @@ -373,7 +600,7 @@ void SET_SYS::SetNotificationSettings(HLERequestContext& ctx) {      rb.Push(ResultSuccess);  } -void SET_SYS::GetAccountNotificationSettings(HLERequestContext& ctx) { +void ISystemSettingsServer::GetAccountNotificationSettings(HLERequestContext& ctx) {      LOG_INFO(Service_SET, "called");      ctx.WriteBuffer(m_system_settings.account_notification_settings); @@ -383,7 +610,7 @@ void SET_SYS::GetAccountNotificationSettings(HLERequestContext& ctx) {      rb.Push(m_system_settings.account_notification_settings_count);  } -void SET_SYS::SetAccountNotificationSettings(HLERequestContext& ctx) { +void ISystemSettingsServer::SetAccountNotificationSettings(HLERequestContext& ctx) {      const auto elements = ctx.GetReadBufferNumElements<AccountNotificationSettings>();      const auto buffer_data = ctx.ReadBuffer(); @@ -432,7 +659,7 @@ static Settings GetSettings() {      return ret;  } -void SET_SYS::GetSettingsItemValueSize(HLERequestContext& ctx) { +void ISystemSettingsServer::GetSettingsItemValueSize(HLERequestContext& ctx) {      LOG_DEBUG(Service_SET, "called");      // The category of the setting. This corresponds to the top-level keys of @@ -457,7 +684,7 @@ void SET_SYS::GetSettingsItemValueSize(HLERequestContext& ctx) {      rb.Push(response_size);  } -void SET_SYS::GetSettingsItemValue(HLERequestContext& ctx) { +void ISystemSettingsServer::GetSettingsItemValue(HLERequestContext& ctx) {      // The category of the setting. This corresponds to the top-level keys of      // system_settings.ini.      const auto setting_category_buf{ctx.ReadBuffer(0)}; @@ -480,7 +707,7 @@ void SET_SYS::GetSettingsItemValue(HLERequestContext& ctx) {      rb.Push(response);  } -void SET_SYS::GetTvSettings(HLERequestContext& ctx) { +void ISystemSettingsServer::GetTvSettings(HLERequestContext& ctx) {      LOG_INFO(Service_SET, "called");      IPC::ResponseBuilder rb{ctx, 10}; @@ -488,7 +715,7 @@ void SET_SYS::GetTvSettings(HLERequestContext& ctx) {      rb.PushRaw(m_system_settings.tv_settings);  } -void SET_SYS::SetTvSettings(HLERequestContext& ctx) { +void ISystemSettingsServer::SetTvSettings(HLERequestContext& ctx) {      IPC::RequestParser rp{ctx};      m_system_settings.tv_settings = rp.PopRaw<TvSettings>();      SetSaveNeeded(); @@ -507,7 +734,7 @@ void SET_SYS::SetTvSettings(HLERequestContext& ctx) {      rb.Push(ResultSuccess);  } -void SET_SYS::GetDebugModeFlag(HLERequestContext& ctx) { +void ISystemSettingsServer::GetDebugModeFlag(HLERequestContext& ctx) {      LOG_DEBUG(Service_SET, "called");      IPC::ResponseBuilder rb{ctx, 3}; @@ -515,7 +742,7 @@ void SET_SYS::GetDebugModeFlag(HLERequestContext& ctx) {      rb.Push<u32>(0);  } -void SET_SYS::GetQuestFlag(HLERequestContext& ctx) { +void ISystemSettingsServer::GetQuestFlag(HLERequestContext& ctx) {      LOG_WARNING(Service_SET, "(STUBBED) called");      IPC::ResponseBuilder rb{ctx, 3}; @@ -523,7 +750,7 @@ void SET_SYS::GetQuestFlag(HLERequestContext& ctx) {      rb.PushEnum(QuestFlag::Retail);  } -void SET_SYS::GetDeviceTimeZoneLocationName(HLERequestContext& ctx) { +void ISystemSettingsServer::GetDeviceTimeZoneLocationName(HLERequestContext& ctx) {      LOG_WARNING(Service_SET, "called");      Service::Time::TimeZone::LocationName name{}; @@ -534,7 +761,7 @@ void SET_SYS::GetDeviceTimeZoneLocationName(HLERequestContext& ctx) {      rb.PushRaw<Service::Time::TimeZone::LocationName>(name);  } -void SET_SYS::SetDeviceTimeZoneLocationName(HLERequestContext& ctx) { +void ISystemSettingsServer::SetDeviceTimeZoneLocationName(HLERequestContext& ctx) {      LOG_WARNING(Service_SET, "called");      IPC::RequestParser rp{ctx}; @@ -546,7 +773,7 @@ void SET_SYS::SetDeviceTimeZoneLocationName(HLERequestContext& ctx) {      rb.Push(res);  } -void SET_SYS::SetRegionCode(HLERequestContext& ctx) { +void ISystemSettingsServer::SetRegionCode(HLERequestContext& ctx) {      IPC::RequestParser rp{ctx};      m_system_settings.region_code = rp.PopEnum<RegionCode>();      SetSaveNeeded(); @@ -557,7 +784,7 @@ void SET_SYS::SetRegionCode(HLERequestContext& ctx) {      rb.Push(ResultSuccess);  } -void SET_SYS::GetNetworkSystemClockContext(HLERequestContext& ctx) { +void ISystemSettingsServer::GetNetworkSystemClockContext(HLERequestContext& ctx) {      LOG_INFO(Service_SET, "called");      Service::Time::Clock::SystemClockContext context{}; @@ -569,7 +796,7 @@ void SET_SYS::GetNetworkSystemClockContext(HLERequestContext& ctx) {      rb.PushRaw(context);  } -void SET_SYS::SetNetworkSystemClockContext(HLERequestContext& ctx) { +void ISystemSettingsServer::SetNetworkSystemClockContext(HLERequestContext& ctx) {      LOG_INFO(Service_SET, "called");      IPC::RequestParser rp{ctx}; @@ -581,7 +808,7 @@ void SET_SYS::SetNetworkSystemClockContext(HLERequestContext& ctx) {      rb.Push(res);  } -void SET_SYS::IsUserSystemClockAutomaticCorrectionEnabled(HLERequestContext& ctx) { +void ISystemSettingsServer::IsUserSystemClockAutomaticCorrectionEnabled(HLERequestContext& ctx) {      LOG_INFO(Service_SET, "called");      bool enabled{}; @@ -592,7 +819,7 @@ void SET_SYS::IsUserSystemClockAutomaticCorrectionEnabled(HLERequestContext& ctx      rb.PushRaw(enabled);  } -void SET_SYS::SetUserSystemClockAutomaticCorrectionEnabled(HLERequestContext& ctx) { +void ISystemSettingsServer::SetUserSystemClockAutomaticCorrectionEnabled(HLERequestContext& ctx) {      LOG_INFO(Service_SET, "called");      IPC::RequestParser rp{ctx}; @@ -604,7 +831,7 @@ void SET_SYS::SetUserSystemClockAutomaticCorrectionEnabled(HLERequestContext& ct      rb.Push(res);  } -void SET_SYS::GetPrimaryAlbumStorage(HLERequestContext& ctx) { +void ISystemSettingsServer::GetPrimaryAlbumStorage(HLERequestContext& ctx) {      LOG_WARNING(Service_SET, "(STUBBED) called");      IPC::ResponseBuilder rb{ctx, 3}; @@ -612,7 +839,7 @@ void SET_SYS::GetPrimaryAlbumStorage(HLERequestContext& ctx) {      rb.PushEnum(PrimaryAlbumStorage::SdCard);  } -void SET_SYS::GetSleepSettings(HLERequestContext& ctx) { +void ISystemSettingsServer::GetSleepSettings(HLERequestContext& ctx) {      LOG_INFO(Service_SET, "called");      IPC::ResponseBuilder rb{ctx, 5}; @@ -620,7 +847,7 @@ void SET_SYS::GetSleepSettings(HLERequestContext& ctx) {      rb.PushRaw(m_system_settings.sleep_settings);  } -void SET_SYS::SetSleepSettings(HLERequestContext& ctx) { +void ISystemSettingsServer::SetSleepSettings(HLERequestContext& ctx) {      IPC::RequestParser rp{ctx};      m_system_settings.sleep_settings = rp.PopRaw<SleepSettings>();      SetSaveNeeded(); @@ -634,14 +861,14 @@ void SET_SYS::SetSleepSettings(HLERequestContext& ctx) {      rb.Push(ResultSuccess);  } -void SET_SYS::GetInitialLaunchSettings(HLERequestContext& ctx) { +void ISystemSettingsServer::GetInitialLaunchSettings(HLERequestContext& ctx) {      LOG_INFO(Service_SET, "called");      IPC::ResponseBuilder rb{ctx, 10};      rb.Push(ResultSuccess);      rb.PushRaw(m_system_settings.initial_launch_settings_packed);  } -void SET_SYS::SetInitialLaunchSettings(HLERequestContext& ctx) { +void ISystemSettingsServer::SetInitialLaunchSettings(HLERequestContext& ctx) {      IPC::RequestParser rp{ctx};      auto inital_launch_settings = rp.PopRaw<InitialLaunchSettings>(); @@ -657,7 +884,7 @@ void SET_SYS::SetInitialLaunchSettings(HLERequestContext& ctx) {      rb.Push(ResultSuccess);  } -void SET_SYS::GetDeviceNickName(HLERequestContext& ctx) { +void ISystemSettingsServer::GetDeviceNickName(HLERequestContext& ctx) {      LOG_DEBUG(Service_SET, "called");      ctx.WriteBuffer(::Settings::values.device_name.GetValue()); @@ -666,7 +893,7 @@ void SET_SYS::GetDeviceNickName(HLERequestContext& ctx) {      rb.Push(ResultSuccess);  } -void SET_SYS::SetDeviceNickName(HLERequestContext& ctx) { +void ISystemSettingsServer::SetDeviceNickName(HLERequestContext& ctx) {      const std::string device_name = Common::StringFromBuffer(ctx.ReadBuffer());      LOG_INFO(Service_SET, "called, device_name={}", device_name); @@ -677,7 +904,7 @@ void SET_SYS::SetDeviceNickName(HLERequestContext& ctx) {      rb.Push(ResultSuccess);  } -void SET_SYS::GetProductModel(HLERequestContext& ctx) { +void ISystemSettingsServer::GetProductModel(HLERequestContext& ctx) {      const u32 product_model = 1;      LOG_WARNING(Service_SET, "(STUBBED) called, product_model={}", product_model); @@ -686,7 +913,7 @@ void SET_SYS::GetProductModel(HLERequestContext& ctx) {      rb.Push(product_model);  } -void SET_SYS::GetMiiAuthorId(HLERequestContext& ctx) { +void ISystemSettingsServer::GetMiiAuthorId(HLERequestContext& ctx) {      const auto author_id = Common::UUID::MakeDefault();      LOG_WARNING(Service_SET, "(STUBBED) called, author_id={}", author_id.FormattedString()); @@ -696,7 +923,7 @@ void SET_SYS::GetMiiAuthorId(HLERequestContext& ctx) {      rb.PushRaw(author_id);  } -void SET_SYS::GetAutoUpdateEnableFlag(HLERequestContext& ctx) { +void ISystemSettingsServer::GetAutoUpdateEnableFlag(HLERequestContext& ctx) {      u8 auto_update_flag{};      LOG_WARNING(Service_SET, "(STUBBED) called, auto_update_flag={}", auto_update_flag); @@ -706,7 +933,7 @@ void SET_SYS::GetAutoUpdateEnableFlag(HLERequestContext& ctx) {      rb.Push(auto_update_flag);  } -void SET_SYS::GetBatteryPercentageFlag(HLERequestContext& ctx) { +void ISystemSettingsServer::GetBatteryPercentageFlag(HLERequestContext& ctx) {      u8 battery_percentage_flag{1};      LOG_WARNING(Service_SET, "(STUBBED) called, battery_percentage_flag={}", @@ -717,7 +944,7 @@ void SET_SYS::GetBatteryPercentageFlag(HLERequestContext& ctx) {      rb.Push(battery_percentage_flag);  } -void SET_SYS::SetExternalSteadyClockInternalOffset(HLERequestContext& ctx) { +void ISystemSettingsServer::SetExternalSteadyClockInternalOffset(HLERequestContext& ctx) {      LOG_DEBUG(Service_SET, "called.");      IPC::RequestParser rp{ctx}; @@ -729,7 +956,7 @@ void SET_SYS::SetExternalSteadyClockInternalOffset(HLERequestContext& ctx) {      rb.Push(res);  } -void SET_SYS::GetExternalSteadyClockInternalOffset(HLERequestContext& ctx) { +void ISystemSettingsServer::GetExternalSteadyClockInternalOffset(HLERequestContext& ctx) {      LOG_DEBUG(Service_SET, "called.");      s64 offset{}; @@ -740,7 +967,7 @@ void SET_SYS::GetExternalSteadyClockInternalOffset(HLERequestContext& ctx) {      rb.Push(offset);  } -void SET_SYS::GetErrorReportSharePermission(HLERequestContext& ctx) { +void ISystemSettingsServer::GetErrorReportSharePermission(HLERequestContext& ctx) {      LOG_WARNING(Service_SET, "(STUBBED) called");      IPC::ResponseBuilder rb{ctx, 3}; @@ -748,7 +975,7 @@ void SET_SYS::GetErrorReportSharePermission(HLERequestContext& ctx) {      rb.PushEnum(ErrorReportSharePermission::Denied);  } -void SET_SYS::GetAppletLaunchFlags(HLERequestContext& ctx) { +void ISystemSettingsServer::GetAppletLaunchFlags(HLERequestContext& ctx) {      LOG_INFO(Service_SET, "called, applet_launch_flag={}", m_system_settings.applet_launch_flag);      IPC::ResponseBuilder rb{ctx, 3}; @@ -756,7 +983,7 @@ void SET_SYS::GetAppletLaunchFlags(HLERequestContext& ctx) {      rb.Push(m_system_settings.applet_launch_flag);  } -void SET_SYS::SetAppletLaunchFlags(HLERequestContext& ctx) { +void ISystemSettingsServer::SetAppletLaunchFlags(HLERequestContext& ctx) {      IPC::RequestParser rp{ctx};      m_system_settings.applet_launch_flag = rp.Pop<u32>();      SetSaveNeeded(); @@ -767,7 +994,7 @@ void SET_SYS::SetAppletLaunchFlags(HLERequestContext& ctx) {      rb.Push(ResultSuccess);  } -void SET_SYS::GetKeyboardLayout(HLERequestContext& ctx) { +void ISystemSettingsServer::GetKeyboardLayout(HLERequestContext& ctx) {      const auto language_code =          available_language_codes[static_cast<s32>(::Settings::values.language_index.GetValue())];      const auto key_code = @@ -786,7 +1013,7 @@ void SET_SYS::GetKeyboardLayout(HLERequestContext& ctx) {      rb.Push(static_cast<u32>(selected_keyboard_layout));  } -void SET_SYS::GetDeviceTimeZoneLocationUpdatedTime(HLERequestContext& ctx) { +void ISystemSettingsServer::GetDeviceTimeZoneLocationUpdatedTime(HLERequestContext& ctx) {      LOG_WARNING(Service_SET, "called.");      Service::Time::Clock::SteadyClockTimePoint time_point{}; @@ -797,7 +1024,7 @@ void SET_SYS::GetDeviceTimeZoneLocationUpdatedTime(HLERequestContext& ctx) {      rb.PushRaw<Service::Time::Clock::SteadyClockTimePoint>(time_point);  } -void SET_SYS::SetDeviceTimeZoneLocationUpdatedTime(HLERequestContext& ctx) { +void ISystemSettingsServer::SetDeviceTimeZoneLocationUpdatedTime(HLERequestContext& ctx) {      LOG_WARNING(Service_SET, "called.");      IPC::RequestParser rp{ctx}; @@ -809,7 +1036,8 @@ void SET_SYS::SetDeviceTimeZoneLocationUpdatedTime(HLERequestContext& ctx) {      rb.Push(res);  } -void SET_SYS::GetUserSystemClockAutomaticCorrectionUpdatedTime(HLERequestContext& ctx) { +void ISystemSettingsServer::GetUserSystemClockAutomaticCorrectionUpdatedTime( +    HLERequestContext& ctx) {      LOG_WARNING(Service_SET, "called.");      Service::Time::Clock::SteadyClockTimePoint time_point{}; @@ -820,7 +1048,8 @@ void SET_SYS::GetUserSystemClockAutomaticCorrectionUpdatedTime(HLERequestContext      rb.PushRaw<Service::Time::Clock::SteadyClockTimePoint>(time_point);  } -void SET_SYS::SetUserSystemClockAutomaticCorrectionUpdatedTime(HLERequestContext& ctx) { +void ISystemSettingsServer::SetUserSystemClockAutomaticCorrectionUpdatedTime( +    HLERequestContext& ctx) {      LOG_WARNING(Service_SET, "called.");      IPC::RequestParser rp{ctx}; @@ -832,7 +1061,7 @@ void SET_SYS::SetUserSystemClockAutomaticCorrectionUpdatedTime(HLERequestContext      rb.Push(res);  } -void SET_SYS::GetChineseTraditionalInputMethod(HLERequestContext& ctx) { +void ISystemSettingsServer::GetChineseTraditionalInputMethod(HLERequestContext& ctx) {      LOG_WARNING(Service_SET, "(STUBBED) called");      IPC::ResponseBuilder rb{ctx, 3}; @@ -840,7 +1069,7 @@ void SET_SYS::GetChineseTraditionalInputMethod(HLERequestContext& ctx) {      rb.PushEnum(ChineseTraditionalInputMethod::Unknown0);  } -void SET_SYS::GetHomeMenuScheme(HLERequestContext& ctx) { +void ISystemSettingsServer::GetHomeMenuScheme(HLERequestContext& ctx) {      LOG_DEBUG(Service_SET, "(STUBBED) called");      const HomeMenuScheme default_color = { @@ -856,7 +1085,7 @@ void SET_SYS::GetHomeMenuScheme(HLERequestContext& ctx) {      rb.PushRaw(default_color);  } -void SET_SYS::GetHomeMenuSchemeModel(HLERequestContext& ctx) { +void ISystemSettingsServer::GetHomeMenuSchemeModel(HLERequestContext& ctx) {      LOG_WARNING(Service_SET, "(STUBBED) called");      IPC::ResponseBuilder rb{ctx, 3}; @@ -864,7 +1093,7 @@ void SET_SYS::GetHomeMenuSchemeModel(HLERequestContext& ctx) {      rb.Push(0);  } -void SET_SYS::GetFieldTestingFlag(HLERequestContext& ctx) { +void ISystemSettingsServer::GetFieldTestingFlag(HLERequestContext& ctx) {      LOG_WARNING(Service_SET, "(STUBBED) called");      IPC::ResponseBuilder rb{ctx, 3}; @@ -872,233 +1101,7 @@ void SET_SYS::GetFieldTestingFlag(HLERequestContext& ctx) {      rb.Push<u8>(false);  } -SET_SYS::SET_SYS(Core::System& system_) : ServiceFramework{system_, "set:sys"}, m_system{system} { -    // clang-format off -    static const FunctionInfo functions[] = { -        {0, &SET_SYS::SetLanguageCode, "SetLanguageCode"}, -        {1, nullptr, "SetNetworkSettings"}, -        {2, nullptr, "GetNetworkSettings"}, -        {3, &SET_SYS::GetFirmwareVersion, "GetFirmwareVersion"}, -        {4, &SET_SYS::GetFirmwareVersion2, "GetFirmwareVersion2"}, -        {5, nullptr, "GetFirmwareVersionDigest"}, -        {7, nullptr, "GetLockScreenFlag"}, -        {8, nullptr, "SetLockScreenFlag"}, -        {9, nullptr, "GetBacklightSettings"}, -        {10, nullptr, "SetBacklightSettings"}, -        {11, nullptr, "SetBluetoothDevicesSettings"}, -        {12, nullptr, "GetBluetoothDevicesSettings"}, -        {13, &SET_SYS::GetExternalSteadyClockSourceId, "GetExternalSteadyClockSourceId"}, -        {14, &SET_SYS::SetExternalSteadyClockSourceId, "SetExternalSteadyClockSourceId"}, -        {15, &SET_SYS::GetUserSystemClockContext, "GetUserSystemClockContext"}, -        {16, &SET_SYS::SetUserSystemClockContext, "SetUserSystemClockContext"}, -        {17, &SET_SYS::GetAccountSettings, "GetAccountSettings"}, -        {18, &SET_SYS::SetAccountSettings, "SetAccountSettings"}, -        {19, nullptr, "GetAudioVolume"}, -        {20, nullptr, "SetAudioVolume"}, -        {21, &SET_SYS::GetEulaVersions, "GetEulaVersions"}, -        {22, &SET_SYS::SetEulaVersions, "SetEulaVersions"}, -        {23, &SET_SYS::GetColorSetId, "GetColorSetId"}, -        {24, &SET_SYS::SetColorSetId, "SetColorSetId"}, -        {25, nullptr, "GetConsoleInformationUploadFlag"}, -        {26, nullptr, "SetConsoleInformationUploadFlag"}, -        {27, nullptr, "GetAutomaticApplicationDownloadFlag"}, -        {28, nullptr, "SetAutomaticApplicationDownloadFlag"}, -        {29, &SET_SYS::GetNotificationSettings, "GetNotificationSettings"}, -        {30, &SET_SYS::SetNotificationSettings, "SetNotificationSettings"}, -        {31, &SET_SYS::GetAccountNotificationSettings, "GetAccountNotificationSettings"}, -        {32, &SET_SYS::SetAccountNotificationSettings, "SetAccountNotificationSettings"}, -        {35, nullptr, "GetVibrationMasterVolume"}, -        {36, nullptr, "SetVibrationMasterVolume"}, -        {37, &SET_SYS::GetSettingsItemValueSize, "GetSettingsItemValueSize"}, -        {38, &SET_SYS::GetSettingsItemValue, "GetSettingsItemValue"}, -        {39, &SET_SYS::GetTvSettings, "GetTvSettings"}, -        {40, &SET_SYS::SetTvSettings, "SetTvSettings"}, -        {41, nullptr, "GetEdid"}, -        {42, nullptr, "SetEdid"}, -        {43, nullptr, "GetAudioOutputMode"}, -        {44, nullptr, "SetAudioOutputMode"}, -        {45, nullptr, "IsForceMuteOnHeadphoneRemoved"}, -        {46, nullptr, "SetForceMuteOnHeadphoneRemoved"}, -        {47, &SET_SYS::GetQuestFlag, "GetQuestFlag"}, -        {48, nullptr, "SetQuestFlag"}, -        {49, nullptr, "GetDataDeletionSettings"}, -        {50, nullptr, "SetDataDeletionSettings"}, -        {51, nullptr, "GetInitialSystemAppletProgramId"}, -        {52, nullptr, "GetOverlayDispProgramId"}, -        {53, &SET_SYS::GetDeviceTimeZoneLocationName, "GetDeviceTimeZoneLocationName"}, -        {54, &SET_SYS::SetDeviceTimeZoneLocationName, "SetDeviceTimeZoneLocationName"}, -        {55, nullptr, "GetWirelessCertificationFileSize"}, -        {56, nullptr, "GetWirelessCertificationFile"}, -        {57, &SET_SYS::SetRegionCode, "SetRegionCode"}, -        {58, &SET_SYS::GetNetworkSystemClockContext, "GetNetworkSystemClockContext"}, -        {59, &SET_SYS::SetNetworkSystemClockContext, "SetNetworkSystemClockContext"}, -        {60, &SET_SYS::IsUserSystemClockAutomaticCorrectionEnabled, "IsUserSystemClockAutomaticCorrectionEnabled"}, -        {61, &SET_SYS::SetUserSystemClockAutomaticCorrectionEnabled, "SetUserSystemClockAutomaticCorrectionEnabled"}, -        {62, &SET_SYS::GetDebugModeFlag, "GetDebugModeFlag"}, -        {63, &SET_SYS::GetPrimaryAlbumStorage, "GetPrimaryAlbumStorage"}, -        {64, nullptr, "SetPrimaryAlbumStorage"}, -        {65, nullptr, "GetUsb30EnableFlag"}, -        {66, nullptr, "SetUsb30EnableFlag"}, -        {67, nullptr, "GetBatteryLot"}, -        {68, nullptr, "GetSerialNumber"}, -        {69, nullptr, "GetNfcEnableFlag"}, -        {70, nullptr, "SetNfcEnableFlag"}, -        {71, &SET_SYS::GetSleepSettings, "GetSleepSettings"}, -        {72, &SET_SYS::SetSleepSettings, "SetSleepSettings"}, -        {73, nullptr, "GetWirelessLanEnableFlag"}, -        {74, nullptr, "SetWirelessLanEnableFlag"}, -        {75, &SET_SYS::GetInitialLaunchSettings, "GetInitialLaunchSettings"}, -        {76, &SET_SYS::SetInitialLaunchSettings, "SetInitialLaunchSettings"}, -        {77, &SET_SYS::GetDeviceNickName, "GetDeviceNickName"}, -        {78, &SET_SYS::SetDeviceNickName, "SetDeviceNickName"}, -        {79, &SET_SYS::GetProductModel, "GetProductModel"}, -        {80, nullptr, "GetLdnChannel"}, -        {81, nullptr, "SetLdnChannel"}, -        {82, nullptr, "AcquireTelemetryDirtyFlagEventHandle"}, -        {83, nullptr, "GetTelemetryDirtyFlags"}, -        {84, nullptr, "GetPtmBatteryLot"}, -        {85, nullptr, "SetPtmBatteryLot"}, -        {86, nullptr, "GetPtmFuelGaugeParameter"}, -        {87, nullptr, "SetPtmFuelGaugeParameter"}, -        {88, nullptr, "GetBluetoothEnableFlag"}, -        {89, nullptr, "SetBluetoothEnableFlag"}, -        {90, &SET_SYS::GetMiiAuthorId, "GetMiiAuthorId"}, -        {91, nullptr, "SetShutdownRtcValue"}, -        {92, nullptr, "GetShutdownRtcValue"}, -        {93, nullptr, "AcquireFatalDirtyFlagEventHandle"}, -        {94, nullptr, "GetFatalDirtyFlags"}, -        {95, &SET_SYS::GetAutoUpdateEnableFlag, "GetAutoUpdateEnableFlag"}, -        {96, nullptr, "SetAutoUpdateEnableFlag"}, -        {97, nullptr, "GetNxControllerSettings"}, -        {98, nullptr, "SetNxControllerSettings"}, -        {99, &SET_SYS::GetBatteryPercentageFlag, "GetBatteryPercentageFlag"}, -        {100, nullptr, "SetBatteryPercentageFlag"}, -        {101, nullptr, "GetExternalRtcResetFlag"}, -        {102, nullptr, "SetExternalRtcResetFlag"}, -        {103, nullptr, "GetUsbFullKeyEnableFlag"}, -        {104, nullptr, "SetUsbFullKeyEnableFlag"}, -        {105, &SET_SYS::SetExternalSteadyClockInternalOffset, "SetExternalSteadyClockInternalOffset"}, -        {106, &SET_SYS::GetExternalSteadyClockInternalOffset, "GetExternalSteadyClockInternalOffset"}, -        {107, nullptr, "GetBacklightSettingsEx"}, -        {108, nullptr, "SetBacklightSettingsEx"}, -        {109, nullptr, "GetHeadphoneVolumeWarningCount"}, -        {110, nullptr, "SetHeadphoneVolumeWarningCount"}, -        {111, nullptr, "GetBluetoothAfhEnableFlag"}, -        {112, nullptr, "SetBluetoothAfhEnableFlag"}, -        {113, nullptr, "GetBluetoothBoostEnableFlag"}, -        {114, nullptr, "SetBluetoothBoostEnableFlag"}, -        {115, nullptr, "GetInRepairProcessEnableFlag"}, -        {116, nullptr, "SetInRepairProcessEnableFlag"}, -        {117, nullptr, "GetHeadphoneVolumeUpdateFlag"}, -        {118, nullptr, "SetHeadphoneVolumeUpdateFlag"}, -        {119, nullptr, "NeedsToUpdateHeadphoneVolume"}, -        {120, nullptr, "GetPushNotificationActivityModeOnSleep"}, -        {121, nullptr, "SetPushNotificationActivityModeOnSleep"}, -        {122, nullptr, "GetServiceDiscoveryControlSettings"}, -        {123, nullptr, "SetServiceDiscoveryControlSettings"}, -        {124, &SET_SYS::GetErrorReportSharePermission, "GetErrorReportSharePermission"}, -        {125, nullptr, "SetErrorReportSharePermission"}, -        {126, &SET_SYS::GetAppletLaunchFlags, "GetAppletLaunchFlags"}, -        {127, &SET_SYS::SetAppletLaunchFlags, "SetAppletLaunchFlags"}, -        {128, nullptr, "GetConsoleSixAxisSensorAccelerationBias"}, -        {129, nullptr, "SetConsoleSixAxisSensorAccelerationBias"}, -        {130, nullptr, "GetConsoleSixAxisSensorAngularVelocityBias"}, -        {131, nullptr, "SetConsoleSixAxisSensorAngularVelocityBias"}, -        {132, nullptr, "GetConsoleSixAxisSensorAccelerationGain"}, -        {133, nullptr, "SetConsoleSixAxisSensorAccelerationGain"}, -        {134, nullptr, "GetConsoleSixAxisSensorAngularVelocityGain"}, -        {135, nullptr, "SetConsoleSixAxisSensorAngularVelocityGain"}, -        {136, &SET_SYS::GetKeyboardLayout, "GetKeyboardLayout"}, -        {137, nullptr, "SetKeyboardLayout"}, -        {138, nullptr, "GetWebInspectorFlag"}, -        {139, nullptr, "GetAllowedSslHosts"}, -        {140, nullptr, "GetHostFsMountPoint"}, -        {141, nullptr, "GetRequiresRunRepairTimeReviser"}, -        {142, nullptr, "SetRequiresRunRepairTimeReviser"}, -        {143, nullptr, "SetBlePairingSettings"}, -        {144, nullptr, "GetBlePairingSettings"}, -        {145, nullptr, "GetConsoleSixAxisSensorAngularVelocityTimeBias"}, -        {146, nullptr, "SetConsoleSixAxisSensorAngularVelocityTimeBias"}, -        {147, nullptr, "GetConsoleSixAxisSensorAngularAcceleration"}, -        {148, nullptr, "SetConsoleSixAxisSensorAngularAcceleration"}, -        {149, nullptr, "GetRebootlessSystemUpdateVersion"}, -        {150, &SET_SYS::GetDeviceTimeZoneLocationUpdatedTime, "GetDeviceTimeZoneLocationUpdatedTime"}, -        {151, &SET_SYS::SetDeviceTimeZoneLocationUpdatedTime, "SetDeviceTimeZoneLocationUpdatedTime"}, -        {152, &SET_SYS::GetUserSystemClockAutomaticCorrectionUpdatedTime, "GetUserSystemClockAutomaticCorrectionUpdatedTime"}, -        {153, &SET_SYS::SetUserSystemClockAutomaticCorrectionUpdatedTime, "SetUserSystemClockAutomaticCorrectionUpdatedTime"}, -        {154, nullptr, "GetAccountOnlineStorageSettings"}, -        {155, nullptr, "SetAccountOnlineStorageSettings"}, -        {156, nullptr, "GetPctlReadyFlag"}, -        {157, nullptr, "SetPctlReadyFlag"}, -        {158, nullptr, "GetAnalogStickUserCalibrationL"}, -        {159, nullptr, "SetAnalogStickUserCalibrationL"}, -        {160, nullptr, "GetAnalogStickUserCalibrationR"}, -        {161, nullptr, "SetAnalogStickUserCalibrationR"}, -        {162, nullptr, "GetPtmBatteryVersion"}, -        {163, nullptr, "SetPtmBatteryVersion"}, -        {164, nullptr, "GetUsb30HostEnableFlag"}, -        {165, nullptr, "SetUsb30HostEnableFlag"}, -        {166, nullptr, "GetUsb30DeviceEnableFlag"}, -        {167, nullptr, "SetUsb30DeviceEnableFlag"}, -        {168, nullptr, "GetThemeId"}, -        {169, nullptr, "SetThemeId"}, -        {170, &SET_SYS::GetChineseTraditionalInputMethod, "GetChineseTraditionalInputMethod"}, -        {171, nullptr, "SetChineseTraditionalInputMethod"}, -        {172, nullptr, "GetPtmCycleCountReliability"}, -        {173, nullptr, "SetPtmCycleCountReliability"}, -        {174, &SET_SYS::GetHomeMenuScheme, "GetHomeMenuScheme"}, -        {175, nullptr, "GetThemeSettings"}, -        {176, nullptr, "SetThemeSettings"}, -        {177, nullptr, "GetThemeKey"}, -        {178, nullptr, "SetThemeKey"}, -        {179, nullptr, "GetZoomFlag"}, -        {180, nullptr, "SetZoomFlag"}, -        {181, nullptr, "GetT"}, -        {182, nullptr, "SetT"}, -        {183, nullptr, "GetPlatformRegion"}, -        {184, nullptr, "SetPlatformRegion"}, -        {185, &SET_SYS::GetHomeMenuSchemeModel, "GetHomeMenuSchemeModel"}, -        {186, nullptr, "GetMemoryUsageRateFlag"}, -        {187, nullptr, "GetTouchScreenMode"}, -        {188, nullptr, "SetTouchScreenMode"}, -        {189, nullptr, "GetButtonConfigSettingsFull"}, -        {190, nullptr, "SetButtonConfigSettingsFull"}, -        {191, nullptr, "GetButtonConfigSettingsEmbedded"}, -        {192, nullptr, "SetButtonConfigSettingsEmbedded"}, -        {193, nullptr, "GetButtonConfigSettingsLeft"}, -        {194, nullptr, "SetButtonConfigSettingsLeft"}, -        {195, nullptr, "GetButtonConfigSettingsRight"}, -        {196, nullptr, "SetButtonConfigSettingsRight"}, -        {197, nullptr, "GetButtonConfigRegisteredSettingsEmbedded"}, -        {198, nullptr, "SetButtonConfigRegisteredSettingsEmbedded"}, -        {199, nullptr, "GetButtonConfigRegisteredSettings"}, -        {200, nullptr, "SetButtonConfigRegisteredSettings"}, -        {201, &SET_SYS::GetFieldTestingFlag, "GetFieldTestingFlag"}, -        {202, nullptr, "SetFieldTestingFlag"}, -        {203, nullptr, "GetPanelCrcMode"}, -        {204, nullptr, "SetPanelCrcMode"}, -        {205, nullptr, "GetNxControllerSettingsEx"}, -        {206, nullptr, "SetNxControllerSettingsEx"}, -        {207, nullptr, "GetHearingProtectionSafeguardFlag"}, -        {208, nullptr, "SetHearingProtectionSafeguardFlag"}, -        {209, nullptr, "GetHearingProtectionSafeguardRemainingTime"}, -        {210, nullptr, "SetHearingProtectionSafeguardRemainingTime"}, -    }; -    // clang-format on - -    RegisterHandlers(functions); - -    SetupSettings(); -    m_save_thread = -        std::jthread([this](std::stop_token stop_token) { StoreSettingsThreadFunc(stop_token); }); -} - -SET_SYS::~SET_SYS() { -    SetSaveNeeded(); -    m_save_thread.request_stop(); -} - -void SET_SYS::SetupSettings() { +void ISystemSettingsServer::SetupSettings() {      auto system_dir =          Common::FS::GetYuzuPath(Common::FS::YuzuPath::NANDDir) / "system/save/8000000000000050";      if (!LoadSettingsFile(system_dir, []() { return DefaultSystemSettings(); })) { @@ -1124,7 +1127,7 @@ void SET_SYS::SetupSettings() {      }  } -void SET_SYS::StoreSettings() { +void ISystemSettingsServer::StoreSettings() {      auto system_dir =          Common::FS::GetYuzuPath(Common::FS::YuzuPath::NANDDir) / "system/save/8000000000000050";      if (!StoreSettingsFile(system_dir, m_system_settings)) { @@ -1150,7 +1153,7 @@ void SET_SYS::StoreSettings() {      }  } -void SET_SYS::StoreSettingsThreadFunc(std::stop_token stop_token) { +void ISystemSettingsServer::StoreSettingsThreadFunc(std::stop_token stop_token) {      Common::SetCurrentThreadName("SettingsStore");      while (Common::StoppableTimedWait(stop_token, std::chrono::minutes(1))) { @@ -1162,13 +1165,14 @@ void SET_SYS::StoreSettingsThreadFunc(std::stop_token stop_token) {      }  } -void SET_SYS::SetSaveNeeded() { +void ISystemSettingsServer::SetSaveNeeded() {      std::scoped_lock l{m_save_needed_mutex};      m_save_needed = true;  } -Result SET_SYS::GetSettingsItemValue(std::vector<u8>& out_value, const std::string& category, -                                     const std::string& name) { +Result ISystemSettingsServer::GetSettingsItemValue(std::vector<u8>& out_value, +                                                   const std::string& category, +                                                   const std::string& name) {      auto settings{GetSettings()};      R_UNLESS(settings.contains(category) && settings[category].contains(name), ResultUnknown); @@ -1176,93 +1180,98 @@ Result SET_SYS::GetSettingsItemValue(std::vector<u8>& out_value, const std::stri      R_SUCCEED();  } -Result SET_SYS::GetExternalSteadyClockSourceId(Common::UUID& out_id) { +Result ISystemSettingsServer::GetExternalSteadyClockSourceId(Common::UUID& out_id) {      out_id = m_private_settings.external_clock_source_id;      R_SUCCEED();  } -Result SET_SYS::SetExternalSteadyClockSourceId(Common::UUID id) { +Result ISystemSettingsServer::SetExternalSteadyClockSourceId(Common::UUID id) {      m_private_settings.external_clock_source_id = id;      SetSaveNeeded();      R_SUCCEED();  } -Result SET_SYS::GetUserSystemClockContext(Service::Time::Clock::SystemClockContext& out_context) { +Result ISystemSettingsServer::GetUserSystemClockContext( +    Service::Time::Clock::SystemClockContext& out_context) {      out_context = m_system_settings.user_system_clock_context;      R_SUCCEED();  } -Result SET_SYS::SetUserSystemClockContext(Service::Time::Clock::SystemClockContext& context) { +Result ISystemSettingsServer::SetUserSystemClockContext( +    Service::Time::Clock::SystemClockContext& context) {      m_system_settings.user_system_clock_context = context;      SetSaveNeeded();      R_SUCCEED();  } -Result SET_SYS::GetDeviceTimeZoneLocationName(Service::Time::TimeZone::LocationName& out_name) { +Result ISystemSettingsServer::GetDeviceTimeZoneLocationName( +    Service::Time::TimeZone::LocationName& out_name) {      out_name = m_system_settings.device_time_zone_location_name;      R_SUCCEED();  } -Result SET_SYS::SetDeviceTimeZoneLocationName(Service::Time::TimeZone::LocationName& name) { +Result ISystemSettingsServer::SetDeviceTimeZoneLocationName( +    Service::Time::TimeZone::LocationName& name) {      m_system_settings.device_time_zone_location_name = name;      SetSaveNeeded();      R_SUCCEED();  } -Result SET_SYS::GetNetworkSystemClockContext( +Result ISystemSettingsServer::GetNetworkSystemClockContext(      Service::Time::Clock::SystemClockContext& out_context) {      out_context = m_system_settings.network_system_clock_context;      R_SUCCEED();  } -Result SET_SYS::SetNetworkSystemClockContext(Service::Time::Clock::SystemClockContext& context) { +Result ISystemSettingsServer::SetNetworkSystemClockContext( +    Service::Time::Clock::SystemClockContext& context) {      m_system_settings.network_system_clock_context = context;      SetSaveNeeded();      R_SUCCEED();  } -Result SET_SYS::IsUserSystemClockAutomaticCorrectionEnabled(bool& out_enabled) { +Result ISystemSettingsServer::IsUserSystemClockAutomaticCorrectionEnabled(bool& out_enabled) {      out_enabled = m_system_settings.user_system_clock_automatic_correction_enabled;      R_SUCCEED();  } -Result SET_SYS::SetUserSystemClockAutomaticCorrectionEnabled(bool enabled) { +Result ISystemSettingsServer::SetUserSystemClockAutomaticCorrectionEnabled(bool enabled) {      m_system_settings.user_system_clock_automatic_correction_enabled = enabled;      SetSaveNeeded();      R_SUCCEED();  } -Result SET_SYS::SetExternalSteadyClockInternalOffset(s64 offset) { +Result ISystemSettingsServer::SetExternalSteadyClockInternalOffset(s64 offset) {      m_private_settings.external_steady_clock_internal_offset = offset;      SetSaveNeeded();      R_SUCCEED();  } -Result SET_SYS::GetExternalSteadyClockInternalOffset(s64& out_offset) { +Result ISystemSettingsServer::GetExternalSteadyClockInternalOffset(s64& out_offset) {      out_offset = m_private_settings.external_steady_clock_internal_offset;      R_SUCCEED();  } -Result SET_SYS::GetDeviceTimeZoneLocationUpdatedTime( +Result ISystemSettingsServer::GetDeviceTimeZoneLocationUpdatedTime(      Service::Time::Clock::SteadyClockTimePoint& out_time_point) {      out_time_point = m_system_settings.device_time_zone_location_updated_time;      R_SUCCEED();  } -Result SET_SYS::SetDeviceTimeZoneLocationUpdatedTime( +Result ISystemSettingsServer::SetDeviceTimeZoneLocationUpdatedTime(      Service::Time::Clock::SteadyClockTimePoint& time_point) {      m_system_settings.device_time_zone_location_updated_time = time_point;      SetSaveNeeded();      R_SUCCEED();  } -Result SET_SYS::GetUserSystemClockAutomaticCorrectionUpdatedTime( +Result ISystemSettingsServer::GetUserSystemClockAutomaticCorrectionUpdatedTime(      Service::Time::Clock::SteadyClockTimePoint& out_time_point) {      out_time_point = m_system_settings.user_system_clock_automatic_correction_updated_time_point;      R_SUCCEED();  } -Result SET_SYS::SetUserSystemClockAutomaticCorrectionUpdatedTime( +Result ISystemSettingsServer::SetUserSystemClockAutomaticCorrectionUpdatedTime(      Service::Time::Clock::SteadyClockTimePoint out_time_point) {      m_system_settings.user_system_clock_automatic_correction_updated_time_point = out_time_point;      SetSaveNeeded(); diff --git a/src/core/hle/service/set/set_sys.h b/src/core/hle/service/set/system_settings_server.h index 853f76fce..6f587e0b3 100644 --- a/src/core/hle/service/set/set_sys.h +++ b/src/core/hle/service/set/system_settings_server.h @@ -47,10 +47,10 @@ static_assert(sizeof(FirmwareVersionFormat) == 0x100, "FirmwareVersionFormat is  Result GetFirmwareVersionImpl(FirmwareVersionFormat& out_firmware, Core::System& system,                                GetFirmwareVersionType type); -class SET_SYS final : public ServiceFramework<SET_SYS> { +class ISystemSettingsServer final : public ServiceFramework<ISystemSettingsServer> {  public: -    explicit SET_SYS(Core::System& system_); -    ~SET_SYS() override; +    explicit ISystemSettingsServer(Core::System& system_); +    ~ISystemSettingsServer() override;      Result GetSettingsItemValue(std::vector<u8>& out_value, const std::string& category,                                  const std::string& name); diff --git a/src/hid_core/resources/npad/npad.cpp b/src/hid_core/resources/npad/npad.cpp index 14871ebee..1f8a0f8ab 100644 --- a/src/hid_core/resources/npad/npad.cpp +++ b/src/hid_core/resources/npad/npad.cpp @@ -870,6 +870,11 @@ void NPad::InitializeVibrationDevice(      const auto aruid = applet_resource_holder.applet_resource->GetActiveAruid();      const auto npad_index = static_cast<Core::HID::NpadIdType>(vibration_device_handle.npad_id);      const auto device_index = static_cast<std::size_t>(vibration_device_handle.device_index); + +    if (aruid == 0) { +        return; +    } +      InitializeVibrationDeviceAtIndex(aruid, npad_index, device_index);  } diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 2a83486f9..4f4c75f5c 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -46,7 +46,7 @@  #include "core/hle/service/am/applet_ae.h"  #include "core/hle/service/am/applet_oe.h"  #include "core/hle/service/am/applets/applets.h" -#include "core/hle/service/set/set_sys.h" +#include "core/hle/service/set/system_settings_server.h"  #include "hid_core/frontend/emulated_controller.h"  #include "hid_core/hid_core.h"  #include "yuzu/multiplayer/state.h" | 
