Make system settings persistent across boots
This commit is contained in:
		| @@ -123,6 +123,12 @@ namespace Common { | |||||||
|     return u32(a) | u32(b) << 8 | u32(c) << 16 | u32(d) << 24; |     return u32(a) | u32(b) << 8 | u32(c) << 16 | u32(d) << 24; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | [[nodiscard]] constexpr u64 MakeMagic(char a, char b, char c, char d, char e, char f, char g, | ||||||
|  |                                       char h) { | ||||||
|  |     return u64(a) << 0 | u64(b) << 8 | u64(c) << 16 | u64(d) << 24 | u64(e) << 32 | u64(f) << 40 | | ||||||
|  |            u64(g) << 48 | u64(h) << 56; | ||||||
|  | } | ||||||
|  |  | ||||||
| // std::size() does not support zero-size C arrays. We're fixing that. | // std::size() does not support zero-size C arrays. We're fixing that. | ||||||
| template <class C> | template <class C> | ||||||
| constexpr auto Size(const C& c) -> decltype(c.size()) { | constexpr auto Size(const C& c) -> decltype(c.size()) { | ||||||
|   | |||||||
| @@ -784,6 +784,12 @@ add_library(core STATIC | |||||||
|     hle/service/service.h |     hle/service/service.h | ||||||
|     hle/service/set/set.cpp |     hle/service/set/set.cpp | ||||||
|     hle/service/set/set.h |     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/private_settings.cpp | ||||||
|  |     hle/service/set/private_settings.h | ||||||
|     hle/service/set/set_cal.cpp |     hle/service/set/set_cal.cpp | ||||||
|     hle/service/set/set_cal.h |     hle/service/set/set_cal.h | ||||||
|     hle/service/set/set_fd.cpp |     hle/service/set/set_fd.cpp | ||||||
| @@ -792,6 +798,8 @@ add_library(core STATIC | |||||||
|     hle/service/set/set_sys.h |     hle/service/set/set_sys.h | ||||||
|     hle/service/set/settings.cpp |     hle/service/set/settings.cpp | ||||||
|     hle/service/set/settings.h |     hle/service/set/settings.h | ||||||
|  |     hle/service/set/system_settings.cpp | ||||||
|  |     hle/service/set/system_settings.h | ||||||
|     hle/service/sm/sm.cpp |     hle/service/sm/sm.cpp | ||||||
|     hle/service/sm/sm.h |     hle/service/sm/sm.h | ||||||
|     hle/service/sm/sm_controller.cpp |     hle/service/sm/sm_controller.cpp | ||||||
|   | |||||||
							
								
								
									
										12
									
								
								src/core/hle/service/set/appln_settings.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								src/core/hle/service/set/appln_settings.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | |||||||
|  | // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project | ||||||
|  | // SPDX-License-Identifier: GPL-2.0-or-later | ||||||
|  |  | ||||||
|  | #include "core/hle/service/set/appln_settings.h" | ||||||
|  |  | ||||||
|  | namespace Service::Set { | ||||||
|  |  | ||||||
|  | ApplnSettings DefaultApplnSettings() { | ||||||
|  |     return {}; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | } // namespace Service::Set | ||||||
							
								
								
									
										35
									
								
								src/core/hle/service/set/appln_settings.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								src/core/hle/service/set/appln_settings.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,35 @@ | |||||||
|  | // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project | ||||||
|  | // SPDX-License-Identifier: GPL-2.0-or-later | ||||||
|  |  | ||||||
|  | #pragma once | ||||||
|  |  | ||||||
|  | #include <array> | ||||||
|  |  | ||||||
|  | #include "common/common_types.h" | ||||||
|  |  | ||||||
|  | namespace Service::Set { | ||||||
|  | struct ApplnSettings { | ||||||
|  |     std::array<u8, 0x10> reserved_000; | ||||||
|  |  | ||||||
|  |     // nn::util::Uuid MiiAuthorId, copied from system settings 0x94B0 | ||||||
|  |     std::array<u8, 0x10> mii_author_id; | ||||||
|  |  | ||||||
|  |     std::array<u8, 0x30> reserved_020; | ||||||
|  |  | ||||||
|  |     // nn::settings::system::ServiceDiscoveryControlSettings | ||||||
|  |     std::array<u8, 0x4> service_discovery_control_settings; | ||||||
|  |  | ||||||
|  |     std::array<u8, 0x20> reserved_054; | ||||||
|  |  | ||||||
|  |     bool in_repair_process_enable_flag; | ||||||
|  |  | ||||||
|  |     std::array<u8, 0x3> pad_075; | ||||||
|  | }; | ||||||
|  | static_assert(offsetof(ApplnSettings, mii_author_id) == 0x10); | ||||||
|  | static_assert(offsetof(ApplnSettings, service_discovery_control_settings) == 0x50); | ||||||
|  | static_assert(offsetof(ApplnSettings, in_repair_process_enable_flag) == 0x74); | ||||||
|  | static_assert(sizeof(ApplnSettings) == 0x78, "ApplnSettings has the wrong size!"); | ||||||
|  |  | ||||||
|  | ApplnSettings DefaultApplnSettings(); | ||||||
|  |  | ||||||
|  | } // namespace Service::Set | ||||||
							
								
								
									
										12
									
								
								src/core/hle/service/set/device_settings.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								src/core/hle/service/set/device_settings.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | |||||||
|  | // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project | ||||||
|  | // SPDX-License-Identifier: GPL-2.0-or-later | ||||||
|  |  | ||||||
|  | #include "core/hle/service/set/device_settings.h" | ||||||
|  |  | ||||||
|  | namespace Service::Set { | ||||||
|  |  | ||||||
|  | DeviceSettings DefaultDeviceSettings() { | ||||||
|  |     return {}; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | } // namespace Service::Set | ||||||
							
								
								
									
										53
									
								
								src/core/hle/service/set/device_settings.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								src/core/hle/service/set/device_settings.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,53 @@ | |||||||
|  | // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project | ||||||
|  | // SPDX-License-Identifier: GPL-2.0-or-later | ||||||
|  |  | ||||||
|  | #pragma once | ||||||
|  |  | ||||||
|  | #include <array> | ||||||
|  |  | ||||||
|  | #include "common/common_types.h" | ||||||
|  |  | ||||||
|  | namespace Service::Set { | ||||||
|  | struct DeviceSettings { | ||||||
|  |     std::array<u8, 0x10> reserved_000; | ||||||
|  |  | ||||||
|  |     // nn::settings::BatteryLot | ||||||
|  |     std::array<u8, 0x18> ptm_battery_lot; | ||||||
|  |     // nn::settings::system::PtmFuelGaugeParameter | ||||||
|  |     std::array<u8, 0x18> ptm_fuel_gauge_parameter; | ||||||
|  |     u8 ptm_battery_version; | ||||||
|  |     // nn::settings::system::PtmCycleCountReliability | ||||||
|  |     u32 ptm_cycle_count_reliability; | ||||||
|  |  | ||||||
|  |     std::array<u8, 0x48> reserved_048; | ||||||
|  |  | ||||||
|  |     // nn::settings::system::AnalogStickUserCalibration L | ||||||
|  |     std::array<u8, 0x10> analog_user_stick_calibration_l; | ||||||
|  |     // nn::settings::system::AnalogStickUserCalibration R | ||||||
|  |     std::array<u8, 0x10> analog_user_stick_calibration_r; | ||||||
|  |  | ||||||
|  |     std::array<u8, 0x20> reserved_0B0; | ||||||
|  |  | ||||||
|  |     // nn::settings::system::ConsoleSixAxisSensorAccelerationBias | ||||||
|  |     std::array<u8, 0xC> console_six_axis_sensor_acceleration_bias; | ||||||
|  |     // nn::settings::system::ConsoleSixAxisSensorAngularVelocityBias | ||||||
|  |     std::array<u8, 0xC> console_six_axis_sensor_angular_velocity_bias; | ||||||
|  |     // nn::settings::system::ConsoleSixAxisSensorAccelerationGain | ||||||
|  |     std::array<u8, 0x24> console_six_axis_sensor_acceleration_gain; | ||||||
|  |     // nn::settings::system::ConsoleSixAxisSensorAngularVelocityGain | ||||||
|  |     std::array<u8, 0x24> console_six_axis_sensor_angular_velocity_gain; | ||||||
|  |     // nn::settings::system::ConsoleSixAxisSensorAngularVelocityTimeBias | ||||||
|  |     std::array<u8, 0xC> console_six_axis_sensor_angular_velocity_time_bias; | ||||||
|  |     // nn::settings::system::ConsoleSixAxisSensorAngularAcceleration | ||||||
|  |     std::array<u8, 0x24> console_six_axis_sensor_angular_acceleration; | ||||||
|  | }; | ||||||
|  | static_assert(offsetof(DeviceSettings, ptm_battery_lot) == 0x10); | ||||||
|  | static_assert(offsetof(DeviceSettings, ptm_cycle_count_reliability) == 0x44); | ||||||
|  | static_assert(offsetof(DeviceSettings, analog_user_stick_calibration_l) == 0x90); | ||||||
|  | static_assert(offsetof(DeviceSettings, console_six_axis_sensor_acceleration_bias) == 0xD0); | ||||||
|  | static_assert(offsetof(DeviceSettings, console_six_axis_sensor_angular_acceleration) == 0x13C); | ||||||
|  | static_assert(sizeof(DeviceSettings) == 0x160, "DeviceSettings has the wrong size!"); | ||||||
|  |  | ||||||
|  | DeviceSettings DefaultDeviceSettings(); | ||||||
|  |  | ||||||
|  | } // namespace Service::Set | ||||||
							
								
								
									
										12
									
								
								src/core/hle/service/set/private_settings.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								src/core/hle/service/set/private_settings.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | |||||||
|  | // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project | ||||||
|  | // SPDX-License-Identifier: GPL-2.0-or-later | ||||||
|  |  | ||||||
|  | #include "core/hle/service/set/private_settings.h" | ||||||
|  |  | ||||||
|  | namespace Service::Set { | ||||||
|  |  | ||||||
|  | PrivateSettings DefaultPrivateSettings() { | ||||||
|  |     return {}; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | } // namespace Service::Set | ||||||
							
								
								
									
										72
									
								
								src/core/hle/service/set/private_settings.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								src/core/hle/service/set/private_settings.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,72 @@ | |||||||
|  | // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project | ||||||
|  | // SPDX-License-Identifier: GPL-2.0-or-later | ||||||
|  |  | ||||||
|  | #pragma once | ||||||
|  |  | ||||||
|  | #include <array> | ||||||
|  |  | ||||||
|  | #include "common/bit_field.h" | ||||||
|  | #include "common/common_funcs.h" | ||||||
|  | #include "common/common_types.h" | ||||||
|  | #include "common/uuid.h" | ||||||
|  | #include "core/hle/service/time/clock_types.h" | ||||||
|  |  | ||||||
|  | namespace Service::Set { | ||||||
|  |  | ||||||
|  | /// 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::InitialLaunchSettings | ||||||
|  | struct InitialLaunchSettings { | ||||||
|  |     InitialLaunchFlag flags; | ||||||
|  |     INSERT_PADDING_BYTES(0x4); | ||||||
|  |     Service::Time::Clock::SteadyClockTimePoint timestamp; | ||||||
|  | }; | ||||||
|  | static_assert(sizeof(InitialLaunchSettings) == 0x20, "InitialLaunchSettings is incorrect size"); | ||||||
|  |  | ||||||
|  | #pragma pack(push, 4) | ||||||
|  | struct InitialLaunchSettingsPacked { | ||||||
|  |     InitialLaunchFlag flags; | ||||||
|  |     Service::Time::Clock::SteadyClockTimePoint timestamp; | ||||||
|  | }; | ||||||
|  | #pragma pack(pop) | ||||||
|  | static_assert(sizeof(InitialLaunchSettingsPacked) == 0x1C, | ||||||
|  |               "InitialLaunchSettingsPacked is incorrect size"); | ||||||
|  |  | ||||||
|  | struct PrivateSettings { | ||||||
|  |     std::array<u8, 0x10> reserved_00; | ||||||
|  |  | ||||||
|  |     // nn::settings::system::InitialLaunchSettings | ||||||
|  |     InitialLaunchSettings initial_launch_settings; | ||||||
|  |  | ||||||
|  |     std::array<u8, 0x20> reserved_30; | ||||||
|  |  | ||||||
|  |     Common::UUID external_clock_source_id; | ||||||
|  |     s64 shutdown_rtc_value; | ||||||
|  |     s64 external_steady_clock_internal_offset; | ||||||
|  |  | ||||||
|  |     std::array<u8, 0x60> reserved_70; | ||||||
|  |  | ||||||
|  |     // nn::settings::system::PlatformRegion | ||||||
|  |     std::array<u8, 0x4> platform_region; | ||||||
|  |  | ||||||
|  |     std::array<u8, 0x4> reserved_D4; | ||||||
|  | }; | ||||||
|  | static_assert(offsetof(PrivateSettings, initial_launch_settings) == 0x10); | ||||||
|  | static_assert(offsetof(PrivateSettings, external_clock_source_id) == 0x50); | ||||||
|  | static_assert(offsetof(PrivateSettings, reserved_70) == 0x70); | ||||||
|  | static_assert(offsetof(PrivateSettings, platform_region) == 0xD0); | ||||||
|  | static_assert(sizeof(PrivateSettings) == 0xD8, "PrivateSettings has the wrong size!"); | ||||||
|  |  | ||||||
|  | PrivateSettings DefaultPrivateSettings(); | ||||||
|  |  | ||||||
|  | } // namespace Service::Set | ||||||
| @@ -4,35 +4,13 @@ | |||||||
| #pragma once | #pragma once | ||||||
|  |  | ||||||
| #include "core/hle/service/service.h" | #include "core/hle/service/service.h" | ||||||
|  | #include "core/hle/service/set/system_settings.h" | ||||||
|  |  | ||||||
| namespace Core { | namespace Core { | ||||||
| class System; | class System; | ||||||
| } | } | ||||||
|  |  | ||||||
| namespace Service::Set { | namespace Service::Set { | ||||||
|  |  | ||||||
| /// This is "nn::settings::LanguageCode", which is a NUL-terminated string stored in a u64. |  | ||||||
| enum class LanguageCode : u64 { |  | ||||||
|     JA = 0x000000000000616A, |  | ||||||
|     EN_US = 0x00000053552D6E65, |  | ||||||
|     FR = 0x0000000000007266, |  | ||||||
|     DE = 0x0000000000006564, |  | ||||||
|     IT = 0x0000000000007469, |  | ||||||
|     ES = 0x0000000000007365, |  | ||||||
|     ZH_CN = 0x0000004E432D687A, |  | ||||||
|     KO = 0x0000000000006F6B, |  | ||||||
|     NL = 0x0000000000006C6E, |  | ||||||
|     PT = 0x0000000000007470, |  | ||||||
|     RU = 0x0000000000007572, |  | ||||||
|     ZH_TW = 0x00000057542D687A, |  | ||||||
|     EN_GB = 0x00000042472D6E65, |  | ||||||
|     FR_CA = 0x00000041432D7266, |  | ||||||
|     ES_419 = 0x00003931342D7365, |  | ||||||
|     ZH_HANS = 0x00736E61482D687A, |  | ||||||
|     ZH_HANT = 0x00746E61482D687A, |  | ||||||
|     PT_BR = 0x00000052422D7470, |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| enum class KeyboardLayout : u64 { | enum class KeyboardLayout : u64 { | ||||||
|     Japanese = 0, |     Japanese = 0, | ||||||
|     EnglishUs = 1, |     EnglishUs = 1, | ||||||
|   | |||||||
| @@ -1,7 +1,12 @@ | |||||||
| // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project | // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project | ||||||
| // SPDX-License-Identifier: GPL-2.0-or-later | // SPDX-License-Identifier: GPL-2.0-or-later | ||||||
|  |  | ||||||
|  | #include <fstream> | ||||||
|  |  | ||||||
| #include "common/assert.h" | #include "common/assert.h" | ||||||
|  | #include "common/fs/file.h" | ||||||
|  | #include "common/fs/fs.h" | ||||||
|  | #include "common/fs/path_util.h" | ||||||
| #include "common/logging/log.h" | #include "common/logging/log.h" | ||||||
| #include "common/settings.h" | #include "common/settings.h" | ||||||
| #include "common/string_util.h" | #include "common/string_util.h" | ||||||
| @@ -19,6 +24,16 @@ | |||||||
|  |  | ||||||
| namespace Service::Set { | namespace Service::Set { | ||||||
|  |  | ||||||
|  | namespace { | ||||||
|  | constexpr u32 SETTINGS_VERSION{1u}; | ||||||
|  | constexpr auto SETTINGS_MAGIC = Common::MakeMagic('y', 'u', 'z', 'u', '_', 's', 'e', 't'); | ||||||
|  | struct SettingsHeader { | ||||||
|  |     u64 magic; | ||||||
|  |     u32 version; | ||||||
|  |     u32 reserved; | ||||||
|  | }; | ||||||
|  | } // Anonymous namespace | ||||||
|  |  | ||||||
| Result GetFirmwareVersionImpl(FirmwareVersionFormat& out_firmware, Core::System& system, | Result GetFirmwareVersionImpl(FirmwareVersionFormat& out_firmware, Core::System& system, | ||||||
|                               GetFirmwareVersionType type) { |                               GetFirmwareVersionType type) { | ||||||
|     constexpr u64 FirmwareVersionSystemDataId = 0x0100000000000809; |     constexpr u64 FirmwareVersionSystemDataId = 0x0100000000000809; | ||||||
| @@ -72,11 +87,120 @@ Result GetFirmwareVersionImpl(FirmwareVersionFormat& out_firmware, Core::System& | |||||||
|     return ResultSuccess; |     return ResultSuccess; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | bool SET_SYS::LoadSettingsFile(std::filesystem::path& path, auto&& default_func) { | ||||||
|  |     using settings_type = decltype(default_func()); | ||||||
|  |  | ||||||
|  |     if (!Common::FS::CreateDirs(path)) { | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     auto settings_file = path / "settings.dat"; | ||||||
|  |     auto exists = std::filesystem::exists(settings_file); | ||||||
|  |     auto file_size_ok = exists && std::filesystem::file_size(settings_file) == | ||||||
|  |                                       sizeof(SettingsHeader) + sizeof(settings_type); | ||||||
|  |  | ||||||
|  |     auto ResetToDefault = [&]() { | ||||||
|  |         auto default_settings{default_func()}; | ||||||
|  |  | ||||||
|  |         SettingsHeader hdr{ | ||||||
|  |             .magic = SETTINGS_MAGIC, | ||||||
|  |             .version = SETTINGS_VERSION, | ||||||
|  |             .reserved = 0u, | ||||||
|  |         }; | ||||||
|  |  | ||||||
|  |         std::ofstream out_settings_file(settings_file, std::ios::out | std::ios::binary); | ||||||
|  |         out_settings_file.write(reinterpret_cast<const char*>(&hdr), sizeof(hdr)); | ||||||
|  |         out_settings_file.write(reinterpret_cast<const char*>(&default_settings), | ||||||
|  |                                 sizeof(settings_type)); | ||||||
|  |         out_settings_file.flush(); | ||||||
|  |         out_settings_file.close(); | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     constexpr auto IsHeaderValid = [](std::ifstream& file) -> bool { | ||||||
|  |         if (!file.is_open()) { | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|  |         SettingsHeader hdr{}; | ||||||
|  |         file.read(reinterpret_cast<char*>(&hdr), sizeof(hdr)); | ||||||
|  |         return hdr.magic == SETTINGS_MAGIC && hdr.version == SETTINGS_VERSION; | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     if (!exists || !file_size_ok) { | ||||||
|  |         ResetToDefault(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     std::ifstream file(settings_file, std::ios::binary | std::ios::in); | ||||||
|  |     if (!IsHeaderValid(file)) { | ||||||
|  |         file.close(); | ||||||
|  |         ResetToDefault(); | ||||||
|  |         file = std::ifstream(settings_file, std::ios::binary | std::ios::in); | ||||||
|  |         if (!IsHeaderValid(file)) { | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if constexpr (std::is_same_v<settings_type, PrivateSettings>) { | ||||||
|  |         file.read(reinterpret_cast<char*>(&m_private_settings), sizeof(settings_type)); | ||||||
|  |     } else if constexpr (std::is_same_v<settings_type, DeviceSettings>) { | ||||||
|  |         file.read(reinterpret_cast<char*>(&m_device_settings), sizeof(settings_type)); | ||||||
|  |     } else if constexpr (std::is_same_v<settings_type, ApplnSettings>) { | ||||||
|  |         file.read(reinterpret_cast<char*>(&m_appln_settings), sizeof(settings_type)); | ||||||
|  |     } else if constexpr (std::is_same_v<settings_type, SystemSettings>) { | ||||||
|  |         file.read(reinterpret_cast<char*>(&m_system_settings), sizeof(settings_type)); | ||||||
|  |     } else { | ||||||
|  |         UNREACHABLE(); | ||||||
|  |     } | ||||||
|  |     file.close(); | ||||||
|  |  | ||||||
|  |     return true; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | bool SET_SYS::StoreSettingsFile(std::filesystem::path& path, auto& settings) { | ||||||
|  |     using settings_type = std::decay_t<decltype(settings)>; | ||||||
|  |  | ||||||
|  |     if (!Common::FS::IsDir(path)) { | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     auto settings_base = path / "settings"; | ||||||
|  |     auto settings_tmp_file = settings_base; | ||||||
|  |     settings_tmp_file = settings_tmp_file.replace_extension("tmp"); | ||||||
|  |     std::ofstream file(settings_tmp_file, std::ios::binary | std::ios::out); | ||||||
|  |     if (!file.is_open()) { | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     SettingsHeader hdr{ | ||||||
|  |         .magic = SETTINGS_MAGIC, | ||||||
|  |         .version = SETTINGS_VERSION, | ||||||
|  |         .reserved = 0u, | ||||||
|  |     }; | ||||||
|  |     file.write(reinterpret_cast<const char*>(&hdr), sizeof(hdr)); | ||||||
|  |  | ||||||
|  |     if constexpr (std::is_same_v<settings_type, PrivateSettings>) { | ||||||
|  |         file.write(reinterpret_cast<const char*>(&m_private_settings), sizeof(settings_type)); | ||||||
|  |     } else if constexpr (std::is_same_v<settings_type, DeviceSettings>) { | ||||||
|  |         file.write(reinterpret_cast<const char*>(&m_device_settings), sizeof(settings_type)); | ||||||
|  |     } else if constexpr (std::is_same_v<settings_type, ApplnSettings>) { | ||||||
|  |         file.write(reinterpret_cast<const char*>(&m_appln_settings), sizeof(settings_type)); | ||||||
|  |     } else if constexpr (std::is_same_v<settings_type, SystemSettings>) { | ||||||
|  |         file.write(reinterpret_cast<const char*>(&m_system_settings), sizeof(settings_type)); | ||||||
|  |     } else { | ||||||
|  |         UNREACHABLE(); | ||||||
|  |     } | ||||||
|  |     file.close(); | ||||||
|  |  | ||||||
|  |     std::filesystem::rename(settings_tmp_file, settings_base.replace_extension("dat")); | ||||||
|  |  | ||||||
|  |     return true; | ||||||
|  | } | ||||||
|  |  | ||||||
| void SET_SYS::SetLanguageCode(HLERequestContext& ctx) { | void SET_SYS::SetLanguageCode(HLERequestContext& ctx) { | ||||||
|     IPC::RequestParser rp{ctx}; |     IPC::RequestParser rp{ctx}; | ||||||
|     language_code_setting = rp.PopEnum<LanguageCode>(); |     m_system_settings.language_code = rp.PopEnum<LanguageCode>(); | ||||||
|  |     SetSaveNeeded(); | ||||||
|  |  | ||||||
|     LOG_INFO(Service_SET, "called, language_code={}", language_code_setting); |     LOG_INFO(Service_SET, "called, language_code={}", m_system_settings.language_code); | ||||||
|  |  | ||||||
|     IPC::ResponseBuilder rb{ctx, 2}; |     IPC::ResponseBuilder rb{ctx, 2}; | ||||||
|     rb.Push(ResultSuccess); |     rb.Push(ResultSuccess); | ||||||
| @@ -112,19 +236,68 @@ void SET_SYS::GetFirmwareVersion2(HLERequestContext& ctx) { | |||||||
|     rb.Push(result); |     rb.Push(result); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | void SET_SYS::GetExternalSteadyClockSourceId(HLERequestContext& ctx) { | ||||||
|  |     LOG_INFO(Service_SET, "called"); | ||||||
|  |  | ||||||
|  |     Common::UUID id{}; | ||||||
|  |     auto res = GetExternalSteadyClockSourceId(id); | ||||||
|  |  | ||||||
|  |     IPC::ResponseBuilder rb{ctx, 2 + sizeof(Common::UUID) / sizeof(u32)}; | ||||||
|  |     rb.Push(res); | ||||||
|  |     rb.PushRaw(id); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void SET_SYS::SetExternalSteadyClockSourceId(HLERequestContext& ctx) { | ||||||
|  |     LOG_INFO(Service_SET, "called"); | ||||||
|  |  | ||||||
|  |     IPC::RequestParser rp{ctx}; | ||||||
|  |     auto id{rp.PopRaw<Common::UUID>()}; | ||||||
|  |  | ||||||
|  |     auto res = SetExternalSteadyClockSourceId(id); | ||||||
|  |  | ||||||
|  |     IPC::ResponseBuilder rb{ctx, 2}; | ||||||
|  |     rb.Push(res); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void SET_SYS::GetUserSystemClockContext(HLERequestContext& ctx) { | ||||||
|  |     LOG_INFO(Service_SET, "called"); | ||||||
|  |  | ||||||
|  |     Service::Time::Clock::SystemClockContext context{}; | ||||||
|  |     auto res = GetUserSystemClockContext(context); | ||||||
|  |  | ||||||
|  |     IPC::ResponseBuilder rb{ctx, | ||||||
|  |                             2 + sizeof(Service::Time::Clock::SystemClockContext) / sizeof(u32)}; | ||||||
|  |     rb.Push(res); | ||||||
|  |     rb.PushRaw(context); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void SET_SYS::SetUserSystemClockContext(HLERequestContext& ctx) { | ||||||
|  |     LOG_INFO(Service_SET, "called"); | ||||||
|  |  | ||||||
|  |     IPC::RequestParser rp{ctx}; | ||||||
|  |     auto context{rp.PopRaw<Service::Time::Clock::SystemClockContext>()}; | ||||||
|  |  | ||||||
|  |     auto res = SetUserSystemClockContext(context); | ||||||
|  |  | ||||||
|  |     IPC::ResponseBuilder rb{ctx, 2}; | ||||||
|  |     rb.Push(res); | ||||||
|  | } | ||||||
|  |  | ||||||
| void SET_SYS::GetAccountSettings(HLERequestContext& ctx) { | void SET_SYS::GetAccountSettings(HLERequestContext& ctx) { | ||||||
|     LOG_INFO(Service_SET, "called"); |     LOG_INFO(Service_SET, "called"); | ||||||
|  |  | ||||||
|     IPC::ResponseBuilder rb{ctx, 3}; |     IPC::ResponseBuilder rb{ctx, 3}; | ||||||
|     rb.Push(ResultSuccess); |     rb.Push(ResultSuccess); | ||||||
|     rb.PushRaw(account_settings); |     rb.PushRaw(m_system_settings.account_settings); | ||||||
| } | } | ||||||
|  |  | ||||||
| void SET_SYS::SetAccountSettings(HLERequestContext& ctx) { | void SET_SYS::SetAccountSettings(HLERequestContext& ctx) { | ||||||
|     IPC::RequestParser rp{ctx}; |     IPC::RequestParser rp{ctx}; | ||||||
|     account_settings = rp.PopRaw<AccountSettings>(); |     m_system_settings.account_settings = rp.PopRaw<AccountSettings>(); | ||||||
|  |     SetSaveNeeded(); | ||||||
|  |  | ||||||
|     LOG_INFO(Service_SET, "called, account_settings_flags={}", account_settings.flags); |     LOG_INFO(Service_SET, "called, account_settings_flags={}", | ||||||
|  |              m_system_settings.account_settings.flags); | ||||||
|  |  | ||||||
|     IPC::ResponseBuilder rb{ctx, 2}; |     IPC::ResponseBuilder rb{ctx, 2}; | ||||||
|     rb.Push(ResultSuccess); |     rb.Push(ResultSuccess); | ||||||
| @@ -133,11 +306,11 @@ void SET_SYS::SetAccountSettings(HLERequestContext& ctx) { | |||||||
| void SET_SYS::GetEulaVersions(HLERequestContext& ctx) { | void SET_SYS::GetEulaVersions(HLERequestContext& ctx) { | ||||||
|     LOG_INFO(Service_SET, "called"); |     LOG_INFO(Service_SET, "called"); | ||||||
|  |  | ||||||
|     ctx.WriteBuffer(eula_versions); |     ctx.WriteBuffer(m_system_settings.eula_versions); | ||||||
|  |  | ||||||
|     IPC::ResponseBuilder rb{ctx, 3}; |     IPC::ResponseBuilder rb{ctx, 3}; | ||||||
|     rb.Push(ResultSuccess); |     rb.Push(ResultSuccess); | ||||||
|     rb.Push(static_cast<u32>(eula_versions.size())); |     rb.Push(m_system_settings.eula_version_count); | ||||||
| } | } | ||||||
|  |  | ||||||
| void SET_SYS::SetEulaVersions(HLERequestContext& ctx) { | void SET_SYS::SetEulaVersions(HLERequestContext& ctx) { | ||||||
| @@ -145,13 +318,12 @@ void SET_SYS::SetEulaVersions(HLERequestContext& ctx) { | |||||||
|     const auto buffer_data = ctx.ReadBuffer(); |     const auto buffer_data = ctx.ReadBuffer(); | ||||||
|  |  | ||||||
|     LOG_INFO(Service_SET, "called, elements={}", elements); |     LOG_INFO(Service_SET, "called, elements={}", elements); | ||||||
|  |     ASSERT(elements <= m_system_settings.eula_versions.size()); | ||||||
|  |  | ||||||
|     eula_versions.resize(elements); |     m_system_settings.eula_version_count = static_cast<u32>(elements); | ||||||
|     for (std::size_t index = 0; index < elements; index++) { |     std::memcpy(&m_system_settings.eula_versions, buffer_data.data(), | ||||||
|         const std::size_t start_index = index * sizeof(EulaVersion); |                 sizeof(EulaVersion) * elements); | ||||||
|         memcpy(eula_versions.data() + start_index, buffer_data.data() + start_index, |     SetSaveNeeded(); | ||||||
|                sizeof(EulaVersion)); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     IPC::ResponseBuilder rb{ctx, 2}; |     IPC::ResponseBuilder rb{ctx, 2}; | ||||||
|     rb.Push(ResultSuccess); |     rb.Push(ResultSuccess); | ||||||
| @@ -162,14 +334,15 @@ void SET_SYS::GetColorSetId(HLERequestContext& ctx) { | |||||||
|  |  | ||||||
|     IPC::ResponseBuilder rb{ctx, 3}; |     IPC::ResponseBuilder rb{ctx, 3}; | ||||||
|     rb.Push(ResultSuccess); |     rb.Push(ResultSuccess); | ||||||
|     rb.PushEnum(color_set); |     rb.PushEnum(m_system_settings.color_set_id); | ||||||
| } | } | ||||||
|  |  | ||||||
| void SET_SYS::SetColorSetId(HLERequestContext& ctx) { | void SET_SYS::SetColorSetId(HLERequestContext& ctx) { | ||||||
|     IPC::RequestParser rp{ctx}; |     IPC::RequestParser rp{ctx}; | ||||||
|     color_set = rp.PopEnum<ColorSet>(); |     m_system_settings.color_set_id = rp.PopEnum<ColorSet>(); | ||||||
|  |     SetSaveNeeded(); | ||||||
|  |  | ||||||
|     LOG_DEBUG(Service_SET, "called, color_set={}", color_set); |     LOG_DEBUG(Service_SET, "called, color_set={}", m_system_settings.color_set_id); | ||||||
|  |  | ||||||
|     IPC::ResponseBuilder rb{ctx, 2}; |     IPC::ResponseBuilder rb{ctx, 2}; | ||||||
|     rb.Push(ResultSuccess); |     rb.Push(ResultSuccess); | ||||||
| @@ -180,17 +353,21 @@ void SET_SYS::GetNotificationSettings(HLERequestContext& ctx) { | |||||||
|  |  | ||||||
|     IPC::ResponseBuilder rb{ctx, 8}; |     IPC::ResponseBuilder rb{ctx, 8}; | ||||||
|     rb.Push(ResultSuccess); |     rb.Push(ResultSuccess); | ||||||
|     rb.PushRaw(notification_settings); |     rb.PushRaw(m_system_settings.notification_settings); | ||||||
| } | } | ||||||
|  |  | ||||||
| void SET_SYS::SetNotificationSettings(HLERequestContext& ctx) { | void SET_SYS::SetNotificationSettings(HLERequestContext& ctx) { | ||||||
|     IPC::RequestParser rp{ctx}; |     IPC::RequestParser rp{ctx}; | ||||||
|     notification_settings = rp.PopRaw<NotificationSettings>(); |     m_system_settings.notification_settings = rp.PopRaw<NotificationSettings>(); | ||||||
|  |     SetSaveNeeded(); | ||||||
|  |  | ||||||
|     LOG_INFO(Service_SET, "called, flags={}, volume={}, head_time={}:{}, tailt_time={}:{}", |     LOG_INFO(Service_SET, "called, flags={}, volume={}, head_time={}:{}, tailt_time={}:{}", | ||||||
|              notification_settings.flags.raw, notification_settings.volume, |              m_system_settings.notification_settings.flags.raw, | ||||||
|              notification_settings.start_time.hour, notification_settings.start_time.minute, |              m_system_settings.notification_settings.volume, | ||||||
|              notification_settings.stop_time.hour, notification_settings.stop_time.minute); |              m_system_settings.notification_settings.start_time.hour, | ||||||
|  |              m_system_settings.notification_settings.start_time.minute, | ||||||
|  |              m_system_settings.notification_settings.stop_time.hour, | ||||||
|  |              m_system_settings.notification_settings.stop_time.minute); | ||||||
|  |  | ||||||
|     IPC::ResponseBuilder rb{ctx, 2}; |     IPC::ResponseBuilder rb{ctx, 2}; | ||||||
|     rb.Push(ResultSuccess); |     rb.Push(ResultSuccess); | ||||||
| @@ -199,11 +376,11 @@ void SET_SYS::SetNotificationSettings(HLERequestContext& ctx) { | |||||||
| void SET_SYS::GetAccountNotificationSettings(HLERequestContext& ctx) { | void SET_SYS::GetAccountNotificationSettings(HLERequestContext& ctx) { | ||||||
|     LOG_INFO(Service_SET, "called"); |     LOG_INFO(Service_SET, "called"); | ||||||
|  |  | ||||||
|     ctx.WriteBuffer(account_notifications); |     ctx.WriteBuffer(m_system_settings.account_notification_settings); | ||||||
|  |  | ||||||
|     IPC::ResponseBuilder rb{ctx, 3}; |     IPC::ResponseBuilder rb{ctx, 3}; | ||||||
|     rb.Push(ResultSuccess); |     rb.Push(ResultSuccess); | ||||||
|     rb.Push(static_cast<u32>(account_notifications.size())); |     rb.Push(m_system_settings.account_notification_settings_count); | ||||||
| } | } | ||||||
|  |  | ||||||
| void SET_SYS::SetAccountNotificationSettings(HLERequestContext& ctx) { | void SET_SYS::SetAccountNotificationSettings(HLERequestContext& ctx) { | ||||||
| @@ -212,12 +389,12 @@ void SET_SYS::SetAccountNotificationSettings(HLERequestContext& ctx) { | |||||||
|  |  | ||||||
|     LOG_INFO(Service_SET, "called, elements={}", elements); |     LOG_INFO(Service_SET, "called, elements={}", elements); | ||||||
|  |  | ||||||
|     account_notifications.resize(elements); |     ASSERT(elements <= m_system_settings.account_notification_settings.size()); | ||||||
|     for (std::size_t index = 0; index < elements; index++) { |  | ||||||
|         const std::size_t start_index = index * sizeof(AccountNotificationSettings); |     m_system_settings.account_notification_settings_count = static_cast<u32>(elements); | ||||||
|         memcpy(account_notifications.data() + start_index, buffer_data.data() + start_index, |     std::memcpy(&m_system_settings.account_notification_settings, buffer_data.data(), | ||||||
|                sizeof(AccountNotificationSettings)); |                 elements * sizeof(AccountNotificationSettings)); | ||||||
|     } |     SetSaveNeeded(); | ||||||
|  |  | ||||||
|     IPC::ResponseBuilder rb{ctx, 2}; |     IPC::ResponseBuilder rb{ctx, 2}; | ||||||
|     rb.Push(ResultSuccess); |     rb.Push(ResultSuccess); | ||||||
| @@ -244,6 +421,14 @@ static Settings GetSettings() { | |||||||
|     ret["hbloader"]["applet_heap_size"] = ToBytes(u64{0x0}); |     ret["hbloader"]["applet_heap_size"] = ToBytes(u64{0x0}); | ||||||
|     ret["hbloader"]["applet_heap_reservation_size"] = ToBytes(u64{0x8600000}); |     ret["hbloader"]["applet_heap_reservation_size"] = ToBytes(u64{0x8600000}); | ||||||
|  |  | ||||||
|  |     // Time | ||||||
|  |     ret["time"]["notify_time_to_fs_interval_seconds"] = ToBytes(s32{600}); | ||||||
|  |     ret["time"]["standard_network_clock_sufficient_accuracy_minutes"] = | ||||||
|  |         ToBytes(s32{43200}); // 30 days | ||||||
|  |     ret["time"]["standard_steady_clock_rtc_update_interval_minutes"] = ToBytes(s32{5}); | ||||||
|  |     ret["time"]["standard_steady_clock_test_offset_minutes"] = ToBytes(s32{0}); | ||||||
|  |     ret["time"]["standard_user_clock_initial_year"] = ToBytes(s32{2023}); | ||||||
|  |  | ||||||
|     return ret; |     return ret; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -273,8 +458,6 @@ void SET_SYS::GetSettingsItemValueSize(HLERequestContext& ctx) { | |||||||
| } | } | ||||||
|  |  | ||||||
| void SET_SYS::GetSettingsItemValue(HLERequestContext& ctx) { | void SET_SYS::GetSettingsItemValue(HLERequestContext& ctx) { | ||||||
|     LOG_DEBUG(Service_SET, "called"); |  | ||||||
|  |  | ||||||
|     // The category of the setting. This corresponds to the top-level keys of |     // The category of the setting. This corresponds to the top-level keys of | ||||||
|     // system_settings.ini. |     // system_settings.ini. | ||||||
|     const auto setting_category_buf{ctx.ReadBuffer(0)}; |     const auto setting_category_buf{ctx.ReadBuffer(0)}; | ||||||
| @@ -285,14 +468,13 @@ void SET_SYS::GetSettingsItemValue(HLERequestContext& ctx) { | |||||||
|     const auto setting_name_buf{ctx.ReadBuffer(1)}; |     const auto setting_name_buf{ctx.ReadBuffer(1)}; | ||||||
|     const std::string setting_name{setting_name_buf.begin(), setting_name_buf.end()}; |     const std::string setting_name{setting_name_buf.begin(), setting_name_buf.end()}; | ||||||
|  |  | ||||||
|     auto settings{GetSettings()}; |     std::vector<u8> value; | ||||||
|     Result response{ResultUnknown}; |     auto response = GetSettingsItemValue(value, setting_category, setting_name); | ||||||
|  |  | ||||||
|     if (settings.contains(setting_category) && settings[setting_category].contains(setting_name)) { |     LOG_INFO(Service_SET, "called. category={}, name={} -- res=0x{:X}", setting_category, | ||||||
|         auto setting_value = settings[setting_category][setting_name]; |              setting_name, response.raw); | ||||||
|         ctx.WriteBuffer(setting_value.data(), setting_value.size()); |  | ||||||
|         response = ResultSuccess; |     ctx.WriteBuffer(value.data(), value.size()); | ||||||
|     } |  | ||||||
|  |  | ||||||
|     IPC::ResponseBuilder rb{ctx, 2}; |     IPC::ResponseBuilder rb{ctx, 2}; | ||||||
|     rb.Push(response); |     rb.Push(response); | ||||||
| @@ -303,19 +485,23 @@ void SET_SYS::GetTvSettings(HLERequestContext& ctx) { | |||||||
|  |  | ||||||
|     IPC::ResponseBuilder rb{ctx, 10}; |     IPC::ResponseBuilder rb{ctx, 10}; | ||||||
|     rb.Push(ResultSuccess); |     rb.Push(ResultSuccess); | ||||||
|     rb.PushRaw(tv_settings); |     rb.PushRaw(m_system_settings.tv_settings); | ||||||
| } | } | ||||||
|  |  | ||||||
| void SET_SYS::SetTvSettings(HLERequestContext& ctx) { | void SET_SYS::SetTvSettings(HLERequestContext& ctx) { | ||||||
|     IPC::RequestParser rp{ctx}; |     IPC::RequestParser rp{ctx}; | ||||||
|     tv_settings = rp.PopRaw<TvSettings>(); |     m_system_settings.tv_settings = rp.PopRaw<TvSettings>(); | ||||||
|  |     SetSaveNeeded(); | ||||||
|  |  | ||||||
|     LOG_INFO(Service_SET, |     LOG_INFO(Service_SET, | ||||||
|              "called, flags={}, cmu_mode={}, constrast_ratio={}, hdmi_content_type={}, " |              "called, flags={}, cmu_mode={}, constrast_ratio={}, hdmi_content_type={}, " | ||||||
|              "rgb_range={}, tv_gama={}, tv_resolution={}, tv_underscan={}", |              "rgb_range={}, tv_gama={}, tv_resolution={}, tv_underscan={}", | ||||||
|              tv_settings.flags.raw, tv_settings.cmu_mode, tv_settings.constrast_ratio, |              m_system_settings.tv_settings.flags.raw, m_system_settings.tv_settings.cmu_mode, | ||||||
|              tv_settings.hdmi_content_type, tv_settings.rgb_range, tv_settings.tv_gama, |              m_system_settings.tv_settings.constrast_ratio, | ||||||
|              tv_settings.tv_resolution, tv_settings.tv_underscan); |              m_system_settings.tv_settings.hdmi_content_type, | ||||||
|  |              m_system_settings.tv_settings.rgb_range, m_system_settings.tv_settings.tv_gama, | ||||||
|  |              m_system_settings.tv_settings.tv_resolution, | ||||||
|  |              m_system_settings.tv_settings.tv_underscan); | ||||||
|  |  | ||||||
|     IPC::ResponseBuilder rb{ctx, 2}; |     IPC::ResponseBuilder rb{ctx, 2}; | ||||||
|     rb.Push(ResultSuccess); |     rb.Push(ResultSuccess); | ||||||
| @@ -329,16 +515,87 @@ void SET_SYS::GetQuestFlag(HLERequestContext& ctx) { | |||||||
|     rb.PushEnum(QuestFlag::Retail); |     rb.PushEnum(QuestFlag::Retail); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | void SET_SYS::GetDeviceTimeZoneLocationName(HLERequestContext& ctx) { | ||||||
|  |     LOG_WARNING(Service_SET, "called"); | ||||||
|  |  | ||||||
|  |     Service::Time::TimeZone::LocationName name{}; | ||||||
|  |     auto res = GetDeviceTimeZoneLocationName(name); | ||||||
|  |  | ||||||
|  |     IPC::ResponseBuilder rb{ctx, 2 + sizeof(Service::Time::TimeZone::LocationName) / sizeof(u32)}; | ||||||
|  |     rb.Push(res); | ||||||
|  |     rb.PushRaw<Service::Time::TimeZone::LocationName>(name); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void SET_SYS::SetDeviceTimeZoneLocationName(HLERequestContext& ctx) { | ||||||
|  |     LOG_WARNING(Service_SET, "called"); | ||||||
|  |  | ||||||
|  |     IPC::RequestParser rp{ctx}; | ||||||
|  |     auto name{rp.PopRaw<Service::Time::TimeZone::LocationName>()}; | ||||||
|  |  | ||||||
|  |     auto res = SetDeviceTimeZoneLocationName(name); | ||||||
|  |  | ||||||
|  |     IPC::ResponseBuilder rb{ctx, 2}; | ||||||
|  |     rb.Push(res); | ||||||
|  | } | ||||||
|  |  | ||||||
| void SET_SYS::SetRegionCode(HLERequestContext& ctx) { | void SET_SYS::SetRegionCode(HLERequestContext& ctx) { | ||||||
|     IPC::RequestParser rp{ctx}; |     IPC::RequestParser rp{ctx}; | ||||||
|     region_code = rp.PopEnum<RegionCode>(); |     m_system_settings.region_code = rp.PopEnum<RegionCode>(); | ||||||
|  |     SetSaveNeeded(); | ||||||
|  |  | ||||||
|     LOG_INFO(Service_SET, "called, region_code={}", region_code); |     LOG_INFO(Service_SET, "called, region_code={}", m_system_settings.region_code); | ||||||
|  |  | ||||||
|     IPC::ResponseBuilder rb{ctx, 2}; |     IPC::ResponseBuilder rb{ctx, 2}; | ||||||
|     rb.Push(ResultSuccess); |     rb.Push(ResultSuccess); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | void SET_SYS::GetNetworkSystemClockContext(HLERequestContext& ctx) { | ||||||
|  |     LOG_INFO(Service_SET, "called"); | ||||||
|  |  | ||||||
|  |     Service::Time::Clock::SystemClockContext context{}; | ||||||
|  |     auto res = GetNetworkSystemClockContext(context); | ||||||
|  |  | ||||||
|  |     IPC::ResponseBuilder rb{ctx, | ||||||
|  |                             2 + sizeof(Service::Time::Clock::SystemClockContext) / sizeof(u32)}; | ||||||
|  |     rb.Push(res); | ||||||
|  |     rb.PushRaw(context); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void SET_SYS::SetNetworkSystemClockContext(HLERequestContext& ctx) { | ||||||
|  |     LOG_INFO(Service_SET, "called"); | ||||||
|  |  | ||||||
|  |     IPC::RequestParser rp{ctx}; | ||||||
|  |     auto context{rp.PopRaw<Service::Time::Clock::SystemClockContext>()}; | ||||||
|  |  | ||||||
|  |     auto res = SetNetworkSystemClockContext(context); | ||||||
|  |  | ||||||
|  |     IPC::ResponseBuilder rb{ctx, 2}; | ||||||
|  |     rb.Push(res); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void SET_SYS::IsUserSystemClockAutomaticCorrectionEnabled(HLERequestContext& ctx) { | ||||||
|  |     LOG_INFO(Service_SET, "called"); | ||||||
|  |  | ||||||
|  |     bool enabled{}; | ||||||
|  |     auto res = IsUserSystemClockAutomaticCorrectionEnabled(enabled); | ||||||
|  |  | ||||||
|  |     IPC::ResponseBuilder rb{ctx, 3}; | ||||||
|  |     rb.Push(res); | ||||||
|  |     rb.PushRaw(enabled); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void SET_SYS::SetUserSystemClockAutomaticCorrectionEnabled(HLERequestContext& ctx) { | ||||||
|  |     LOG_INFO(Service_SET, "called"); | ||||||
|  |  | ||||||
|  |     IPC::RequestParser rp{ctx}; | ||||||
|  |     auto enabled{rp.Pop<bool>()}; | ||||||
|  |  | ||||||
|  |     auto res = SetUserSystemClockAutomaticCorrectionEnabled(enabled); | ||||||
|  |  | ||||||
|  |     IPC::ResponseBuilder rb{ctx, 2}; | ||||||
|  |     rb.Push(res); | ||||||
|  | } | ||||||
|  |  | ||||||
| void SET_SYS::GetPrimaryAlbumStorage(HLERequestContext& ctx) { | void SET_SYS::GetPrimaryAlbumStorage(HLERequestContext& ctx) { | ||||||
|     LOG_WARNING(Service_SET, "(STUBBED) called"); |     LOG_WARNING(Service_SET, "(STUBBED) called"); | ||||||
|  |  | ||||||
| @@ -352,16 +609,18 @@ void SET_SYS::GetSleepSettings(HLERequestContext& ctx) { | |||||||
|  |  | ||||||
|     IPC::ResponseBuilder rb{ctx, 5}; |     IPC::ResponseBuilder rb{ctx, 5}; | ||||||
|     rb.Push(ResultSuccess); |     rb.Push(ResultSuccess); | ||||||
|     rb.PushRaw(sleep_settings); |     rb.PushRaw(m_system_settings.sleep_settings); | ||||||
| } | } | ||||||
|  |  | ||||||
| void SET_SYS::SetSleepSettings(HLERequestContext& ctx) { | void SET_SYS::SetSleepSettings(HLERequestContext& ctx) { | ||||||
|     IPC::RequestParser rp{ctx}; |     IPC::RequestParser rp{ctx}; | ||||||
|     sleep_settings = rp.PopRaw<SleepSettings>(); |     m_system_settings.sleep_settings = rp.PopRaw<SleepSettings>(); | ||||||
|  |     SetSaveNeeded(); | ||||||
|  |  | ||||||
|     LOG_INFO(Service_SET, "called, flags={}, handheld_sleep_plan={}, console_sleep_plan={}", |     LOG_INFO(Service_SET, "called, flags={}, handheld_sleep_plan={}, console_sleep_plan={}", | ||||||
|              sleep_settings.flags.raw, sleep_settings.handheld_sleep_plan, |              m_system_settings.sleep_settings.flags.raw, | ||||||
|              sleep_settings.console_sleep_plan); |              m_system_settings.sleep_settings.handheld_sleep_plan, | ||||||
|  |              m_system_settings.sleep_settings.console_sleep_plan); | ||||||
|  |  | ||||||
|     IPC::ResponseBuilder rb{ctx, 2}; |     IPC::ResponseBuilder rb{ctx, 2}; | ||||||
|     rb.Push(ResultSuccess); |     rb.Push(ResultSuccess); | ||||||
| @@ -371,15 +630,20 @@ void SET_SYS::GetInitialLaunchSettings(HLERequestContext& ctx) { | |||||||
|     LOG_INFO(Service_SET, "called"); |     LOG_INFO(Service_SET, "called"); | ||||||
|     IPC::ResponseBuilder rb{ctx, 10}; |     IPC::ResponseBuilder rb{ctx, 10}; | ||||||
|     rb.Push(ResultSuccess); |     rb.Push(ResultSuccess); | ||||||
|     rb.PushRaw(launch_settings); |     rb.PushRaw(m_system_settings.initial_launch_settings_packed); | ||||||
| } | } | ||||||
|  |  | ||||||
| void SET_SYS::SetInitialLaunchSettings(HLERequestContext& ctx) { | void SET_SYS::SetInitialLaunchSettings(HLERequestContext& ctx) { | ||||||
|     IPC::RequestParser rp{ctx}; |     IPC::RequestParser rp{ctx}; | ||||||
|     launch_settings = rp.PopRaw<InitialLaunchSettings>(); |     auto inital_launch_settings = rp.PopRaw<InitialLaunchSettings>(); | ||||||
|  |  | ||||||
|     LOG_INFO(Service_SET, "called, flags={}, timestamp={}", launch_settings.flags.raw, |     m_system_settings.initial_launch_settings_packed.flags = inital_launch_settings.flags; | ||||||
|              launch_settings.timestamp.time_point); |     m_system_settings.initial_launch_settings_packed.timestamp = inital_launch_settings.timestamp; | ||||||
|  |     SetSaveNeeded(); | ||||||
|  |  | ||||||
|  |     LOG_INFO(Service_SET, "called, flags={}, timestamp={}", | ||||||
|  |              m_system_settings.initial_launch_settings_packed.flags.raw, | ||||||
|  |              m_system_settings.initial_launch_settings_packed.timestamp.time_point); | ||||||
|  |  | ||||||
|     IPC::ResponseBuilder rb{ctx, 2}; |     IPC::ResponseBuilder rb{ctx, 2}; | ||||||
|     rb.Push(ResultSuccess); |     rb.Push(ResultSuccess); | ||||||
| @@ -437,13 +701,37 @@ void SET_SYS::GetAutoUpdateEnableFlag(HLERequestContext& ctx) { | |||||||
| void SET_SYS::GetBatteryPercentageFlag(HLERequestContext& ctx) { | void SET_SYS::GetBatteryPercentageFlag(HLERequestContext& ctx) { | ||||||
|     u8 battery_percentage_flag{1}; |     u8 battery_percentage_flag{1}; | ||||||
|  |  | ||||||
|     LOG_DEBUG(Service_SET, "(STUBBED) called, battery_percentage_flag={}", battery_percentage_flag); |     LOG_WARNING(Service_SET, "(STUBBED) called, battery_percentage_flag={}", | ||||||
|  |                 battery_percentage_flag); | ||||||
|  |  | ||||||
|     IPC::ResponseBuilder rb{ctx, 3}; |     IPC::ResponseBuilder rb{ctx, 3}; | ||||||
|     rb.Push(ResultSuccess); |     rb.Push(ResultSuccess); | ||||||
|     rb.Push(battery_percentage_flag); |     rb.Push(battery_percentage_flag); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | void SET_SYS::SetExternalSteadyClockInternalOffset(HLERequestContext& ctx) { | ||||||
|  |     LOG_DEBUG(Service_SET, "called."); | ||||||
|  |  | ||||||
|  |     IPC::RequestParser rp{ctx}; | ||||||
|  |     auto offset{rp.Pop<s64>()}; | ||||||
|  |  | ||||||
|  |     auto res = SetExternalSteadyClockInternalOffset(offset); | ||||||
|  |  | ||||||
|  |     IPC::ResponseBuilder rb{ctx, 2}; | ||||||
|  |     rb.Push(res); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void SET_SYS::GetExternalSteadyClockInternalOffset(HLERequestContext& ctx) { | ||||||
|  |     LOG_DEBUG(Service_SET, "called."); | ||||||
|  |  | ||||||
|  |     s64 offset{}; | ||||||
|  |     auto res = GetExternalSteadyClockInternalOffset(offset); | ||||||
|  |  | ||||||
|  |     IPC::ResponseBuilder rb{ctx, 4}; | ||||||
|  |     rb.Push(res); | ||||||
|  |     rb.Push(offset); | ||||||
|  | } | ||||||
|  |  | ||||||
| void SET_SYS::GetErrorReportSharePermission(HLERequestContext& ctx) { | void SET_SYS::GetErrorReportSharePermission(HLERequestContext& ctx) { | ||||||
|     LOG_WARNING(Service_SET, "(STUBBED) called"); |     LOG_WARNING(Service_SET, "(STUBBED) called"); | ||||||
|  |  | ||||||
| @@ -453,18 +741,19 @@ void SET_SYS::GetErrorReportSharePermission(HLERequestContext& ctx) { | |||||||
| } | } | ||||||
|  |  | ||||||
| void SET_SYS::GetAppletLaunchFlags(HLERequestContext& ctx) { | void SET_SYS::GetAppletLaunchFlags(HLERequestContext& ctx) { | ||||||
|     LOG_INFO(Service_SET, "called, applet_launch_flag={}", applet_launch_flag); |     LOG_INFO(Service_SET, "called, applet_launch_flag={}", m_system_settings.applet_launch_flag); | ||||||
|  |  | ||||||
|     IPC::ResponseBuilder rb{ctx, 3}; |     IPC::ResponseBuilder rb{ctx, 3}; | ||||||
|     rb.Push(ResultSuccess); |     rb.Push(ResultSuccess); | ||||||
|     rb.Push(applet_launch_flag); |     rb.Push(m_system_settings.applet_launch_flag); | ||||||
| } | } | ||||||
|  |  | ||||||
| void SET_SYS::SetAppletLaunchFlags(HLERequestContext& ctx) { | void SET_SYS::SetAppletLaunchFlags(HLERequestContext& ctx) { | ||||||
|     IPC::RequestParser rp{ctx}; |     IPC::RequestParser rp{ctx}; | ||||||
|     applet_launch_flag = rp.Pop<u32>(); |     m_system_settings.applet_launch_flag = rp.Pop<u32>(); | ||||||
|  |     SetSaveNeeded(); | ||||||
|  |  | ||||||
|     LOG_INFO(Service_SET, "called, applet_launch_flag={}", applet_launch_flag); |     LOG_INFO(Service_SET, "called, applet_launch_flag={}", m_system_settings.applet_launch_flag); | ||||||
|  |  | ||||||
|     IPC::ResponseBuilder rb{ctx, 2}; |     IPC::ResponseBuilder rb{ctx, 2}; | ||||||
|     rb.Push(ResultSuccess); |     rb.Push(ResultSuccess); | ||||||
| @@ -489,6 +778,52 @@ void SET_SYS::GetKeyboardLayout(HLERequestContext& ctx) { | |||||||
|     rb.Push(static_cast<u32>(selected_keyboard_layout)); |     rb.Push(static_cast<u32>(selected_keyboard_layout)); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | void SET_SYS::GetDeviceTimeZoneLocationUpdatedTime(HLERequestContext& ctx) { | ||||||
|  |     LOG_WARNING(Service_SET, "called."); | ||||||
|  |  | ||||||
|  |     Service::Time::Clock::SteadyClockTimePoint time_point{}; | ||||||
|  |     auto res = GetDeviceTimeZoneLocationUpdatedTime(time_point); | ||||||
|  |  | ||||||
|  |     IPC::ResponseBuilder rb{ctx, 4}; | ||||||
|  |     rb.Push(res); | ||||||
|  |     rb.PushRaw<Service::Time::Clock::SteadyClockTimePoint>(time_point); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void SET_SYS::SetDeviceTimeZoneLocationUpdatedTime(HLERequestContext& ctx) { | ||||||
|  |     LOG_WARNING(Service_SET, "called."); | ||||||
|  |  | ||||||
|  |     IPC::RequestParser rp{ctx}; | ||||||
|  |     auto time_point{rp.PopRaw<Service::Time::Clock::SteadyClockTimePoint>()}; | ||||||
|  |  | ||||||
|  |     auto res = SetDeviceTimeZoneLocationUpdatedTime(time_point); | ||||||
|  |  | ||||||
|  |     IPC::ResponseBuilder rb{ctx, 2}; | ||||||
|  |     rb.Push(res); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void SET_SYS::GetUserSystemClockAutomaticCorrectionUpdatedTime(HLERequestContext& ctx) { | ||||||
|  |     LOG_WARNING(Service_SET, "called."); | ||||||
|  |  | ||||||
|  |     Service::Time::Clock::SteadyClockTimePoint time_point{}; | ||||||
|  |     auto res = GetUserSystemClockAutomaticCorrectionUpdatedTime(time_point); | ||||||
|  |  | ||||||
|  |     IPC::ResponseBuilder rb{ctx, 4}; | ||||||
|  |     rb.Push(res); | ||||||
|  |     rb.PushRaw<Service::Time::Clock::SteadyClockTimePoint>(time_point); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void SET_SYS::SetUserSystemClockAutomaticCorrectionUpdatedTime(HLERequestContext& ctx) { | ||||||
|  |     LOG_WARNING(Service_SET, "called."); | ||||||
|  |  | ||||||
|  |     IPC::RequestParser rp{ctx}; | ||||||
|  |     auto time_point{rp.PopRaw<Service::Time::Clock::SteadyClockTimePoint>()}; | ||||||
|  |  | ||||||
|  |     auto res = SetUserSystemClockAutomaticCorrectionUpdatedTime(time_point); | ||||||
|  |  | ||||||
|  |     IPC::ResponseBuilder rb{ctx, 2}; | ||||||
|  |     rb.Push(res); | ||||||
|  | } | ||||||
|  |  | ||||||
| void SET_SYS::GetChineseTraditionalInputMethod(HLERequestContext& ctx) { | void SET_SYS::GetChineseTraditionalInputMethod(HLERequestContext& ctx) { | ||||||
|     LOG_WARNING(Service_SET, "(STUBBED) called"); |     LOG_WARNING(Service_SET, "(STUBBED) called"); | ||||||
|  |  | ||||||
| @@ -508,7 +843,7 @@ void SET_SYS::GetHomeMenuScheme(HLERequestContext& ctx) { | |||||||
|         .extra = 0xFF000000, |         .extra = 0xFF000000, | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     IPC::ResponseBuilder rb{ctx, 7}; |     IPC::ResponseBuilder rb{ctx, 2 + sizeof(HomeMenuScheme) / sizeof(u32)}; | ||||||
|     rb.Push(ResultSuccess); |     rb.Push(ResultSuccess); | ||||||
|     rb.PushRaw(default_color); |     rb.PushRaw(default_color); | ||||||
| } | } | ||||||
| @@ -520,6 +855,7 @@ void SET_SYS::GetHomeMenuSchemeModel(HLERequestContext& ctx) { | |||||||
|     rb.Push(ResultSuccess); |     rb.Push(ResultSuccess); | ||||||
|     rb.Push(0); |     rb.Push(0); | ||||||
| } | } | ||||||
|  |  | ||||||
| void SET_SYS::GetFieldTestingFlag(HLERequestContext& ctx) { | void SET_SYS::GetFieldTestingFlag(HLERequestContext& ctx) { | ||||||
|     LOG_WARNING(Service_SET, "(STUBBED) called"); |     LOG_WARNING(Service_SET, "(STUBBED) called"); | ||||||
|  |  | ||||||
| @@ -528,7 +864,7 @@ void SET_SYS::GetFieldTestingFlag(HLERequestContext& ctx) { | |||||||
|     rb.Push<u8>(false); |     rb.Push<u8>(false); | ||||||
| } | } | ||||||
|  |  | ||||||
| SET_SYS::SET_SYS(Core::System& system_) : ServiceFramework{system_, "set:sys"} { | SET_SYS::SET_SYS(Core::System& system_) : ServiceFramework{system_, "set:sys"}, m_system{system} { | ||||||
|     // clang-format off |     // clang-format off | ||||||
|     static const FunctionInfo functions[] = { |     static const FunctionInfo functions[] = { | ||||||
|         {0, &SET_SYS::SetLanguageCode, "SetLanguageCode"}, |         {0, &SET_SYS::SetLanguageCode, "SetLanguageCode"}, | ||||||
| @@ -543,10 +879,10 @@ SET_SYS::SET_SYS(Core::System& system_) : ServiceFramework{system_, "set:sys"} { | |||||||
|         {10, nullptr, "SetBacklightSettings"}, |         {10, nullptr, "SetBacklightSettings"}, | ||||||
|         {11, nullptr, "SetBluetoothDevicesSettings"}, |         {11, nullptr, "SetBluetoothDevicesSettings"}, | ||||||
|         {12, nullptr, "GetBluetoothDevicesSettings"}, |         {12, nullptr, "GetBluetoothDevicesSettings"}, | ||||||
|         {13, nullptr, "GetExternalSteadyClockSourceId"}, |         {13, &SET_SYS::GetExternalSteadyClockSourceId, "GetExternalSteadyClockSourceId"}, | ||||||
|         {14, nullptr, "SetExternalSteadyClockSourceId"}, |         {14, &SET_SYS::SetExternalSteadyClockSourceId, "SetExternalSteadyClockSourceId"}, | ||||||
|         {15, nullptr, "GetUserSystemClockContext"}, |         {15, &SET_SYS::GetUserSystemClockContext, "GetUserSystemClockContext"}, | ||||||
|         {16, nullptr, "SetUserSystemClockContext"}, |         {16, &SET_SYS::SetUserSystemClockContext, "SetUserSystemClockContext"}, | ||||||
|         {17, &SET_SYS::GetAccountSettings, "GetAccountSettings"}, |         {17, &SET_SYS::GetAccountSettings, "GetAccountSettings"}, | ||||||
|         {18, &SET_SYS::SetAccountSettings, "SetAccountSettings"}, |         {18, &SET_SYS::SetAccountSettings, "SetAccountSettings"}, | ||||||
|         {19, nullptr, "GetAudioVolume"}, |         {19, nullptr, "GetAudioVolume"}, | ||||||
| @@ -581,15 +917,15 @@ SET_SYS::SET_SYS(Core::System& system_) : ServiceFramework{system_, "set:sys"} { | |||||||
|         {50, nullptr, "SetDataDeletionSettings"}, |         {50, nullptr, "SetDataDeletionSettings"}, | ||||||
|         {51, nullptr, "GetInitialSystemAppletProgramId"}, |         {51, nullptr, "GetInitialSystemAppletProgramId"}, | ||||||
|         {52, nullptr, "GetOverlayDispProgramId"}, |         {52, nullptr, "GetOverlayDispProgramId"}, | ||||||
|         {53, nullptr, "GetDeviceTimeZoneLocationName"}, |         {53, &SET_SYS::GetDeviceTimeZoneLocationName, "GetDeviceTimeZoneLocationName"}, | ||||||
|         {54, nullptr, "SetDeviceTimeZoneLocationName"}, |         {54, &SET_SYS::SetDeviceTimeZoneLocationName, "SetDeviceTimeZoneLocationName"}, | ||||||
|         {55, nullptr, "GetWirelessCertificationFileSize"}, |         {55, nullptr, "GetWirelessCertificationFileSize"}, | ||||||
|         {56, nullptr, "GetWirelessCertificationFile"}, |         {56, nullptr, "GetWirelessCertificationFile"}, | ||||||
|         {57, &SET_SYS::SetRegionCode, "SetRegionCode"}, |         {57, &SET_SYS::SetRegionCode, "SetRegionCode"}, | ||||||
|         {58, nullptr, "GetNetworkSystemClockContext"}, |         {58, &SET_SYS::GetNetworkSystemClockContext, "GetNetworkSystemClockContext"}, | ||||||
|         {59, nullptr, "SetNetworkSystemClockContext"}, |         {59, &SET_SYS::SetNetworkSystemClockContext, "SetNetworkSystemClockContext"}, | ||||||
|         {60, nullptr, "IsUserSystemClockAutomaticCorrectionEnabled"}, |         {60, &SET_SYS::IsUserSystemClockAutomaticCorrectionEnabled, "IsUserSystemClockAutomaticCorrectionEnabled"}, | ||||||
|         {61, nullptr, "SetUserSystemClockAutomaticCorrectionEnabled"}, |         {61, &SET_SYS::SetUserSystemClockAutomaticCorrectionEnabled, "SetUserSystemClockAutomaticCorrectionEnabled"}, | ||||||
|         {62, nullptr, "GetDebugModeFlag"}, |         {62, nullptr, "GetDebugModeFlag"}, | ||||||
|         {63, &SET_SYS::GetPrimaryAlbumStorage, "GetPrimaryAlbumStorage"}, |         {63, &SET_SYS::GetPrimaryAlbumStorage, "GetPrimaryAlbumStorage"}, | ||||||
|         {64, nullptr, "SetPrimaryAlbumStorage"}, |         {64, nullptr, "SetPrimaryAlbumStorage"}, | ||||||
| @@ -633,8 +969,8 @@ SET_SYS::SET_SYS(Core::System& system_) : ServiceFramework{system_, "set:sys"} { | |||||||
|         {102, nullptr, "SetExternalRtcResetFlag"}, |         {102, nullptr, "SetExternalRtcResetFlag"}, | ||||||
|         {103, nullptr, "GetUsbFullKeyEnableFlag"}, |         {103, nullptr, "GetUsbFullKeyEnableFlag"}, | ||||||
|         {104, nullptr, "SetUsbFullKeyEnableFlag"}, |         {104, nullptr, "SetUsbFullKeyEnableFlag"}, | ||||||
|         {105, nullptr, "SetExternalSteadyClockInternalOffset"}, |         {105, &SET_SYS::SetExternalSteadyClockInternalOffset, "SetExternalSteadyClockInternalOffset"}, | ||||||
|         {106, nullptr, "GetExternalSteadyClockInternalOffset"}, |         {106, &SET_SYS::GetExternalSteadyClockInternalOffset, "GetExternalSteadyClockInternalOffset"}, | ||||||
|         {107, nullptr, "GetBacklightSettingsEx"}, |         {107, nullptr, "GetBacklightSettingsEx"}, | ||||||
|         {108, nullptr, "SetBacklightSettingsEx"}, |         {108, nullptr, "SetBacklightSettingsEx"}, | ||||||
|         {109, nullptr, "GetHeadphoneVolumeWarningCount"}, |         {109, nullptr, "GetHeadphoneVolumeWarningCount"}, | ||||||
| @@ -678,10 +1014,10 @@ SET_SYS::SET_SYS(Core::System& system_) : ServiceFramework{system_, "set:sys"} { | |||||||
|         {147, nullptr, "GetConsoleSixAxisSensorAngularAcceleration"}, |         {147, nullptr, "GetConsoleSixAxisSensorAngularAcceleration"}, | ||||||
|         {148, nullptr, "SetConsoleSixAxisSensorAngularAcceleration"}, |         {148, nullptr, "SetConsoleSixAxisSensorAngularAcceleration"}, | ||||||
|         {149, nullptr, "GetRebootlessSystemUpdateVersion"}, |         {149, nullptr, "GetRebootlessSystemUpdateVersion"}, | ||||||
|         {150, nullptr, "GetDeviceTimeZoneLocationUpdatedTime"}, |         {150, &SET_SYS::GetDeviceTimeZoneLocationUpdatedTime, "GetDeviceTimeZoneLocationUpdatedTime"}, | ||||||
|         {151, nullptr, "SetDeviceTimeZoneLocationUpdatedTime"}, |         {151, &SET_SYS::SetDeviceTimeZoneLocationUpdatedTime, "SetDeviceTimeZoneLocationUpdatedTime"}, | ||||||
|         {152, nullptr, "GetUserSystemClockAutomaticCorrectionUpdatedTime"}, |         {152, &SET_SYS::GetUserSystemClockAutomaticCorrectionUpdatedTime, "GetUserSystemClockAutomaticCorrectionUpdatedTime"}, | ||||||
|         {153, nullptr, "SetUserSystemClockAutomaticCorrectionUpdatedTime"}, |         {153, &SET_SYS::SetUserSystemClockAutomaticCorrectionUpdatedTime, "SetUserSystemClockAutomaticCorrectionUpdatedTime"}, | ||||||
|         {154, nullptr, "GetAccountOnlineStorageSettings"}, |         {154, nullptr, "GetAccountOnlineStorageSettings"}, | ||||||
|         {155, nullptr, "SetAccountOnlineStorageSettings"}, |         {155, nullptr, "SetAccountOnlineStorageSettings"}, | ||||||
|         {156, nullptr, "GetPctlReadyFlag"}, |         {156, nullptr, "GetPctlReadyFlag"}, | ||||||
| @@ -743,8 +1079,184 @@ SET_SYS::SET_SYS(Core::System& system_) : ServiceFramework{system_, "set:sys"} { | |||||||
|     // clang-format on |     // clang-format on | ||||||
|  |  | ||||||
|     RegisterHandlers(functions); |     RegisterHandlers(functions); | ||||||
|  |  | ||||||
|  |     SetupSettings(); | ||||||
|  |     m_save_thread = | ||||||
|  |         std::jthread([this](std::stop_token stop_token) { StoreSettingsThreadFunc(stop_token); }); | ||||||
| } | } | ||||||
|  |  | ||||||
| SET_SYS::~SET_SYS() = default; | SET_SYS::~SET_SYS() { | ||||||
|  |     SetSaveNeeded(); | ||||||
|  |     m_save_thread.request_stop(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void SET_SYS::SetupSettings() { | ||||||
|  |     auto system_dir = | ||||||
|  |         Common::FS::GetYuzuPath(Common::FS::YuzuPath::NANDDir) / "system/save/8000000000000050"; | ||||||
|  |     if (!LoadSettingsFile(system_dir, []() { return DefaultSystemSettings(); })) { | ||||||
|  |         ASSERT(false); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     auto private_dir = | ||||||
|  |         Common::FS::GetYuzuPath(Common::FS::YuzuPath::NANDDir) / "system/save/8000000000000052"; | ||||||
|  |     if (!LoadSettingsFile(private_dir, []() { return DefaultPrivateSettings(); })) { | ||||||
|  |         ASSERT(false); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     auto device_dir = | ||||||
|  |         Common::FS::GetYuzuPath(Common::FS::YuzuPath::NANDDir) / "system/save/8000000000000053"; | ||||||
|  |     if (!LoadSettingsFile(device_dir, []() { return DefaultDeviceSettings(); })) { | ||||||
|  |         ASSERT(false); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     auto appln_dir = | ||||||
|  |         Common::FS::GetYuzuPath(Common::FS::YuzuPath::NANDDir) / "system/save/8000000000000054"; | ||||||
|  |     if (!LoadSettingsFile(appln_dir, []() { return DefaultApplnSettings(); })) { | ||||||
|  |         ASSERT(false); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void SET_SYS::StoreSettings() { | ||||||
|  |     auto system_dir = | ||||||
|  |         Common::FS::GetYuzuPath(Common::FS::YuzuPath::NANDDir) / "system/save/8000000000000050"; | ||||||
|  |     if (!StoreSettingsFile(system_dir, m_system_settings)) { | ||||||
|  |         LOG_ERROR(HW_GPU, "Failed to store System settings"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     auto private_dir = | ||||||
|  |         Common::FS::GetYuzuPath(Common::FS::YuzuPath::NANDDir) / "system/save/8000000000000052"; | ||||||
|  |     if (!StoreSettingsFile(private_dir, m_private_settings)) { | ||||||
|  |         LOG_ERROR(HW_GPU, "Failed to store Private settings"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     auto device_dir = | ||||||
|  |         Common::FS::GetYuzuPath(Common::FS::YuzuPath::NANDDir) / "system/save/8000000000000053"; | ||||||
|  |     if (!StoreSettingsFile(device_dir, m_device_settings)) { | ||||||
|  |         LOG_ERROR(HW_GPU, "Failed to store Device settings"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     auto appln_dir = | ||||||
|  |         Common::FS::GetYuzuPath(Common::FS::YuzuPath::NANDDir) / "system/save/8000000000000054"; | ||||||
|  |     if (!StoreSettingsFile(appln_dir, m_appln_settings)) { | ||||||
|  |         LOG_ERROR(HW_GPU, "Failed to store ApplLn settings"); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void SET_SYS::StoreSettingsThreadFunc(std::stop_token stop_token) { | ||||||
|  |     while (Common::StoppableTimedWait(stop_token, std::chrono::minutes(1))) { | ||||||
|  |         std::scoped_lock l{m_save_needed_mutex}; | ||||||
|  |         if (!std::exchange(m_save_needed, false)) { | ||||||
|  |             continue; | ||||||
|  |         } | ||||||
|  |         StoreSettings(); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void SET_SYS::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) { | ||||||
|  |     auto settings{GetSettings()}; | ||||||
|  |     R_UNLESS(settings.contains(category) && settings[category].contains(name), ResultUnknown); | ||||||
|  |  | ||||||
|  |     out_value = settings[category][name]; | ||||||
|  |     R_SUCCEED(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | Result SET_SYS::GetExternalSteadyClockSourceId(Common::UUID& out_id) { | ||||||
|  |     out_id = m_private_settings.external_clock_source_id; | ||||||
|  |     R_SUCCEED(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | Result SET_SYS::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) { | ||||||
|  |     out_context = m_system_settings.user_system_clock_context; | ||||||
|  |     R_SUCCEED(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | Result SET_SYS::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) { | ||||||
|  |     out_name = m_system_settings.device_time_zone_location_name; | ||||||
|  |     R_SUCCEED(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | Result SET_SYS::SetDeviceTimeZoneLocationName(Service::Time::TimeZone::LocationName& name) { | ||||||
|  |     m_system_settings.device_time_zone_location_name = name; | ||||||
|  |     SetSaveNeeded(); | ||||||
|  |     R_SUCCEED(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | Result SET_SYS::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) { | ||||||
|  |     m_system_settings.network_system_clock_context = context; | ||||||
|  |     SetSaveNeeded(); | ||||||
|  |     R_SUCCEED(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | Result SET_SYS::IsUserSystemClockAutomaticCorrectionEnabled(bool& out_enabled) { | ||||||
|  |     out_enabled = m_system_settings.user_system_clock_automatic_correction_enabled; | ||||||
|  |     R_SUCCEED(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | Result SET_SYS::SetUserSystemClockAutomaticCorrectionEnabled(bool enabled) { | ||||||
|  |     m_system_settings.user_system_clock_automatic_correction_enabled = enabled; | ||||||
|  |     SetSaveNeeded(); | ||||||
|  |     R_SUCCEED(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | Result SET_SYS::SetExternalSteadyClockInternalOffset(s64 offset) { | ||||||
|  |     m_private_settings.external_steady_clock_internal_offset = offset; | ||||||
|  |     SetSaveNeeded(); | ||||||
|  |     R_SUCCEED(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | Result SET_SYS::GetExternalSteadyClockInternalOffset(s64& out_offset) { | ||||||
|  |     out_offset = m_private_settings.external_steady_clock_internal_offset; | ||||||
|  |     R_SUCCEED(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | Result SET_SYS::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( | ||||||
|  |     Service::Time::Clock::SteadyClockTimePoint& time_point) { | ||||||
|  |     m_system_settings.device_time_zone_location_updated_time = time_point; | ||||||
|  |     SetSaveNeeded(); | ||||||
|  |     R_SUCCEED(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | Result SET_SYS::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( | ||||||
|  |     Service::Time::Clock::SteadyClockTimePoint out_time_point) { | ||||||
|  |     m_system_settings.user_system_clock_automatic_correction_updated_time_point = out_time_point; | ||||||
|  |     SetSaveNeeded(); | ||||||
|  |     R_SUCCEED(); | ||||||
|  | } | ||||||
|  |  | ||||||
| } // namespace Service::Set | } // namespace Service::Set | ||||||
|   | |||||||
| @@ -3,17 +3,27 @@ | |||||||
|  |  | ||||||
| #pragma once | #pragma once | ||||||
|  |  | ||||||
|  | #include <filesystem> | ||||||
|  | #include <mutex> | ||||||
|  | #include <string> | ||||||
|  | #include <thread> | ||||||
|  |  | ||||||
|  | #include "common/polyfill_thread.h" | ||||||
| #include "common/uuid.h" | #include "common/uuid.h" | ||||||
| #include "core/hle/result.h" | #include "core/hle/result.h" | ||||||
| #include "core/hle/service/service.h" | #include "core/hle/service/service.h" | ||||||
|  | #include "core/hle/service/set/appln_settings.h" | ||||||
|  | #include "core/hle/service/set/device_settings.h" | ||||||
|  | #include "core/hle/service/set/private_settings.h" | ||||||
|  | #include "core/hle/service/set/system_settings.h" | ||||||
| #include "core/hle/service/time/clock_types.h" | #include "core/hle/service/time/clock_types.h" | ||||||
|  | #include "core/hle/service/time/time_zone_types.h" | ||||||
|  |  | ||||||
| namespace Core { | namespace Core { | ||||||
| class System; | class System; | ||||||
| } | } | ||||||
|  |  | ||||||
| namespace Service::Set { | namespace Service::Set { | ||||||
| enum class LanguageCode : u64; |  | ||||||
| enum class GetFirmwareVersionType { | enum class GetFirmwareVersionType { | ||||||
|     Version1, |     Version1, | ||||||
|     Version2, |     Version2, | ||||||
| @@ -42,270 +52,38 @@ public: | |||||||
|     explicit SET_SYS(Core::System& system_); |     explicit SET_SYS(Core::System& system_); | ||||||
|     ~SET_SYS() override; |     ~SET_SYS() override; | ||||||
|  |  | ||||||
|  |     Result GetSettingsItemValue(std::vector<u8>& out_value, const std::string& category, | ||||||
|  |                                 const std::string& name); | ||||||
|  |  | ||||||
|  |     Result GetExternalSteadyClockSourceId(Common::UUID& out_id); | ||||||
|  |     Result SetExternalSteadyClockSourceId(Common::UUID id); | ||||||
|  |     Result GetUserSystemClockContext(Service::Time::Clock::SystemClockContext& out_context); | ||||||
|  |     Result SetUserSystemClockContext(Service::Time::Clock::SystemClockContext& context); | ||||||
|  |     Result GetDeviceTimeZoneLocationName(Service::Time::TimeZone::LocationName& out_name); | ||||||
|  |     Result SetDeviceTimeZoneLocationName(Service::Time::TimeZone::LocationName& name); | ||||||
|  |     Result GetNetworkSystemClockContext(Service::Time::Clock::SystemClockContext& out_context); | ||||||
|  |     Result SetNetworkSystemClockContext(Service::Time::Clock::SystemClockContext& context); | ||||||
|  |     Result IsUserSystemClockAutomaticCorrectionEnabled(bool& out_enabled); | ||||||
|  |     Result SetUserSystemClockAutomaticCorrectionEnabled(bool enabled); | ||||||
|  |     Result SetExternalSteadyClockInternalOffset(s64 offset); | ||||||
|  |     Result GetExternalSteadyClockInternalOffset(s64& out_offset); | ||||||
|  |     Result GetDeviceTimeZoneLocationUpdatedTime( | ||||||
|  |         Service::Time::Clock::SteadyClockTimePoint& out_time_point); | ||||||
|  |     Result SetDeviceTimeZoneLocationUpdatedTime( | ||||||
|  |         Service::Time::Clock::SteadyClockTimePoint& time_point); | ||||||
|  |     Result GetUserSystemClockAutomaticCorrectionUpdatedTime( | ||||||
|  |         Service::Time::Clock::SteadyClockTimePoint& out_time_point); | ||||||
|  |     Result SetUserSystemClockAutomaticCorrectionUpdatedTime( | ||||||
|  |         Service::Time::Clock::SteadyClockTimePoint time_point); | ||||||
|  |  | ||||||
| private: | private: | ||||||
|     /// Indicates the current theme set by the system settings |  | ||||||
|     enum class ColorSet : u32 { |  | ||||||
|         BasicWhite = 0, |  | ||||||
|         BasicBlack = 1, |  | ||||||
|     }; |  | ||||||
|  |  | ||||||
|     /// 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"); |  | ||||||
|  |  | ||||||
|     /// This is nn::settings::system::HomeMenuScheme |  | ||||||
|     struct HomeMenuScheme { |  | ||||||
|         u32 main; |  | ||||||
|         u32 back; |  | ||||||
|         u32 sub; |  | ||||||
|         u32 bezel; |  | ||||||
|         u32 extra; |  | ||||||
|     }; |  | ||||||
|     static_assert(sizeof(HomeMenuScheme) == 0x14, "HomeMenuScheme is incorrect size"); |  | ||||||
|  |  | ||||||
|     void SetLanguageCode(HLERequestContext& ctx); |     void SetLanguageCode(HLERequestContext& ctx); | ||||||
|     void GetFirmwareVersion(HLERequestContext& ctx); |     void GetFirmwareVersion(HLERequestContext& ctx); | ||||||
|     void GetFirmwareVersion2(HLERequestContext& ctx); |     void GetFirmwareVersion2(HLERequestContext& ctx); | ||||||
|  |     void GetExternalSteadyClockSourceId(HLERequestContext& ctx); | ||||||
|  |     void SetExternalSteadyClockSourceId(HLERequestContext& ctx); | ||||||
|  |     void GetUserSystemClockContext(HLERequestContext& ctx); | ||||||
|  |     void SetUserSystemClockContext(HLERequestContext& ctx); | ||||||
|     void GetAccountSettings(HLERequestContext& ctx); |     void GetAccountSettings(HLERequestContext& ctx); | ||||||
|     void SetAccountSettings(HLERequestContext& ctx); |     void SetAccountSettings(HLERequestContext& ctx); | ||||||
|     void GetEulaVersions(HLERequestContext& ctx); |     void GetEulaVersions(HLERequestContext& ctx); | ||||||
| @@ -321,7 +99,13 @@ private: | |||||||
|     void GetTvSettings(HLERequestContext& ctx); |     void GetTvSettings(HLERequestContext& ctx); | ||||||
|     void SetTvSettings(HLERequestContext& ctx); |     void SetTvSettings(HLERequestContext& ctx); | ||||||
|     void GetQuestFlag(HLERequestContext& ctx); |     void GetQuestFlag(HLERequestContext& ctx); | ||||||
|  |     void GetDeviceTimeZoneLocationName(HLERequestContext& ctx); | ||||||
|  |     void SetDeviceTimeZoneLocationName(HLERequestContext& ctx); | ||||||
|     void SetRegionCode(HLERequestContext& ctx); |     void SetRegionCode(HLERequestContext& ctx); | ||||||
|  |     void GetNetworkSystemClockContext(HLERequestContext& ctx); | ||||||
|  |     void SetNetworkSystemClockContext(HLERequestContext& ctx); | ||||||
|  |     void IsUserSystemClockAutomaticCorrectionEnabled(HLERequestContext& ctx); | ||||||
|  |     void SetUserSystemClockAutomaticCorrectionEnabled(HLERequestContext& ctx); | ||||||
|     void GetPrimaryAlbumStorage(HLERequestContext& ctx); |     void GetPrimaryAlbumStorage(HLERequestContext& ctx); | ||||||
|     void GetSleepSettings(HLERequestContext& ctx); |     void GetSleepSettings(HLERequestContext& ctx); | ||||||
|     void SetSleepSettings(HLERequestContext& ctx); |     void SetSleepSettings(HLERequestContext& ctx); | ||||||
| @@ -333,59 +117,36 @@ private: | |||||||
|     void GetMiiAuthorId(HLERequestContext& ctx); |     void GetMiiAuthorId(HLERequestContext& ctx); | ||||||
|     void GetAutoUpdateEnableFlag(HLERequestContext& ctx); |     void GetAutoUpdateEnableFlag(HLERequestContext& ctx); | ||||||
|     void GetBatteryPercentageFlag(HLERequestContext& ctx); |     void GetBatteryPercentageFlag(HLERequestContext& ctx); | ||||||
|  |     void SetExternalSteadyClockInternalOffset(HLERequestContext& ctx); | ||||||
|  |     void GetExternalSteadyClockInternalOffset(HLERequestContext& ctx); | ||||||
|     void GetErrorReportSharePermission(HLERequestContext& ctx); |     void GetErrorReportSharePermission(HLERequestContext& ctx); | ||||||
|     void GetAppletLaunchFlags(HLERequestContext& ctx); |     void GetAppletLaunchFlags(HLERequestContext& ctx); | ||||||
|     void SetAppletLaunchFlags(HLERequestContext& ctx); |     void SetAppletLaunchFlags(HLERequestContext& ctx); | ||||||
|     void GetKeyboardLayout(HLERequestContext& ctx); |     void GetKeyboardLayout(HLERequestContext& ctx); | ||||||
|  |     void GetDeviceTimeZoneLocationUpdatedTime(HLERequestContext& ctx); | ||||||
|  |     void SetDeviceTimeZoneLocationUpdatedTime(HLERequestContext& ctx); | ||||||
|  |     void GetUserSystemClockAutomaticCorrectionUpdatedTime(HLERequestContext& ctx); | ||||||
|  |     void SetUserSystemClockAutomaticCorrectionUpdatedTime(HLERequestContext& ctx); | ||||||
|     void GetChineseTraditionalInputMethod(HLERequestContext& ctx); |     void GetChineseTraditionalInputMethod(HLERequestContext& ctx); | ||||||
|     void GetFieldTestingFlag(HLERequestContext& ctx); |  | ||||||
|     void GetHomeMenuScheme(HLERequestContext& ctx); |     void GetHomeMenuScheme(HLERequestContext& ctx); | ||||||
|     void GetHomeMenuSchemeModel(HLERequestContext& ctx); |     void GetHomeMenuSchemeModel(HLERequestContext& ctx); | ||||||
|  |     void GetFieldTestingFlag(HLERequestContext& ctx); | ||||||
|  |  | ||||||
|     AccountSettings account_settings{ |     bool LoadSettingsFile(std::filesystem::path& path, auto&& default_func); | ||||||
|         .flags = {}, |     bool StoreSettingsFile(std::filesystem::path& path, auto& settings); | ||||||
|     }; |     void SetupSettings(); | ||||||
|  |     void StoreSettings(); | ||||||
|  |     void StoreSettingsThreadFunc(std::stop_token stop_token); | ||||||
|  |     void SetSaveNeeded(); | ||||||
|  |  | ||||||
|     ColorSet color_set = ColorSet::BasicWhite; |     Core::System& m_system; | ||||||
|  |     SystemSettings m_system_settings{}; | ||||||
|     NotificationSettings notification_settings{ |     PrivateSettings m_private_settings{}; | ||||||
|         .flags = {0x300}, |     DeviceSettings m_device_settings{}; | ||||||
|         .volume = NotificationVolume::High, |     ApplnSettings m_appln_settings{}; | ||||||
|         .start_time = {.hour = 9, .minute = 0}, |     std::jthread m_save_thread; | ||||||
|         .stop_time = {.hour = 21, .minute = 0}, |     std::mutex m_save_needed_mutex; | ||||||
|     }; |     bool m_save_needed{false}; | ||||||
|  |  | ||||||
|     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 | } // namespace Service::Set | ||||||
|   | |||||||
							
								
								
									
										51
									
								
								src/core/hle/service/set/system_settings.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								src/core/hle/service/set/system_settings.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,51 @@ | |||||||
|  | // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project | ||||||
|  | // SPDX-License-Identifier: GPL-2.0-or-later | ||||||
|  |  | ||||||
|  | #include "core/hle/service/set/system_settings.h" | ||||||
|  |  | ||||||
|  | namespace Service::Set { | ||||||
|  |  | ||||||
|  | SystemSettings DefaultSystemSettings() { | ||||||
|  |     SystemSettings settings{}; | ||||||
|  |  | ||||||
|  |     settings.version = 0x140000; | ||||||
|  |     settings.flags = 7; | ||||||
|  |  | ||||||
|  |     settings.color_set_id = ColorSet::BasicWhite; | ||||||
|  |  | ||||||
|  |     settings.notification_settings = { | ||||||
|  |         .flags{0x300}, | ||||||
|  |         .volume = NotificationVolume::High, | ||||||
|  |         .start_time = {.hour = 9, .minute = 0}, | ||||||
|  |         .stop_time = {.hour = 21, .minute = 0}, | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     settings.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, | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     settings.initial_launch_settings_packed = { | ||||||
|  |         .flags = {0x10001}, | ||||||
|  |         .timestamp = {}, | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     settings.sleep_settings = { | ||||||
|  |         .flags = {0x3}, | ||||||
|  |         .handheld_sleep_plan = HandheldSleepPlan::Sleep10Min, | ||||||
|  |         .console_sleep_plan = ConsoleSleepPlan::Sleep1Hour, | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     settings.device_time_zone_location_name = {"UTC"}; | ||||||
|  |     settings.user_system_clock_automatic_correction_enabled = false; | ||||||
|  |  | ||||||
|  |     return settings; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | } // namespace Service::Set | ||||||
							
								
								
									
										699
									
								
								src/core/hle/service/set/system_settings.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										699
									
								
								src/core/hle/service/set/system_settings.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,699 @@ | |||||||
|  | // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project | ||||||
|  | // SPDX-License-Identifier: GPL-2.0-or-later | ||||||
|  |  | ||||||
|  | #pragma once | ||||||
|  |  | ||||||
|  | #include <array> | ||||||
|  |  | ||||||
|  | #include "common/bit_field.h" | ||||||
|  | #include "common/common_funcs.h" | ||||||
|  | #include "common/common_types.h" | ||||||
|  | #include "core/hle/service/set/private_settings.h" | ||||||
|  | #include "core/hle/service/time/clock_types.h" | ||||||
|  |  | ||||||
|  | namespace Service::Set { | ||||||
|  |  | ||||||
|  | /// This is "nn::settings::LanguageCode", which is a NUL-terminated string stored in a u64. | ||||||
|  | enum class LanguageCode : u64 { | ||||||
|  |     JA = 0x000000000000616A, | ||||||
|  |     EN_US = 0x00000053552D6E65, | ||||||
|  |     FR = 0x0000000000007266, | ||||||
|  |     DE = 0x0000000000006564, | ||||||
|  |     IT = 0x0000000000007469, | ||||||
|  |     ES = 0x0000000000007365, | ||||||
|  |     ZH_CN = 0x0000004E432D687A, | ||||||
|  |     KO = 0x0000000000006F6B, | ||||||
|  |     NL = 0x0000000000006C6E, | ||||||
|  |     PT = 0x0000000000007470, | ||||||
|  |     RU = 0x0000000000007572, | ||||||
|  |     ZH_TW = 0x00000057542D687A, | ||||||
|  |     EN_GB = 0x00000042472D6E65, | ||||||
|  |     FR_CA = 0x00000041432D7266, | ||||||
|  |     ES_419 = 0x00003931342D7365, | ||||||
|  |     ZH_HANS = 0x00736E61482D687A, | ||||||
|  |     ZH_HANT = 0x00746E61482D687A, | ||||||
|  |     PT_BR = 0x00000052422D7470, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | /// This is nn::settings::system::ErrorReportSharePermission | ||||||
|  | enum class ErrorReportSharePermission : u32 { | ||||||
|  |     NotConfirmed, | ||||||
|  |     Granted, | ||||||
|  |     Denied, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | /// This is nn::settings::system::ChineseTraditionalInputMethod | ||||||
|  | enum class ChineseTraditionalInputMethod : u32 { | ||||||
|  |     Unknown0 = 0, | ||||||
|  |     Unknown1 = 1, | ||||||
|  |     Unknown2 = 2, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | /// This is nn::settings::system::HomeMenuScheme | ||||||
|  | struct HomeMenuScheme { | ||||||
|  |     u32 main; | ||||||
|  |     u32 back; | ||||||
|  |     u32 sub; | ||||||
|  |     u32 bezel; | ||||||
|  |     u32 extra; | ||||||
|  | }; | ||||||
|  | static_assert(sizeof(HomeMenuScheme) == 0x14, "HomeMenuScheme is incorrect size"); | ||||||
|  |  | ||||||
|  | /// Indicates the current theme set by the system settings | ||||||
|  | enum class ColorSet : u32 { | ||||||
|  |     BasicWhite = 0, | ||||||
|  |     BasicBlack = 1, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | /// Indicates the current console is a retail or kiosk unit | ||||||
|  | enum class QuestFlag : u8 { | ||||||
|  |     Retail = 0, | ||||||
|  |     Kiosk = 1, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | /// This is nn::settings::system::RegionCode | ||||||
|  | enum class RegionCode : u32 { | ||||||
|  |     Japan, | ||||||
|  |     Usa, | ||||||
|  |     Europe, | ||||||
|  |     Australia, | ||||||
|  |     HongKongTaiwanKorea, | ||||||
|  |     China, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | /// This is nn::settings::system::AccountSettings | ||||||
|  | struct AccountSettings { | ||||||
|  |     u32 flags; | ||||||
|  | }; | ||||||
|  | static_assert(sizeof(AccountSettings) == 4, "AccountSettings is an invalid size"); | ||||||
|  |  | ||||||
|  | /// This is nn::settings::system::NotificationVolume | ||||||
|  | enum class NotificationVolume : u32 { | ||||||
|  |     Mute, | ||||||
|  |     Low, | ||||||
|  |     High, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | /// 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::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::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::FriendPresenceOverlayPermission | ||||||
|  | enum class FriendPresenceOverlayPermission : u8 { | ||||||
|  |     NotConfirmed, | ||||||
|  |     NoDisplay, | ||||||
|  |     FavoriteFriends, | ||||||
|  |     Friends, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | /// 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::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::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::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::PrimaryAlbumStorage | ||||||
|  | enum class PrimaryAlbumStorage : u32 { | ||||||
|  |     Nand, | ||||||
|  |     SdCard, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | /// 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::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::SleepSettings | ||||||
|  | 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::EulaVersionClockType | ||||||
|  | enum class EulaVersionClockType : u32 { | ||||||
|  |     NetworkSystemClock, | ||||||
|  |     SteadyClock, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | /// This is nn::settings::system::EulaVersion | ||||||
|  | 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"); | ||||||
|  |  | ||||||
|  | struct SystemSettings { | ||||||
|  |     // 0/unwritten (1.0.0), 0x20000 (2.0.0), 0x30000 (3.0.0-3.0.1), 0x40001 (4.0.0-4.1.0), 0x50000 | ||||||
|  |     // (5.0.0-5.1.0), 0x60000 (6.0.0-6.2.0), 0x70000 (7.0.0), 0x80000 (8.0.0-8.1.1), 0x90000 | ||||||
|  |     // (9.0.0-10.0.4), 0x100100 (10.1.0+), 0x120000 (12.0.0-12.1.0), 0x130000 (13.0.0-13.2.1), | ||||||
|  |     // 0x140000 (14.0.0+) | ||||||
|  |     u32 version; | ||||||
|  |     // 0/unwritten (1.0.0), 1 (6.0.0-8.1.0), 2 (8.1.1), 7 (9.0.0+). | ||||||
|  |     // if (flags & 2), defaults are written for AnalogStickUserCalibration | ||||||
|  |     u32 flags; | ||||||
|  |  | ||||||
|  |     std::array<u8, 0x8> reserved_00008; | ||||||
|  |  | ||||||
|  |     // nn::settings::LanguageCode | ||||||
|  |     LanguageCode language_code; | ||||||
|  |  | ||||||
|  |     std::array<u8, 0x38> reserved_00018; | ||||||
|  |  | ||||||
|  |     // nn::settings::system::NetworkSettings | ||||||
|  |     u32 network_setting_count; | ||||||
|  |     bool wireless_lan_enable_flag; | ||||||
|  |     std::array<u8, 0x3> pad_00055; | ||||||
|  |  | ||||||
|  |     std::array<u8, 0x8> reserved_00058; | ||||||
|  |  | ||||||
|  |     // nn::settings::system::NetworkSettings | ||||||
|  |     std::array<std::array<u8, 0x400>, 32> network_settings_1B0; | ||||||
|  |  | ||||||
|  |     // nn::settings::system::BluetoothDevicesSettings | ||||||
|  |     std::array<u8, 0x4> bluetooth_device_settings_count; | ||||||
|  |     bool bluetooth_enable_flag; | ||||||
|  |     std::array<u8, 0x3> pad_08065; | ||||||
|  |     bool bluetooth_afh_enable_flag; | ||||||
|  |     std::array<u8, 0x3> pad_08069; | ||||||
|  |     bool bluetooth_boost_enable_flag; | ||||||
|  |     std::array<u8, 0x3> pad_0806D; | ||||||
|  |     std::array<std::array<u8, 0x200>, 10> bluetooth_device_settings_first_10; | ||||||
|  |  | ||||||
|  |     s32 ldn_channel; | ||||||
|  |  | ||||||
|  |     std::array<u8, 0x3C> reserved_09474; | ||||||
|  |  | ||||||
|  |     // nn::util::Uuid MiiAuthorId | ||||||
|  |     std::array<u8, 0x10> mii_author_id; | ||||||
|  |  | ||||||
|  |     std::array<u8, 0x30> reserved_094C0; | ||||||
|  |  | ||||||
|  |     // nn::settings::system::NxControllerSettings | ||||||
|  |     u32 nx_controller_settings_count; | ||||||
|  |  | ||||||
|  |     std::array<u8, 0xC> reserved_094F4; | ||||||
|  |  | ||||||
|  |     // nn::settings::system::NxControllerSettings, | ||||||
|  |     // nn::settings::system::NxControllerLegacySettings on 13.0.0+ | ||||||
|  |     std::array<std::array<u8, 0x40>, 10> nx_controller_legacy_settings; | ||||||
|  |  | ||||||
|  |     std::array<u8, 0x170> reserved_09780; | ||||||
|  |  | ||||||
|  |     bool external_rtc_reset_flag; | ||||||
|  |     std::array<u8, 0x3> pad_098F1; | ||||||
|  |  | ||||||
|  |     std::array<u8, 0x3C> reserved_098F4; | ||||||
|  |  | ||||||
|  |     s32 push_notification_activity_mode_on_sleep; | ||||||
|  |  | ||||||
|  |     std::array<u8, 0x3C> reserved_09934; | ||||||
|  |  | ||||||
|  |     // nn::settings::system::ErrorReportSharePermission | ||||||
|  |     ErrorReportSharePermission error_report_share_permssion; | ||||||
|  |  | ||||||
|  |     std::array<u8, 0x3C> reserved_09974; | ||||||
|  |  | ||||||
|  |     // nn::settings::KeyboardLayout | ||||||
|  |     std::array<u8, 0x4> keyboard_layout; | ||||||
|  |  | ||||||
|  |     std::array<u8, 0x3C> reserved_099B4; | ||||||
|  |  | ||||||
|  |     bool web_inspector_flag; | ||||||
|  |     std::array<u8, 0x3> pad_099F1; | ||||||
|  |  | ||||||
|  |     // nn::settings::system::AllowedSslHost | ||||||
|  |     u32 allowed_ssl_host_count; | ||||||
|  |  | ||||||
|  |     bool memory_usage_rate_flag; | ||||||
|  |     std::array<u8, 0x3> pad_099F9; | ||||||
|  |  | ||||||
|  |     std::array<u8, 0x34> reserved_099FC; | ||||||
|  |  | ||||||
|  |     // nn::settings::system::HostFsMountPoint | ||||||
|  |     std::array<u8, 0x100> host_fs_mount_point; | ||||||
|  |  | ||||||
|  |     // nn::settings::system::AllowedSslHost | ||||||
|  |     std::array<std::array<u8, 0x100>, 8> allowed_ssl_hosts; | ||||||
|  |  | ||||||
|  |     std::array<u8, 0x6C0> reserved_0A330; | ||||||
|  |  | ||||||
|  |     // nn::settings::system::BlePairingSettings | ||||||
|  |     u32 ble_pairing_settings_count; | ||||||
|  |     std::array<u8, 0xC> reserved_0A9F4; | ||||||
|  |     std::array<std::array<u8, 0x80>, 10> ble_pairing_settings; | ||||||
|  |  | ||||||
|  |     // nn::settings::system::AccountOnlineStorageSettings | ||||||
|  |     u32 account_online_storage_settings_count; | ||||||
|  |     std::array<u8, 0xC> reserved_0AF04; | ||||||
|  |     std::array<std::array<u8, 0x40>, 8> account_online_storage_settings; | ||||||
|  |  | ||||||
|  |     bool pctl_ready_flag; | ||||||
|  |     std::array<u8, 0x3> pad_0B111; | ||||||
|  |  | ||||||
|  |     std::array<u8, 0x3C> reserved_0B114; | ||||||
|  |  | ||||||
|  |     // nn::settings::system::ThemeId | ||||||
|  |     std::array<u8, 0x80> theme_id_type0; | ||||||
|  |     std::array<u8, 0x80> theme_id_type1; | ||||||
|  |  | ||||||
|  |     std::array<u8, 0x100> reserved_0B250; | ||||||
|  |  | ||||||
|  |     // nn::settings::ChineseTraditionalInputMethod | ||||||
|  |     ChineseTraditionalInputMethod chinese_traditional_input_method; | ||||||
|  |  | ||||||
|  |     std::array<u8, 0x3C> reserved_0B354; | ||||||
|  |  | ||||||
|  |     bool zoom_flag; | ||||||
|  |     std::array<u8, 0x3> pad_0B391; | ||||||
|  |  | ||||||
|  |     std::array<u8, 0x3C> reserved_0B394; | ||||||
|  |  | ||||||
|  |     // nn::settings::system::ButtonConfigRegisteredSettings | ||||||
|  |     u32 button_config_registered_settings_count; | ||||||
|  |     std::array<u8, 0xC> reserved_0B3D4; | ||||||
|  |  | ||||||
|  |     // nn::settings::system::ButtonConfigSettings | ||||||
|  |     u32 button_config_settings_count; | ||||||
|  |     std::array<u8, 0x4> reserved_0B3E4; | ||||||
|  |     std::array<std::array<u8, 0x5A8>, 5> button_config_settings; | ||||||
|  |     std::array<u8, 0x13B0> reserved_0D030; | ||||||
|  |     u32 button_config_settings_embedded_count; | ||||||
|  |     std::array<u8, 0x4> reserved_0E3E4; | ||||||
|  |     std::array<std::array<u8, 0x5A8>, 5> button_config_settings_embedded; | ||||||
|  |     std::array<u8, 0x13B0> reserved_10030; | ||||||
|  |     u32 button_config_settings_left_count; | ||||||
|  |     std::array<u8, 0x4> reserved_113E4; | ||||||
|  |     std::array<std::array<u8, 0x5A8>, 5> button_config_settings_left; | ||||||
|  |     std::array<u8, 0x13B0> reserved_13030; | ||||||
|  |     u32 button_config_settings_right_count; | ||||||
|  |     std::array<u8, 0x4> reserved_143E4; | ||||||
|  |     std::array<std::array<u8, 0x5A8>, 5> button_config_settings_right; | ||||||
|  |     std::array<u8, 0x73B0> reserved_16030; | ||||||
|  |     // nn::settings::system::ButtonConfigRegisteredSettings | ||||||
|  |     std::array<u8, 0x5C8> button_config_registered_settings_embedded; | ||||||
|  |     std::array<std::array<u8, 0x5C8>, 10> button_config_registered_settings; | ||||||
|  |  | ||||||
|  |     std::array<u8, 0x7FF8> reserved_21378; | ||||||
|  |  | ||||||
|  |     // nn::settings::system::ConsoleSixAxisSensorAccelerationBias | ||||||
|  |     std::array<u8, 0xC> console_six_axis_sensor_acceleration_bias; | ||||||
|  |     // nn::settings::system::ConsoleSixAxisSensorAngularVelocityBias | ||||||
|  |     std::array<u8, 0xC> console_six_axis_sensor_angular_velocity_bias; | ||||||
|  |     // nn::settings::system::ConsoleSixAxisSensorAccelerationGain | ||||||
|  |     std::array<u8, 0x24> console_six_axis_sensor_acceleration_gain; | ||||||
|  |     // nn::settings::system::ConsoleSixAxisSensorAngularVelocityGain | ||||||
|  |     std::array<u8, 0x24> console_six_axis_sensor_angular_velocity_gain; | ||||||
|  |     // nn::settings::system::ConsoleSixAxisSensorAngularVelocityTimeBias | ||||||
|  |     std::array<u8, 0xC> console_six_axis_sensor_angular_velocity_time_bias; | ||||||
|  |     // nn::settings::system::ConsoleSixAxisSensorAngularAcceleration | ||||||
|  |     std::array<u8, 0x24> console_six_axis_sensor_angular_velocity_acceleration; | ||||||
|  |  | ||||||
|  |     std::array<u8, 0x70> reserved_29400; | ||||||
|  |  | ||||||
|  |     bool lock_screen_flag; | ||||||
|  |     std::array<u8, 0x3> pad_29471; | ||||||
|  |  | ||||||
|  |     std::array<u8, 0x4> reserved_249274; | ||||||
|  |  | ||||||
|  |     ColorSet color_set_id; | ||||||
|  |  | ||||||
|  |     QuestFlag quest_flag; | ||||||
|  |  | ||||||
|  |     // nn::settings::system::RegionCode | ||||||
|  |     RegionCode region_code; | ||||||
|  |  | ||||||
|  |     // Different to nn::settings::system::InitialLaunchSettings? | ||||||
|  |     InitialLaunchSettingsPacked initial_launch_settings_packed; | ||||||
|  |  | ||||||
|  |     bool battery_percentage_flag; | ||||||
|  |     std::array<u8, 0x3> pad_294A1; | ||||||
|  |  | ||||||
|  |     // BitFlagSet<32, nn::settings::system::AppletLaunchFlag> | ||||||
|  |     u32 applet_launch_flag; | ||||||
|  |  | ||||||
|  |     // nn::settings::system::ThemeSettings | ||||||
|  |     std::array<u8, 0x8> theme_settings; | ||||||
|  |     // nn::fssystem::ArchiveMacKey | ||||||
|  |     std::array<u8, 0x10> theme_key; | ||||||
|  |  | ||||||
|  |     bool field_testing_flag; | ||||||
|  |     std::array<u8, 0x3> pad_294C1; | ||||||
|  |  | ||||||
|  |     s32 panel_crc_mode; | ||||||
|  |  | ||||||
|  |     std::array<u8, 0x28> reserved_294C8; | ||||||
|  |  | ||||||
|  |     // nn::settings::system::BacklightSettings | ||||||
|  |     std::array<u8, 0x2C> backlight_settings_mixed_up; | ||||||
|  |  | ||||||
|  |     std::array<u8, 0x64> reserved_2951C; | ||||||
|  |  | ||||||
|  |     // nn::time::SystemClockContext | ||||||
|  |     Service::Time::Clock::SystemClockContext user_system_clock_context; | ||||||
|  |     Service::Time::Clock::SystemClockContext network_system_clock_context; | ||||||
|  |     bool user_system_clock_automatic_correction_enabled; | ||||||
|  |     std::array<u8, 0x3> pad_295C1; | ||||||
|  |     std::array<u8, 0x4> reserved_295C4; | ||||||
|  |     // nn::time::SteadyClockTimePoint | ||||||
|  |     Service::Time::Clock::SteadyClockTimePoint | ||||||
|  |         user_system_clock_automatic_correction_updated_time_point; | ||||||
|  |  | ||||||
|  |     std::array<u8, 0x10> reserved_295E0; | ||||||
|  |  | ||||||
|  |     // nn::settings::system::AccountSettings | ||||||
|  |     AccountSettings account_settings; | ||||||
|  |  | ||||||
|  |     std::array<u8, 0xFC> reserved_295F4; | ||||||
|  |  | ||||||
|  |     // nn::settings::system::AudioVolume | ||||||
|  |     std::array<u8, 0x8> audio_volume_type0; | ||||||
|  |     std::array<u8, 0x8> audio_volume_type1; | ||||||
|  |     // nn::settings::system::AudioOutputMode | ||||||
|  |     s32 audio_output_mode_type0; | ||||||
|  |     s32 audio_output_mode_type1; | ||||||
|  |     s32 audio_output_mode_type2; | ||||||
|  |     bool force_mute_on_headphone_removed; | ||||||
|  |     std::array<u8, 0x3> pad_2970D; | ||||||
|  |     s32 headphone_volume_warning_count; | ||||||
|  |     bool heaphone_volume_update_flag; | ||||||
|  |     std::array<u8, 0x3> pad_29715; | ||||||
|  |     // nn::settings::system::AudioVolume | ||||||
|  |     std::array<u8, 0x8> audio_volume_type2; | ||||||
|  |     // nn::settings::system::AudioOutputMode | ||||||
|  |     s32 audio_output_mode_type3; | ||||||
|  |     s32 audio_output_mode_type4; | ||||||
|  |     bool hearing_protection_safeguard_flag; | ||||||
|  |     std::array<u8, 0x3> pad_29729; | ||||||
|  |     std::array<u8, 0x4> reserved_2972C; | ||||||
|  |     s64 hearing_protection_safeguard_remaining_time; | ||||||
|  |     std::array<u8, 0x38> reserved_29738; | ||||||
|  |  | ||||||
|  |     bool console_information_upload_flag; | ||||||
|  |     std::array<u8, 0x3> pad_29771; | ||||||
|  |  | ||||||
|  |     std::array<u8, 0x3C> reserved_29774; | ||||||
|  |  | ||||||
|  |     bool automatic_application_download_flag; | ||||||
|  |     std::array<u8, 0x3> pad_297B1; | ||||||
|  |  | ||||||
|  |     std::array<u8, 0x4> reserved_297B4; | ||||||
|  |  | ||||||
|  |     // nn::settings::system::NotificationSettings | ||||||
|  |     NotificationSettings notification_settings; | ||||||
|  |  | ||||||
|  |     std::array<u8, 0x60> reserved_297D0; | ||||||
|  |  | ||||||
|  |     // nn::settings::system::AccountNotificationSettings | ||||||
|  |     u32 account_notification_settings_count; | ||||||
|  |     std::array<u8, 0xC> reserved_29834; | ||||||
|  |     std::array<AccountNotificationSettings, 8> account_notification_settings; | ||||||
|  |  | ||||||
|  |     std::array<u8, 0x140> reserved_29900; | ||||||
|  |  | ||||||
|  |     f32 vibration_master_volume; | ||||||
|  |  | ||||||
|  |     bool usb_full_key_enable_flag; | ||||||
|  |     std::array<u8, 0x3> pad_29A45; | ||||||
|  |  | ||||||
|  |     // nn::settings::system::AnalogStickUserCalibration | ||||||
|  |     std::array<u8, 0x10> analog_stick_user_calibration_left; | ||||||
|  |     std::array<u8, 0x10> analog_stick_user_calibration_right; | ||||||
|  |  | ||||||
|  |     // nn::settings::system::TouchScreenMode | ||||||
|  |     s32 touch_screen_mode; | ||||||
|  |  | ||||||
|  |     std::array<u8, 0x14> reserved_29A6C; | ||||||
|  |  | ||||||
|  |     // nn::settings::system::TvSettings | ||||||
|  |     TvSettings tv_settings; | ||||||
|  |  | ||||||
|  |     // nn::settings::system::Edid | ||||||
|  |     std::array<u8, 0x100> edid; | ||||||
|  |  | ||||||
|  |     std::array<u8, 0x2E0> reserved_29BA0; | ||||||
|  |  | ||||||
|  |     // nn::settings::system::DataDeletionSettings | ||||||
|  |     std::array<u8, 0x8> data_deletion_settings; | ||||||
|  |  | ||||||
|  |     std::array<u8, 0x38> reserved_29E88; | ||||||
|  |  | ||||||
|  |     // nn::ncm::ProgramId | ||||||
|  |     std::array<u8, 0x8> initial_system_applet_program_id; | ||||||
|  |     std::array<u8, 0x8> overlay_disp_program_id; | ||||||
|  |  | ||||||
|  |     std::array<u8, 0x4> reserved_29ED0; | ||||||
|  |  | ||||||
|  |     bool requires_run_repair_time_reviser; | ||||||
|  |  | ||||||
|  |     std::array<u8, 0x6B> reserved_29ED5; | ||||||
|  |  | ||||||
|  |     // nn::time::LocationName | ||||||
|  |     Service::Time::TimeZone::LocationName device_time_zone_location_name; | ||||||
|  |     std::array<u8, 0x4> reserved_29F64; | ||||||
|  |     // nn::time::SteadyClockTimePoint | ||||||
|  |     Service::Time::Clock::SteadyClockTimePoint device_time_zone_location_updated_time; | ||||||
|  |  | ||||||
|  |     std::array<u8, 0xC0> reserved_29F80; | ||||||
|  |  | ||||||
|  |     // nn::settings::system::PrimaryAlbumStorage | ||||||
|  |     PrimaryAlbumStorage primary_album_storage; | ||||||
|  |  | ||||||
|  |     std::array<u8, 0x3C> reserved_2A044; | ||||||
|  |  | ||||||
|  |     bool usb_30_enable_flag; | ||||||
|  |     std::array<u8, 0x3> pad_2A081; | ||||||
|  |     bool usb_30_host_enable_flag; | ||||||
|  |     std::array<u8, 0x3> pad_2A085; | ||||||
|  |     bool usb_30_device_enable_flag; | ||||||
|  |     std::array<u8, 0x3> pad_2A089; | ||||||
|  |  | ||||||
|  |     std::array<u8, 0x34> reserved_2A08C; | ||||||
|  |  | ||||||
|  |     bool nfc_enable_flag; | ||||||
|  |     std::array<u8, 0x3> pad_2A0C1; | ||||||
|  |  | ||||||
|  |     std::array<u8, 0x3C> reserved_2A0C4; | ||||||
|  |  | ||||||
|  |     // nn::settings::system::SleepSettings | ||||||
|  |     SleepSettings sleep_settings; | ||||||
|  |  | ||||||
|  |     std::array<u8, 0x34> reserved_2A10C; | ||||||
|  |  | ||||||
|  |     // nn::settings::system::EulaVersion | ||||||
|  |     u32 eula_version_count; | ||||||
|  |     std::array<u8, 0xC> reserved_2A144; | ||||||
|  |     std::array<EulaVersion, 32> eula_versions; | ||||||
|  |  | ||||||
|  |     std::array<u8, 0x200> reserved_2A750; | ||||||
|  |  | ||||||
|  |     // nn::settings::system::DeviceNickName | ||||||
|  |     std::array<u8, 0x80> device_nick_name; | ||||||
|  |  | ||||||
|  |     std::array<u8, 0x80> reserved_2A9D0; | ||||||
|  |  | ||||||
|  |     bool auto_update_enable_flag; | ||||||
|  |     std::array<u8, 0x3> pad_2AA51; | ||||||
|  |  | ||||||
|  |     std::array<u8, 0x4C> reserved_2AA54; | ||||||
|  |  | ||||||
|  |     // nn::settings::system::BluetoothDevicesSettings | ||||||
|  |     std::array<std::array<u8, 0x200>, 14> bluetooth_device_settings_last_14; | ||||||
|  |  | ||||||
|  |     std::array<u8, 0x2000> reserved_2C6A0; | ||||||
|  |  | ||||||
|  |     // nn::settings::system::NxControllerSettings | ||||||
|  |     std::array<std::array<u8, 0x800>, 10> nx_controller_settings_data_from_offset_30; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | static_assert(offsetof(SystemSettings, language_code) == 0x10); | ||||||
|  | static_assert(offsetof(SystemSettings, network_setting_count) == 0x50); | ||||||
|  | static_assert(offsetof(SystemSettings, network_settings_1B0) == 0x60); | ||||||
|  | static_assert(offsetof(SystemSettings, bluetooth_device_settings_count) == 0x8060); | ||||||
|  | static_assert(offsetof(SystemSettings, bluetooth_enable_flag) == 0x8064); | ||||||
|  | static_assert(offsetof(SystemSettings, bluetooth_device_settings_first_10) == 0x8070); | ||||||
|  | static_assert(offsetof(SystemSettings, ldn_channel) == 0x9470); | ||||||
|  | static_assert(offsetof(SystemSettings, mii_author_id) == 0x94B0); | ||||||
|  | static_assert(offsetof(SystemSettings, nx_controller_settings_count) == 0x94F0); | ||||||
|  | static_assert(offsetof(SystemSettings, nx_controller_legacy_settings) == 0x9500); | ||||||
|  | static_assert(offsetof(SystemSettings, external_rtc_reset_flag) == 0x98F0); | ||||||
|  | static_assert(offsetof(SystemSettings, push_notification_activity_mode_on_sleep) == 0x9930); | ||||||
|  | static_assert(offsetof(SystemSettings, allowed_ssl_host_count) == 0x99F4); | ||||||
|  | static_assert(offsetof(SystemSettings, host_fs_mount_point) == 0x9A30); | ||||||
|  | static_assert(offsetof(SystemSettings, allowed_ssl_hosts) == 0x9B30); | ||||||
|  | static_assert(offsetof(SystemSettings, ble_pairing_settings_count) == 0xA9F0); | ||||||
|  | static_assert(offsetof(SystemSettings, ble_pairing_settings) == 0xAA00); | ||||||
|  | static_assert(offsetof(SystemSettings, account_online_storage_settings_count) == 0xAF00); | ||||||
|  | static_assert(offsetof(SystemSettings, account_online_storage_settings) == 0xAF10); | ||||||
|  | static_assert(offsetof(SystemSettings, pctl_ready_flag) == 0xB110); | ||||||
|  | static_assert(offsetof(SystemSettings, theme_id_type0) == 0xB150); | ||||||
|  | static_assert(offsetof(SystemSettings, chinese_traditional_input_method) == 0xB350); | ||||||
|  | static_assert(offsetof(SystemSettings, button_config_registered_settings_count) == 0xB3D0); | ||||||
|  | static_assert(offsetof(SystemSettings, button_config_settings_count) == 0xB3E0); | ||||||
|  | static_assert(offsetof(SystemSettings, button_config_settings) == 0xB3E8); | ||||||
|  | static_assert(offsetof(SystemSettings, button_config_registered_settings_embedded) == 0x1D3E0); | ||||||
|  | static_assert(offsetof(SystemSettings, console_six_axis_sensor_acceleration_bias) == 0x29370); | ||||||
|  | static_assert(offsetof(SystemSettings, lock_screen_flag) == 0x29470); | ||||||
|  | static_assert(offsetof(SystemSettings, battery_percentage_flag) == 0x294A0); | ||||||
|  | static_assert(offsetof(SystemSettings, field_testing_flag) == 0x294C0); | ||||||
|  | static_assert(offsetof(SystemSettings, backlight_settings_mixed_up) == 0x294F0); | ||||||
|  | static_assert(offsetof(SystemSettings, user_system_clock_context) == 0x29580); | ||||||
|  | static_assert(offsetof(SystemSettings, network_system_clock_context) == 0x295A0); | ||||||
|  | static_assert(offsetof(SystemSettings, user_system_clock_automatic_correction_enabled) == 0x295C0); | ||||||
|  | static_assert(offsetof(SystemSettings, user_system_clock_automatic_correction_updated_time_point) == | ||||||
|  |               0x295C8); | ||||||
|  | static_assert(offsetof(SystemSettings, account_settings) == 0x295F0); | ||||||
|  | static_assert(offsetof(SystemSettings, audio_volume_type0) == 0x296F0); | ||||||
|  | static_assert(offsetof(SystemSettings, hearing_protection_safeguard_remaining_time) == 0x29730); | ||||||
|  | static_assert(offsetof(SystemSettings, automatic_application_download_flag) == 0x297B0); | ||||||
|  | static_assert(offsetof(SystemSettings, notification_settings) == 0x297B8); | ||||||
|  | static_assert(offsetof(SystemSettings, account_notification_settings) == 0x29840); | ||||||
|  | static_assert(offsetof(SystemSettings, vibration_master_volume) == 0x29A40); | ||||||
|  | static_assert(offsetof(SystemSettings, analog_stick_user_calibration_left) == 0x29A48); | ||||||
|  | static_assert(offsetof(SystemSettings, touch_screen_mode) == 0x29A68); | ||||||
|  | static_assert(offsetof(SystemSettings, edid) == 0x29AA0); | ||||||
|  | static_assert(offsetof(SystemSettings, data_deletion_settings) == 0x29E80); | ||||||
|  | static_assert(offsetof(SystemSettings, requires_run_repair_time_reviser) == 0x29ED4); | ||||||
|  | static_assert(offsetof(SystemSettings, device_time_zone_location_name) == 0x29F40); | ||||||
|  | static_assert(offsetof(SystemSettings, nfc_enable_flag) == 0x2A0C0); | ||||||
|  | static_assert(offsetof(SystemSettings, eula_version_count) == 0x2A140); | ||||||
|  | static_assert(offsetof(SystemSettings, device_nick_name) == 0x2A950); | ||||||
|  | static_assert(offsetof(SystemSettings, bluetooth_device_settings_last_14) == 0x2AAA0); | ||||||
|  | static_assert(offsetof(SystemSettings, nx_controller_settings_data_from_offset_30) == 0x2E6A0); | ||||||
|  |  | ||||||
|  | static_assert(sizeof(SystemSettings) == 0x336A0, "SystemSettings has the wrong size!"); | ||||||
|  |  | ||||||
|  | SystemSettings DefaultSystemSettings(); | ||||||
|  |  | ||||||
|  | } // namespace Service::Set | ||||||
		Reference in New Issue
	
	Block a user