Преглед изворни кода

Merge pull request #11210 from german77/settings

service: set: Implement system settings for Qlaunch
liamwhite пре 3 година
родитељ
комит
00d9a9c44e

+ 0 - 24
src/core/hle/service/am/am.h

@@ -22,30 +22,6 @@ class Nvnflinger;
 
 namespace Service::AM {
 
-// This is nn::settings::Language
-enum SystemLanguage {
-    Japanese = 0,
-    English = 1, // en-US
-    French = 2,
-    German = 3,
-    Italian = 4,
-    Spanish = 5,
-    Chinese = 6,
-    Korean = 7,
-    Dutch = 8,
-    Portuguese = 9,
-    Russian = 10,
-    Taiwanese = 11,
-    BritishEnglish = 12, // en-GB
-    CanadianFrench = 13,
-    LatinAmericanSpanish = 14, // es-419
-    // 4.0.0+
-    SimplifiedChinese = 15,
-    TraditionalChinese = 16,
-    // 10.1.0+
-    BrazilianPortuguese = 17,
-};
-
 class AppletMessageQueue {
 public:
     // This is nn::am::AppletMessage

+ 0 - 60
src/core/hle/service/set/set.cpp

@@ -11,66 +11,6 @@
 
 namespace Service::Set {
 namespace {
-constexpr std::array<LanguageCode, 18> available_language_codes = {{
-    LanguageCode::JA,
-    LanguageCode::EN_US,
-    LanguageCode::FR,
-    LanguageCode::DE,
-    LanguageCode::IT,
-    LanguageCode::ES,
-    LanguageCode::ZH_CN,
-    LanguageCode::KO,
-    LanguageCode::NL,
-    LanguageCode::PT,
-    LanguageCode::RU,
-    LanguageCode::ZH_TW,
-    LanguageCode::EN_GB,
-    LanguageCode::FR_CA,
-    LanguageCode::ES_419,
-    LanguageCode::ZH_HANS,
-    LanguageCode::ZH_HANT,
-    LanguageCode::PT_BR,
-}};
-
-enum class KeyboardLayout : u64 {
-    Japanese = 0,
-    EnglishUs = 1,
-    EnglishUsInternational = 2,
-    EnglishUk = 3,
-    French = 4,
-    FrenchCa = 5,
-    Spanish = 6,
-    SpanishLatin = 7,
-    German = 8,
-    Italian = 9,
-    Portuguese = 10,
-    Russian = 11,
-    Korean = 12,
-    ChineseSimplified = 13,
-    ChineseTraditional = 14,
-};
-
-constexpr std::array<std::pair<LanguageCode, KeyboardLayout>, 18> language_to_layout{{
-    {LanguageCode::JA, KeyboardLayout::Japanese},
-    {LanguageCode::EN_US, KeyboardLayout::EnglishUs},
-    {LanguageCode::FR, KeyboardLayout::French},
-    {LanguageCode::DE, KeyboardLayout::German},
-    {LanguageCode::IT, KeyboardLayout::Italian},
-    {LanguageCode::ES, KeyboardLayout::Spanish},
-    {LanguageCode::ZH_CN, KeyboardLayout::ChineseSimplified},
-    {LanguageCode::KO, KeyboardLayout::Korean},
-    {LanguageCode::NL, KeyboardLayout::EnglishUsInternational},
-    {LanguageCode::PT, KeyboardLayout::Portuguese},
-    {LanguageCode::RU, KeyboardLayout::Russian},
-    {LanguageCode::ZH_TW, KeyboardLayout::ChineseTraditional},
-    {LanguageCode::EN_GB, KeyboardLayout::EnglishUk},
-    {LanguageCode::FR_CA, KeyboardLayout::FrenchCa},
-    {LanguageCode::ES_419, KeyboardLayout::SpanishLatin},
-    {LanguageCode::ZH_HANS, KeyboardLayout::ChineseSimplified},
-    {LanguageCode::ZH_HANT, KeyboardLayout::ChineseTraditional},
-    {LanguageCode::PT_BR, KeyboardLayout::Portuguese},
-}};
-
 constexpr std::size_t PRE_4_0_0_MAX_ENTRIES = 0xF;
 constexpr std::size_t POST_4_0_0_MAX_ENTRIES = 0x40;
 

+ 61 - 0
src/core/hle/service/set/set.h

@@ -32,6 +32,67 @@ enum class LanguageCode : u64 {
     ZH_HANT = 0x00746E61482D687A,
     PT_BR = 0x00000052422D7470,
 };
+
+enum class KeyboardLayout : u64 {
+    Japanese = 0,
+    EnglishUs = 1,
+    EnglishUsInternational = 2,
+    EnglishUk = 3,
+    French = 4,
+    FrenchCa = 5,
+    Spanish = 6,
+    SpanishLatin = 7,
+    German = 8,
+    Italian = 9,
+    Portuguese = 10,
+    Russian = 11,
+    Korean = 12,
+    ChineseSimplified = 13,
+    ChineseTraditional = 14,
+};
+
+constexpr std::array<LanguageCode, 18> available_language_codes = {{
+    LanguageCode::JA,
+    LanguageCode::EN_US,
+    LanguageCode::FR,
+    LanguageCode::DE,
+    LanguageCode::IT,
+    LanguageCode::ES,
+    LanguageCode::ZH_CN,
+    LanguageCode::KO,
+    LanguageCode::NL,
+    LanguageCode::PT,
+    LanguageCode::RU,
+    LanguageCode::ZH_TW,
+    LanguageCode::EN_GB,
+    LanguageCode::FR_CA,
+    LanguageCode::ES_419,
+    LanguageCode::ZH_HANS,
+    LanguageCode::ZH_HANT,
+    LanguageCode::PT_BR,
+}};
+
+static constexpr std::array<std::pair<LanguageCode, KeyboardLayout>, 18> language_to_layout{{
+    {LanguageCode::JA, KeyboardLayout::Japanese},
+    {LanguageCode::EN_US, KeyboardLayout::EnglishUs},
+    {LanguageCode::FR, KeyboardLayout::French},
+    {LanguageCode::DE, KeyboardLayout::German},
+    {LanguageCode::IT, KeyboardLayout::Italian},
+    {LanguageCode::ES, KeyboardLayout::Spanish},
+    {LanguageCode::ZH_CN, KeyboardLayout::ChineseSimplified},
+    {LanguageCode::KO, KeyboardLayout::Korean},
+    {LanguageCode::NL, KeyboardLayout::EnglishUsInternational},
+    {LanguageCode::PT, KeyboardLayout::Portuguese},
+    {LanguageCode::RU, KeyboardLayout::Russian},
+    {LanguageCode::ZH_TW, KeyboardLayout::ChineseTraditional},
+    {LanguageCode::EN_GB, KeyboardLayout::EnglishUk},
+    {LanguageCode::FR_CA, KeyboardLayout::FrenchCa},
+    {LanguageCode::ES_419, KeyboardLayout::SpanishLatin},
+    {LanguageCode::ZH_HANS, KeyboardLayout::ChineseSimplified},
+    {LanguageCode::ZH_HANT, KeyboardLayout::ChineseTraditional},
+    {LanguageCode::PT_BR, KeyboardLayout::Portuguese},
+}};
+
 LanguageCode GetLanguageCodeFromIndex(std::size_t idx);
 
 class SET final : public ServiceFramework<SET> {

+ 342 - 33
src/core/hle/service/set/set_sys.cpp

@@ -4,10 +4,12 @@
 #include "common/assert.h"
 #include "common/logging/log.h"
 #include "common/settings.h"
+#include "common/string_util.h"
 #include "core/file_sys/errors.h"
 #include "core/file_sys/system_archive/system_version.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"
 
 namespace Service::Set {
@@ -73,6 +75,16 @@ void GetFirmwareVersionImpl(HLERequestContext& ctx, GetFirmwareVersionType type)
 }
 } // Anonymous namespace
 
+void SET_SYS::SetLanguageCode(HLERequestContext& ctx) {
+    IPC::RequestParser rp{ctx};
+    language_code_setting = rp.PopEnum<LanguageCode>();
+
+    LOG_INFO(Service_SET, "called, language_code={}", language_code_setting);
+
+    IPC::ResponseBuilder rb{ctx, 2};
+    rb.Push(ResultSuccess);
+}
+
 void SET_SYS::GetFirmwareVersion(HLERequestContext& ctx) {
     LOG_DEBUG(Service_SET, "called");
     GetFirmwareVersionImpl(ctx, GetFirmwareVersionType::Version1);
@@ -83,21 +95,113 @@ void SET_SYS::GetFirmwareVersion2(HLERequestContext& ctx) {
     GetFirmwareVersionImpl(ctx, GetFirmwareVersionType::Version2);
 }
 
+void SET_SYS::GetAccountSettings(HLERequestContext& ctx) {
+    LOG_INFO(Service_SET, "called");
+
+    IPC::ResponseBuilder rb{ctx, 3};
+    rb.Push(ResultSuccess);
+    rb.PushRaw(account_settings);
+}
+
+void SET_SYS::SetAccountSettings(HLERequestContext& ctx) {
+    IPC::RequestParser rp{ctx};
+    account_settings = rp.PopRaw<AccountSettings>();
+
+    LOG_INFO(Service_SET, "called, account_settings_flags={}", account_settings.flags);
+
+    IPC::ResponseBuilder rb{ctx, 2};
+    rb.Push(ResultSuccess);
+}
+
+void SET_SYS::GetEulaVersions(HLERequestContext& ctx) {
+    LOG_INFO(Service_SET, "called");
+
+    ctx.WriteBuffer(eula_versions);
+
+    IPC::ResponseBuilder rb{ctx, 3};
+    rb.Push(ResultSuccess);
+    rb.Push(static_cast<u32>(eula_versions.size()));
+}
+
+void SET_SYS::SetEulaVersions(HLERequestContext& ctx) {
+    const auto elements = ctx.GetReadBufferNumElements<EulaVersion>();
+    const auto buffer_data = ctx.ReadBuffer();
+
+    LOG_INFO(Service_SET, "called, elements={}", elements);
+
+    eula_versions.resize(elements);
+    for (std::size_t index = 0; index < elements; index++) {
+        const std::size_t start_index = index * sizeof(EulaVersion);
+        memcpy(eula_versions.data() + start_index, buffer_data.data() + start_index,
+               sizeof(EulaVersion));
+    }
+
+    IPC::ResponseBuilder rb{ctx, 2};
+    rb.Push(ResultSuccess);
+}
+
 void SET_SYS::GetColorSetId(HLERequestContext& ctx) {
     LOG_DEBUG(Service_SET, "called");
 
     IPC::ResponseBuilder rb{ctx, 3};
-
     rb.Push(ResultSuccess);
     rb.PushEnum(color_set);
 }
 
 void SET_SYS::SetColorSetId(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_SET, "called");
-
     IPC::RequestParser rp{ctx};
     color_set = rp.PopEnum<ColorSet>();
 
+    LOG_DEBUG(Service_SET, "called, color_set={}", color_set);
+
+    IPC::ResponseBuilder rb{ctx, 2};
+    rb.Push(ResultSuccess);
+}
+
+void SET_SYS::GetNotificationSettings(HLERequestContext& ctx) {
+    LOG_INFO(Service_SET, "called");
+
+    IPC::ResponseBuilder rb{ctx, 8};
+    rb.Push(ResultSuccess);
+    rb.PushRaw(notification_settings);
+}
+
+void SET_SYS::SetNotificationSettings(HLERequestContext& ctx) {
+    IPC::RequestParser rp{ctx};
+    notification_settings = rp.PopRaw<NotificationSettings>();
+
+    LOG_INFO(Service_SET, "called, flags={}, volume={}, head_time={}:{}, tailt_time={}:{}",
+             notification_settings.flags.raw, notification_settings.volume,
+             notification_settings.start_time.hour, notification_settings.start_time.minute,
+             notification_settings.stop_time.hour, notification_settings.stop_time.minute);
+
+    IPC::ResponseBuilder rb{ctx, 2};
+    rb.Push(ResultSuccess);
+}
+
+void SET_SYS::GetAccountNotificationSettings(HLERequestContext& ctx) {
+    LOG_INFO(Service_SET, "called");
+
+    ctx.WriteBuffer(account_notifications);
+
+    IPC::ResponseBuilder rb{ctx, 3};
+    rb.Push(ResultSuccess);
+    rb.Push(static_cast<u32>(account_notifications.size()));
+}
+
+void SET_SYS::SetAccountNotificationSettings(HLERequestContext& ctx) {
+    const auto elements = ctx.GetReadBufferNumElements<AccountNotificationSettings>();
+    const auto buffer_data = ctx.ReadBuffer();
+
+    LOG_INFO(Service_SET, "called, elements={}", elements);
+
+    account_notifications.resize(elements);
+    for (std::size_t index = 0; index < elements; index++) {
+        const std::size_t start_index = index * sizeof(AccountNotificationSettings);
+        memcpy(account_notifications.data() + start_index, buffer_data.data() + start_index,
+               sizeof(AccountNotificationSettings));
+    }
+
     IPC::ResponseBuilder rb{ctx, 2};
     rb.Push(ResultSuccess);
 }
@@ -177,17 +281,218 @@ void SET_SYS::GetSettingsItemValue(HLERequestContext& ctx) {
     rb.Push(response);
 }
 
+void SET_SYS::GetTvSettings(HLERequestContext& ctx) {
+    LOG_INFO(Service_SET, "called");
+
+    IPC::ResponseBuilder rb{ctx, 10};
+    rb.Push(ResultSuccess);
+    rb.PushRaw(tv_settings);
+}
+
+void SET_SYS::SetTvSettings(HLERequestContext& ctx) {
+    IPC::RequestParser rp{ctx};
+    tv_settings = rp.PopRaw<TvSettings>();
+
+    LOG_INFO(Service_SET,
+             "called, flags={}, cmu_mode={}, constrast_ratio={}, hdmi_content_type={}, "
+             "rgb_range={}, tv_gama={}, tv_resolution={}, tv_underscan={}",
+             tv_settings.flags.raw, tv_settings.cmu_mode, tv_settings.constrast_ratio,
+             tv_settings.hdmi_content_type, tv_settings.rgb_range, tv_settings.tv_gama,
+             tv_settings.tv_resolution, tv_settings.tv_underscan);
+
+    IPC::ResponseBuilder rb{ctx, 2};
+    rb.Push(ResultSuccess);
+}
+
+void SET_SYS::GetQuestFlag(HLERequestContext& ctx) {
+    LOG_WARNING(Service_SET, "(STUBBED) called");
+
+    IPC::ResponseBuilder rb{ctx, 3};
+    rb.Push(ResultSuccess);
+    rb.PushEnum(QuestFlag::Retail);
+}
+
+void SET_SYS::SetRegionCode(HLERequestContext& ctx) {
+    IPC::RequestParser rp{ctx};
+    region_code = rp.PopEnum<RegionCode>();
+
+    LOG_INFO(Service_SET, "called, region_code={}", region_code);
+
+    IPC::ResponseBuilder rb{ctx, 2};
+    rb.Push(ResultSuccess);
+}
+
+void SET_SYS::GetPrimaryAlbumStorage(HLERequestContext& ctx) {
+    LOG_WARNING(Service_SET, "(STUBBED) called");
+
+    IPC::ResponseBuilder rb{ctx, 3};
+    rb.Push(ResultSuccess);
+    rb.PushEnum(PrimaryAlbumStorage::SdCard);
+}
+
+void SET_SYS::GetSleepSettings(HLERequestContext& ctx) {
+    LOG_INFO(Service_SET, "called");
+
+    IPC::ResponseBuilder rb{ctx, 5};
+    rb.Push(ResultSuccess);
+    rb.PushRaw(sleep_settings);
+}
+
+void SET_SYS::SetSleepSettings(HLERequestContext& ctx) {
+    IPC::RequestParser rp{ctx};
+    sleep_settings = rp.PopRaw<SleepSettings>();
+
+    LOG_INFO(Service_SET, "called, flags={}, handheld_sleep_plan={}, console_sleep_plan={}",
+             sleep_settings.flags.raw, sleep_settings.handheld_sleep_plan,
+             sleep_settings.console_sleep_plan);
+
+    IPC::ResponseBuilder rb{ctx, 2};
+    rb.Push(ResultSuccess);
+}
+
+void SET_SYS::GetInitialLaunchSettings(HLERequestContext& ctx) {
+    LOG_INFO(Service_SET, "called");
+    IPC::ResponseBuilder rb{ctx, 10};
+    rb.Push(ResultSuccess);
+    rb.PushRaw(launch_settings);
+}
+
+void SET_SYS::SetInitialLaunchSettings(HLERequestContext& ctx) {
+    IPC::RequestParser rp{ctx};
+    launch_settings = rp.PopRaw<InitialLaunchSettings>();
+
+    LOG_INFO(Service_SET, "called, flags={}, timestamp={}", launch_settings.flags.raw,
+             launch_settings.timestamp.time_point);
+
+    IPC::ResponseBuilder rb{ctx, 2};
+    rb.Push(ResultSuccess);
+}
+
 void SET_SYS::GetDeviceNickName(HLERequestContext& ctx) {
     LOG_DEBUG(Service_SET, "called");
+
+    ctx.WriteBuffer(::Settings::values.device_name.GetValue());
+
     IPC::ResponseBuilder rb{ctx, 2};
     rb.Push(ResultSuccess);
-    ctx.WriteBuffer(::Settings::values.device_name.GetValue());
+}
+
+void SET_SYS::SetDeviceNickName(HLERequestContext& ctx) {
+    const std::string device_name = Common::StringFromBuffer(ctx.ReadBuffer());
+
+    LOG_INFO(Service_SET, "called, device_name={}", device_name);
+
+    ::Settings::values.device_name = device_name;
+
+    IPC::ResponseBuilder rb{ctx, 2};
+    rb.Push(ResultSuccess);
+}
+
+void SET_SYS::GetProductModel(HLERequestContext& ctx) {
+    const u32 product_model = 1;
+
+    LOG_WARNING(Service_SET, "(STUBBED) called, product_model={}", product_model);
+    IPC::ResponseBuilder rb{ctx, 3};
+    rb.Push(ResultSuccess);
+    rb.Push(product_model);
+}
+
+void SET_SYS::GetMiiAuthorId(HLERequestContext& ctx) {
+    const auto author_id = Common::UUID::MakeDefault();
+
+    LOG_WARNING(Service_SET, "(STUBBED) called, author_id={}", author_id.FormattedString());
+
+    IPC::ResponseBuilder rb{ctx, 6};
+    rb.Push(ResultSuccess);
+    rb.PushRaw(author_id);
+}
+
+void SET_SYS::GetAutoUpdateEnableFlag(HLERequestContext& ctx) {
+    u8 auto_update_flag{};
+
+    LOG_WARNING(Service_SET, "(STUBBED) called, auto_update_flag={}", auto_update_flag);
+
+    IPC::ResponseBuilder rb{ctx, 3};
+    rb.Push(ResultSuccess);
+    rb.Push(auto_update_flag);
+}
+
+void SET_SYS::GetBatteryPercentageFlag(HLERequestContext& ctx) {
+    u8 battery_percentage_flag{1};
+
+    LOG_WARNING(Service_SET, "(STUBBED) called, battery_percentage_flag={}",
+                battery_percentage_flag);
+
+    IPC::ResponseBuilder rb{ctx, 3};
+    rb.Push(ResultSuccess);
+    rb.Push(battery_percentage_flag);
+}
+
+void SET_SYS::GetErrorReportSharePermission(HLERequestContext& ctx) {
+    LOG_WARNING(Service_SET, "(STUBBED) called");
+
+    IPC::ResponseBuilder rb{ctx, 3};
+    rb.Push(ResultSuccess);
+    rb.PushEnum(ErrorReportSharePermission::Denied);
+}
+
+void SET_SYS::GetAppletLaunchFlags(HLERequestContext& ctx) {
+    LOG_INFO(Service_SET, "called, applet_launch_flag={}", applet_launch_flag);
+
+    IPC::ResponseBuilder rb{ctx, 3};
+    rb.Push(ResultSuccess);
+    rb.Push(applet_launch_flag);
+}
+
+void SET_SYS::SetAppletLaunchFlags(HLERequestContext& ctx) {
+    IPC::RequestParser rp{ctx};
+    applet_launch_flag = rp.Pop<u32>();
+
+    LOG_INFO(Service_SET, "called, applet_launch_flag={}", applet_launch_flag);
+
+    IPC::ResponseBuilder rb{ctx, 2};
+    rb.Push(ResultSuccess);
+}
+
+void SET_SYS::GetKeyboardLayout(HLERequestContext& ctx) {
+    const auto language_code =
+        available_language_codes[static_cast<s32>(::Settings::values.language_index.GetValue())];
+    const auto key_code =
+        std::find_if(language_to_layout.cbegin(), language_to_layout.cend(),
+                     [=](const auto& element) { return element.first == language_code; });
+
+    KeyboardLayout selected_keyboard_layout = KeyboardLayout::EnglishUs;
+    if (key_code != language_to_layout.end()) {
+        selected_keyboard_layout = key_code->second;
+    }
+
+    LOG_INFO(Service_SET, "called, selected_keyboard_layout={}", selected_keyboard_layout);
+
+    IPC::ResponseBuilder rb{ctx, 3};
+    rb.Push(ResultSuccess);
+    rb.Push(static_cast<u32>(selected_keyboard_layout));
+}
+
+void SET_SYS::GetChineseTraditionalInputMethod(HLERequestContext& ctx) {
+    LOG_WARNING(Service_SET, "(STUBBED) called");
+
+    IPC::ResponseBuilder rb{ctx, 3};
+    rb.Push(ResultSuccess);
+    rb.PushEnum(ChineseTraditionalInputMethod::Unknown0);
+}
+
+void SET_SYS::GetFieldTestingFlag(HLERequestContext& ctx) {
+    LOG_WARNING(Service_SET, "(STUBBED) called");
+
+    IPC::ResponseBuilder rb{ctx, 3};
+    rb.Push(ResultSuccess);
+    rb.Push<u8>(false);
 }
 
 SET_SYS::SET_SYS(Core::System& system_) : ServiceFramework{system_, "set:sys"} {
     // clang-format off
     static const FunctionInfo functions[] = {
-        {0, nullptr, "SetLanguageCode"},
+        {0, &SET_SYS::SetLanguageCode, "SetLanguageCode"},
         {1, nullptr, "SetNetworkSettings"},
         {2, nullptr, "GetNetworkSettings"},
         {3, &SET_SYS::GetFirmwareVersion, "GetFirmwareVersion"},
@@ -203,35 +508,35 @@ SET_SYS::SET_SYS(Core::System& system_) : ServiceFramework{system_, "set:sys"} {
         {14, nullptr, "SetExternalSteadyClockSourceId"},
         {15, nullptr, "GetUserSystemClockContext"},
         {16, nullptr, "SetUserSystemClockContext"},
-        {17, nullptr, "GetAccountSettings"},
-        {18, nullptr, "SetAccountSettings"},
+        {17, &SET_SYS::GetAccountSettings, "GetAccountSettings"},
+        {18, &SET_SYS::SetAccountSettings, "SetAccountSettings"},
         {19, nullptr, "GetAudioVolume"},
         {20, nullptr, "SetAudioVolume"},
-        {21, nullptr, "GetEulaVersions"},
-        {22, nullptr, "SetEulaVersions"},
+        {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, nullptr, "GetNotificationSettings"},
-        {30, nullptr, "SetNotificationSettings"},
-        {31, nullptr, "GetAccountNotificationSettings"},
-        {32, nullptr, "SetAccountNotificationSettings"},
+        {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, nullptr, "GetTvSettings"},
-        {40, nullptr, "SetTvSettings"},
+        {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, nullptr, "GetQuestFlag"},
+        {47, &SET_SYS::GetQuestFlag, "GetQuestFlag"},
         {48, nullptr, "SetQuestFlag"},
         {49, nullptr, "GetDataDeletionSettings"},
         {50, nullptr, "SetDataDeletionSettings"},
@@ -241,13 +546,13 @@ SET_SYS::SET_SYS(Core::System& system_) : ServiceFramework{system_, "set:sys"} {
         {54, nullptr, "SetDeviceTimeZoneLocationName"},
         {55, nullptr, "GetWirelessCertificationFileSize"},
         {56, nullptr, "GetWirelessCertificationFile"},
-        {57, nullptr, "SetRegionCode"},
+        {57, &SET_SYS::SetRegionCode, "SetRegionCode"},
         {58, nullptr, "GetNetworkSystemClockContext"},
         {59, nullptr, "SetNetworkSystemClockContext"},
         {60, nullptr, "IsUserSystemClockAutomaticCorrectionEnabled"},
         {61, nullptr, "SetUserSystemClockAutomaticCorrectionEnabled"},
         {62, nullptr, "GetDebugModeFlag"},
-        {63, nullptr, "GetPrimaryAlbumStorage"},
+        {63, &SET_SYS::GetPrimaryAlbumStorage, "GetPrimaryAlbumStorage"},
         {64, nullptr, "SetPrimaryAlbumStorage"},
         {65, nullptr, "GetUsb30EnableFlag"},
         {66, nullptr, "SetUsb30EnableFlag"},
@@ -255,15 +560,15 @@ SET_SYS::SET_SYS(Core::System& system_) : ServiceFramework{system_, "set:sys"} {
         {68, nullptr, "GetSerialNumber"},
         {69, nullptr, "GetNfcEnableFlag"},
         {70, nullptr, "SetNfcEnableFlag"},
-        {71, nullptr, "GetSleepSettings"},
-        {72, nullptr, "SetSleepSettings"},
+        {71, &SET_SYS::GetSleepSettings, "GetSleepSettings"},
+        {72, &SET_SYS::SetSleepSettings, "SetSleepSettings"},
         {73, nullptr, "GetWirelessLanEnableFlag"},
         {74, nullptr, "SetWirelessLanEnableFlag"},
-        {75, nullptr, "GetInitialLaunchSettings"},
-        {76, nullptr, "SetInitialLaunchSettings"},
+        {75, &SET_SYS::GetInitialLaunchSettings, "GetInitialLaunchSettings"},
+        {76, &SET_SYS::SetInitialLaunchSettings, "SetInitialLaunchSettings"},
         {77, &SET_SYS::GetDeviceNickName, "GetDeviceNickName"},
-        {78, nullptr, "SetDeviceNickName"},
-        {79, nullptr, "GetProductModel"},
+        {78, &SET_SYS::SetDeviceNickName, "SetDeviceNickName"},
+        {79, &SET_SYS::GetProductModel, "GetProductModel"},
         {80, nullptr, "GetLdnChannel"},
         {81, nullptr, "SetLdnChannel"},
         {82, nullptr, "AcquireTelemetryDirtyFlagEventHandle"},
@@ -274,16 +579,16 @@ SET_SYS::SET_SYS(Core::System& system_) : ServiceFramework{system_, "set:sys"} {
         {87, nullptr, "SetPtmFuelGaugeParameter"},
         {88, nullptr, "GetBluetoothEnableFlag"},
         {89, nullptr, "SetBluetoothEnableFlag"},
-        {90, nullptr, "GetMiiAuthorId"},
+        {90, &SET_SYS::GetMiiAuthorId, "GetMiiAuthorId"},
         {91, nullptr, "SetShutdownRtcValue"},
         {92, nullptr, "GetShutdownRtcValue"},
         {93, nullptr, "AcquireFatalDirtyFlagEventHandle"},
         {94, nullptr, "GetFatalDirtyFlags"},
-        {95, nullptr, "GetAutoUpdateEnableFlag"},
+        {95, &SET_SYS::GetAutoUpdateEnableFlag, "GetAutoUpdateEnableFlag"},
         {96, nullptr, "SetAutoUpdateEnableFlag"},
         {97, nullptr, "GetNxControllerSettings"},
         {98, nullptr, "SetNxControllerSettings"},
-        {99, nullptr, "GetBatteryPercentageFlag"},
+        {99, &SET_SYS::GetBatteryPercentageFlag, "GetBatteryPercentageFlag"},
         {100, nullptr, "SetBatteryPercentageFlag"},
         {101, nullptr, "GetExternalRtcResetFlag"},
         {102, nullptr, "SetExternalRtcResetFlag"},
@@ -308,10 +613,10 @@ SET_SYS::SET_SYS(Core::System& system_) : ServiceFramework{system_, "set:sys"} {
         {121, nullptr, "SetPushNotificationActivityModeOnSleep"},
         {122, nullptr, "GetServiceDiscoveryControlSettings"},
         {123, nullptr, "SetServiceDiscoveryControlSettings"},
-        {124, nullptr, "GetErrorReportSharePermission"},
+        {124, &SET_SYS::GetErrorReportSharePermission, "GetErrorReportSharePermission"},
         {125, nullptr, "SetErrorReportSharePermission"},
-        {126, nullptr, "GetAppletLaunchFlags"},
-        {127, nullptr, "SetAppletLaunchFlags"},
+        {126, &SET_SYS::GetAppletLaunchFlags, "GetAppletLaunchFlags"},
+        {127, &SET_SYS::SetAppletLaunchFlags, "SetAppletLaunchFlags"},
         {128, nullptr, "GetConsoleSixAxisSensorAccelerationBias"},
         {129, nullptr, "SetConsoleSixAxisSensorAccelerationBias"},
         {130, nullptr, "GetConsoleSixAxisSensorAngularVelocityBias"},
@@ -320,7 +625,7 @@ SET_SYS::SET_SYS(Core::System& system_) : ServiceFramework{system_, "set:sys"} {
         {133, nullptr, "SetConsoleSixAxisSensorAccelerationGain"},
         {134, nullptr, "GetConsoleSixAxisSensorAngularVelocityGain"},
         {135, nullptr, "SetConsoleSixAxisSensorAngularVelocityGain"},
-        {136, nullptr, "GetKeyboardLayout"},
+        {136, &SET_SYS::GetKeyboardLayout, "GetKeyboardLayout"},
         {137, nullptr, "SetKeyboardLayout"},
         {138, nullptr, "GetWebInspectorFlag"},
         {139, nullptr, "GetAllowedSslHosts"},
@@ -354,7 +659,7 @@ SET_SYS::SET_SYS(Core::System& system_) : ServiceFramework{system_, "set:sys"} {
         {167, nullptr, "SetUsb30DeviceEnableFlag"},
         {168, nullptr, "GetThemeId"},
         {169, nullptr, "SetThemeId"},
-        {170, nullptr, "GetChineseTraditionalInputMethod"},
+        {170, &SET_SYS::GetChineseTraditionalInputMethod, "GetChineseTraditionalInputMethod"},
         {171, nullptr, "SetChineseTraditionalInputMethod"},
         {172, nullptr, "GetPtmCycleCountReliability"},
         {173, nullptr, "SetPtmCycleCountReliability"},
@@ -385,12 +690,16 @@ SET_SYS::SET_SYS(Core::System& system_) : ServiceFramework{system_, "set:sys"} {
         {198, nullptr, "SetButtonConfigRegisteredSettingsEmbedded"},
         {199, nullptr, "GetButtonConfigRegisteredSettings"},
         {200, nullptr, "SetButtonConfigRegisteredSettings"},
-        {201, nullptr, "GetFieldTestingFlag"},
+        {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
 

+ 320 - 2
src/core/hle/service/set/set_sys.h

@@ -3,7 +3,9 @@
 
 #pragma once
 
+#include "common/uuid.h"
 #include "core/hle/service/service.h"
+#include "core/hle/service/time/clock_types.h"
 
 namespace Core {
 class System;
@@ -23,15 +25,331 @@ private:
         BasicBlack = 1,
     };
 
-    void GetSettingsItemValueSize(HLERequestContext& ctx);
-    void GetSettingsItemValue(HLERequestContext& ctx);
+    /// Indicates the current console is a retail or kiosk unit
+    enum class QuestFlag : u8 {
+        Retail = 0,
+        Kiosk = 1,
+    };
+
+    /// This is nn::settings::system::TvResolution
+    enum class TvResolution : u32 {
+        Auto,
+        Resolution1080p,
+        Resolution720p,
+        Resolution480p,
+    };
+
+    /// This is nn::settings::system::HdmiContentType
+    enum class HdmiContentType : u32 {
+        None,
+        Graphics,
+        Cinema,
+        Photo,
+        Game,
+    };
+
+    /// This is nn::settings::system::RgbRange
+    enum class RgbRange : u32 {
+        Auto,
+        Full,
+        Limited,
+    };
+
+    /// This is nn::settings::system::CmuMode
+    enum class CmuMode : u32 {
+        None,
+        ColorInvert,
+        HighContrast,
+        GrayScale,
+    };
+
+    /// This is nn::settings::system::PrimaryAlbumStorage
+    enum class PrimaryAlbumStorage : u32 {
+        Nand,
+        SdCard,
+    };
+
+    /// This is nn::settings::system::NotificationVolume
+    enum class NotificationVolume : u32 {
+        Mute,
+        Low,
+        High,
+    };
+
+    /// This is nn::settings::system::ChineseTraditionalInputMethod
+    enum class ChineseTraditionalInputMethod : u32 {
+        Unknown0 = 0,
+        Unknown1 = 1,
+        Unknown2 = 2,
+    };
+
+    /// This is nn::settings::system::ErrorReportSharePermission
+    enum class ErrorReportSharePermission : u32 {
+        NotConfirmed,
+        Granted,
+        Denied,
+    };
+
+    /// This is nn::settings::system::FriendPresenceOverlayPermission
+    enum class FriendPresenceOverlayPermission : u8 {
+        NotConfirmed,
+        NoDisplay,
+        FavoriteFriends,
+        Friends,
+    };
+
+    /// This is nn::settings::system::HandheldSleepPlan
+    enum class HandheldSleepPlan : u32 {
+        Sleep1Min,
+        Sleep3Min,
+        Sleep5Min,
+        Sleep10Min,
+        Sleep30Min,
+        Never,
+    };
+
+    /// This is nn::settings::system::ConsoleSleepPlan
+    enum class ConsoleSleepPlan : u32 {
+        Sleep1Hour,
+        Sleep2Hour,
+        Sleep3Hour,
+        Sleep6Hour,
+        Sleep12Hour,
+        Never,
+    };
+
+    /// This is nn::settings::system::RegionCode
+    enum class RegionCode : u32 {
+        Japan,
+        Usa,
+        Europe,
+        Australia,
+        HongKongTaiwanKorea,
+        China,
+    };
+
+    /// This is nn::settings::system::EulaVersionClockType
+    enum class EulaVersionClockType : u32 {
+        NetworkSystemClock,
+        SteadyClock,
+    };
+
+    /// This is nn::settings::system::SleepFlag
+    struct SleepFlag {
+        union {
+            u32 raw{};
+
+            BitField<0, 1, u32> SleepsWhilePlayingMedia;
+            BitField<1, 1, u32> WakesAtPowerStateChange;
+        };
+    };
+    static_assert(sizeof(SleepFlag) == 4, "TvFlag is an invalid size");
+
+    /// This is nn::settings::system::TvFlag
+    struct TvFlag {
+        union {
+            u32 raw{};
+
+            BitField<0, 1, u32> Allows4k;
+            BitField<1, 1, u32> Allows3d;
+            BitField<2, 1, u32> AllowsCec;
+            BitField<3, 1, u32> PreventsScreenBurnIn;
+        };
+    };
+    static_assert(sizeof(TvFlag) == 4, "TvFlag is an invalid size");
+
+    /// This is nn::settings::system::InitialLaunchFlag
+    struct InitialLaunchFlag {
+        union {
+            u32 raw{};
+
+            BitField<0, 1, u32> InitialLaunchCompletionFlag;
+            BitField<8, 1, u32> InitialLaunchUserAdditionFlag;
+            BitField<16, 1, u32> InitialLaunchTimestampFlag;
+        };
+    };
+    static_assert(sizeof(InitialLaunchFlag) == 4, "InitialLaunchFlag is an invalid size");
+
+    /// This is nn::settings::system::NotificationFlag
+    struct NotificationFlag {
+        union {
+            u32 raw{};
+
+            BitField<0, 1, u32> RingtoneFlag;
+            BitField<1, 1, u32> DownloadCompletionFlag;
+            BitField<8, 1, u32> EnablesNews;
+            BitField<9, 1, u32> IncomingLampFlag;
+        };
+    };
+    static_assert(sizeof(NotificationFlag) == 4, "NotificationFlag is an invalid size");
+
+    /// This is nn::settings::system::AccountNotificationFlag
+    struct AccountNotificationFlag {
+        union {
+            u32 raw{};
+
+            BitField<0, 1, u32> FriendOnlineFlag;
+            BitField<1, 1, u32> FriendRequestFlag;
+            BitField<8, 1, u32> CoralInvitationFlag;
+        };
+    };
+    static_assert(sizeof(AccountNotificationFlag) == 4,
+                  "AccountNotificationFlag is an invalid size");
+
+    /// This is nn::settings::system::TvSettings
+    struct TvSettings {
+        TvFlag flags;
+        TvResolution tv_resolution;
+        HdmiContentType hdmi_content_type;
+        RgbRange rgb_range;
+        CmuMode cmu_mode;
+        u32 tv_underscan;
+        f32 tv_gama;
+        f32 constrast_ratio;
+    };
+    static_assert(sizeof(TvSettings) == 0x20, "TvSettings is an invalid size");
+
+    /// This is nn::settings::system::NotificationTime
+    struct NotificationTime {
+        u32 hour;
+        u32 minute;
+    };
+    static_assert(sizeof(NotificationTime) == 0x8, "NotificationTime is an invalid size");
+
+    /// This is nn::settings::system::NotificationSettings
+    struct NotificationSettings {
+        NotificationFlag flags;
+        NotificationVolume volume;
+        NotificationTime start_time;
+        NotificationTime stop_time;
+    };
+    static_assert(sizeof(NotificationSettings) == 0x18, "NotificationSettings is an invalid size");
+
+    /// This is nn::settings::system::AccountSettings
+    struct AccountSettings {
+        u32 flags;
+    };
+    static_assert(sizeof(AccountSettings) == 0x4, "AccountSettings is an invalid size");
+
+    /// This is nn::settings::system::AccountNotificationSettings
+    struct AccountNotificationSettings {
+        Common::UUID uid;
+        AccountNotificationFlag flags;
+        FriendPresenceOverlayPermission friend_presence_permission;
+        FriendPresenceOverlayPermission friend_invitation_permission;
+        INSERT_PADDING_BYTES(0x2);
+    };
+    static_assert(sizeof(AccountNotificationSettings) == 0x18,
+                  "AccountNotificationSettings is an invalid size");
+
+    /// This is nn::settings::system::InitialLaunchSettings
+    struct SleepSettings {
+        SleepFlag flags;
+        HandheldSleepPlan handheld_sleep_plan;
+        ConsoleSleepPlan console_sleep_plan;
+    };
+    static_assert(sizeof(SleepSettings) == 0xc, "SleepSettings is incorrect size");
+
+    /// This is nn::settings::system::InitialLaunchSettings
+    struct InitialLaunchSettings {
+        InitialLaunchFlag flags;
+        INSERT_PADDING_BYTES(0x4);
+        Time::Clock::SteadyClockTimePoint timestamp;
+    };
+    static_assert(sizeof(InitialLaunchSettings) == 0x20, "InitialLaunchSettings is incorrect size");
+
+    /// This is nn::settings::system::InitialLaunchSettings
+    struct EulaVersion {
+        u32 version;
+        RegionCode region_code;
+        EulaVersionClockType clock_type;
+        INSERT_PADDING_BYTES(0x4);
+        s64 posix_time;
+        Time::Clock::SteadyClockTimePoint timestamp;
+    };
+    static_assert(sizeof(EulaVersion) == 0x30, "EulaVersion is incorrect size");
+
+    void SetLanguageCode(HLERequestContext& ctx);
     void GetFirmwareVersion(HLERequestContext& ctx);
     void GetFirmwareVersion2(HLERequestContext& ctx);
+    void GetAccountSettings(HLERequestContext& ctx);
+    void SetAccountSettings(HLERequestContext& ctx);
+    void GetEulaVersions(HLERequestContext& ctx);
+    void SetEulaVersions(HLERequestContext& ctx);
     void GetColorSetId(HLERequestContext& ctx);
     void SetColorSetId(HLERequestContext& ctx);
+    void GetNotificationSettings(HLERequestContext& ctx);
+    void SetNotificationSettings(HLERequestContext& ctx);
+    void GetAccountNotificationSettings(HLERequestContext& ctx);
+    void SetAccountNotificationSettings(HLERequestContext& ctx);
+    void GetSettingsItemValueSize(HLERequestContext& ctx);
+    void GetSettingsItemValue(HLERequestContext& ctx);
+    void GetTvSettings(HLERequestContext& ctx);
+    void SetTvSettings(HLERequestContext& ctx);
+    void GetQuestFlag(HLERequestContext& ctx);
+    void SetRegionCode(HLERequestContext& ctx);
+    void GetPrimaryAlbumStorage(HLERequestContext& ctx);
+    void GetSleepSettings(HLERequestContext& ctx);
+    void SetSleepSettings(HLERequestContext& ctx);
+    void GetInitialLaunchSettings(HLERequestContext& ctx);
+    void SetInitialLaunchSettings(HLERequestContext& ctx);
     void GetDeviceNickName(HLERequestContext& ctx);
+    void SetDeviceNickName(HLERequestContext& ctx);
+    void GetProductModel(HLERequestContext& ctx);
+    void GetMiiAuthorId(HLERequestContext& ctx);
+    void GetAutoUpdateEnableFlag(HLERequestContext& ctx);
+    void GetBatteryPercentageFlag(HLERequestContext& ctx);
+    void GetErrorReportSharePermission(HLERequestContext& ctx);
+    void GetAppletLaunchFlags(HLERequestContext& ctx);
+    void SetAppletLaunchFlags(HLERequestContext& ctx);
+    void GetKeyboardLayout(HLERequestContext& ctx);
+    void GetChineseTraditionalInputMethod(HLERequestContext& ctx);
+    void GetFieldTestingFlag(HLERequestContext& ctx);
+
+    AccountSettings account_settings{
+        .flags = {},
+    };
 
     ColorSet color_set = ColorSet::BasicWhite;
+
+    NotificationSettings notification_settings{
+        .flags = {0x300},
+        .volume = NotificationVolume::High,
+        .start_time = {.hour = 9, .minute = 0},
+        .stop_time = {.hour = 21, .minute = 0},
+    };
+
+    std::vector<AccountNotificationSettings> account_notifications{};
+
+    TvSettings tv_settings{
+        .flags = {0xc},
+        .tv_resolution = TvResolution::Auto,
+        .hdmi_content_type = HdmiContentType::Game,
+        .rgb_range = RgbRange::Auto,
+        .cmu_mode = CmuMode::None,
+        .tv_underscan = {},
+        .tv_gama = 1.0f,
+        .constrast_ratio = 0.5f,
+    };
+
+    InitialLaunchSettings launch_settings{
+        .flags = {0x10001},
+        .timestamp = {},
+    };
+
+    SleepSettings sleep_settings{
+        .flags = {0x3},
+        .handheld_sleep_plan = HandheldSleepPlan::Sleep10Min,
+        .console_sleep_plan = ConsoleSleepPlan::Sleep1Hour,
+    };
+
+    u32 applet_launch_flag{};
+
+    std::vector<EulaVersion> eula_versions{};
+
+    RegionCode region_code;
+
+    LanguageCode language_code_setting;
 };
 
 } // namespace Service::Set