diff options
Diffstat (limited to '')
34 files changed, 3302 insertions, 2703 deletions
diff --git a/src/core/hle/service/set/appln_settings.cpp b/src/core/hle/service/set/appln_settings.cpp deleted file mode 100644 index a5d802757..000000000 --- a/src/core/hle/service/set/appln_settings.cpp +++ /dev/null @@ -1,12 +0,0 @@ -// 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 diff --git a/src/core/hle/service/set/appln_settings.h b/src/core/hle/service/set/appln_settings.h deleted file mode 100644 index 126375860..000000000 --- a/src/core/hle/service/set/appln_settings.h +++ /dev/null @@ -1,36 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include <array> -#include <cstddef> - -#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 diff --git a/src/core/hle/service/set/device_settings.cpp b/src/core/hle/service/set/device_settings.cpp deleted file mode 100644 index e423ce38a..000000000 --- a/src/core/hle/service/set/device_settings.cpp +++ /dev/null @@ -1,12 +0,0 @@ -// 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 diff --git a/src/core/hle/service/set/device_settings.h b/src/core/hle/service/set/device_settings.h deleted file mode 100644 index f291d0ebe..000000000 --- a/src/core/hle/service/set/device_settings.h +++ /dev/null @@ -1,54 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include <array> -#include <cstddef> - -#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 diff --git a/src/core/hle/service/set/factory_settings_server.cpp b/src/core/hle/service/set/factory_settings_server.cpp new file mode 100644 index 000000000..a8e307ae2 --- /dev/null +++ b/src/core/hle/service/set/factory_settings_server.cpp @@ -0,0 +1,63 @@ +// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "core/hle/service/set/factory_settings_server.h" + +namespace Service::Set { + +IFactorySettingsServer::IFactorySettingsServer(Core::System& system_) + : ServiceFramework{system_, "set:cal"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "GetBluetoothBdAddress"}, + {1, nullptr, "GetConfigurationId1"}, + {2, nullptr, "GetAccelerometerOffset"}, + {3, nullptr, "GetAccelerometerScale"}, + {4, nullptr, "GetGyroscopeOffset"}, + {5, nullptr, "GetGyroscopeScale"}, + {6, nullptr, "GetWirelessLanMacAddress"}, + {7, nullptr, "GetWirelessLanCountryCodeCount"}, + {8, nullptr, "GetWirelessLanCountryCodes"}, + {9, nullptr, "GetSerialNumber"}, + {10, nullptr, "SetInitialSystemAppletProgramId"}, + {11, nullptr, "SetOverlayDispProgramId"}, + {12, nullptr, "GetBatteryLot"}, + {14, nullptr, "GetEciDeviceCertificate"}, + {15, nullptr, "GetEticketDeviceCertificate"}, + {16, nullptr, "GetSslKey"}, + {17, nullptr, "GetSslCertificate"}, + {18, nullptr, "GetGameCardKey"}, + {19, nullptr, "GetGameCardCertificate"}, + {20, nullptr, "GetEciDeviceKey"}, + {21, nullptr, "GetEticketDeviceKey"}, + {22, nullptr, "GetSpeakerParameter"}, + {23, nullptr, "GetLcdVendorId"}, + {24, nullptr, "GetEciDeviceCertificate2"}, + {25, nullptr, "GetEciDeviceKey2"}, + {26, nullptr, "GetAmiiboKey"}, + {27, nullptr, "GetAmiiboEcqvCertificate"}, + {28, nullptr, "GetAmiiboEcdsaCertificate"}, + {29, nullptr, "GetAmiiboEcqvBlsKey"}, + {30, nullptr, "GetAmiiboEcqvBlsCertificate"}, + {31, nullptr, "GetAmiiboEcqvBlsRootCertificate"}, + {32, nullptr, "GetUsbTypeCPowerSourceCircuitVersion"}, + {33, nullptr, "GetAnalogStickModuleTypeL"}, + {34, nullptr, "GetAnalogStickModelParameterL"}, + {35, nullptr, "GetAnalogStickFactoryCalibrationL"}, + {36, nullptr, "GetAnalogStickModuleTypeR"}, + {37, nullptr, "GetAnalogStickModelParameterR"}, + {38, nullptr, "GetAnalogStickFactoryCalibrationR"}, + {39, nullptr, "GetConsoleSixAxisSensorModuleType"}, + {40, nullptr, "GetConsoleSixAxisSensorHorizontalOffset"}, + {41, nullptr, "GetBatteryVersion"}, + {42, nullptr, "GetDeviceId"}, + {43, nullptr, "GetConsoleSixAxisSensorMountType"}, + }; + // clang-format on + + RegisterHandlers(functions); +} + +IFactorySettingsServer::~IFactorySettingsServer() = default; + +} // namespace Service::Set diff --git a/src/core/hle/service/set/factory_settings_server.h b/src/core/hle/service/set/factory_settings_server.h new file mode 100644 index 000000000..e64cd1380 --- /dev/null +++ b/src/core/hle/service/set/factory_settings_server.h @@ -0,0 +1,20 @@ +// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "core/hle/service/service.h" + +namespace Core { +class System; +} + +namespace Service::Set { + +class IFactorySettingsServer final : public ServiceFramework<IFactorySettingsServer> { +public: + explicit IFactorySettingsServer(Core::System& system_); + ~IFactorySettingsServer() override; +}; + +} // namespace Service::Set diff --git a/src/core/hle/service/set/firmware_debug_settings_server.cpp b/src/core/hle/service/set/firmware_debug_settings_server.cpp new file mode 100644 index 000000000..b3a5e623b --- /dev/null +++ b/src/core/hle/service/set/firmware_debug_settings_server.cpp @@ -0,0 +1,29 @@ +// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "core/hle/service/set/firmware_debug_settings_server.h" + +namespace Service::Set { + +IFirmwareDebugSettingsServer::IFirmwareDebugSettingsServer(Core::System& system_) + : ServiceFramework{system_, "set:fd"} { + // clang-format off + static const FunctionInfo functions[] = { + {2, nullptr, "SetSettingsItemValue"}, + {3, nullptr, "ResetSettingsItemValue"}, + {4, nullptr, "CreateSettingsItemKeyIterator"}, + {10, nullptr, "ReadSettings"}, + {11, nullptr, "ResetSettings"}, + {20, nullptr, "SetWebInspectorFlag"}, + {21, nullptr, "SetAllowedSslHosts"}, + {22, nullptr, "SetHostFsMountPoint"}, + {23, nullptr, "SetMemoryUsageRateFlag"}, + }; + // clang-format on + + RegisterHandlers(functions); +} + +IFirmwareDebugSettingsServer::~IFirmwareDebugSettingsServer() = default; + +} // namespace Service::Set diff --git a/src/core/hle/service/set/firmware_debug_settings_server.h b/src/core/hle/service/set/firmware_debug_settings_server.h new file mode 100644 index 000000000..5dae2263e --- /dev/null +++ b/src/core/hle/service/set/firmware_debug_settings_server.h @@ -0,0 +1,20 @@ +// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "core/hle/service/service.h" + +namespace Core { +class System; +} + +namespace Service::Set { + +class IFirmwareDebugSettingsServer final : public ServiceFramework<IFirmwareDebugSettingsServer> { +public: + explicit IFirmwareDebugSettingsServer(Core::System& system_); + ~IFirmwareDebugSettingsServer() override; +}; + +} // namespace Service::Set diff --git a/src/core/hle/service/set/private_settings.cpp b/src/core/hle/service/set/private_settings.cpp deleted file mode 100644 index 70bf65727..000000000 --- a/src/core/hle/service/set/private_settings.cpp +++ /dev/null @@ -1,12 +0,0 @@ -// 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 diff --git a/src/core/hle/service/set/private_settings.h b/src/core/hle/service/set/private_settings.h index b63eaf45c..b02291ce7 100644 --- a/src/core/hle/service/set/private_settings.h +++ b/src/core/hle/service/set/private_settings.h @@ -9,7 +9,7 @@ #include "common/common_funcs.h" #include "common/common_types.h" #include "common/uuid.h" -#include "core/hle/service/time/clock_types.h" +#include "core/hle/service/psc/time/common.h" namespace Service::Set { @@ -29,14 +29,14 @@ static_assert(sizeof(InitialLaunchFlag) == 4, "InitialLaunchFlag is an invalid s struct InitialLaunchSettings { InitialLaunchFlag flags; INSERT_PADDING_BYTES(0x4); - Service::Time::Clock::SteadyClockTimePoint timestamp; + Service::PSC::Time::SteadyClockTimePoint timestamp; }; static_assert(sizeof(InitialLaunchSettings) == 0x20, "InitialLaunchSettings is incorrect size"); #pragma pack(push, 4) struct InitialLaunchSettingsPacked { InitialLaunchFlag flags; - Service::Time::Clock::SteadyClockTimePoint timestamp; + Service::PSC::Time::SteadyClockTimePoint timestamp; }; #pragma pack(pop) static_assert(sizeof(InitialLaunchSettingsPacked) == 0x1C, diff --git a/src/core/hle/service/set/set.cpp b/src/core/hle/service/set/set.cpp deleted file mode 100644 index 2082b8ef7..000000000 --- a/src/core/hle/service/set/set.cpp +++ /dev/null @@ -1,166 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#include <algorithm> -#include <array> -#include <chrono> -#include "common/logging/log.h" -#include "common/settings.h" -#include "core/hle/service/ipc_helpers.h" -#include "core/hle/service/set/set.h" - -namespace Service::Set { -namespace { -constexpr std::size_t PRE_4_0_0_MAX_ENTRIES = 0xF; -constexpr std::size_t POST_4_0_0_MAX_ENTRIES = 0x40; - -constexpr Result ResultInvalidLanguage{ErrorModule::Settings, 625}; - -void PushResponseLanguageCode(HLERequestContext& ctx, std::size_t num_language_codes) { - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(ResultSuccess); - rb.Push(static_cast<u32>(num_language_codes)); -} - -void GetAvailableLanguageCodesImpl(HLERequestContext& ctx, std::size_t max_entries) { - const std::size_t requested_amount = ctx.GetWriteBufferNumElements<LanguageCode>(); - const std::size_t max_amount = std::min(requested_amount, max_entries); - const std::size_t copy_amount = std::min(available_language_codes.size(), max_amount); - const std::size_t copy_size = copy_amount * sizeof(LanguageCode); - - ctx.WriteBuffer(available_language_codes.data(), copy_size); - PushResponseLanguageCode(ctx, copy_amount); -} - -void GetKeyCodeMapImpl(HLERequestContext& ctx) { - const auto language_code = - available_language_codes[static_cast<s32>(Settings::values.language_index.GetValue())]; - const auto key_code = - std::find_if(language_to_layout.cbegin(), language_to_layout.cend(), - [=](const auto& element) { return element.first == language_code; }); - KeyboardLayout layout = KeyboardLayout::EnglishUs; - if (key_code == language_to_layout.cend()) { - LOG_ERROR(Service_SET, - "Could not find keyboard layout for language index {}, defaulting to English us", - Settings::values.language_index.GetValue()); - } else { - layout = key_code->second; - } - - ctx.WriteBuffer(layout); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); -} -} // Anonymous namespace - -LanguageCode GetLanguageCodeFromIndex(std::size_t index) { - return available_language_codes.at(index); -} - -void SET::GetAvailableLanguageCodes(HLERequestContext& ctx) { - LOG_DEBUG(Service_SET, "called"); - - GetAvailableLanguageCodesImpl(ctx, PRE_4_0_0_MAX_ENTRIES); -} - -void SET::MakeLanguageCode(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - const auto index = rp.Pop<u32>(); - - if (index >= available_language_codes.size()) { - LOG_ERROR(Service_SET, "Invalid language code index! index={}", index); - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(Set::ResultInvalidLanguage); - return; - } - - IPC::ResponseBuilder rb{ctx, 4}; - rb.Push(ResultSuccess); - rb.PushEnum(available_language_codes[index]); -} - -void SET::GetAvailableLanguageCodes2(HLERequestContext& ctx) { - LOG_DEBUG(Service_SET, "called"); - - GetAvailableLanguageCodesImpl(ctx, POST_4_0_0_MAX_ENTRIES); -} - -void SET::GetAvailableLanguageCodeCount(HLERequestContext& ctx) { - LOG_DEBUG(Service_SET, "called"); - - PushResponseLanguageCode(ctx, PRE_4_0_0_MAX_ENTRIES); -} - -void SET::GetAvailableLanguageCodeCount2(HLERequestContext& ctx) { - LOG_DEBUG(Service_SET, "called"); - - PushResponseLanguageCode(ctx, POST_4_0_0_MAX_ENTRIES); -} - -void SET::GetQuestFlag(HLERequestContext& ctx) { - LOG_DEBUG(Service_SET, "called"); - - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(ResultSuccess); - rb.Push(static_cast<s32>(Settings::values.quest_flag.GetValue())); -} - -void SET::GetLanguageCode(HLERequestContext& ctx) { - LOG_DEBUG(Service_SET, "called {}", Settings::values.language_index.GetValue()); - - IPC::ResponseBuilder rb{ctx, 4}; - rb.Push(ResultSuccess); - rb.PushEnum( - available_language_codes[static_cast<s32>(Settings::values.language_index.GetValue())]); -} - -void SET::GetRegionCode(HLERequestContext& ctx) { - LOG_DEBUG(Service_SET, "called"); - - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(ResultSuccess); - rb.Push(static_cast<u32>(Settings::values.region_index.GetValue())); -} - -void SET::GetKeyCodeMap(HLERequestContext& ctx) { - LOG_DEBUG(Service_SET, "Called {}", ctx.Description()); - GetKeyCodeMapImpl(ctx); -} - -void SET::GetKeyCodeMap2(HLERequestContext& ctx) { - LOG_DEBUG(Service_SET, "Called {}", ctx.Description()); - GetKeyCodeMapImpl(ctx); -} - -void SET::GetDeviceNickName(HLERequestContext& ctx) { - LOG_DEBUG(Service_SET, "called"); - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); - ctx.WriteBuffer(Settings::values.device_name.GetValue()); -} - -SET::SET(Core::System& system_) : ServiceFramework{system_, "set"} { - // clang-format off - static const FunctionInfo functions[] = { - {0, &SET::GetLanguageCode, "GetLanguageCode"}, - {1, &SET::GetAvailableLanguageCodes, "GetAvailableLanguageCodes"}, - {2, &SET::MakeLanguageCode, "MakeLanguageCode"}, - {3, &SET::GetAvailableLanguageCodeCount, "GetAvailableLanguageCodeCount"}, - {4, &SET::GetRegionCode, "GetRegionCode"}, - {5, &SET::GetAvailableLanguageCodes2, "GetAvailableLanguageCodes2"}, - {6, &SET::GetAvailableLanguageCodeCount2, "GetAvailableLanguageCodeCount2"}, - {7, &SET::GetKeyCodeMap, "GetKeyCodeMap"}, - {8, &SET::GetQuestFlag, "GetQuestFlag"}, - {9, &SET::GetKeyCodeMap2, "GetKeyCodeMap2"}, - {10, nullptr, "GetFirmwareVersionForDebug"}, - {11, &SET::GetDeviceNickName, "GetDeviceNickName"}, - }; - // clang-format on - - RegisterHandlers(functions); -} - -SET::~SET() = default; - -} // namespace Service::Set diff --git a/src/core/hle/service/set/set.h b/src/core/hle/service/set/set.h deleted file mode 100644 index 6ef3da410..000000000 --- a/src/core/hle/service/set/set.h +++ /dev/null @@ -1,95 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include "core/hle/service/service.h" -#include "core/hle/service/set/system_settings.h" - -namespace Core { -class System; -} - -namespace Service::Set { -enum class KeyboardLayout : u64 { - Japanese = 0, - EnglishUs = 1, - EnglishUsInternational = 2, - EnglishUk = 3, - French = 4, - FrenchCa = 5, - Spanish = 6, - SpanishLatin = 7, - German = 8, - Italian = 9, - Portuguese = 10, - Russian = 11, - Korean = 12, - ChineseSimplified = 13, - ChineseTraditional = 14, -}; - -constexpr std::array<LanguageCode, 18> available_language_codes = {{ - LanguageCode::JA, - LanguageCode::EN_US, - LanguageCode::FR, - LanguageCode::DE, - LanguageCode::IT, - LanguageCode::ES, - LanguageCode::ZH_CN, - LanguageCode::KO, - LanguageCode::NL, - LanguageCode::PT, - LanguageCode::RU, - LanguageCode::ZH_TW, - LanguageCode::EN_GB, - LanguageCode::FR_CA, - LanguageCode::ES_419, - LanguageCode::ZH_HANS, - LanguageCode::ZH_HANT, - LanguageCode::PT_BR, -}}; - -static constexpr std::array<std::pair<LanguageCode, KeyboardLayout>, 18> language_to_layout{{ - {LanguageCode::JA, KeyboardLayout::Japanese}, - {LanguageCode::EN_US, KeyboardLayout::EnglishUs}, - {LanguageCode::FR, KeyboardLayout::French}, - {LanguageCode::DE, KeyboardLayout::German}, - {LanguageCode::IT, KeyboardLayout::Italian}, - {LanguageCode::ES, KeyboardLayout::Spanish}, - {LanguageCode::ZH_CN, KeyboardLayout::ChineseSimplified}, - {LanguageCode::KO, KeyboardLayout::Korean}, - {LanguageCode::NL, KeyboardLayout::EnglishUsInternational}, - {LanguageCode::PT, KeyboardLayout::Portuguese}, - {LanguageCode::RU, KeyboardLayout::Russian}, - {LanguageCode::ZH_TW, KeyboardLayout::ChineseTraditional}, - {LanguageCode::EN_GB, KeyboardLayout::EnglishUk}, - {LanguageCode::FR_CA, KeyboardLayout::FrenchCa}, - {LanguageCode::ES_419, KeyboardLayout::SpanishLatin}, - {LanguageCode::ZH_HANS, KeyboardLayout::ChineseSimplified}, - {LanguageCode::ZH_HANT, KeyboardLayout::ChineseTraditional}, - {LanguageCode::PT_BR, KeyboardLayout::Portuguese}, -}}; - -LanguageCode GetLanguageCodeFromIndex(std::size_t idx); - -class SET final : public ServiceFramework<SET> { -public: - explicit SET(Core::System& system_); - ~SET() override; - -private: - void GetLanguageCode(HLERequestContext& ctx); - void GetAvailableLanguageCodes(HLERequestContext& ctx); - void MakeLanguageCode(HLERequestContext& ctx); - void GetAvailableLanguageCodes2(HLERequestContext& ctx); - void GetAvailableLanguageCodeCount(HLERequestContext& ctx); - void GetAvailableLanguageCodeCount2(HLERequestContext& ctx); - void GetQuestFlag(HLERequestContext& ctx); - void GetRegionCode(HLERequestContext& ctx); - void GetKeyCodeMap(HLERequestContext& ctx); - void GetKeyCodeMap2(HLERequestContext& ctx); - void GetDeviceNickName(HLERequestContext& ctx); -}; - -} // namespace Service::Set diff --git a/src/core/hle/service/set/set_cal.cpp b/src/core/hle/service/set/set_cal.cpp deleted file mode 100644 index d2c0d536f..000000000 --- a/src/core/hle/service/set/set_cal.cpp +++ /dev/null @@ -1,62 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#include "core/hle/service/set/set_cal.h" - -namespace Service::Set { - -SET_CAL::SET_CAL(Core::System& system_) : ServiceFramework{system_, "set:cal"} { - // clang-format off - static const FunctionInfo functions[] = { - {0, nullptr, "GetBluetoothBdAddress"}, - {1, nullptr, "GetConfigurationId1"}, - {2, nullptr, "GetAccelerometerOffset"}, - {3, nullptr, "GetAccelerometerScale"}, - {4, nullptr, "GetGyroscopeOffset"}, - {5, nullptr, "GetGyroscopeScale"}, - {6, nullptr, "GetWirelessLanMacAddress"}, - {7, nullptr, "GetWirelessLanCountryCodeCount"}, - {8, nullptr, "GetWirelessLanCountryCodes"}, - {9, nullptr, "GetSerialNumber"}, - {10, nullptr, "SetInitialSystemAppletProgramId"}, - {11, nullptr, "SetOverlayDispProgramId"}, - {12, nullptr, "GetBatteryLot"}, - {14, nullptr, "GetEciDeviceCertificate"}, - {15, nullptr, "GetEticketDeviceCertificate"}, - {16, nullptr, "GetSslKey"}, - {17, nullptr, "GetSslCertificate"}, - {18, nullptr, "GetGameCardKey"}, - {19, nullptr, "GetGameCardCertificate"}, - {20, nullptr, "GetEciDeviceKey"}, - {21, nullptr, "GetEticketDeviceKey"}, - {22, nullptr, "GetSpeakerParameter"}, - {23, nullptr, "GetLcdVendorId"}, - {24, nullptr, "GetEciDeviceCertificate2"}, - {25, nullptr, "GetEciDeviceKey2"}, - {26, nullptr, "GetAmiiboKey"}, - {27, nullptr, "GetAmiiboEcqvCertificate"}, - {28, nullptr, "GetAmiiboEcdsaCertificate"}, - {29, nullptr, "GetAmiiboEcqvBlsKey"}, - {30, nullptr, "GetAmiiboEcqvBlsCertificate"}, - {31, nullptr, "GetAmiiboEcqvBlsRootCertificate"}, - {32, nullptr, "GetUsbTypeCPowerSourceCircuitVersion"}, - {33, nullptr, "GetAnalogStickModuleTypeL"}, - {34, nullptr, "GetAnalogStickModelParameterL"}, - {35, nullptr, "GetAnalogStickFactoryCalibrationL"}, - {36, nullptr, "GetAnalogStickModuleTypeR"}, - {37, nullptr, "GetAnalogStickModelParameterR"}, - {38, nullptr, "GetAnalogStickFactoryCalibrationR"}, - {39, nullptr, "GetConsoleSixAxisSensorModuleType"}, - {40, nullptr, "GetConsoleSixAxisSensorHorizontalOffset"}, - {41, nullptr, "GetBatteryVersion"}, - {42, nullptr, "GetDeviceId"}, - {43, nullptr, "GetConsoleSixAxisSensorMountType"}, - }; - // clang-format on - - RegisterHandlers(functions); -} - -SET_CAL::~SET_CAL() = default; - -} // namespace Service::Set diff --git a/src/core/hle/service/set/set_cal.h b/src/core/hle/service/set/set_cal.h deleted file mode 100644 index 8f50278ed..000000000 --- a/src/core/hle/service/set/set_cal.h +++ /dev/null @@ -1,20 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include "core/hle/service/service.h" - -namespace Core { -class System; -} - -namespace Service::Set { - -class SET_CAL final : public ServiceFramework<SET_CAL> { -public: - explicit SET_CAL(Core::System& system_); - ~SET_CAL() override; -}; - -} // namespace Service::Set diff --git a/src/core/hle/service/set/set_fd.cpp b/src/core/hle/service/set/set_fd.cpp deleted file mode 100644 index 278ef32e1..000000000 --- a/src/core/hle/service/set/set_fd.cpp +++ /dev/null @@ -1,28 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#include "core/hle/service/set/set_fd.h" - -namespace Service::Set { - -SET_FD::SET_FD(Core::System& system_) : ServiceFramework{system_, "set:fd"} { - // clang-format off - static const FunctionInfo functions[] = { - {2, nullptr, "SetSettingsItemValue"}, - {3, nullptr, "ResetSettingsItemValue"}, - {4, nullptr, "CreateSettingsItemKeyIterator"}, - {10, nullptr, "ReadSettings"}, - {11, nullptr, "ResetSettings"}, - {20, nullptr, "SetWebInspectorFlag"}, - {21, nullptr, "SetAllowedSslHosts"}, - {22, nullptr, "SetHostFsMountPoint"}, - {23, nullptr, "SetMemoryUsageRateFlag"}, - }; - // clang-format on - - RegisterHandlers(functions); -} - -SET_FD::~SET_FD() = default; - -} // namespace Service::Set diff --git a/src/core/hle/service/set/set_fd.h b/src/core/hle/service/set/set_fd.h deleted file mode 100644 index 150a7cbce..000000000 --- a/src/core/hle/service/set/set_fd.h +++ /dev/null @@ -1,20 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include "core/hle/service/service.h" - -namespace Core { -class System; -} - -namespace Service::Set { - -class SET_FD final : public ServiceFramework<SET_FD> { -public: - explicit SET_FD(Core::System& system_); - ~SET_FD() override; -}; - -} // namespace Service::Set diff --git a/src/core/hle/service/set/set_sys.cpp b/src/core/hle/service/set/set_sys.cpp deleted file mode 100644 index 8e637f963..000000000 --- a/src/core/hle/service/set/set_sys.cpp +++ /dev/null @@ -1,1272 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#include <fstream> - -#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/settings.h" -#include "common/string_util.h" -#include "core/core.h" -#include "core/file_sys/content_archive.h" -#include "core/file_sys/errors.h" -#include "core/file_sys/nca_metadata.h" -#include "core/file_sys/registered_cache.h" -#include "core/file_sys/romfs.h" -#include "core/file_sys/system_archive/system_archive.h" -#include "core/hle/service/filesystem/filesystem.h" -#include "core/hle/service/ipc_helpers.h" -#include "core/hle/service/set/set.h" -#include "core/hle/service/set/set_sys.h" - -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, - GetFirmwareVersionType type) { - constexpr u64 FirmwareVersionSystemDataId = 0x0100000000000809; - auto& fsc = system.GetFileSystemController(); - - // Attempt to load version data from disk - const FileSys::RegisteredCache* bis_system{}; - std::unique_ptr<FileSys::NCA> nca{}; - FileSys::VirtualDir romfs{}; - - bis_system = fsc.GetSystemNANDContents(); - if (bis_system) { - nca = bis_system->GetEntry(FirmwareVersionSystemDataId, FileSys::ContentRecordType::Data); - } - if (nca) { - if (auto nca_romfs = nca->GetRomFS(); nca_romfs) { - romfs = FileSys::ExtractRomFS(nca_romfs); - } - } - if (!romfs) { - romfs = FileSys::ExtractRomFS( - FileSys::SystemArchive::SynthesizeSystemArchive(FirmwareVersionSystemDataId)); - } - - const auto early_exit_failure = [](std::string_view desc, Result code) { - LOG_ERROR(Service_SET, "General failure while attempting to resolve firmware version ({}).", - desc); - return code; - }; - - const auto ver_file = romfs->GetFile("file"); - if (ver_file == nullptr) { - return early_exit_failure("The system version archive didn't contain the file 'file'.", - FileSys::ERROR_INVALID_ARGUMENT); - } - - auto data = ver_file->ReadAllBytes(); - if (data.size() != sizeof(FirmwareVersionFormat)) { - return early_exit_failure("The system version file 'file' was not the correct size.", - FileSys::ERROR_OUT_OF_BOUNDS); - } - - std::memcpy(&out_firmware, data.data(), sizeof(FirmwareVersionFormat)); - - // If the command is GetFirmwareVersion (as opposed to GetFirmwareVersion2), hardware will - // zero out the REVISION_MINOR field. - if (type == GetFirmwareVersionType::Version1) { - out_firmware.revision_minor = 0; - } - - 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) { - IPC::RequestParser rp{ctx}; - m_system_settings.language_code = rp.PopEnum<LanguageCode>(); - SetSaveNeeded(); - - LOG_INFO(Service_SET, "called, language_code={}", m_system_settings.language_code); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); -} - -void SET_SYS::GetFirmwareVersion(HLERequestContext& ctx) { - LOG_DEBUG(Service_SET, "called"); - - FirmwareVersionFormat firmware_data{}; - const auto result = - GetFirmwareVersionImpl(firmware_data, system, GetFirmwareVersionType::Version1); - - if (result.IsSuccess()) { - ctx.WriteBuffer(firmware_data); - } - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(result); -} - -void SET_SYS::GetFirmwareVersion2(HLERequestContext& ctx) { - LOG_DEBUG(Service_SET, "called"); - - FirmwareVersionFormat firmware_data{}; - const auto result = - GetFirmwareVersionImpl(firmware_data, system, GetFirmwareVersionType::Version2); - - if (result.IsSuccess()) { - ctx.WriteBuffer(firmware_data); - } - - IPC::ResponseBuilder rb{ctx, 2}; - 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) { - LOG_INFO(Service_SET, "called"); - - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(ResultSuccess); - rb.PushRaw(m_system_settings.account_settings); -} - -void SET_SYS::SetAccountSettings(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - m_system_settings.account_settings = rp.PopRaw<AccountSettings>(); - SetSaveNeeded(); - - LOG_INFO(Service_SET, "called, account_settings_flags={}", - m_system_settings.account_settings.flags); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); -} - -void SET_SYS::GetEulaVersions(HLERequestContext& ctx) { - LOG_INFO(Service_SET, "called"); - - ctx.WriteBuffer(m_system_settings.eula_versions); - - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(ResultSuccess); - rb.Push(m_system_settings.eula_version_count); -} - -void SET_SYS::SetEulaVersions(HLERequestContext& ctx) { - const auto elements = ctx.GetReadBufferNumElements<EulaVersion>(); - const auto buffer_data = ctx.ReadBuffer(); - - LOG_INFO(Service_SET, "called, elements={}", elements); - ASSERT(elements <= m_system_settings.eula_versions.size()); - - m_system_settings.eula_version_count = static_cast<u32>(elements); - std::memcpy(&m_system_settings.eula_versions, buffer_data.data(), - sizeof(EulaVersion) * elements); - SetSaveNeeded(); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); -} - -void SET_SYS::GetColorSetId(HLERequestContext& ctx) { - LOG_DEBUG(Service_SET, "called"); - - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(ResultSuccess); - rb.PushEnum(m_system_settings.color_set_id); -} - -void SET_SYS::SetColorSetId(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - m_system_settings.color_set_id = rp.PopEnum<ColorSet>(); - SetSaveNeeded(); - - LOG_DEBUG(Service_SET, "called, color_set={}", m_system_settings.color_set_id); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); -} - -void SET_SYS::GetNotificationSettings(HLERequestContext& ctx) { - LOG_INFO(Service_SET, "called"); - - IPC::ResponseBuilder rb{ctx, 8}; - rb.Push(ResultSuccess); - rb.PushRaw(m_system_settings.notification_settings); -} - -void SET_SYS::SetNotificationSettings(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - m_system_settings.notification_settings = rp.PopRaw<NotificationSettings>(); - SetSaveNeeded(); - - LOG_INFO(Service_SET, "called, flags={}, volume={}, head_time={}:{}, tailt_time={}:{}", - m_system_settings.notification_settings.flags.raw, - m_system_settings.notification_settings.volume, - 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}; - rb.Push(ResultSuccess); -} - -void SET_SYS::GetAccountNotificationSettings(HLERequestContext& ctx) { - LOG_INFO(Service_SET, "called"); - - ctx.WriteBuffer(m_system_settings.account_notification_settings); - - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(ResultSuccess); - rb.Push(m_system_settings.account_notification_settings_count); -} - -void SET_SYS::SetAccountNotificationSettings(HLERequestContext& ctx) { - const auto elements = ctx.GetReadBufferNumElements<AccountNotificationSettings>(); - const auto buffer_data = ctx.ReadBuffer(); - - LOG_INFO(Service_SET, "called, elements={}", elements); - - ASSERT(elements <= m_system_settings.account_notification_settings.size()); - - m_system_settings.account_notification_settings_count = static_cast<u32>(elements); - std::memcpy(&m_system_settings.account_notification_settings, buffer_data.data(), - elements * sizeof(AccountNotificationSettings)); - SetSaveNeeded(); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); -} - -// FIXME: implement support for the real system_settings.ini - -template <typename T> -static std::vector<u8> ToBytes(const T& value) { - static_assert(std::is_trivially_copyable_v<T>); - - const auto* begin = reinterpret_cast<const u8*>(&value); - const auto* end = begin + sizeof(T); - - return std::vector<u8>(begin, end); -} - -using Settings = - std::map<std::string, std::map<std::string, std::vector<u8>, std::less<>>, std::less<>>; - -static Settings GetSettings() { - Settings ret; - - ret["hbloader"]["applet_heap_size"] = ToBytes(u64{0x0}); - 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; -} - -void SET_SYS::GetSettingsItemValueSize(HLERequestContext& ctx) { - LOG_DEBUG(Service_SET, "called"); - - // The category of the setting. This corresponds to the top-level keys of - // system_settings.ini. - const auto setting_category_buf{ctx.ReadBuffer(0)}; - const std::string setting_category{setting_category_buf.begin(), setting_category_buf.end()}; - - // The name of the setting. This corresponds to the second-level keys of - // system_settings.ini. - const auto setting_name_buf{ctx.ReadBuffer(1)}; - const std::string setting_name{setting_name_buf.begin(), setting_name_buf.end()}; - - auto settings{GetSettings()}; - u64 response_size{0}; - - if (settings.contains(setting_category) && settings[setting_category].contains(setting_name)) { - response_size = settings[setting_category][setting_name].size(); - } - - IPC::ResponseBuilder rb{ctx, 4}; - rb.Push(response_size == 0 ? ResultUnknown : ResultSuccess); - rb.Push(response_size); -} - -void SET_SYS::GetSettingsItemValue(HLERequestContext& ctx) { - // The category of the setting. This corresponds to the top-level keys of - // system_settings.ini. - const auto setting_category_buf{ctx.ReadBuffer(0)}; - const std::string setting_category{setting_category_buf.begin(), setting_category_buf.end()}; - - // The name of the setting. This corresponds to the second-level keys of - // system_settings.ini. - const auto setting_name_buf{ctx.ReadBuffer(1)}; - const std::string setting_name{setting_name_buf.begin(), setting_name_buf.end()}; - - std::vector<u8> value; - auto response = GetSettingsItemValue(value, setting_category, setting_name); - - LOG_INFO(Service_SET, "called. category={}, name={} -- res=0x{:X}", setting_category, - setting_name, response.raw); - - ctx.WriteBuffer(value.data(), value.size()); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(response); -} - -void SET_SYS::GetTvSettings(HLERequestContext& ctx) { - LOG_INFO(Service_SET, "called"); - - IPC::ResponseBuilder rb{ctx, 10}; - rb.Push(ResultSuccess); - rb.PushRaw(m_system_settings.tv_settings); -} - -void SET_SYS::SetTvSettings(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - m_system_settings.tv_settings = rp.PopRaw<TvSettings>(); - SetSaveNeeded(); - - LOG_INFO(Service_SET, - "called, flags={}, cmu_mode={}, constrast_ratio={}, hdmi_content_type={}, " - "rgb_range={}, tv_gama={}, tv_resolution={}, tv_underscan={}", - m_system_settings.tv_settings.flags.raw, m_system_settings.tv_settings.cmu_mode, - m_system_settings.tv_settings.constrast_ratio, - 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}; - rb.Push(ResultSuccess); -} - -void SET_SYS::GetDebugModeFlag(HLERequestContext& ctx) { - LOG_DEBUG(Service_SET, "called"); - - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(ResultSuccess); - rb.Push<u32>(0); -} - -void SET_SYS::GetQuestFlag(HLERequestContext& ctx) { - LOG_WARNING(Service_SET, "(STUBBED) called"); - - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(ResultSuccess); - rb.PushEnum(QuestFlag::Retail); -} - -void SET_SYS::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) { - IPC::RequestParser rp{ctx}; - m_system_settings.region_code = rp.PopEnum<RegionCode>(); - SetSaveNeeded(); - - LOG_INFO(Service_SET, "called, region_code={}", m_system_settings.region_code); - - IPC::ResponseBuilder rb{ctx, 2}; - 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) { - LOG_WARNING(Service_SET, "(STUBBED) called"); - - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(ResultSuccess); - rb.PushEnum(PrimaryAlbumStorage::SdCard); -} - -void SET_SYS::GetSleepSettings(HLERequestContext& ctx) { - LOG_INFO(Service_SET, "called"); - - IPC::ResponseBuilder rb{ctx, 5}; - rb.Push(ResultSuccess); - rb.PushRaw(m_system_settings.sleep_settings); -} - -void SET_SYS::SetSleepSettings(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - m_system_settings.sleep_settings = rp.PopRaw<SleepSettings>(); - SetSaveNeeded(); - - LOG_INFO(Service_SET, "called, flags={}, handheld_sleep_plan={}, console_sleep_plan={}", - m_system_settings.sleep_settings.flags.raw, - m_system_settings.sleep_settings.handheld_sleep_plan, - m_system_settings.sleep_settings.console_sleep_plan); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); -} - -void SET_SYS::GetInitialLaunchSettings(HLERequestContext& ctx) { - LOG_INFO(Service_SET, "called"); - IPC::ResponseBuilder rb{ctx, 10}; - rb.Push(ResultSuccess); - rb.PushRaw(m_system_settings.initial_launch_settings_packed); -} - -void SET_SYS::SetInitialLaunchSettings(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - auto inital_launch_settings = rp.PopRaw<InitialLaunchSettings>(); - - m_system_settings.initial_launch_settings_packed.flags = inital_launch_settings.flags; - 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}; - rb.Push(ResultSuccess); -} - -void SET_SYS::GetDeviceNickName(HLERequestContext& ctx) { - LOG_DEBUG(Service_SET, "called"); - - ctx.WriteBuffer(::Settings::values.device_name.GetValue()); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); -} - -void SET_SYS::SetDeviceNickName(HLERequestContext& ctx) { - const std::string device_name = Common::StringFromBuffer(ctx.ReadBuffer()); - - LOG_INFO(Service_SET, "called, device_name={}", device_name); - - ::Settings::values.device_name = device_name; - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); -} - -void SET_SYS::GetProductModel(HLERequestContext& ctx) { - const u32 product_model = 1; - - LOG_WARNING(Service_SET, "(STUBBED) called, product_model={}", product_model); - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(ResultSuccess); - rb.Push(product_model); -} - -void SET_SYS::GetMiiAuthorId(HLERequestContext& ctx) { - const auto author_id = Common::UUID::MakeDefault(); - - LOG_WARNING(Service_SET, "(STUBBED) called, author_id={}", author_id.FormattedString()); - - IPC::ResponseBuilder rb{ctx, 6}; - rb.Push(ResultSuccess); - rb.PushRaw(author_id); -} - -void SET_SYS::GetAutoUpdateEnableFlag(HLERequestContext& ctx) { - u8 auto_update_flag{}; - - LOG_WARNING(Service_SET, "(STUBBED) called, auto_update_flag={}", auto_update_flag); - - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(ResultSuccess); - rb.Push(auto_update_flag); -} - -void SET_SYS::GetBatteryPercentageFlag(HLERequestContext& ctx) { - u8 battery_percentage_flag{1}; - - LOG_WARNING(Service_SET, "(STUBBED) called, battery_percentage_flag={}", - battery_percentage_flag); - - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(ResultSuccess); - rb.Push(battery_percentage_flag); -} - -void SET_SYS::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) { - LOG_WARNING(Service_SET, "(STUBBED) called"); - - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(ResultSuccess); - rb.PushEnum(ErrorReportSharePermission::Denied); -} - -void SET_SYS::GetAppletLaunchFlags(HLERequestContext& ctx) { - LOG_INFO(Service_SET, "called, applet_launch_flag={}", m_system_settings.applet_launch_flag); - - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(ResultSuccess); - rb.Push(m_system_settings.applet_launch_flag); -} - -void SET_SYS::SetAppletLaunchFlags(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - m_system_settings.applet_launch_flag = rp.Pop<u32>(); - SetSaveNeeded(); - - LOG_INFO(Service_SET, "called, applet_launch_flag={}", m_system_settings.applet_launch_flag); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); -} - -void SET_SYS::GetKeyboardLayout(HLERequestContext& ctx) { - const auto language_code = - available_language_codes[static_cast<s32>(::Settings::values.language_index.GetValue())]; - const auto key_code = - std::find_if(language_to_layout.cbegin(), language_to_layout.cend(), - [=](const auto& element) { return element.first == language_code; }); - - KeyboardLayout selected_keyboard_layout = KeyboardLayout::EnglishUs; - if (key_code != language_to_layout.end()) { - selected_keyboard_layout = key_code->second; - } - - LOG_INFO(Service_SET, "called, selected_keyboard_layout={}", selected_keyboard_layout); - - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(ResultSuccess); - rb.Push(static_cast<u32>(selected_keyboard_layout)); -} - -void SET_SYS::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) { - LOG_WARNING(Service_SET, "(STUBBED) called"); - - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(ResultSuccess); - rb.PushEnum(ChineseTraditionalInputMethod::Unknown0); -} - -void SET_SYS::GetHomeMenuScheme(HLERequestContext& ctx) { - LOG_DEBUG(Service_SET, "(STUBBED) called"); - - const HomeMenuScheme default_color = { - .main = 0xFF323232, - .back = 0xFF323232, - .sub = 0xFFFFFFFF, - .bezel = 0xFFFFFFFF, - .extra = 0xFF000000, - }; - - IPC::ResponseBuilder rb{ctx, 2 + sizeof(HomeMenuScheme) / sizeof(u32)}; - rb.Push(ResultSuccess); - rb.PushRaw(default_color); -} - -void SET_SYS::GetHomeMenuSchemeModel(HLERequestContext& ctx) { - LOG_WARNING(Service_SET, "(STUBBED) called"); - - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(ResultSuccess); - rb.Push(0); -} - -void SET_SYS::GetFieldTestingFlag(HLERequestContext& ctx) { - LOG_WARNING(Service_SET, "(STUBBED) called"); - - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(ResultSuccess); - rb.Push<u8>(false); -} - -SET_SYS::SET_SYS(Core::System& system_) : ServiceFramework{system_, "set:sys"}, m_system{system} { - // clang-format off - static const FunctionInfo functions[] = { - {0, &SET_SYS::SetLanguageCode, "SetLanguageCode"}, - {1, nullptr, "SetNetworkSettings"}, - {2, nullptr, "GetNetworkSettings"}, - {3, &SET_SYS::GetFirmwareVersion, "GetFirmwareVersion"}, - {4, &SET_SYS::GetFirmwareVersion2, "GetFirmwareVersion2"}, - {5, nullptr, "GetFirmwareVersionDigest"}, - {7, nullptr, "GetLockScreenFlag"}, - {8, nullptr, "SetLockScreenFlag"}, - {9, nullptr, "GetBacklightSettings"}, - {10, nullptr, "SetBacklightSettings"}, - {11, nullptr, "SetBluetoothDevicesSettings"}, - {12, nullptr, "GetBluetoothDevicesSettings"}, - {13, &SET_SYS::GetExternalSteadyClockSourceId, "GetExternalSteadyClockSourceId"}, - {14, &SET_SYS::SetExternalSteadyClockSourceId, "SetExternalSteadyClockSourceId"}, - {15, &SET_SYS::GetUserSystemClockContext, "GetUserSystemClockContext"}, - {16, &SET_SYS::SetUserSystemClockContext, "SetUserSystemClockContext"}, - {17, &SET_SYS::GetAccountSettings, "GetAccountSettings"}, - {18, &SET_SYS::SetAccountSettings, "SetAccountSettings"}, - {19, nullptr, "GetAudioVolume"}, - {20, nullptr, "SetAudioVolume"}, - {21, &SET_SYS::GetEulaVersions, "GetEulaVersions"}, - {22, &SET_SYS::SetEulaVersions, "SetEulaVersions"}, - {23, &SET_SYS::GetColorSetId, "GetColorSetId"}, - {24, &SET_SYS::SetColorSetId, "SetColorSetId"}, - {25, nullptr, "GetConsoleInformationUploadFlag"}, - {26, nullptr, "SetConsoleInformationUploadFlag"}, - {27, nullptr, "GetAutomaticApplicationDownloadFlag"}, - {28, nullptr, "SetAutomaticApplicationDownloadFlag"}, - {29, &SET_SYS::GetNotificationSettings, "GetNotificationSettings"}, - {30, &SET_SYS::SetNotificationSettings, "SetNotificationSettings"}, - {31, &SET_SYS::GetAccountNotificationSettings, "GetAccountNotificationSettings"}, - {32, &SET_SYS::SetAccountNotificationSettings, "SetAccountNotificationSettings"}, - {35, nullptr, "GetVibrationMasterVolume"}, - {36, nullptr, "SetVibrationMasterVolume"}, - {37, &SET_SYS::GetSettingsItemValueSize, "GetSettingsItemValueSize"}, - {38, &SET_SYS::GetSettingsItemValue, "GetSettingsItemValue"}, - {39, &SET_SYS::GetTvSettings, "GetTvSettings"}, - {40, &SET_SYS::SetTvSettings, "SetTvSettings"}, - {41, nullptr, "GetEdid"}, - {42, nullptr, "SetEdid"}, - {43, nullptr, "GetAudioOutputMode"}, - {44, nullptr, "SetAudioOutputMode"}, - {45, nullptr, "IsForceMuteOnHeadphoneRemoved"}, - {46, nullptr, "SetForceMuteOnHeadphoneRemoved"}, - {47, &SET_SYS::GetQuestFlag, "GetQuestFlag"}, - {48, nullptr, "SetQuestFlag"}, - {49, nullptr, "GetDataDeletionSettings"}, - {50, nullptr, "SetDataDeletionSettings"}, - {51, nullptr, "GetInitialSystemAppletProgramId"}, - {52, nullptr, "GetOverlayDispProgramId"}, - {53, &SET_SYS::GetDeviceTimeZoneLocationName, "GetDeviceTimeZoneLocationName"}, - {54, &SET_SYS::SetDeviceTimeZoneLocationName, "SetDeviceTimeZoneLocationName"}, - {55, nullptr, "GetWirelessCertificationFileSize"}, - {56, nullptr, "GetWirelessCertificationFile"}, - {57, &SET_SYS::SetRegionCode, "SetRegionCode"}, - {58, &SET_SYS::GetNetworkSystemClockContext, "GetNetworkSystemClockContext"}, - {59, &SET_SYS::SetNetworkSystemClockContext, "SetNetworkSystemClockContext"}, - {60, &SET_SYS::IsUserSystemClockAutomaticCorrectionEnabled, "IsUserSystemClockAutomaticCorrectionEnabled"}, - {61, &SET_SYS::SetUserSystemClockAutomaticCorrectionEnabled, "SetUserSystemClockAutomaticCorrectionEnabled"}, - {62, &SET_SYS::GetDebugModeFlag, "GetDebugModeFlag"}, - {63, &SET_SYS::GetPrimaryAlbumStorage, "GetPrimaryAlbumStorage"}, - {64, nullptr, "SetPrimaryAlbumStorage"}, - {65, nullptr, "GetUsb30EnableFlag"}, - {66, nullptr, "SetUsb30EnableFlag"}, - {67, nullptr, "GetBatteryLot"}, - {68, nullptr, "GetSerialNumber"}, - {69, nullptr, "GetNfcEnableFlag"}, - {70, nullptr, "SetNfcEnableFlag"}, - {71, &SET_SYS::GetSleepSettings, "GetSleepSettings"}, - {72, &SET_SYS::SetSleepSettings, "SetSleepSettings"}, - {73, nullptr, "GetWirelessLanEnableFlag"}, - {74, nullptr, "SetWirelessLanEnableFlag"}, - {75, &SET_SYS::GetInitialLaunchSettings, "GetInitialLaunchSettings"}, - {76, &SET_SYS::SetInitialLaunchSettings, "SetInitialLaunchSettings"}, - {77, &SET_SYS::GetDeviceNickName, "GetDeviceNickName"}, - {78, &SET_SYS::SetDeviceNickName, "SetDeviceNickName"}, - {79, &SET_SYS::GetProductModel, "GetProductModel"}, - {80, nullptr, "GetLdnChannel"}, - {81, nullptr, "SetLdnChannel"}, - {82, nullptr, "AcquireTelemetryDirtyFlagEventHandle"}, - {83, nullptr, "GetTelemetryDirtyFlags"}, - {84, nullptr, "GetPtmBatteryLot"}, - {85, nullptr, "SetPtmBatteryLot"}, - {86, nullptr, "GetPtmFuelGaugeParameter"}, - {87, nullptr, "SetPtmFuelGaugeParameter"}, - {88, nullptr, "GetBluetoothEnableFlag"}, - {89, nullptr, "SetBluetoothEnableFlag"}, - {90, &SET_SYS::GetMiiAuthorId, "GetMiiAuthorId"}, - {91, nullptr, "SetShutdownRtcValue"}, - {92, nullptr, "GetShutdownRtcValue"}, - {93, nullptr, "AcquireFatalDirtyFlagEventHandle"}, - {94, nullptr, "GetFatalDirtyFlags"}, - {95, &SET_SYS::GetAutoUpdateEnableFlag, "GetAutoUpdateEnableFlag"}, - {96, nullptr, "SetAutoUpdateEnableFlag"}, - {97, nullptr, "GetNxControllerSettings"}, - {98, nullptr, "SetNxControllerSettings"}, - {99, &SET_SYS::GetBatteryPercentageFlag, "GetBatteryPercentageFlag"}, - {100, nullptr, "SetBatteryPercentageFlag"}, - {101, nullptr, "GetExternalRtcResetFlag"}, - {102, nullptr, "SetExternalRtcResetFlag"}, - {103, nullptr, "GetUsbFullKeyEnableFlag"}, - {104, nullptr, "SetUsbFullKeyEnableFlag"}, - {105, &SET_SYS::SetExternalSteadyClockInternalOffset, "SetExternalSteadyClockInternalOffset"}, - {106, &SET_SYS::GetExternalSteadyClockInternalOffset, "GetExternalSteadyClockInternalOffset"}, - {107, nullptr, "GetBacklightSettingsEx"}, - {108, nullptr, "SetBacklightSettingsEx"}, - {109, nullptr, "GetHeadphoneVolumeWarningCount"}, - {110, nullptr, "SetHeadphoneVolumeWarningCount"}, - {111, nullptr, "GetBluetoothAfhEnableFlag"}, - {112, nullptr, "SetBluetoothAfhEnableFlag"}, - {113, nullptr, "GetBluetoothBoostEnableFlag"}, - {114, nullptr, "SetBluetoothBoostEnableFlag"}, - {115, nullptr, "GetInRepairProcessEnableFlag"}, - {116, nullptr, "SetInRepairProcessEnableFlag"}, - {117, nullptr, "GetHeadphoneVolumeUpdateFlag"}, - {118, nullptr, "SetHeadphoneVolumeUpdateFlag"}, - {119, nullptr, "NeedsToUpdateHeadphoneVolume"}, - {120, nullptr, "GetPushNotificationActivityModeOnSleep"}, - {121, nullptr, "SetPushNotificationActivityModeOnSleep"}, - {122, nullptr, "GetServiceDiscoveryControlSettings"}, - {123, nullptr, "SetServiceDiscoveryControlSettings"}, - {124, &SET_SYS::GetErrorReportSharePermission, "GetErrorReportSharePermission"}, - {125, nullptr, "SetErrorReportSharePermission"}, - {126, &SET_SYS::GetAppletLaunchFlags, "GetAppletLaunchFlags"}, - {127, &SET_SYS::SetAppletLaunchFlags, "SetAppletLaunchFlags"}, - {128, nullptr, "GetConsoleSixAxisSensorAccelerationBias"}, - {129, nullptr, "SetConsoleSixAxisSensorAccelerationBias"}, - {130, nullptr, "GetConsoleSixAxisSensorAngularVelocityBias"}, - {131, nullptr, "SetConsoleSixAxisSensorAngularVelocityBias"}, - {132, nullptr, "GetConsoleSixAxisSensorAccelerationGain"}, - {133, nullptr, "SetConsoleSixAxisSensorAccelerationGain"}, - {134, nullptr, "GetConsoleSixAxisSensorAngularVelocityGain"}, - {135, nullptr, "SetConsoleSixAxisSensorAngularVelocityGain"}, - {136, &SET_SYS::GetKeyboardLayout, "GetKeyboardLayout"}, - {137, nullptr, "SetKeyboardLayout"}, - {138, nullptr, "GetWebInspectorFlag"}, - {139, nullptr, "GetAllowedSslHosts"}, - {140, nullptr, "GetHostFsMountPoint"}, - {141, nullptr, "GetRequiresRunRepairTimeReviser"}, - {142, nullptr, "SetRequiresRunRepairTimeReviser"}, - {143, nullptr, "SetBlePairingSettings"}, - {144, nullptr, "GetBlePairingSettings"}, - {145, nullptr, "GetConsoleSixAxisSensorAngularVelocityTimeBias"}, - {146, nullptr, "SetConsoleSixAxisSensorAngularVelocityTimeBias"}, - {147, nullptr, "GetConsoleSixAxisSensorAngularAcceleration"}, - {148, nullptr, "SetConsoleSixAxisSensorAngularAcceleration"}, - {149, nullptr, "GetRebootlessSystemUpdateVersion"}, - {150, &SET_SYS::GetDeviceTimeZoneLocationUpdatedTime, "GetDeviceTimeZoneLocationUpdatedTime"}, - {151, &SET_SYS::SetDeviceTimeZoneLocationUpdatedTime, "SetDeviceTimeZoneLocationUpdatedTime"}, - {152, &SET_SYS::GetUserSystemClockAutomaticCorrectionUpdatedTime, "GetUserSystemClockAutomaticCorrectionUpdatedTime"}, - {153, &SET_SYS::SetUserSystemClockAutomaticCorrectionUpdatedTime, "SetUserSystemClockAutomaticCorrectionUpdatedTime"}, - {154, nullptr, "GetAccountOnlineStorageSettings"}, - {155, nullptr, "SetAccountOnlineStorageSettings"}, - {156, nullptr, "GetPctlReadyFlag"}, - {157, nullptr, "SetPctlReadyFlag"}, - {158, nullptr, "GetAnalogStickUserCalibrationL"}, - {159, nullptr, "SetAnalogStickUserCalibrationL"}, - {160, nullptr, "GetAnalogStickUserCalibrationR"}, - {161, nullptr, "SetAnalogStickUserCalibrationR"}, - {162, nullptr, "GetPtmBatteryVersion"}, - {163, nullptr, "SetPtmBatteryVersion"}, - {164, nullptr, "GetUsb30HostEnableFlag"}, - {165, nullptr, "SetUsb30HostEnableFlag"}, - {166, nullptr, "GetUsb30DeviceEnableFlag"}, - {167, nullptr, "SetUsb30DeviceEnableFlag"}, - {168, nullptr, "GetThemeId"}, - {169, nullptr, "SetThemeId"}, - {170, &SET_SYS::GetChineseTraditionalInputMethod, "GetChineseTraditionalInputMethod"}, - {171, nullptr, "SetChineseTraditionalInputMethod"}, - {172, nullptr, "GetPtmCycleCountReliability"}, - {173, nullptr, "SetPtmCycleCountReliability"}, - {174, &SET_SYS::GetHomeMenuScheme, "GetHomeMenuScheme"}, - {175, nullptr, "GetThemeSettings"}, - {176, nullptr, "SetThemeSettings"}, - {177, nullptr, "GetThemeKey"}, - {178, nullptr, "SetThemeKey"}, - {179, nullptr, "GetZoomFlag"}, - {180, nullptr, "SetZoomFlag"}, - {181, nullptr, "GetT"}, - {182, nullptr, "SetT"}, - {183, nullptr, "GetPlatformRegion"}, - {184, nullptr, "SetPlatformRegion"}, - {185, &SET_SYS::GetHomeMenuSchemeModel, "GetHomeMenuSchemeModel"}, - {186, nullptr, "GetMemoryUsageRateFlag"}, - {187, nullptr, "GetTouchScreenMode"}, - {188, nullptr, "SetTouchScreenMode"}, - {189, nullptr, "GetButtonConfigSettingsFull"}, - {190, nullptr, "SetButtonConfigSettingsFull"}, - {191, nullptr, "GetButtonConfigSettingsEmbedded"}, - {192, nullptr, "SetButtonConfigSettingsEmbedded"}, - {193, nullptr, "GetButtonConfigSettingsLeft"}, - {194, nullptr, "SetButtonConfigSettingsLeft"}, - {195, nullptr, "GetButtonConfigSettingsRight"}, - {196, nullptr, "SetButtonConfigSettingsRight"}, - {197, nullptr, "GetButtonConfigRegisteredSettingsEmbedded"}, - {198, nullptr, "SetButtonConfigRegisteredSettingsEmbedded"}, - {199, nullptr, "GetButtonConfigRegisteredSettings"}, - {200, nullptr, "SetButtonConfigRegisteredSettings"}, - {201, &SET_SYS::GetFieldTestingFlag, "GetFieldTestingFlag"}, - {202, nullptr, "SetFieldTestingFlag"}, - {203, nullptr, "GetPanelCrcMode"}, - {204, nullptr, "SetPanelCrcMode"}, - {205, nullptr, "GetNxControllerSettingsEx"}, - {206, nullptr, "SetNxControllerSettingsEx"}, - {207, nullptr, "GetHearingProtectionSafeguardFlag"}, - {208, nullptr, "SetHearingProtectionSafeguardFlag"}, - {209, nullptr, "GetHearingProtectionSafeguardRemainingTime"}, - {210, nullptr, "SetHearingProtectionSafeguardRemainingTime"}, - }; - // clang-format on - - RegisterHandlers(functions); - - SetupSettings(); - m_save_thread = - std::jthread([this](std::stop_token stop_token) { StoreSettingsThreadFunc(stop_token); }); -} - -SET_SYS::~SET_SYS() { - SetSaveNeeded(); - m_save_thread.request_stop(); -} - -void SET_SYS::SetupSettings() { - 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) { - Common::SetCurrentThreadName("SettingsStore"); - - 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 diff --git a/src/core/hle/service/set/set_sys.h b/src/core/hle/service/set/set_sys.h deleted file mode 100644 index 853f76fce..000000000 --- a/src/core/hle/service/set/set_sys.h +++ /dev/null @@ -1,153 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include <filesystem> -#include <mutex> -#include <string> -#include <thread> - -#include "common/polyfill_thread.h" -#include "common/uuid.h" -#include "core/hle/result.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/time_zone_types.h" - -namespace Core { -class System; -} - -namespace Service::Set { -enum class GetFirmwareVersionType { - Version1, - Version2, -}; - -struct FirmwareVersionFormat { - u8 major; - u8 minor; - u8 micro; - INSERT_PADDING_BYTES(1); - u8 revision_major; - u8 revision_minor; - INSERT_PADDING_BYTES(2); - std::array<char, 0x20> platform; - std::array<u8, 0x40> version_hash; - std::array<char, 0x18> display_version; - std::array<char, 0x80> display_title; -}; -static_assert(sizeof(FirmwareVersionFormat) == 0x100, "FirmwareVersionFormat is an invalid size"); - -Result GetFirmwareVersionImpl(FirmwareVersionFormat& out_firmware, Core::System& system, - GetFirmwareVersionType type); - -class SET_SYS final : public ServiceFramework<SET_SYS> { -public: - explicit SET_SYS(Core::System& system_); - ~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: - void SetLanguageCode(HLERequestContext& ctx); - void GetFirmwareVersion(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 SetAccountSettings(HLERequestContext& ctx); - void GetEulaVersions(HLERequestContext& ctx); - void SetEulaVersions(HLERequestContext& ctx); - void GetColorSetId(HLERequestContext& ctx); - void SetColorSetId(HLERequestContext& ctx); - void GetNotificationSettings(HLERequestContext& ctx); - void SetNotificationSettings(HLERequestContext& ctx); - void GetAccountNotificationSettings(HLERequestContext& ctx); - void SetAccountNotificationSettings(HLERequestContext& ctx); - void GetSettingsItemValueSize(HLERequestContext& ctx); - void GetSettingsItemValue(HLERequestContext& ctx); - void GetTvSettings(HLERequestContext& ctx); - void SetTvSettings(HLERequestContext& ctx); - void GetDebugModeFlag(HLERequestContext& ctx); - void GetQuestFlag(HLERequestContext& ctx); - void GetDeviceTimeZoneLocationName(HLERequestContext& ctx); - void SetDeviceTimeZoneLocationName(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 GetSleepSettings(HLERequestContext& ctx); - void SetSleepSettings(HLERequestContext& ctx); - void GetInitialLaunchSettings(HLERequestContext& ctx); - void SetInitialLaunchSettings(HLERequestContext& ctx); - void GetDeviceNickName(HLERequestContext& ctx); - void SetDeviceNickName(HLERequestContext& ctx); - void GetProductModel(HLERequestContext& ctx); - void GetMiiAuthorId(HLERequestContext& ctx); - void GetAutoUpdateEnableFlag(HLERequestContext& ctx); - void GetBatteryPercentageFlag(HLERequestContext& ctx); - void SetExternalSteadyClockInternalOffset(HLERequestContext& ctx); - void GetExternalSteadyClockInternalOffset(HLERequestContext& ctx); - void GetErrorReportSharePermission(HLERequestContext& ctx); - void GetAppletLaunchFlags(HLERequestContext& ctx); - void SetAppletLaunchFlags(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 GetHomeMenuScheme(HLERequestContext& ctx); - void GetHomeMenuSchemeModel(HLERequestContext& ctx); - void GetFieldTestingFlag(HLERequestContext& ctx); - - bool LoadSettingsFile(std::filesystem::path& path, auto&& default_func); - bool StoreSettingsFile(std::filesystem::path& path, auto& settings); - void SetupSettings(); - void StoreSettings(); - void StoreSettingsThreadFunc(std::stop_token stop_token); - void SetSaveNeeded(); - - Core::System& m_system; - SystemSettings m_system_settings{}; - PrivateSettings m_private_settings{}; - DeviceSettings m_device_settings{}; - ApplnSettings m_appln_settings{}; - std::jthread m_save_thread; - std::mutex m_save_needed_mutex; - bool m_save_needed{false}; -}; - -} // namespace Service::Set diff --git a/src/core/hle/service/set/setting_formats/appln_settings.cpp b/src/core/hle/service/set/setting_formats/appln_settings.cpp new file mode 100644 index 000000000..f7c7d5b91 --- /dev/null +++ b/src/core/hle/service/set/setting_formats/appln_settings.cpp @@ -0,0 +1,16 @@ +// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "core/hle/service/set/setting_formats/appln_settings.h" + +namespace Service::Set { + +ApplnSettings DefaultApplnSettings() { + ApplnSettings settings{}; + + settings.mii_author_id = Common::UUID::MakeDefault(); + + return settings; +} + +} // namespace Service::Set diff --git a/src/core/hle/service/set/setting_formats/appln_settings.h b/src/core/hle/service/set/setting_formats/appln_settings.h new file mode 100644 index 000000000..ba9af998a --- /dev/null +++ b/src/core/hle/service/set/setting_formats/appln_settings.h @@ -0,0 +1,35 @@ +// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include <array> +#include <cstddef> + +#include "common/common_types.h" +#include "common/uuid.h" +#include "core/hle/service/set/settings_types.h" + +namespace Service::Set { +struct ApplnSettings { + INSERT_PADDING_BYTES(0x10); // Reserved + + // nn::util::Uuid MiiAuthorId, copied from system settings 0x94B0 + Common::UUID mii_author_id; + INSERT_PADDING_BYTES(0x30); // Reserved + + // nn::settings::system::ServiceDiscoveryControlSettings + u32 service_discovery_control_settings; + INSERT_PADDING_BYTES(0x20); // Reserved + + bool in_repair_process_enable_flag; + INSERT_PADDING_BYTES(0x3); +}; +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 diff --git a/src/core/hle/service/set/setting_formats/device_settings.cpp b/src/core/hle/service/set/setting_formats/device_settings.cpp new file mode 100644 index 000000000..5f295404d --- /dev/null +++ b/src/core/hle/service/set/setting_formats/device_settings.cpp @@ -0,0 +1,12 @@ +// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "core/hle/service/set/setting_formats/device_settings.h" + +namespace Service::Set { + +DeviceSettings DefaultDeviceSettings() { + return {}; +} + +} // namespace Service::Set diff --git a/src/core/hle/service/set/setting_formats/device_settings.h b/src/core/hle/service/set/setting_formats/device_settings.h new file mode 100644 index 000000000..2827756f6 --- /dev/null +++ b/src/core/hle/service/set/setting_formats/device_settings.h @@ -0,0 +1,54 @@ +// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include <array> +#include <cstddef> + +#include "common/common_types.h" +#include "common/vector_math.h" +#include "core/hle/service/set/settings_types.h" + +namespace Service::Set { +struct DeviceSettings { + INSERT_PADDING_BYTES(0x10); // Reserved + + // 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; + INSERT_PADDING_BYTES(0x48); // Reserved + + // 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; + INSERT_PADDING_BYTES(0x20); // Reserved + + // nn::settings::system::ConsoleSixAxisSensorAccelerationBias + Common::Vec3<f32> console_six_axis_sensor_acceleration_bias; + // nn::settings::system::ConsoleSixAxisSensorAngularVelocityBias + Common::Vec3<f32> 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 + Common::Vec3<f32> 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 diff --git a/src/core/hle/service/set/setting_formats/private_settings.cpp b/src/core/hle/service/set/setting_formats/private_settings.cpp new file mode 100644 index 000000000..81c362482 --- /dev/null +++ b/src/core/hle/service/set/setting_formats/private_settings.cpp @@ -0,0 +1,12 @@ +// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "core/hle/service/set/setting_formats/private_settings.h" + +namespace Service::Set { + +PrivateSettings DefaultPrivateSettings() { + return {}; +} + +} // namespace Service::Set diff --git a/src/core/hle/service/set/setting_formats/private_settings.h b/src/core/hle/service/set/setting_formats/private_settings.h new file mode 100644 index 000000000..6579e95e0 --- /dev/null +++ b/src/core/hle/service/set/setting_formats/private_settings.h @@ -0,0 +1,38 @@ +// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include <array> + +#include "common/common_types.h" +#include "common/uuid.h" +#include "core/hle/service/set/settings_types.h" + +namespace Service::Set { + +struct PrivateSettings { + INSERT_PADDING_BYTES(0x10); // Reserved + + InitialLaunchSettings initial_launch_settings; + INSERT_PADDING_BYTES(0x20); // Reserved + + Common::UUID external_clock_source_id; + s64 shutdown_rtc_value; + s64 external_steady_clock_internal_offset; + INSERT_PADDING_BYTES(0x60); // Reserved + + // nn::settings::system::PlatformRegion + s32 platform_region; + INSERT_PADDING_BYTES(0x4); // Reserved +}; +static_assert(offsetof(PrivateSettings, initial_launch_settings) == 0x10); +static_assert(offsetof(PrivateSettings, external_clock_source_id) == 0x50); +static_assert(offsetof(PrivateSettings, shutdown_rtc_value) == 0x60); +static_assert(offsetof(PrivateSettings, external_steady_clock_internal_offset) == 0x68); +static_assert(offsetof(PrivateSettings, platform_region) == 0xD0); +static_assert(sizeof(PrivateSettings) == 0xD8, "PrivateSettings has the wrong size!"); + +PrivateSettings DefaultPrivateSettings(); + +} // namespace Service::Set diff --git a/src/core/hle/service/set/setting_formats/system_settings.cpp b/src/core/hle/service/set/setting_formats/system_settings.cpp new file mode 100644 index 000000000..16ded43bf --- /dev/null +++ b/src/core/hle/service/set/setting_formats/system_settings.cpp @@ -0,0 +1,70 @@ +// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "common/settings.h" +#include "core/hle/service/set/setting_formats/system_settings.h" + +namespace Service::Set { + +SystemSettings DefaultSystemSettings() { + SystemSettings settings{}; + + settings.version = 0x140000; + settings.flags = 7; + + settings.mii_author_id = Common::UUID::MakeDefault(); + + 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, + .contrast_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 = true; + + settings.primary_album_storage = PrimaryAlbumStorage::SdCard; + settings.battery_percentage_flag = true; + settings.chinese_traditional_input_method = ChineseTraditionalInputMethod::Unknown0; + settings.vibration_master_volume = 1.0f; + + const auto language_code = + available_language_codes[static_cast<s32>(::Settings::values.language_index.GetValue())]; + const auto key_code = + std::find_if(language_to_layout.cbegin(), language_to_layout.cend(), + [=](const auto& element) { return element.first == language_code; }); + + settings.keyboard_layout = KeyboardLayout::EnglishUs; + if (key_code != language_to_layout.end()) { + settings.keyboard_layout = key_code->second; + } + + return settings; +} + +} // namespace Service::Set diff --git a/src/core/hle/service/set/setting_formats/system_settings.h b/src/core/hle/service/set/setting_formats/system_settings.h new file mode 100644 index 000000000..ebc373da5 --- /dev/null +++ b/src/core/hle/service/set/setting_formats/system_settings.h @@ -0,0 +1,391 @@ +// 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 "common/vector_math.h" +#include "core/hle/service/set/setting_formats/private_settings.h" +#include "core/hle/service/set/settings_types.h" + +namespace Service::Set { + +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; + INSERT_PADDING_BYTES(0x8); // Reserved + + LanguageCode language_code; + INSERT_PADDING_BYTES(0x38); // Reserved + + // nn::settings::system::NetworkSettings + u32 network_setting_count; + bool wireless_lan_enable_flag; + INSERT_PADDING_BYTES(0x3); + INSERT_PADDING_BYTES(0x8); // Reserved + + // 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; + INSERT_PADDING_BYTES(0x3); + bool bluetooth_afh_enable_flag; + INSERT_PADDING_BYTES(0x3); + bool bluetooth_boost_enable_flag; + INSERT_PADDING_BYTES(0x3); + std::array<std::array<u8, 0x200>, 10> bluetooth_device_settings_first_10; + + s32 ldn_channel; + INSERT_PADDING_BYTES(0x3C); // Reserved + + // nn::util::Uuid MiiAuthorId + Common::UUID mii_author_id; + + INSERT_PADDING_BYTES(0x30); // Reserved + + // nn::settings::system::NxControllerSettings + u32 nx_controller_settings_count; + + INSERT_PADDING_BYTES(0xC); // Reserved + + // nn::settings::system::NxControllerSettings, + // nn::settings::system::NxControllerLegacySettings on 13.0.0+ + std::array<std::array<u8, 0x40>, 10> nx_controller_legacy_settings; + INSERT_PADDING_BYTES(0x170); // Reserved + + bool external_rtc_reset_flag; + INSERT_PADDING_BYTES(0x3); + INSERT_PADDING_BYTES(0x3C); // Reserved + + s32 push_notification_activity_mode_on_sleep; + INSERT_PADDING_BYTES(0x3C); // Reserved + + ErrorReportSharePermission error_report_share_permission; + INSERT_PADDING_BYTES(0x3C); // Reserved + + KeyboardLayout keyboard_layout; + INSERT_PADDING_BYTES(0x3C); // Reserved + + bool web_inspector_flag; + INSERT_PADDING_BYTES(0x3); + + // nn::settings::system::AllowedSslHost + u32 allowed_ssl_host_count; + + bool memory_usage_rate_flag; + INSERT_PADDING_BYTES(0x3); + INSERT_PADDING_BYTES(0x34); // Reserved + + // 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; + INSERT_PADDING_BYTES(0x6C0); // Reserved + + // nn::settings::system::BlePairingSettings + u32 ble_pairing_settings_count; + INSERT_PADDING_BYTES(0xC); // Reserved + std::array<std::array<u8, 0x80>, 10> ble_pairing_settings; + + // nn::settings::system::AccountOnlineStorageSettings + u32 account_online_storage_settings_count; + INSERT_PADDING_BYTES(0xC); // Reserved + std::array<std::array<u8, 0x40>, 8> account_online_storage_settings; + + bool pctl_ready_flag; + INSERT_PADDING_BYTES(0x3); + INSERT_PADDING_BYTES(0x3C); // Reserved + + // nn::settings::system::ThemeId + std::array<u8, 0x80> theme_id_type0; + std::array<u8, 0x80> theme_id_type1; + INSERT_PADDING_BYTES(0x100); // Reserved + + ChineseTraditionalInputMethod chinese_traditional_input_method; + INSERT_PADDING_BYTES(0x3C); // Reserved + + bool zoom_flag; + INSERT_PADDING_BYTES(0x3); + INSERT_PADDING_BYTES(0x3C); // Reserved + + // nn::settings::system::ButtonConfigRegisteredSettings + u32 button_config_registered_settings_count; + INSERT_PADDING_BYTES(0xC); // Reserved + + // nn::settings::system::ButtonConfigSettings + u32 button_config_settings_count; + INSERT_PADDING_BYTES(0x4); // Reserved + std::array<std::array<u8, 0x5A8>, 5> button_config_settings; + INSERT_PADDING_BYTES(0x13B0); // Reserved + u32 button_config_settings_embedded_count; + INSERT_PADDING_BYTES(0x4); // Reserved + std::array<std::array<u8, 0x5A8>, 5> button_config_settings_embedded; + INSERT_PADDING_BYTES(0x13B0); // Reserved + u32 button_config_settings_left_count; + INSERT_PADDING_BYTES(0x4); // Reserved + std::array<std::array<u8, 0x5A8>, 5> button_config_settings_left; + INSERT_PADDING_BYTES(0x13B0); // Reserved + u32 button_config_settings_right_count; + INSERT_PADDING_BYTES(0x4); // Reserved + std::array<std::array<u8, 0x5A8>, 5> button_config_settings_right; + INSERT_PADDING_BYTES(0x73B0); // Reserved + // nn::settings::system::ButtonConfigRegisteredSettings + std::array<u8, 0x5C8> button_config_registered_settings_embedded; + std::array<std::array<u8, 0x5C8>, 10> button_config_registered_settings; + INSERT_PADDING_BYTES(0x7FF8); // Reserved + + // nn::settings::system::ConsoleSixAxisSensorAccelerationBias + Common::Vec3<f32> console_six_axis_sensor_acceleration_bias; + // nn::settings::system::ConsoleSixAxisSensorAngularVelocityBias + Common::Vec3<f32> 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 + Common::Vec3<f32> console_six_axis_sensor_angular_velocity_time_bias; + // nn::settings::system::ConsoleSixAxisSensorAngularAcceleration + std::array<u8, 0x24> console_six_axis_sensor_angular_velocity_acceleration; + INSERT_PADDING_BYTES(0x70); // Reserved + + bool lock_screen_flag; + INSERT_PADDING_BYTES(0x3); + INSERT_PADDING_BYTES(0x4); // Reserved + + ColorSet color_set_id; + + QuestFlag quest_flag; + + SystemRegionCode region_code; + + // Different to nn::settings::system::InitialLaunchSettings? + InitialLaunchSettingsPacked initial_launch_settings_packed; + + bool battery_percentage_flag; + INSERT_PADDING_BYTES(0x3); + + // 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; + INSERT_PADDING_BYTES(0x3); + + s32 panel_crc_mode; + INSERT_PADDING_BYTES(0x28); // Reserved + + // nn::settings::system::BacklightSettings + std::array<u8, 0x2C> backlight_settings_mixed_up; + INSERT_PADDING_BYTES(0x64); // Reserved + + // nn::time::SystemClockContext + Service::PSC::Time::SystemClockContext user_system_clock_context; + Service::PSC::Time::SystemClockContext network_system_clock_context; + bool user_system_clock_automatic_correction_enabled; + INSERT_PADDING_BYTES(0x3); + INSERT_PADDING_BYTES(0x4); // Reserved + // nn::time::SteadyClockTimePoint + Service::PSC::Time::SteadyClockTimePoint + user_system_clock_automatic_correction_updated_time_point; + INSERT_PADDING_BYTES(0x10); // Reserved + + AccountSettings account_settings; + INSERT_PADDING_BYTES(0xFC); // Reserved + + // nn::settings::system::AudioVolume + std::array<u8, 0x8> audio_volume_type0; + std::array<u8, 0x8> audio_volume_type1; + AudioOutputMode audio_output_mode_hdmi; + AudioOutputMode audio_output_mode_speaker; + AudioOutputMode audio_output_mode_headphone; + bool force_mute_on_headphone_removed; + INSERT_PADDING_BYTES(0x3); + s32 headphone_volume_warning_count; + bool heaphone_volume_update_flag; + INSERT_PADDING_BYTES(0x3); + // nn::settings::system::AudioVolume + std::array<u8, 0x8> audio_volume_type2; + AudioOutputMode audio_output_mode_type3; + AudioOutputMode audio_output_mode_type4; + bool hearing_protection_safeguard_flag; + INSERT_PADDING_BYTES(0x3); + INSERT_PADDING_BYTES(0x4); // Reserved + s64 hearing_protection_safeguard_remaining_time; + INSERT_PADDING_BYTES(0x38); // Reserved + + bool console_information_upload_flag; + INSERT_PADDING_BYTES(0x3); + INSERT_PADDING_BYTES(0x3C); // Reserved + + bool automatic_application_download_flag; + INSERT_PADDING_BYTES(0x3); + INSERT_PADDING_BYTES(0x4); // Reserved + + NotificationSettings notification_settings; + INSERT_PADDING_BYTES(0x60); // Reserved + + // nn::settings::system::AccountNotificationSettings + u32 account_notification_settings_count; + INSERT_PADDING_BYTES(0xC); // Reserved + std::array<AccountNotificationSettings, 8> account_notification_settings; + INSERT_PADDING_BYTES(0x140); // Reserved + + f32 vibration_master_volume; + + bool usb_full_key_enable_flag; + INSERT_PADDING_BYTES(0x3); + + // 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; + INSERT_PADDING_BYTES(0x14); // Reserved + + TvSettings tv_settings; + + // nn::settings::system::Edid + std::array<u8, 0x100> edid; + INSERT_PADDING_BYTES(0x2E0); // Reserved + + // nn::settings::system::DataDeletionSettings + std::array<u8, 0x8> data_deletion_settings; + INSERT_PADDING_BYTES(0x38); // Reserved + + // nn::ncm::ProgramId + std::array<u8, 0x8> initial_system_applet_program_id; + std::array<u8, 0x8> overlay_disp_program_id; + INSERT_PADDING_BYTES(0x4); // Reserved + + bool requires_run_repair_time_reviser; + INSERT_PADDING_BYTES(0x6B); // Reserved + + // nn::time::LocationName + Service::PSC::Time::LocationName device_time_zone_location_name; + INSERT_PADDING_BYTES(0x4); // Reserved + // nn::time::SteadyClockTimePoint + Service::PSC::Time::SteadyClockTimePoint device_time_zone_location_updated_time; + + INSERT_PADDING_BYTES(0xC0); // Reserved + + // nn::settings::system::PrimaryAlbumStorage + PrimaryAlbumStorage primary_album_storage; + INSERT_PADDING_BYTES(0x3C); // Reserved + + bool usb_30_enable_flag; + INSERT_PADDING_BYTES(0x3); + bool usb_30_host_enable_flag; + INSERT_PADDING_BYTES(0x3); + bool usb_30_device_enable_flag; + INSERT_PADDING_BYTES(0x3); + INSERT_PADDING_BYTES(0x34); // Reserved + + bool nfc_enable_flag; + INSERT_PADDING_BYTES(0x3); + INSERT_PADDING_BYTES(0x3C); // Reserved + + // nn::settings::system::SleepSettings + SleepSettings sleep_settings; + INSERT_PADDING_BYTES(0x34); // Reserved + + // nn::settings::system::EulaVersion + u32 eula_version_count; + INSERT_PADDING_BYTES(0xC); // Reserved + std::array<EulaVersion, 32> eula_versions; + INSERT_PADDING_BYTES(0x200); // Reserved + + // nn::settings::system::DeviceNickName + std::array<u8, 0x80> device_nick_name; + INSERT_PADDING_BYTES(0x80); // Reserved + + bool auto_update_enable_flag; + INSERT_PADDING_BYTES(0x3); + INSERT_PADDING_BYTES(0x4C); // Reserved + + // nn::settings::system::BluetoothDevicesSettings + std::array<std::array<u8, 0x200>, 14> bluetooth_device_settings_last_14; + INSERT_PADDING_BYTES(0x2000); // Reserved + + // 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 diff --git a/src/core/hle/service/set/settings.cpp b/src/core/hle/service/set/settings.cpp index c48844f77..73d021ff4 100644 --- a/src/core/hle/service/set/settings.cpp +++ b/src/core/hle/service/set/settings.cpp @@ -2,21 +2,24 @@ // SPDX-License-Identifier: GPL-2.0-or-later #include "core/hle/service/server_manager.h" -#include "core/hle/service/set/set.h" -#include "core/hle/service/set/set_cal.h" -#include "core/hle/service/set/set_fd.h" -#include "core/hle/service/set/set_sys.h" +#include "core/hle/service/set/factory_settings_server.h" +#include "core/hle/service/set/firmware_debug_settings_server.h" #include "core/hle/service/set/settings.h" +#include "core/hle/service/set/settings_server.h" +#include "core/hle/service/set/system_settings_server.h" namespace Service::Set { void LoopProcess(Core::System& system) { auto server_manager = std::make_unique<ServerManager>(system); - server_manager->RegisterNamedService("set", std::make_shared<SET>(system)); - server_manager->RegisterNamedService("set:cal", std::make_shared<SET_CAL>(system)); - server_manager->RegisterNamedService("set:fd", std::make_shared<SET_FD>(system)); - server_manager->RegisterNamedService("set:sys", std::make_shared<SET_SYS>(system)); + server_manager->RegisterNamedService("set", std::make_shared<ISettingsServer>(system)); + server_manager->RegisterNamedService("set:cal", + std::make_shared<IFactorySettingsServer>(system)); + server_manager->RegisterNamedService("set:fd", + std::make_shared<IFirmwareDebugSettingsServer>(system)); + server_manager->RegisterNamedService("set:sys", + std::make_shared<ISystemSettingsServer>(system)); ServerManager::RunServer(std::move(server_manager)); } diff --git a/src/core/hle/service/set/settings_server.cpp b/src/core/hle/service/set/settings_server.cpp new file mode 100644 index 000000000..b2caa00ff --- /dev/null +++ b/src/core/hle/service/set/settings_server.cpp @@ -0,0 +1,166 @@ +// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include <algorithm> +#include <array> +#include <chrono> +#include "common/logging/log.h" +#include "common/settings.h" +#include "core/hle/service/ipc_helpers.h" +#include "core/hle/service/set/settings_server.h" + +namespace Service::Set { +namespace { +constexpr std::size_t PRE_4_0_0_MAX_ENTRIES = 0xF; +constexpr std::size_t POST_4_0_0_MAX_ENTRIES = 0x40; + +constexpr Result ResultInvalidLanguage{ErrorModule::Settings, 625}; + +void PushResponseLanguageCode(HLERequestContext& ctx, std::size_t num_language_codes) { + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(ResultSuccess); + rb.Push(static_cast<u32>(num_language_codes)); +} + +void GetAvailableLanguageCodesImpl(HLERequestContext& ctx, std::size_t max_entries) { + const std::size_t requested_amount = ctx.GetWriteBufferNumElements<LanguageCode>(); + const std::size_t max_amount = std::min(requested_amount, max_entries); + const std::size_t copy_amount = std::min(available_language_codes.size(), max_amount); + const std::size_t copy_size = copy_amount * sizeof(LanguageCode); + + ctx.WriteBuffer(available_language_codes.data(), copy_size); + PushResponseLanguageCode(ctx, copy_amount); +} + +void GetKeyCodeMapImpl(HLERequestContext& ctx) { + const auto language_code = + available_language_codes[static_cast<s32>(Settings::values.language_index.GetValue())]; + const auto key_code = + std::find_if(language_to_layout.cbegin(), language_to_layout.cend(), + [=](const auto& element) { return element.first == language_code; }); + KeyboardLayout layout = KeyboardLayout::EnglishUs; + if (key_code == language_to_layout.cend()) { + LOG_ERROR(Service_SET, + "Could not find keyboard layout for language index {}, defaulting to English us", + Settings::values.language_index.GetValue()); + } else { + layout = key_code->second; + } + + ctx.WriteBuffer(layout); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); +} +} // Anonymous namespace + +LanguageCode GetLanguageCodeFromIndex(std::size_t index) { + return available_language_codes.at(index); +} + +ISettingsServer::ISettingsServer(Core::System& system_) : ServiceFramework{system_, "set"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, &ISettingsServer::GetLanguageCode, "GetLanguageCode"}, + {1, &ISettingsServer::GetAvailableLanguageCodes, "GetAvailableLanguageCodes"}, + {2, &ISettingsServer::MakeLanguageCode, "MakeLanguageCode"}, + {3, &ISettingsServer::GetAvailableLanguageCodeCount, "GetAvailableLanguageCodeCount"}, + {4, &ISettingsServer::GetRegionCode, "GetRegionCode"}, + {5, &ISettingsServer::GetAvailableLanguageCodes2, "GetAvailableLanguageCodes2"}, + {6, &ISettingsServer::GetAvailableLanguageCodeCount2, "GetAvailableLanguageCodeCount2"}, + {7, &ISettingsServer::GetKeyCodeMap, "GetKeyCodeMap"}, + {8, &ISettingsServer::GetQuestFlag, "GetQuestFlag"}, + {9, &ISettingsServer::GetKeyCodeMap2, "GetKeyCodeMap2"}, + {10, nullptr, "GetFirmwareVersionForDebug"}, + {11, &ISettingsServer::GetDeviceNickName, "GetDeviceNickName"}, + }; + // clang-format on + + RegisterHandlers(functions); +} + +ISettingsServer::~ISettingsServer() = default; + +void ISettingsServer::GetAvailableLanguageCodes(HLERequestContext& ctx) { + LOG_DEBUG(Service_SET, "called"); + + GetAvailableLanguageCodesImpl(ctx, PRE_4_0_0_MAX_ENTRIES); +} + +void ISettingsServer::MakeLanguageCode(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + const auto index = rp.Pop<u32>(); + + if (index >= available_language_codes.size()) { + LOG_ERROR(Service_SET, "Invalid language code index! index={}", index); + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(Set::ResultInvalidLanguage); + return; + } + + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(ResultSuccess); + rb.PushEnum(available_language_codes[index]); +} + +void ISettingsServer::GetAvailableLanguageCodes2(HLERequestContext& ctx) { + LOG_DEBUG(Service_SET, "called"); + + GetAvailableLanguageCodesImpl(ctx, POST_4_0_0_MAX_ENTRIES); +} + +void ISettingsServer::GetAvailableLanguageCodeCount(HLERequestContext& ctx) { + LOG_DEBUG(Service_SET, "called"); + + PushResponseLanguageCode(ctx, PRE_4_0_0_MAX_ENTRIES); +} + +void ISettingsServer::GetAvailableLanguageCodeCount2(HLERequestContext& ctx) { + LOG_DEBUG(Service_SET, "called"); + + PushResponseLanguageCode(ctx, POST_4_0_0_MAX_ENTRIES); +} + +void ISettingsServer::GetQuestFlag(HLERequestContext& ctx) { + LOG_DEBUG(Service_SET, "called"); + + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(ResultSuccess); + rb.Push(static_cast<s32>(Settings::values.quest_flag.GetValue())); +} + +void ISettingsServer::GetLanguageCode(HLERequestContext& ctx) { + LOG_DEBUG(Service_SET, "called {}", Settings::values.language_index.GetValue()); + + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(ResultSuccess); + rb.PushEnum( + available_language_codes[static_cast<s32>(Settings::values.language_index.GetValue())]); +} + +void ISettingsServer::GetRegionCode(HLERequestContext& ctx) { + LOG_DEBUG(Service_SET, "called"); + + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(ResultSuccess); + rb.Push(static_cast<u32>(Settings::values.region_index.GetValue())); +} + +void ISettingsServer::GetKeyCodeMap(HLERequestContext& ctx) { + LOG_DEBUG(Service_SET, "Called {}", ctx.Description()); + GetKeyCodeMapImpl(ctx); +} + +void ISettingsServer::GetKeyCodeMap2(HLERequestContext& ctx) { + LOG_DEBUG(Service_SET, "Called {}", ctx.Description()); + GetKeyCodeMapImpl(ctx); +} + +void ISettingsServer::GetDeviceNickName(HLERequestContext& ctx) { + LOG_DEBUG(Service_SET, "called"); + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); + ctx.WriteBuffer(Settings::values.device_name.GetValue()); +} + +} // namespace Service::Set diff --git a/src/core/hle/service/set/settings_server.h b/src/core/hle/service/set/settings_server.h new file mode 100644 index 000000000..8304e8424 --- /dev/null +++ b/src/core/hle/service/set/settings_server.h @@ -0,0 +1,36 @@ +// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "core/hle/service/service.h" +#include "core/hle/service/set/settings_types.h" + +namespace Core { +class System; +} + +namespace Service::Set { + +LanguageCode GetLanguageCodeFromIndex(std::size_t idx); + +class ISettingsServer final : public ServiceFramework<ISettingsServer> { +public: + explicit ISettingsServer(Core::System& system_); + ~ISettingsServer() override; + +private: + void GetLanguageCode(HLERequestContext& ctx); + void GetAvailableLanguageCodes(HLERequestContext& ctx); + void MakeLanguageCode(HLERequestContext& ctx); + void GetAvailableLanguageCodes2(HLERequestContext& ctx); + void GetAvailableLanguageCodeCount(HLERequestContext& ctx); + void GetAvailableLanguageCodeCount2(HLERequestContext& ctx); + void GetQuestFlag(HLERequestContext& ctx); + void GetRegionCode(HLERequestContext& ctx); + void GetKeyCodeMap(HLERequestContext& ctx); + void GetKeyCodeMap2(HLERequestContext& ctx); + void GetDeviceNickName(HLERequestContext& ctx); +}; + +} // namespace Service::Set diff --git a/src/core/hle/service/set/settings_types.h b/src/core/hle/service/set/settings_types.h new file mode 100644 index 000000000..ceb85b82a --- /dev/null +++ b/src/core/hle/service/set/settings_types.h @@ -0,0 +1,475 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-3.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/psc/time/common.h" + +namespace Service::Set { + +/// This is nn::settings::system::AudioOutputMode +enum class AudioOutputMode : u32 { + ch_1, + ch_2, + ch_5_1, + ch_7_1, +}; + +/// This is nn::settings::system::AudioOutputModeTarget +enum class AudioOutputModeTarget : u32 { + None, + Hdmi, + Speaker, + Headphone, + Type3, + Type4, +}; + +/// This is nn::settings::system::AudioVolumeTarget +enum class AudioVolumeTarget : u32 { + Speaker, + Headphone, +}; + +/// This is nn::settings::system::ClockSourceId +enum class ClockSourceId : u32 { + NetworkSystemClock, + SteadyClock, +}; + +/// This is nn::settings::system::CmuMode +enum class CmuMode : u32 { + None, + ColorInvert, + HighContrast, + GrayScale, +}; + +/// This is nn::settings::system::ChineseTraditionalInputMethod +enum class ChineseTraditionalInputMethod : u32 { + Unknown0 = 0, + Unknown1 = 1, + Unknown2 = 2, +}; + +/// Indicates the current theme set by the system settings +enum class ColorSet : u32 { + BasicWhite = 0, + BasicBlack = 1, +}; + +/// This is nn::settings::system::ConsoleSleepPlan +enum class ConsoleSleepPlan : u32 { + Sleep1Hour, + Sleep2Hour, + Sleep3Hour, + Sleep6Hour, + Sleep12Hour, + Never, +}; + +/// This is nn::settings::system::ErrorReportSharePermission +enum class ErrorReportSharePermission : u32 { + NotConfirmed, + Granted, + Denied, +}; + +/// This is nn::settings::system::EulaVersionClockType +enum class EulaVersionClockType : u32 { + NetworkSystemClock, + SteadyClock, +}; + +/// This is nn::settings::factory::RegionCode +enum class FactoryRegionCode : u32 { + Japan, + Usa, + Europe, + Australia, + China, + Korea, + Taiwan, +}; + +/// This is nn::settings::system::FriendPresenceOverlayPermission +enum class FriendPresenceOverlayPermission : u8 { + NotConfirmed, + NoDisplay, + FavoriteFriends, + Friends, +}; + +enum class GetFirmwareVersionType { + Version1, + Version2, +}; + +/// This is nn::settings::system::HandheldSleepPlan +enum class HandheldSleepPlan : u32 { + Sleep1Min, + Sleep3Min, + Sleep5Min, + Sleep10Min, + Sleep30Min, + Never, +}; + +/// This is nn::settings::system::HdmiContentType +enum class HdmiContentType : u32 { + None, + Graphics, + Cinema, + Photo, + Game, +}; + +enum class KeyboardLayout : u32 { + Japanese = 0, + EnglishUs = 1, + EnglishUsInternational = 2, + EnglishUk = 3, + French = 4, + FrenchCa = 5, + Spanish = 6, + SpanishLatin = 7, + German = 8, + Italian = 9, + Portuguese = 10, + Russian = 11, + Korean = 12, + ChineseSimplified = 13, + ChineseTraditional = 14, +}; + +/// 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::NotificationVolume +enum class NotificationVolume : u32 { + Mute, + Low, + High, +}; + +/// This is nn::settings::system::PrimaryAlbumStorage +enum class PrimaryAlbumStorage : u32 { + Nand, + SdCard, +}; + +/// Indicates the current console is a retail or kiosk unit +enum class QuestFlag : u8 { + Retail = 0, + Kiosk = 1, +}; + +/// This is nn::settings::system::RgbRange +enum class RgbRange : u32 { + Auto, + Full, + Limited, +}; + +/// This is nn::settings::system::RegionCode +enum class SystemRegionCode : u32 { + Japan, + Usa, + Europe, + Australia, + HongKongTaiwanKorea, + China, +}; + +/// This is nn::settings::system::TouchScreenMode +enum class TouchScreenMode : u32 { + Stylus, + Standard, +}; + +/// This is nn::settings::system::TvResolution +enum class TvResolution : u32 { + Auto, + Resolution1080p, + Resolution720p, + Resolution480p, +}; + +constexpr std::array<LanguageCode, 18> available_language_codes = {{ + LanguageCode::JA, + LanguageCode::EN_US, + LanguageCode::FR, + LanguageCode::DE, + LanguageCode::IT, + LanguageCode::ES, + LanguageCode::ZH_CN, + LanguageCode::KO, + LanguageCode::NL, + LanguageCode::PT, + LanguageCode::RU, + LanguageCode::ZH_TW, + LanguageCode::EN_GB, + LanguageCode::FR_CA, + LanguageCode::ES_419, + LanguageCode::ZH_HANS, + LanguageCode::ZH_HANT, + LanguageCode::PT_BR, +}}; + +static constexpr std::array<std::pair<LanguageCode, KeyboardLayout>, 18> language_to_layout{{ + {LanguageCode::JA, KeyboardLayout::Japanese}, + {LanguageCode::EN_US, KeyboardLayout::EnglishUs}, + {LanguageCode::FR, KeyboardLayout::French}, + {LanguageCode::DE, KeyboardLayout::German}, + {LanguageCode::IT, KeyboardLayout::Italian}, + {LanguageCode::ES, KeyboardLayout::Spanish}, + {LanguageCode::ZH_CN, KeyboardLayout::ChineseSimplified}, + {LanguageCode::KO, KeyboardLayout::Korean}, + {LanguageCode::NL, KeyboardLayout::EnglishUsInternational}, + {LanguageCode::PT, KeyboardLayout::Portuguese}, + {LanguageCode::RU, KeyboardLayout::Russian}, + {LanguageCode::ZH_TW, KeyboardLayout::ChineseTraditional}, + {LanguageCode::EN_GB, KeyboardLayout::EnglishUk}, + {LanguageCode::FR_CA, KeyboardLayout::FrenchCa}, + {LanguageCode::ES_419, KeyboardLayout::SpanishLatin}, + {LanguageCode::ZH_HANS, KeyboardLayout::ChineseSimplified}, + {LanguageCode::ZH_HANT, KeyboardLayout::ChineseTraditional}, + {LanguageCode::PT_BR, KeyboardLayout::Portuguese}, +}}; + +/// 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::AccountSettings +struct AccountSettings { + u32 flags; +}; +static_assert(sizeof(AccountSettings) == 4, "AccountSettings is an invalid size"); + +/// This is nn::settings::system::DataDeletionFlag +struct DataDeletionFlag { + union { + u32 raw{}; + + BitField<0, 1, u32> AutomaticDeletionFlag; + }; +}; +static_assert(sizeof(DataDeletionFlag) == 4, "DataDeletionFlag 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::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::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"); + +struct PlatformConfig { + union { + u32 raw{}; + BitField<0, 1, u32> has_rail_interface; + BitField<1, 1, u32> has_sio_mcu; + }; +}; +static_assert(sizeof(PlatformConfig) == 0x4, "PlatformConfig 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::UserSelectorFlag +struct UserSelectorFlag { + union { + u32 raw{}; + + BitField<0, 1, u32> SkipIfSingleUser; + BitField<31, 1, u32> Unknown; + }; +}; +static_assert(sizeof(UserSelectorFlag) == 4, "UserSelectorFlag 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::factory::BatteryLot +struct BatteryLot { + std::array<char, 0x18> lot_number; +}; +static_assert(sizeof(BatteryLot) == 0x18, "BatteryLot is an invalid size"); + +/// This is nn::settings::system::EulaVersion +struct EulaVersion { + u32 version; + SystemRegionCode region_code; + EulaVersionClockType clock_type; + INSERT_PADDING_BYTES(0x4); + s64 posix_time; + Service::PSC::Time::SteadyClockTimePoint timestamp; +}; +static_assert(sizeof(EulaVersion) == 0x30, "EulaVersion is incorrect size"); + +struct FirmwareVersionFormat { + u8 major; + u8 minor; + u8 micro; + INSERT_PADDING_BYTES(1); + u8 revision_major; + u8 revision_minor; + INSERT_PADDING_BYTES(2); + std::array<char, 0x20> platform; + std::array<u8, 0x40> version_hash; + std::array<char, 0x18> display_version; + std::array<char, 0x80> display_title; +}; +static_assert(sizeof(FirmwareVersionFormat) == 0x100, "FirmwareVersionFormat is an invalid 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"); + +/// This is nn::settings::system::InitialLaunchSettings +struct InitialLaunchSettings { + InitialLaunchFlag flags; + INSERT_PADDING_BYTES(0x4); + Service::PSC::Time::SteadyClockTimePoint timestamp; +}; +static_assert(sizeof(InitialLaunchSettings) == 0x20, "InitialLaunchSettings is incorrect size"); + +#pragma pack(push, 4) +struct InitialLaunchSettingsPacked { + InitialLaunchFlag flags; + Service::PSC::Time::SteadyClockTimePoint timestamp; +}; +#pragma pack(pop) +static_assert(sizeof(InitialLaunchSettingsPacked) == 0x1C, + "InitialLaunchSettingsPacked is incorrect 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::factory::SerialNumber +struct SerialNumber { + std::array<char, 0x18> serial_number; +}; +static_assert(sizeof(SerialNumber) == 0x18, "SerialNumber 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::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 contrast_ratio; +}; +static_assert(sizeof(TvSettings) == 0x20, "TvSettings is an invalid size"); + +} // namespace Service::Set diff --git a/src/core/hle/service/set/system_settings.cpp b/src/core/hle/service/set/system_settings.cpp deleted file mode 100644 index 2723417ad..000000000 --- a/src/core/hle/service/set/system_settings.cpp +++ /dev/null @@ -1,51 +0,0 @@ -// 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 diff --git a/src/core/hle/service/set/system_settings.h b/src/core/hle/service/set/system_settings.h deleted file mode 100644 index ded2906ad..000000000 --- a/src/core/hle/service/set/system_settings.h +++ /dev/null @@ -1,699 +0,0 @@ -// 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 diff --git a/src/core/hle/service/set/system_settings_server.cpp b/src/core/hle/service/set/system_settings_server.cpp new file mode 100644 index 000000000..100cb2db4 --- /dev/null +++ b/src/core/hle/service/set/system_settings_server.cpp @@ -0,0 +1,1673 @@ +// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include <fstream> + +#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/settings.h" +#include "common/string_util.h" +#include "core/core.h" +#include "core/file_sys/content_archive.h" +#include "core/file_sys/errors.h" +#include "core/file_sys/nca_metadata.h" +#include "core/file_sys/registered_cache.h" +#include "core/file_sys/romfs.h" +#include "core/file_sys/system_archive/system_archive.h" +#include "core/hle/service/filesystem/filesystem.h" +#include "core/hle/service/ipc_helpers.h" +#include "core/hle/service/set/settings_server.h" +#include "core/hle/service/set/system_settings_server.h" + +namespace Service::Set { + +namespace { +constexpr u32 SETTINGS_VERSION{2u}; +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, + GetFirmwareVersionType type) { + constexpr u64 FirmwareVersionSystemDataId = 0x0100000000000809; + auto& fsc = system.GetFileSystemController(); + + // Attempt to load version data from disk + const FileSys::RegisteredCache* bis_system{}; + std::unique_ptr<FileSys::NCA> nca{}; + FileSys::VirtualDir romfs{}; + + bis_system = fsc.GetSystemNANDContents(); + if (bis_system) { + nca = bis_system->GetEntry(FirmwareVersionSystemDataId, FileSys::ContentRecordType::Data); + } + if (nca) { + if (auto nca_romfs = nca->GetRomFS(); nca_romfs) { + romfs = FileSys::ExtractRomFS(nca_romfs); + } + } + if (!romfs) { + romfs = FileSys::ExtractRomFS( + FileSys::SystemArchive::SynthesizeSystemArchive(FirmwareVersionSystemDataId)); + } + + const auto early_exit_failure = [](std::string_view desc, Result code) { + LOG_ERROR(Service_SET, "General failure while attempting to resolve firmware version ({}).", + desc); + return code; + }; + + const auto ver_file = romfs->GetFile("file"); + if (ver_file == nullptr) { + return early_exit_failure("The system version archive didn't contain the file 'file'.", + FileSys::ResultInvalidArgument); + } + + auto data = ver_file->ReadAllBytes(); + if (data.size() != sizeof(FirmwareVersionFormat)) { + return early_exit_failure("The system version file 'file' was not the correct size.", + FileSys::ResultOutOfRange); + } + + std::memcpy(&out_firmware, data.data(), sizeof(FirmwareVersionFormat)); + + // If the command is GetFirmwareVersion (as opposed to GetFirmwareVersion2), hardware will + // zero out the REVISION_MINOR field. + if (type == GetFirmwareVersionType::Version1) { + out_firmware.revision_minor = 0; + } + + return ResultSuccess; +} + +ISystemSettingsServer::ISystemSettingsServer(Core::System& system_) + : ServiceFramework{system_, "set:sys"}, m_system{system} { + // clang-format off + static const FunctionInfo functions[] = { + {0, &ISystemSettingsServer::SetLanguageCode, "SetLanguageCode"}, + {1, nullptr, "SetNetworkSettings"}, + {2, nullptr, "GetNetworkSettings"}, + {3, &ISystemSettingsServer::GetFirmwareVersion, "GetFirmwareVersion"}, + {4, &ISystemSettingsServer::GetFirmwareVersion2, "GetFirmwareVersion2"}, + {5, nullptr, "GetFirmwareVersionDigest"}, + {7, &ISystemSettingsServer::GetLockScreenFlag, "GetLockScreenFlag"}, + {8, &ISystemSettingsServer::SetLockScreenFlag, "SetLockScreenFlag"}, + {9, nullptr, "GetBacklightSettings"}, + {10, nullptr, "SetBacklightSettings"}, + {11, nullptr, "SetBluetoothDevicesSettings"}, + {12, nullptr, "GetBluetoothDevicesSettings"}, + {13, &ISystemSettingsServer::GetExternalSteadyClockSourceId, "GetExternalSteadyClockSourceId"}, + {14, &ISystemSettingsServer::SetExternalSteadyClockSourceId, "SetExternalSteadyClockSourceId"}, + {15, &ISystemSettingsServer::GetUserSystemClockContext, "GetUserSystemClockContext"}, + {16, &ISystemSettingsServer::SetUserSystemClockContext, "SetUserSystemClockContext"}, + {17, &ISystemSettingsServer::GetAccountSettings, "GetAccountSettings"}, + {18, &ISystemSettingsServer::SetAccountSettings, "SetAccountSettings"}, + {19, nullptr, "GetAudioVolume"}, + {20, nullptr, "SetAudioVolume"}, + {21, &ISystemSettingsServer::GetEulaVersions, "GetEulaVersions"}, + {22, &ISystemSettingsServer::SetEulaVersions, "SetEulaVersions"}, + {23, &ISystemSettingsServer::GetColorSetId, "GetColorSetId"}, + {24, &ISystemSettingsServer::SetColorSetId, "SetColorSetId"}, + {25, nullptr, "GetConsoleInformationUploadFlag"}, + {26, nullptr, "SetConsoleInformationUploadFlag"}, + {27, nullptr, "GetAutomaticApplicationDownloadFlag"}, + {28, nullptr, "SetAutomaticApplicationDownloadFlag"}, + {29, &ISystemSettingsServer::GetNotificationSettings, "GetNotificationSettings"}, + {30, &ISystemSettingsServer::SetNotificationSettings, "SetNotificationSettings"}, + {31, &ISystemSettingsServer::GetAccountNotificationSettings, "GetAccountNotificationSettings"}, + {32, &ISystemSettingsServer::SetAccountNotificationSettings, "SetAccountNotificationSettings"}, + {35, &ISystemSettingsServer::GetVibrationMasterVolume, "GetVibrationMasterVolume"}, + {36, &ISystemSettingsServer::SetVibrationMasterVolume, "SetVibrationMasterVolume"}, + {37, &ISystemSettingsServer::GetSettingsItemValueSize, "GetSettingsItemValueSize"}, + {38, &ISystemSettingsServer::GetSettingsItemValue, "GetSettingsItemValue"}, + {39, &ISystemSettingsServer::GetTvSettings, "GetTvSettings"}, + {40, &ISystemSettingsServer::SetTvSettings, "SetTvSettings"}, + {41, nullptr, "GetEdid"}, + {42, nullptr, "SetEdid"}, + {43, &ISystemSettingsServer::GetAudioOutputMode, "GetAudioOutputMode"}, + {44, &ISystemSettingsServer::SetAudioOutputMode, "SetAudioOutputMode"}, + {45, &ISystemSettingsServer::GetSpeakerAutoMuteFlag , "GetSpeakerAutoMuteFlag"}, + {46, &ISystemSettingsServer::SetSpeakerAutoMuteFlag , "SetSpeakerAutoMuteFlag"}, + {47, &ISystemSettingsServer::GetQuestFlag, "GetQuestFlag"}, + {48, &ISystemSettingsServer::SetQuestFlag, "SetQuestFlag"}, + {49, nullptr, "GetDataDeletionSettings"}, + {50, nullptr, "SetDataDeletionSettings"}, + {51, nullptr, "GetInitialSystemAppletProgramId"}, + {52, nullptr, "GetOverlayDispProgramId"}, + {53, &ISystemSettingsServer::GetDeviceTimeZoneLocationName, "GetDeviceTimeZoneLocationName"}, + {54, &ISystemSettingsServer::SetDeviceTimeZoneLocationName, "SetDeviceTimeZoneLocationName"}, + {55, nullptr, "GetWirelessCertificationFileSize"}, + {56, nullptr, "GetWirelessCertificationFile"}, + {57, &ISystemSettingsServer::SetRegionCode, "SetRegionCode"}, + {58, &ISystemSettingsServer::GetNetworkSystemClockContext, "GetNetworkSystemClockContext"}, + {59, &ISystemSettingsServer::SetNetworkSystemClockContext, "SetNetworkSystemClockContext"}, + {60, &ISystemSettingsServer::IsUserSystemClockAutomaticCorrectionEnabled, "IsUserSystemClockAutomaticCorrectionEnabled"}, + {61, &ISystemSettingsServer::SetUserSystemClockAutomaticCorrectionEnabled, "SetUserSystemClockAutomaticCorrectionEnabled"}, + {62, &ISystemSettingsServer::GetDebugModeFlag, "GetDebugModeFlag"}, + {63, &ISystemSettingsServer::GetPrimaryAlbumStorage, "GetPrimaryAlbumStorage"}, + {64, &ISystemSettingsServer::SetPrimaryAlbumStorage, "SetPrimaryAlbumStorage"}, + {65, nullptr, "GetUsb30EnableFlag"}, + {66, nullptr, "SetUsb30EnableFlag"}, + {67, &ISystemSettingsServer::GetBatteryLot, "GetBatteryLot"}, + {68, &ISystemSettingsServer::GetSerialNumber, "GetSerialNumber"}, + {69, &ISystemSettingsServer::GetNfcEnableFlag, "GetNfcEnableFlag"}, + {70, &ISystemSettingsServer::SetNfcEnableFlag, "SetNfcEnableFlag"}, + {71, &ISystemSettingsServer::GetSleepSettings, "GetSleepSettings"}, + {72, &ISystemSettingsServer::SetSleepSettings, "SetSleepSettings"}, + {73, &ISystemSettingsServer::GetWirelessLanEnableFlag, "GetWirelessLanEnableFlag"}, + {74, &ISystemSettingsServer::SetWirelessLanEnableFlag, "SetWirelessLanEnableFlag"}, + {75, &ISystemSettingsServer::GetInitialLaunchSettings, "GetInitialLaunchSettings"}, + {76, &ISystemSettingsServer::SetInitialLaunchSettings, "SetInitialLaunchSettings"}, + {77, &ISystemSettingsServer::GetDeviceNickName, "GetDeviceNickName"}, + {78, &ISystemSettingsServer::SetDeviceNickName, "SetDeviceNickName"}, + {79, &ISystemSettingsServer::GetProductModel, "GetProductModel"}, + {80, nullptr, "GetLdnChannel"}, + {81, nullptr, "SetLdnChannel"}, + {82, nullptr, "AcquireTelemetryDirtyFlagEventHandle"}, + {83, nullptr, "GetTelemetryDirtyFlags"}, + {84, nullptr, "GetPtmBatteryLot"}, + {85, nullptr, "SetPtmBatteryLot"}, + {86, nullptr, "GetPtmFuelGaugeParameter"}, + {87, nullptr, "SetPtmFuelGaugeParameter"}, + {88, &ISystemSettingsServer::GetBluetoothEnableFlag, "GetBluetoothEnableFlag"}, + {89, &ISystemSettingsServer::SetBluetoothEnableFlag, "SetBluetoothEnableFlag"}, + {90, &ISystemSettingsServer::GetMiiAuthorId, "GetMiiAuthorId"}, + {91, nullptr, "SetShutdownRtcValue"}, + {92, nullptr, "GetShutdownRtcValue"}, + {93, nullptr, "AcquireFatalDirtyFlagEventHandle"}, + {94, nullptr, "GetFatalDirtyFlags"}, + {95, &ISystemSettingsServer::GetAutoUpdateEnableFlag, "GetAutoUpdateEnableFlag"}, + {96, &ISystemSettingsServer::SetAutoUpdateEnableFlag, "SetAutoUpdateEnableFlag"}, + {97, nullptr, "GetNxControllerSettings"}, + {98, nullptr, "SetNxControllerSettings"}, + {99, &ISystemSettingsServer::GetBatteryPercentageFlag, "GetBatteryPercentageFlag"}, + {100, &ISystemSettingsServer::SetBatteryPercentageFlag, "SetBatteryPercentageFlag"}, + {101, nullptr, "GetExternalRtcResetFlag"}, + {102, nullptr, "SetExternalRtcResetFlag"}, + {103, nullptr, "GetUsbFullKeyEnableFlag"}, + {104, nullptr, "SetUsbFullKeyEnableFlag"}, + {105, &ISystemSettingsServer::SetExternalSteadyClockInternalOffset, "SetExternalSteadyClockInternalOffset"}, + {106, &ISystemSettingsServer::GetExternalSteadyClockInternalOffset, "GetExternalSteadyClockInternalOffset"}, + {107, nullptr, "GetBacklightSettingsEx"}, + {108, nullptr, "SetBacklightSettingsEx"}, + {109, nullptr, "GetHeadphoneVolumeWarningCount"}, + {110, nullptr, "SetHeadphoneVolumeWarningCount"}, + {111, nullptr, "GetBluetoothAfhEnableFlag"}, + {112, nullptr, "SetBluetoothAfhEnableFlag"}, + {113, nullptr, "GetBluetoothBoostEnableFlag"}, + {114, nullptr, "SetBluetoothBoostEnableFlag"}, + {115, nullptr, "GetInRepairProcessEnableFlag"}, + {116, nullptr, "SetInRepairProcessEnableFlag"}, + {117, nullptr, "GetHeadphoneVolumeUpdateFlag"}, + {118, nullptr, "SetHeadphoneVolumeUpdateFlag"}, + {119, nullptr, "NeedsToUpdateHeadphoneVolume"}, + {120, &ISystemSettingsServer::GetPushNotificationActivityModeOnSleep, "GetPushNotificationActivityModeOnSleep"}, + {121, &ISystemSettingsServer::SetPushNotificationActivityModeOnSleep, "SetPushNotificationActivityModeOnSleep"}, + {122, nullptr, "GetServiceDiscoveryControlSettings"}, + {123, nullptr, "SetServiceDiscoveryControlSettings"}, + {124, &ISystemSettingsServer::GetErrorReportSharePermission, "GetErrorReportSharePermission"}, + {125, &ISystemSettingsServer::SetErrorReportSharePermission, "SetErrorReportSharePermission"}, + {126, &ISystemSettingsServer::GetAppletLaunchFlags, "GetAppletLaunchFlags"}, + {127, &ISystemSettingsServer::SetAppletLaunchFlags, "SetAppletLaunchFlags"}, + {128, nullptr, "GetConsoleSixAxisSensorAccelerationBias"}, + {129, nullptr, "SetConsoleSixAxisSensorAccelerationBias"}, + {130, nullptr, "GetConsoleSixAxisSensorAngularVelocityBias"}, + {131, nullptr, "SetConsoleSixAxisSensorAngularVelocityBias"}, + {132, nullptr, "GetConsoleSixAxisSensorAccelerationGain"}, + {133, nullptr, "SetConsoleSixAxisSensorAccelerationGain"}, + {134, nullptr, "GetConsoleSixAxisSensorAngularVelocityGain"}, + {135, nullptr, "SetConsoleSixAxisSensorAngularVelocityGain"}, + {136, &ISystemSettingsServer::GetKeyboardLayout, "GetKeyboardLayout"}, + {137, &ISystemSettingsServer::SetKeyboardLayout, "SetKeyboardLayout"}, + {138, nullptr, "GetWebInspectorFlag"}, + {139, nullptr, "GetAllowedSslHosts"}, + {140, nullptr, "GetHostFsMountPoint"}, + {141, nullptr, "GetRequiresRunRepairTimeReviser"}, + {142, nullptr, "SetRequiresRunRepairTimeReviser"}, + {143, nullptr, "SetBlePairingSettings"}, + {144, nullptr, "GetBlePairingSettings"}, + {145, nullptr, "GetConsoleSixAxisSensorAngularVelocityTimeBias"}, + {146, nullptr, "SetConsoleSixAxisSensorAngularVelocityTimeBias"}, + {147, nullptr, "GetConsoleSixAxisSensorAngularAcceleration"}, + {148, nullptr, "SetConsoleSixAxisSensorAngularAcceleration"}, + {149, nullptr, "GetRebootlessSystemUpdateVersion"}, + {150, &ISystemSettingsServer::GetDeviceTimeZoneLocationUpdatedTime, "GetDeviceTimeZoneLocationUpdatedTime"}, + {151, &ISystemSettingsServer::SetDeviceTimeZoneLocationUpdatedTime, "SetDeviceTimeZoneLocationUpdatedTime"}, + {152, &ISystemSettingsServer::GetUserSystemClockAutomaticCorrectionUpdatedTime, "GetUserSystemClockAutomaticCorrectionUpdatedTime"}, + {153, &ISystemSettingsServer::SetUserSystemClockAutomaticCorrectionUpdatedTime, "SetUserSystemClockAutomaticCorrectionUpdatedTime"}, + {154, nullptr, "GetAccountOnlineStorageSettings"}, + {155, nullptr, "SetAccountOnlineStorageSettings"}, + {156, nullptr, "GetPctlReadyFlag"}, + {157, nullptr, "SetPctlReadyFlag"}, + {158, nullptr, "GetAnalogStickUserCalibrationL"}, + {159, nullptr, "SetAnalogStickUserCalibrationL"}, + {160, nullptr, "GetAnalogStickUserCalibrationR"}, + {161, nullptr, "SetAnalogStickUserCalibrationR"}, + {162, nullptr, "GetPtmBatteryVersion"}, + {163, nullptr, "SetPtmBatteryVersion"}, + {164, nullptr, "GetUsb30HostEnableFlag"}, + {165, nullptr, "SetUsb30HostEnableFlag"}, + {166, nullptr, "GetUsb30DeviceEnableFlag"}, + {167, nullptr, "SetUsb30DeviceEnableFlag"}, + {168, nullptr, "GetThemeId"}, + {169, nullptr, "SetThemeId"}, + {170, &ISystemSettingsServer::GetChineseTraditionalInputMethod, "GetChineseTraditionalInputMethod"}, + {171, nullptr, "SetChineseTraditionalInputMethod"}, + {172, nullptr, "GetPtmCycleCountReliability"}, + {173, nullptr, "SetPtmCycleCountReliability"}, + {174, &ISystemSettingsServer::GetHomeMenuScheme, "GetHomeMenuScheme"}, + {175, nullptr, "GetThemeSettings"}, + {176, nullptr, "SetThemeSettings"}, + {177, nullptr, "GetThemeKey"}, + {178, nullptr, "SetThemeKey"}, + {179, nullptr, "GetZoomFlag"}, + {180, nullptr, "SetZoomFlag"}, + {181, nullptr, "GetT"}, + {182, nullptr, "SetT"}, + {183, nullptr, "GetPlatformRegion"}, + {184, nullptr, "SetPlatformRegion"}, + {185, &ISystemSettingsServer::GetHomeMenuSchemeModel, "GetHomeMenuSchemeModel"}, + {186, nullptr, "GetMemoryUsageRateFlag"}, + {187, nullptr, "GetTouchScreenMode"}, + {188, nullptr, "SetTouchScreenMode"}, + {189, nullptr, "GetButtonConfigSettingsFull"}, + {190, nullptr, "SetButtonConfigSettingsFull"}, + {191, nullptr, "GetButtonConfigSettingsEmbedded"}, + {192, nullptr, "SetButtonConfigSettingsEmbedded"}, + {193, nullptr, "GetButtonConfigSettingsLeft"}, + {194, nullptr, "SetButtonConfigSettingsLeft"}, + {195, nullptr, "GetButtonConfigSettingsRight"}, + {196, nullptr, "SetButtonConfigSettingsRight"}, + {197, nullptr, "GetButtonConfigRegisteredSettingsEmbedded"}, + {198, nullptr, "SetButtonConfigRegisteredSettingsEmbedded"}, + {199, nullptr, "GetButtonConfigRegisteredSettings"}, + {200, nullptr, "SetButtonConfigRegisteredSettings"}, + {201, &ISystemSettingsServer::GetFieldTestingFlag, "GetFieldTestingFlag"}, + {202, nullptr, "SetFieldTestingFlag"}, + {203, &ISystemSettingsServer::GetPanelCrcMode, "GetPanelCrcMode"}, + {204, &ISystemSettingsServer::SetPanelCrcMode, "SetPanelCrcMode"}, + {205, nullptr, "GetNxControllerSettingsEx"}, + {206, nullptr, "SetNxControllerSettingsEx"}, + {207, nullptr, "GetHearingProtectionSafeguardFlag"}, + {208, nullptr, "SetHearingProtectionSafeguardFlag"}, + {209, nullptr, "GetHearingProtectionSafeguardRemainingTime"}, + {210, nullptr, "SetHearingProtectionSafeguardRemainingTime"}, + }; + // clang-format on + + RegisterHandlers(functions); + + SetupSettings(); + m_save_thread = + std::jthread([this](std::stop_token stop_token) { StoreSettingsThreadFunc(stop_token); }); +} + +ISystemSettingsServer::~ISystemSettingsServer() { + SetSaveNeeded(); + m_save_thread.request_stop(); +} + +bool ISystemSettingsServer::LoadSettingsFile(std::filesystem::path& path, auto&& default_func) { + using settings_type = decltype(default_func()); + + if (!Common::FS::CreateDirs(path)) { + 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 ISystemSettingsServer::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"; + std::filesystem::path 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 ISystemSettingsServer::SetLanguageCode(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + m_system_settings.language_code = rp.PopEnum<LanguageCode>(); + SetSaveNeeded(); + + LOG_INFO(Service_SET, "called, language_code={}", m_system_settings.language_code); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); +} + +void ISystemSettingsServer::GetFirmwareVersion(HLERequestContext& ctx) { + LOG_DEBUG(Service_SET, "called"); + + FirmwareVersionFormat firmware_data{}; + const auto result = + GetFirmwareVersionImpl(firmware_data, system, GetFirmwareVersionType::Version1); + + if (result.IsSuccess()) { + ctx.WriteBuffer(firmware_data); + } + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(result); +} + +void ISystemSettingsServer::GetFirmwareVersion2(HLERequestContext& ctx) { + LOG_DEBUG(Service_SET, "called"); + + FirmwareVersionFormat firmware_data{}; + const auto result = + GetFirmwareVersionImpl(firmware_data, system, GetFirmwareVersionType::Version2); + + if (result.IsSuccess()) { + ctx.WriteBuffer(firmware_data); + } + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(result); +} + +void ISystemSettingsServer::GetExternalSteadyClockSourceId(HLERequestContext& ctx) { + LOG_INFO(Service_SET, "called"); + + Common::UUID id{}; + const auto res = GetExternalSteadyClockSourceId(id); + + IPC::ResponseBuilder rb{ctx, 2 + sizeof(Common::UUID) / sizeof(u32)}; + rb.Push(res); + rb.PushRaw(id); +} + +void ISystemSettingsServer::SetExternalSteadyClockSourceId(HLERequestContext& ctx) { + LOG_INFO(Service_SET, "called"); + + IPC::RequestParser rp{ctx}; + const auto id{rp.PopRaw<Common::UUID>()}; + + const auto res = SetExternalSteadyClockSourceId(id); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(res); +} + +void ISystemSettingsServer::GetUserSystemClockContext(HLERequestContext& ctx) { + LOG_INFO(Service_SET, "called"); + + Service::PSC::Time::SystemClockContext context{}; + const auto res = GetUserSystemClockContext(context); + + IPC::ResponseBuilder rb{ctx, 2 + sizeof(Service::PSC::Time::SystemClockContext) / sizeof(u32)}; + rb.Push(res); + rb.PushRaw(context); +} + +void ISystemSettingsServer::SetUserSystemClockContext(HLERequestContext& ctx) { + LOG_INFO(Service_SET, "called"); + + IPC::RequestParser rp{ctx}; + const auto context{rp.PopRaw<Service::PSC::Time::SystemClockContext>()}; + + const auto res = SetUserSystemClockContext(context); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(res); +} + +void ISystemSettingsServer::GetLockScreenFlag(HLERequestContext& ctx) { + LOG_INFO(Service_SET, "called, lock_screen_flag={}", m_system_settings.lock_screen_flag); + + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(ResultSuccess); + rb.Push(m_system_settings.lock_screen_flag); +} + +void ISystemSettingsServer::SetLockScreenFlag(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + m_system_settings.lock_screen_flag = rp.Pop<bool>(); + SetSaveNeeded(); + + LOG_INFO(Service_SET, "called, lock_screen_flag={}", m_system_settings.lock_screen_flag); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); +} + +void ISystemSettingsServer::GetAccountSettings(HLERequestContext& ctx) { + LOG_INFO(Service_SET, "called"); + + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(ResultSuccess); + rb.PushRaw(m_system_settings.account_settings); +} + +void ISystemSettingsServer::SetAccountSettings(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + m_system_settings.account_settings = rp.PopRaw<AccountSettings>(); + SetSaveNeeded(); + + LOG_INFO(Service_SET, "called, account_settings_flags={}", + m_system_settings.account_settings.flags); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); +} + +void ISystemSettingsServer::GetEulaVersions(HLERequestContext& ctx) { + LOG_INFO(Service_SET, "called, elements={}", m_system_settings.eula_version_count); + + ctx.WriteBuffer(m_system_settings.eula_versions); + + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(ResultSuccess); + rb.Push(m_system_settings.eula_version_count); +} + +void ISystemSettingsServer::SetEulaVersions(HLERequestContext& ctx) { + const auto elements = ctx.GetReadBufferNumElements<EulaVersion>(); + const auto buffer_data = ctx.ReadBuffer(); + + LOG_INFO(Service_SET, "called, elements={}", elements); + ASSERT(elements <= m_system_settings.eula_versions.size()); + + m_system_settings.eula_version_count = static_cast<u32>(elements); + std::memcpy(&m_system_settings.eula_versions, buffer_data.data(), + sizeof(EulaVersion) * elements); + SetSaveNeeded(); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); +} + +void ISystemSettingsServer::GetColorSetId(HLERequestContext& ctx) { + LOG_DEBUG(Service_SET, "called, color_set=", m_system_settings.color_set_id); + + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(ResultSuccess); + rb.PushEnum(m_system_settings.color_set_id); +} + +void ISystemSettingsServer::SetColorSetId(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + m_system_settings.color_set_id = rp.PopEnum<ColorSet>(); + SetSaveNeeded(); + + LOG_DEBUG(Service_SET, "called, color_set={}", m_system_settings.color_set_id); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); +} + +void ISystemSettingsServer::GetNotificationSettings(HLERequestContext& ctx) { + LOG_INFO(Service_SET, "called, flags={}, volume={}, head_time={}:{}, tailt_time={}:{}", + m_system_settings.notification_settings.flags.raw, + m_system_settings.notification_settings.volume, + 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, 8}; + rb.Push(ResultSuccess); + rb.PushRaw(m_system_settings.notification_settings); +} + +void ISystemSettingsServer::SetNotificationSettings(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + m_system_settings.notification_settings = rp.PopRaw<NotificationSettings>(); + SetSaveNeeded(); + + LOG_INFO(Service_SET, "called, flags={}, volume={}, head_time={}:{}, tailt_time={}:{}", + m_system_settings.notification_settings.flags.raw, + m_system_settings.notification_settings.volume, + 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}; + rb.Push(ResultSuccess); +} + +void ISystemSettingsServer::GetAccountNotificationSettings(HLERequestContext& ctx) { + LOG_INFO(Service_SET, "called, elements={}", + m_system_settings.account_notification_settings_count); + + ctx.WriteBuffer(m_system_settings.account_notification_settings); + + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(ResultSuccess); + rb.Push(m_system_settings.account_notification_settings_count); +} + +void ISystemSettingsServer::SetAccountNotificationSettings(HLERequestContext& ctx) { + const auto elements = ctx.GetReadBufferNumElements<AccountNotificationSettings>(); + const auto buffer_data = ctx.ReadBuffer(); + + LOG_INFO(Service_SET, "called, elements={}", elements); + + ASSERT(elements <= m_system_settings.account_notification_settings.size()); + + m_system_settings.account_notification_settings_count = static_cast<u32>(elements); + std::memcpy(&m_system_settings.account_notification_settings, buffer_data.data(), + elements * sizeof(AccountNotificationSettings)); + SetSaveNeeded(); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); +} + +void ISystemSettingsServer::GetVibrationMasterVolume(HLERequestContext& ctx) { + f32 vibration_master_volume = {}; + const auto result = GetVibrationMasterVolume(vibration_master_volume); + + LOG_INFO(Service_SET, "called, master_volume={}", vibration_master_volume); + + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(result); + rb.Push(vibration_master_volume); +} + +void ISystemSettingsServer::SetVibrationMasterVolume(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + const auto vibration_master_volume = rp.PopRaw<f32>(); + + LOG_INFO(Service_SET, "called, elements={}", m_system_settings.vibration_master_volume); + + const auto result = SetVibrationMasterVolume(vibration_master_volume); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(result); +} + +// FIXME: implement support for the real system_settings.ini + +template <typename T> +static std::vector<u8> ToBytes(const T& value) { + static_assert(std::is_trivially_copyable_v<T>); + + const auto* begin = reinterpret_cast<const u8*>(&value); + const auto* end = begin + sizeof(T); + + return std::vector<u8>(begin, end); +} + +using Settings = + std::map<std::string, std::map<std::string, std::vector<u8>, std::less<>>, std::less<>>; + +static Settings GetSettings() { + Settings ret; + + // AM + ret["hbloader"]["applet_heap_size"] = ToBytes(u64{0x0}); + 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}); + + // HID + ret["hid"]["has_rail_interface"] = ToBytes(bool{true}); + ret["hid"]["has_sio_mcu"] = ToBytes(bool{true}); + ret["hid_debug"]["enables_debugpad"] = ToBytes(bool{true}); + ret["hid_debug"]["manages_devices"] = ToBytes(bool{true}); + ret["hid_debug"]["manages_touch_ic_i2c"] = ToBytes(bool{true}); + ret["hid_debug"]["emulate_future_device"] = ToBytes(bool{false}); + ret["hid_debug"]["emulate_mcu_hardware_error"] = ToBytes(bool{false}); + ret["hid_debug"]["enables_rail"] = ToBytes(bool{true}); + ret["hid_debug"]["emulate_firmware_update_failure"] = ToBytes(bool{false}); + ret["hid_debug"]["failure_firmware_update"] = ToBytes(s32{0}); + ret["hid_debug"]["ble_disabled"] = ToBytes(bool{false}); + ret["hid_debug"]["dscale_disabled"] = ToBytes(bool{false}); + ret["hid_debug"]["force_handheld"] = ToBytes(bool{true}); + ret["hid_debug"]["disabled_features_per_id"] = std::vector<u8>(0xa8); + ret["hid_debug"]["touch_firmware_auto_update_disabled"] = ToBytes(bool{false}); + + // Mii + ret["mii"]["is_db_test_mode_enabled"] = ToBytes(bool{false}); + + // Settings + ret["settings_debug"]["is_debug_mode_enabled"] = ToBytes(bool{false}); + + // Error + ret["err"]["applet_auto_close"] = ToBytes(bool{false}); + + return ret; +} + +void ISystemSettingsServer::GetSettingsItemValueSize(HLERequestContext& ctx) { + LOG_DEBUG(Service_SET, "called"); + + // The category of the setting. This corresponds to the top-level keys of + // system_settings.ini. + const auto setting_category_buf{ctx.ReadBuffer(0)}; + const std::string setting_category{Common::StringFromBuffer(setting_category_buf)}; + + // The name of the setting. This corresponds to the second-level keys of + // system_settings.ini. + const auto setting_name_buf{ctx.ReadBuffer(1)}; + const std::string setting_name{Common::StringFromBuffer(setting_name_buf)}; + + auto settings{GetSettings()}; + u64 response_size{0}; + + if (settings.contains(setting_category) && settings[setting_category].contains(setting_name)) { + response_size = settings[setting_category][setting_name].size(); + } + + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(response_size == 0 ? ResultUnknown : ResultSuccess); + rb.Push(response_size); +} + +void ISystemSettingsServer::GetSettingsItemValue(HLERequestContext& ctx) { + // The category of the setting. This corresponds to the top-level keys of + // system_settings.ini. + const auto setting_category_buf{ctx.ReadBuffer(0)}; + const std::string setting_category{Common::StringFromBuffer(setting_category_buf)}; + + // The name of the setting. This corresponds to the second-level keys of + // system_settings.ini. + const auto setting_name_buf{ctx.ReadBuffer(1)}; + const std::string setting_name{Common::StringFromBuffer(setting_name_buf)}; + + std::vector<u8> value; + auto response = GetSettingsItemValue(value, setting_category, setting_name); + + LOG_INFO(Service_SET, "called. category={}, name={} -- res=0x{:X}", setting_category, + setting_name, response.raw); + + ctx.WriteBuffer(value.data(), value.size()); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(response); +} + +void ISystemSettingsServer::GetTvSettings(HLERequestContext& ctx) { + LOG_INFO(Service_SET, + "called, flags={}, cmu_mode={}, contrast_ratio={}, hdmi_content_type={}, " + "rgb_range={}, tv_gama={}, tv_resolution={}, tv_underscan={}", + m_system_settings.tv_settings.flags.raw, m_system_settings.tv_settings.cmu_mode, + m_system_settings.tv_settings.contrast_ratio, + 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, 10}; + rb.Push(ResultSuccess); + rb.PushRaw(m_system_settings.tv_settings); +} + +void ISystemSettingsServer::SetTvSettings(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + m_system_settings.tv_settings = rp.PopRaw<TvSettings>(); + SetSaveNeeded(); + + LOG_INFO(Service_SET, + "called, flags={}, cmu_mode={}, contrast_ratio={}, hdmi_content_type={}, " + "rgb_range={}, tv_gama={}, tv_resolution={}, tv_underscan={}", + m_system_settings.tv_settings.flags.raw, m_system_settings.tv_settings.cmu_mode, + m_system_settings.tv_settings.contrast_ratio, + 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}; + rb.Push(ResultSuccess); +} + +void ISystemSettingsServer::GetAudioOutputMode(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + const auto target{rp.PopEnum<AudioOutputModeTarget>()}; + + AudioOutputMode output_mode{}; + const auto result = GetAudioOutputMode(output_mode, target); + + LOG_INFO(Service_SET, "called, target={}, output_mode={}", target, output_mode); + + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(result); + rb.PushEnum(output_mode); +} + +void ISystemSettingsServer::SetAudioOutputMode(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + const auto target{rp.PopEnum<AudioOutputModeTarget>()}; + const auto output_mode{rp.PopEnum<AudioOutputMode>()}; + + const auto result = SetAudioOutputMode(target, output_mode); + + LOG_INFO(Service_SET, "called, target={}, output_mode={}", target, output_mode); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(result); +} + +void ISystemSettingsServer::GetSpeakerAutoMuteFlag(HLERequestContext& ctx) { + LOG_INFO(Service_SET, "called, force_mute_on_headphone_removed={}", + m_system_settings.force_mute_on_headphone_removed); + + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(ResultSuccess); + rb.PushRaw(m_system_settings.force_mute_on_headphone_removed); +} + +void ISystemSettingsServer::SetSpeakerAutoMuteFlag(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + m_system_settings.force_mute_on_headphone_removed = rp.PopRaw<bool>(); + SetSaveNeeded(); + + LOG_INFO(Service_SET, "called, force_mute_on_headphone_removed={}", + m_system_settings.force_mute_on_headphone_removed); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); +} + +void ISystemSettingsServer::GetQuestFlag(HLERequestContext& ctx) { + LOG_INFO(Service_SET, "called, quest_flag={}", m_system_settings.quest_flag); + + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(ResultSuccess); + rb.PushEnum(m_system_settings.quest_flag); +} + +void ISystemSettingsServer::SetQuestFlag(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + m_system_settings.quest_flag = rp.PopEnum<QuestFlag>(); + SetSaveNeeded(); + + LOG_INFO(Service_SET, "called, quest_flag={}", m_system_settings.quest_flag); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); +} + +void ISystemSettingsServer::GetDeviceTimeZoneLocationName(HLERequestContext& ctx) { + LOG_INFO(Service_SET, "called"); + + Service::PSC::Time::LocationName name{}; + const auto res = GetDeviceTimeZoneLocationName(name); + + IPC::ResponseBuilder rb{ctx, 2 + sizeof(Service::PSC::Time::LocationName) / sizeof(u32)}; + rb.Push(res); + rb.PushRaw<Service::PSC::Time::LocationName>(name); +} + +void ISystemSettingsServer::SetDeviceTimeZoneLocationName(HLERequestContext& ctx) { + LOG_INFO(Service_SET, "called"); + + IPC::RequestParser rp{ctx}; + auto name{rp.PopRaw<Service::PSC::Time::LocationName>()}; + + const auto res = SetDeviceTimeZoneLocationName(name); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(res); +} + +void ISystemSettingsServer::SetRegionCode(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + m_system_settings.region_code = rp.PopEnum<SystemRegionCode>(); + SetSaveNeeded(); + + LOG_INFO(Service_SET, "called, region_code={}", m_system_settings.region_code); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); +} + +void ISystemSettingsServer::GetNetworkSystemClockContext(HLERequestContext& ctx) { + LOG_INFO(Service_SET, "called"); + + Service::PSC::Time::SystemClockContext context{}; + const auto res = GetNetworkSystemClockContext(context); + + IPC::ResponseBuilder rb{ctx, 2 + sizeof(Service::PSC::Time::SystemClockContext) / sizeof(u32)}; + rb.Push(res); + rb.PushRaw(context); +} + +void ISystemSettingsServer::SetNetworkSystemClockContext(HLERequestContext& ctx) { + LOG_INFO(Service_SET, "called"); + + IPC::RequestParser rp{ctx}; + const auto context{rp.PopRaw<Service::PSC::Time::SystemClockContext>()}; + + const auto res = SetNetworkSystemClockContext(context); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(res); +} + +void ISystemSettingsServer::IsUserSystemClockAutomaticCorrectionEnabled(HLERequestContext& ctx) { + LOG_INFO(Service_SET, "called"); + + bool enabled{}; + const auto res = IsUserSystemClockAutomaticCorrectionEnabled(enabled); + + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(res); + rb.PushRaw(enabled); +} + +void ISystemSettingsServer::SetUserSystemClockAutomaticCorrectionEnabled(HLERequestContext& ctx) { + LOG_INFO(Service_SET, "called"); + + IPC::RequestParser rp{ctx}; + auto enabled{rp.Pop<bool>()}; + + const auto res = SetUserSystemClockAutomaticCorrectionEnabled(enabled); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(res); +} + +void ISystemSettingsServer::GetDebugModeFlag(HLERequestContext& ctx) { + bool is_debug_mode_enabled = false; + GetSettingsItemValue<bool>(is_debug_mode_enabled, "settings_debug", "is_debug_mode_enabled"); + + LOG_DEBUG(Service_SET, "called, is_debug_mode_enabled={}", is_debug_mode_enabled); + + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(ResultSuccess); + rb.Push(is_debug_mode_enabled); +} + +void ISystemSettingsServer::GetPrimaryAlbumStorage(HLERequestContext& ctx) { + LOG_INFO(Service_SET, "called, primary_album_storage={}", + m_system_settings.primary_album_storage); + + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(ResultSuccess); + rb.PushEnum(m_system_settings.primary_album_storage); +} + +void ISystemSettingsServer::SetPrimaryAlbumStorage(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + m_system_settings.primary_album_storage = rp.PopEnum<PrimaryAlbumStorage>(); + SetSaveNeeded(); + + LOG_INFO(Service_SET, "called, primary_album_storage={}", + m_system_settings.primary_album_storage); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); +} + +void ISystemSettingsServer::GetBatteryLot(HLERequestContext& ctx) { + BatteryLot battery_lot = {"YUZUEMULATOR123456789"}; + + LOG_INFO(Service_SET, "called"); + + IPC::ResponseBuilder rb{ctx, 8}; + rb.Push(ResultSuccess); + rb.PushRaw(battery_lot); +} + +void ISystemSettingsServer::GetSerialNumber(HLERequestContext& ctx) { + SerialNumber console_serial = {"YUZ10012345678"}; + + LOG_INFO(Service_SET, "called"); + + IPC::ResponseBuilder rb{ctx, 8}; + rb.Push(ResultSuccess); + rb.PushRaw(console_serial); +} + +void ISystemSettingsServer::GetNfcEnableFlag(HLERequestContext& ctx) { + LOG_INFO(Service_SET, "called, nfc_enable_flag={}", m_system_settings.nfc_enable_flag); + + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(ResultSuccess); + rb.Push<u8>(m_system_settings.nfc_enable_flag); +} + +void ISystemSettingsServer::SetNfcEnableFlag(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + m_system_settings.nfc_enable_flag = rp.Pop<bool>(); + SetSaveNeeded(); + + LOG_INFO(Service_SET, "called, nfc_enable_flag={}", m_system_settings.nfc_enable_flag); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); +} + +void ISystemSettingsServer::GetSleepSettings(HLERequestContext& ctx) { + LOG_INFO(Service_SET, "called, flags={}, handheld_sleep_plan={}, console_sleep_plan={}", + m_system_settings.sleep_settings.flags.raw, + m_system_settings.sleep_settings.handheld_sleep_plan, + m_system_settings.sleep_settings.console_sleep_plan); + + IPC::ResponseBuilder rb{ctx, 5}; + rb.Push(ResultSuccess); + rb.PushRaw(m_system_settings.sleep_settings); +} + +void ISystemSettingsServer::SetSleepSettings(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + m_system_settings.sleep_settings = rp.PopRaw<SleepSettings>(); + SetSaveNeeded(); + + LOG_INFO(Service_SET, "called, flags={}, handheld_sleep_plan={}, console_sleep_plan={}", + m_system_settings.sleep_settings.flags.raw, + m_system_settings.sleep_settings.handheld_sleep_plan, + m_system_settings.sleep_settings.console_sleep_plan); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); +} + +void ISystemSettingsServer::GetWirelessLanEnableFlag(HLERequestContext& ctx) { + LOG_INFO(Service_SET, "called, wireless_lan_enable_flag={}", + m_system_settings.wireless_lan_enable_flag); + + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(ResultSuccess); + rb.Push(m_system_settings.wireless_lan_enable_flag); +} + +void ISystemSettingsServer::SetWirelessLanEnableFlag(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + m_system_settings.wireless_lan_enable_flag = rp.Pop<bool>(); + SetSaveNeeded(); + + LOG_INFO(Service_SET, "called, wireless_lan_enable_flag={}", + m_system_settings.wireless_lan_enable_flag); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); +} + +void ISystemSettingsServer::GetInitialLaunchSettings(HLERequestContext& ctx) { + 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, 10}; + rb.Push(ResultSuccess); + rb.PushRaw(m_system_settings.initial_launch_settings_packed); +} + +void ISystemSettingsServer::SetInitialLaunchSettings(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + auto initial_launch_settings = rp.PopRaw<InitialLaunchSettings>(); + + m_system_settings.initial_launch_settings_packed.flags = initial_launch_settings.flags; + m_system_settings.initial_launch_settings_packed.timestamp = initial_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}; + rb.Push(ResultSuccess); +} + +void ISystemSettingsServer::GetDeviceNickName(HLERequestContext& ctx) { + LOG_DEBUG(Service_SET, "called"); + + ctx.WriteBuffer(::Settings::values.device_name.GetValue()); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); +} + +void ISystemSettingsServer::SetDeviceNickName(HLERequestContext& ctx) { + const std::string device_name = Common::StringFromBuffer(ctx.ReadBuffer()); + + LOG_INFO(Service_SET, "called, device_name={}", device_name); + + ::Settings::values.device_name = device_name; + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); +} + +void ISystemSettingsServer::GetProductModel(HLERequestContext& ctx) { + const u32 product_model = 1; + + LOG_WARNING(Service_SET, "(STUBBED) called, product_model={}", product_model); + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(ResultSuccess); + rb.Push(product_model); +} + +void ISystemSettingsServer::GetBluetoothEnableFlag(HLERequestContext& ctx) { + LOG_INFO(Service_SET, "called, bluetooth_enable_flag={}", + m_system_settings.bluetooth_enable_flag); + + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(ResultSuccess); + rb.Push<u8>(m_system_settings.bluetooth_enable_flag); +} + +void ISystemSettingsServer::SetBluetoothEnableFlag(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + m_system_settings.bluetooth_enable_flag = rp.Pop<bool>(); + SetSaveNeeded(); + + LOG_INFO(Service_SET, "called, bluetooth_enable_flag={}", + m_system_settings.bluetooth_enable_flag); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); +} + +void ISystemSettingsServer::GetMiiAuthorId(HLERequestContext& ctx) { + if (m_system_settings.mii_author_id.IsInvalid()) { + m_system_settings.mii_author_id = Common::UUID::MakeDefault(); + SetSaveNeeded(); + } + + LOG_INFO(Service_SET, "called, author_id={}", + m_system_settings.mii_author_id.FormattedString()); + + IPC::ResponseBuilder rb{ctx, 6}; + rb.Push(ResultSuccess); + rb.PushRaw(m_system_settings.mii_author_id); +} + +void ISystemSettingsServer::GetAutoUpdateEnableFlag(HLERequestContext& ctx) { + LOG_INFO(Service_SET, "called, auto_update_flag={}", m_system_settings.auto_update_enable_flag); + + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(ResultSuccess); + rb.Push(m_system_settings.auto_update_enable_flag); +} + +void ISystemSettingsServer::SetAutoUpdateEnableFlag(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + m_system_settings.auto_update_enable_flag = rp.Pop<bool>(); + SetSaveNeeded(); + + LOG_INFO(Service_SET, "called, auto_update_flag={}", m_system_settings.auto_update_enable_flag); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); +} + +void ISystemSettingsServer::GetBatteryPercentageFlag(HLERequestContext& ctx) { + LOG_DEBUG(Service_SET, "called, battery_percentage_flag={}", + m_system_settings.battery_percentage_flag); + + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(ResultSuccess); + rb.Push(m_system_settings.battery_percentage_flag); +} + +void ISystemSettingsServer::SetBatteryPercentageFlag(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + m_system_settings.battery_percentage_flag = rp.Pop<bool>(); + SetSaveNeeded(); + + LOG_INFO(Service_SET, "called, battery_percentage_flag={}", + m_system_settings.battery_percentage_flag); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); +} + +void ISystemSettingsServer::SetExternalSteadyClockInternalOffset(HLERequestContext& ctx) { + LOG_DEBUG(Service_SET, "called."); + + IPC::RequestParser rp{ctx}; + auto offset{rp.Pop<s64>()}; + + const auto res = SetExternalSteadyClockInternalOffset(offset); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(res); +} + +void ISystemSettingsServer::GetExternalSteadyClockInternalOffset(HLERequestContext& ctx) { + LOG_DEBUG(Service_SET, "called."); + + s64 offset{}; + const auto res = GetExternalSteadyClockInternalOffset(offset); + + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(res); + rb.Push(offset); +} + +void ISystemSettingsServer::GetPushNotificationActivityModeOnSleep(HLERequestContext& ctx) { + LOG_INFO(Service_SET, "called, push_notification_activity_mode_on_sleep={}", + m_system_settings.push_notification_activity_mode_on_sleep); + + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(ResultSuccess); + rb.Push(m_system_settings.push_notification_activity_mode_on_sleep); +} + +void ISystemSettingsServer::SetPushNotificationActivityModeOnSleep(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + m_system_settings.push_notification_activity_mode_on_sleep = rp.Pop<s32>(); + SetSaveNeeded(); + + LOG_INFO(Service_SET, "called, push_notification_activity_mode_on_sleep={}", + m_system_settings.push_notification_activity_mode_on_sleep); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); +} + +void ISystemSettingsServer::GetErrorReportSharePermission(HLERequestContext& ctx) { + LOG_INFO(Service_SET, "called, error_report_share_permission={}", + m_system_settings.error_report_share_permission); + + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(ResultSuccess); + rb.PushEnum(m_system_settings.error_report_share_permission); +} + +void ISystemSettingsServer::SetErrorReportSharePermission(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + m_system_settings.error_report_share_permission = rp.PopEnum<ErrorReportSharePermission>(); + SetSaveNeeded(); + + LOG_INFO(Service_SET, "called, error_report_share_permission={}", + m_system_settings.error_report_share_permission); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); +} + +void ISystemSettingsServer::GetAppletLaunchFlags(HLERequestContext& ctx) { + LOG_INFO(Service_SET, "called, applet_launch_flag={}", m_system_settings.applet_launch_flag); + + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(ResultSuccess); + rb.Push(m_system_settings.applet_launch_flag); +} + +void ISystemSettingsServer::SetAppletLaunchFlags(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + m_system_settings.applet_launch_flag = rp.Pop<u32>(); + SetSaveNeeded(); + + LOG_INFO(Service_SET, "called, applet_launch_flag={}", m_system_settings.applet_launch_flag); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); +} + +void ISystemSettingsServer::GetKeyboardLayout(HLERequestContext& ctx) { + LOG_INFO(Service_SET, "called, keyboard_layout={}", m_system_settings.keyboard_layout); + + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(ResultSuccess); + rb.Push(static_cast<u32>(m_system_settings.keyboard_layout)); +} + +void ISystemSettingsServer::SetKeyboardLayout(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + m_system_settings.keyboard_layout = rp.PopRaw<KeyboardLayout>(); + SetSaveNeeded(); + + LOG_INFO(Service_SET, "called, keyboard_layout={}", m_system_settings.keyboard_layout); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); +} + +void ISystemSettingsServer::GetDeviceTimeZoneLocationUpdatedTime(HLERequestContext& ctx) { + LOG_INFO(Service_SET, "called"); + + Service::PSC::Time::SteadyClockTimePoint time_point{}; + const auto res = GetDeviceTimeZoneLocationUpdatedTime(time_point); + + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(res); + rb.PushRaw<Service::PSC::Time::SteadyClockTimePoint>(time_point); +} + +void ISystemSettingsServer::SetDeviceTimeZoneLocationUpdatedTime(HLERequestContext& ctx) { + LOG_INFO(Service_SET, "called"); + + IPC::RequestParser rp{ctx}; + auto time_point{rp.PopRaw<Service::PSC::Time::SteadyClockTimePoint>()}; + + const auto res = SetDeviceTimeZoneLocationUpdatedTime(time_point); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(res); +} + +void ISystemSettingsServer::GetUserSystemClockAutomaticCorrectionUpdatedTime( + HLERequestContext& ctx) { + LOG_INFO(Service_SET, "called"); + + Service::PSC::Time::SteadyClockTimePoint time_point{}; + const auto res = GetUserSystemClockAutomaticCorrectionUpdatedTime(time_point); + + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(res); + rb.PushRaw<Service::PSC::Time::SteadyClockTimePoint>(time_point); +} + +void ISystemSettingsServer::SetUserSystemClockAutomaticCorrectionUpdatedTime( + HLERequestContext& ctx) { + LOG_INFO(Service_SET, "called"); + + IPC::RequestParser rp{ctx}; + const auto time_point{rp.PopRaw<Service::PSC::Time::SteadyClockTimePoint>()}; + + const auto res = SetUserSystemClockAutomaticCorrectionUpdatedTime(time_point); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(res); +} + +void ISystemSettingsServer::GetChineseTraditionalInputMethod(HLERequestContext& ctx) { + LOG_INFO(Service_SET, "called, chinese_traditional_input_method={}", + m_system_settings.chinese_traditional_input_method); + + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(ResultSuccess); + rb.PushEnum(m_system_settings.chinese_traditional_input_method); +} + +void ISystemSettingsServer::GetHomeMenuScheme(HLERequestContext& ctx) { + LOG_DEBUG(Service_SET, "(STUBBED) called"); + + const HomeMenuScheme default_color = { + .main = 0xFF323232, + .back = 0xFF323232, + .sub = 0xFFFFFFFF, + .bezel = 0xFFFFFFFF, + .extra = 0xFF000000, + }; + + IPC::ResponseBuilder rb{ctx, 2 + sizeof(HomeMenuScheme) / sizeof(u32)}; + rb.Push(ResultSuccess); + rb.PushRaw(default_color); +} + +void ISystemSettingsServer::GetHomeMenuSchemeModel(HLERequestContext& ctx) { + LOG_WARNING(Service_SET, "(STUBBED) called"); + + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(ResultSuccess); + rb.Push(0); +} + +void ISystemSettingsServer::GetFieldTestingFlag(HLERequestContext& ctx) { + LOG_INFO(Service_SET, "called, field_testing_flag={}", m_system_settings.field_testing_flag); + + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(ResultSuccess); + rb.Push(m_system_settings.field_testing_flag); +} + +void ISystemSettingsServer::GetPanelCrcMode(HLERequestContext& ctx) { + LOG_INFO(Service_SET, "called, panel_crc_mode={}", m_system_settings.panel_crc_mode); + + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(ResultSuccess); + rb.Push(m_system_settings.panel_crc_mode); +} + +void ISystemSettingsServer::SetPanelCrcMode(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + m_system_settings.panel_crc_mode = rp.PopRaw<s32>(); + SetSaveNeeded(); + + LOG_INFO(Service_SET, "called, panel_crc_mode={}", m_system_settings.panel_crc_mode); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); +} + +void ISystemSettingsServer::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 ISystemSettingsServer::StoreSettings() { + auto system_dir = + Common::FS::GetYuzuPath(Common::FS::YuzuPath::NANDDir) / "system/save/8000000000000050"; + if (!StoreSettingsFile(system_dir, m_system_settings)) { + LOG_ERROR(Service_SET, "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(Service_SET, "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(Service_SET, "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(Service_SET, "Failed to store ApplLn settings"); + } +} + +void ISystemSettingsServer::StoreSettingsThreadFunc(std::stop_token stop_token) { + Common::SetCurrentThreadName("SettingsStore"); + + 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 ISystemSettingsServer::SetSaveNeeded() { + std::scoped_lock l{m_save_needed_mutex}; + m_save_needed = true; +} + +Result ISystemSettingsServer::GetSettingsItemValue(std::vector<u8>& out_value, + const std::string& category, + const std::string& name) { + auto settings{GetSettings()}; + R_UNLESS(settings.contains(category) && settings[category].contains(name), ResultUnknown); + + out_value = settings[category][name]; + R_SUCCEED(); +} + +Result ISystemSettingsServer::GetVibrationMasterVolume(f32& out_volume) const { + out_volume = m_system_settings.vibration_master_volume; + R_SUCCEED(); +} + +Result ISystemSettingsServer::SetVibrationMasterVolume(f32 volume) { + m_system_settings.vibration_master_volume = volume; + SetSaveNeeded(); + R_SUCCEED(); +} + +Result ISystemSettingsServer::GetAudioOutputMode(AudioOutputMode& out_output_mode, + AudioOutputModeTarget target) const { + switch (target) { + case AudioOutputModeTarget::Hdmi: + out_output_mode = m_system_settings.audio_output_mode_hdmi; + break; + case AudioOutputModeTarget::Speaker: + out_output_mode = m_system_settings.audio_output_mode_speaker; + break; + case AudioOutputModeTarget::Headphone: + out_output_mode = m_system_settings.audio_output_mode_headphone; + break; + case AudioOutputModeTarget::Type3: + out_output_mode = m_system_settings.audio_output_mode_type3; + break; + case AudioOutputModeTarget::Type4: + out_output_mode = m_system_settings.audio_output_mode_type4; + break; + default: + LOG_ERROR(Service_SET, "Invalid audio output mode target {}", target); + } + R_SUCCEED(); +} + +Result ISystemSettingsServer::SetAudioOutputMode(AudioOutputModeTarget target, + AudioOutputMode output_mode) { + switch (target) { + case AudioOutputModeTarget::Hdmi: + m_system_settings.audio_output_mode_hdmi = output_mode; + break; + case AudioOutputModeTarget::Speaker: + m_system_settings.audio_output_mode_speaker = output_mode; + break; + case AudioOutputModeTarget::Headphone: + m_system_settings.audio_output_mode_headphone = output_mode; + break; + case AudioOutputModeTarget::Type3: + m_system_settings.audio_output_mode_type3 = output_mode; + break; + case AudioOutputModeTarget::Type4: + m_system_settings.audio_output_mode_type4 = output_mode; + break; + default: + LOG_ERROR(Service_SET, "Invalid audio output mode target {}", target); + } + SetSaveNeeded(); + R_SUCCEED(); +} + +Result ISystemSettingsServer::GetSpeakerAutoMuteFlag(bool& is_auto_mute) const { + is_auto_mute = m_system_settings.force_mute_on_headphone_removed; + R_SUCCEED(); +} + +Result ISystemSettingsServer::SetSpeakerAutoMuteFlag(bool is_auto_mute) { + m_system_settings.force_mute_on_headphone_removed = is_auto_mute; + SetSaveNeeded(); + R_SUCCEED(); +} + +Result ISystemSettingsServer::GetExternalSteadyClockSourceId(Common::UUID& out_id) const { + out_id = m_private_settings.external_clock_source_id; + R_SUCCEED(); +} + +Result ISystemSettingsServer::SetExternalSteadyClockSourceId(const Common::UUID& id) { + m_private_settings.external_clock_source_id = id; + SetSaveNeeded(); + R_SUCCEED(); +} + +Result ISystemSettingsServer::GetUserSystemClockContext( + Service::PSC::Time::SystemClockContext& out_context) const { + out_context = m_system_settings.user_system_clock_context; + R_SUCCEED(); +} + +Result ISystemSettingsServer::SetUserSystemClockContext( + const Service::PSC::Time::SystemClockContext& context) { + m_system_settings.user_system_clock_context = context; + SetSaveNeeded(); + R_SUCCEED(); +} + +Result ISystemSettingsServer::GetDeviceTimeZoneLocationName( + Service::PSC::Time::LocationName& out_name) const { + out_name = m_system_settings.device_time_zone_location_name; + R_SUCCEED(); +} + +Result ISystemSettingsServer::SetDeviceTimeZoneLocationName( + const Service::PSC::Time::LocationName& name) { + m_system_settings.device_time_zone_location_name = name; + SetSaveNeeded(); + R_SUCCEED(); +} + +Result ISystemSettingsServer::GetNetworkSystemClockContext( + Service::PSC::Time::SystemClockContext& out_context) const { + out_context = m_system_settings.network_system_clock_context; + R_SUCCEED(); +} + +Result ISystemSettingsServer::SetNetworkSystemClockContext( + const Service::PSC::Time::SystemClockContext& context) { + m_system_settings.network_system_clock_context = context; + SetSaveNeeded(); + R_SUCCEED(); +} + +Result ISystemSettingsServer::IsUserSystemClockAutomaticCorrectionEnabled(bool& out_enabled) const { + out_enabled = m_system_settings.user_system_clock_automatic_correction_enabled; + R_SUCCEED(); +} + +Result ISystemSettingsServer::SetUserSystemClockAutomaticCorrectionEnabled(bool enabled) { + m_system_settings.user_system_clock_automatic_correction_enabled = enabled; + SetSaveNeeded(); + R_SUCCEED(); +} + +Result ISystemSettingsServer::SetExternalSteadyClockInternalOffset(s64 offset) { + m_private_settings.external_steady_clock_internal_offset = offset; + SetSaveNeeded(); + R_SUCCEED(); +} + +Result ISystemSettingsServer::GetExternalSteadyClockInternalOffset(s64& out_offset) const { + out_offset = m_private_settings.external_steady_clock_internal_offset; + R_SUCCEED(); +} + +Result ISystemSettingsServer::GetDeviceTimeZoneLocationUpdatedTime( + Service::PSC::Time::SteadyClockTimePoint& out_time_point) const { + out_time_point = m_system_settings.device_time_zone_location_updated_time; + R_SUCCEED(); +} + +Result ISystemSettingsServer::SetDeviceTimeZoneLocationUpdatedTime( + const Service::PSC::Time::SteadyClockTimePoint& time_point) { + m_system_settings.device_time_zone_location_updated_time = time_point; + SetSaveNeeded(); + R_SUCCEED(); +} + +Result ISystemSettingsServer::GetUserSystemClockAutomaticCorrectionUpdatedTime( + Service::PSC::Time::SteadyClockTimePoint& out_time_point) const { + out_time_point = m_system_settings.user_system_clock_automatic_correction_updated_time_point; + R_SUCCEED(); +} + +Result ISystemSettingsServer::SetUserSystemClockAutomaticCorrectionUpdatedTime( + const Service::PSC::Time::SteadyClockTimePoint& out_time_point) { + m_system_settings.user_system_clock_automatic_correction_updated_time_point = out_time_point; + SetSaveNeeded(); + R_SUCCEED(); +} + +} // namespace Service::Set diff --git a/src/core/hle/service/set/system_settings_server.h b/src/core/hle/service/set/system_settings_server.h new file mode 100644 index 000000000..1982b9723 --- /dev/null +++ b/src/core/hle/service/set/system_settings_server.h @@ -0,0 +1,178 @@ +// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include <filesystem> +#include <mutex> +#include <string> +#include <thread> + +#include "common/polyfill_thread.h" +#include "common/uuid.h" +#include "core/hle/result.h" +#include "core/hle/service/psc/time/common.h" +#include "core/hle/service/service.h" +#include "core/hle/service/set/setting_formats/appln_settings.h" +#include "core/hle/service/set/setting_formats/device_settings.h" +#include "core/hle/service/set/setting_formats/private_settings.h" +#include "core/hle/service/set/setting_formats/system_settings.h" +#include "core/hle/service/set/settings_types.h" + +namespace Core { +class System; +} + +namespace Service::Set { + +Result GetFirmwareVersionImpl(FirmwareVersionFormat& out_firmware, Core::System& system, + GetFirmwareVersionType type); + +class ISystemSettingsServer final : public ServiceFramework<ISystemSettingsServer> { +public: + explicit ISystemSettingsServer(Core::System& system_); + ~ISystemSettingsServer() override; + + Result GetSettingsItemValue(std::vector<u8>& out_value, const std::string& category, + const std::string& name); + + template <typename T> + Result GetSettingsItemValue(T& value, const std::string& category, const std::string& name) { + std::vector<u8> data; + const auto result = GetSettingsItemValue(data, category, name); + if (result.IsError()) { + return result; + } + ASSERT(data.size() >= sizeof(T)); + std::memcpy(&value, data.data(), sizeof(T)); + return result; + } + + Result GetVibrationMasterVolume(f32& out_volume) const; + Result SetVibrationMasterVolume(f32 volume); + Result GetAudioOutputMode(AudioOutputMode& out_output_mode, AudioOutputModeTarget target) const; + Result SetAudioOutputMode(AudioOutputModeTarget target, AudioOutputMode output_mode); + Result GetSpeakerAutoMuteFlag(bool& is_auto_mute) const; + Result SetSpeakerAutoMuteFlag(bool auto_mute); + Result GetExternalSteadyClockSourceId(Common::UUID& out_id) const; + Result SetExternalSteadyClockSourceId(const Common::UUID& id); + Result GetUserSystemClockContext(Service::PSC::Time::SystemClockContext& out_context) const; + Result SetUserSystemClockContext(const Service::PSC::Time::SystemClockContext& context); + Result GetDeviceTimeZoneLocationName(Service::PSC::Time::LocationName& out_name) const; + Result SetDeviceTimeZoneLocationName(const Service::PSC::Time::LocationName& name); + Result GetNetworkSystemClockContext(Service::PSC::Time::SystemClockContext& out_context) const; + Result SetNetworkSystemClockContext(const Service::PSC::Time::SystemClockContext& context); + Result IsUserSystemClockAutomaticCorrectionEnabled(bool& out_enabled) const; + Result SetUserSystemClockAutomaticCorrectionEnabled(bool enabled); + Result SetExternalSteadyClockInternalOffset(s64 offset); + Result GetExternalSteadyClockInternalOffset(s64& out_offset) const; + Result GetDeviceTimeZoneLocationUpdatedTime( + Service::PSC::Time::SteadyClockTimePoint& out_time_point) const; + Result SetDeviceTimeZoneLocationUpdatedTime( + const Service::PSC::Time::SteadyClockTimePoint& time_point); + Result GetUserSystemClockAutomaticCorrectionUpdatedTime( + Service::PSC::Time::SteadyClockTimePoint& out_time_point) const; + Result SetUserSystemClockAutomaticCorrectionUpdatedTime( + const Service::PSC::Time::SteadyClockTimePoint& time_point); + +private: + void SetLanguageCode(HLERequestContext& ctx); + void GetFirmwareVersion(HLERequestContext& ctx); + void GetFirmwareVersion2(HLERequestContext& ctx); + void GetLockScreenFlag(HLERequestContext& ctx); + void SetLockScreenFlag(HLERequestContext& ctx); + void GetExternalSteadyClockSourceId(HLERequestContext& ctx); + void SetExternalSteadyClockSourceId(HLERequestContext& ctx); + void GetUserSystemClockContext(HLERequestContext& ctx); + void SetUserSystemClockContext(HLERequestContext& ctx); + void GetAccountSettings(HLERequestContext& ctx); + void SetAccountSettings(HLERequestContext& ctx); + void GetEulaVersions(HLERequestContext& ctx); + void SetEulaVersions(HLERequestContext& ctx); + void GetColorSetId(HLERequestContext& ctx); + void SetColorSetId(HLERequestContext& ctx); + void GetNotificationSettings(HLERequestContext& ctx); + void SetNotificationSettings(HLERequestContext& ctx); + void GetAccountNotificationSettings(HLERequestContext& ctx); + void SetAccountNotificationSettings(HLERequestContext& ctx); + void GetVibrationMasterVolume(HLERequestContext& ctx); + void SetVibrationMasterVolume(HLERequestContext& ctx); + void GetSettingsItemValueSize(HLERequestContext& ctx); + void GetSettingsItemValue(HLERequestContext& ctx); + void GetTvSettings(HLERequestContext& ctx); + void SetTvSettings(HLERequestContext& ctx); + void GetAudioOutputMode(HLERequestContext& ctx); + void SetAudioOutputMode(HLERequestContext& ctx); + void GetSpeakerAutoMuteFlag(HLERequestContext& ctx); + void SetSpeakerAutoMuteFlag(HLERequestContext& ctx); + void GetDebugModeFlag(HLERequestContext& ctx); + void GetQuestFlag(HLERequestContext& ctx); + void SetQuestFlag(HLERequestContext& ctx); + void GetDeviceTimeZoneLocationName(HLERequestContext& ctx); + void SetDeviceTimeZoneLocationName(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 SetPrimaryAlbumStorage(HLERequestContext& ctx); + void GetBatteryLot(HLERequestContext& ctx); + void GetSerialNumber(HLERequestContext& ctx); + void GetNfcEnableFlag(HLERequestContext& ctx); + void SetNfcEnableFlag(HLERequestContext& ctx); + void GetSleepSettings(HLERequestContext& ctx); + void SetSleepSettings(HLERequestContext& ctx); + void GetWirelessLanEnableFlag(HLERequestContext& ctx); + void SetWirelessLanEnableFlag(HLERequestContext& ctx); + void GetInitialLaunchSettings(HLERequestContext& ctx); + void SetInitialLaunchSettings(HLERequestContext& ctx); + void GetDeviceNickName(HLERequestContext& ctx); + void SetDeviceNickName(HLERequestContext& ctx); + void GetProductModel(HLERequestContext& ctx); + void GetBluetoothEnableFlag(HLERequestContext& ctx); + void SetBluetoothEnableFlag(HLERequestContext& ctx); + void GetMiiAuthorId(HLERequestContext& ctx); + void GetAutoUpdateEnableFlag(HLERequestContext& ctx); + void SetAutoUpdateEnableFlag(HLERequestContext& ctx); + void GetBatteryPercentageFlag(HLERequestContext& ctx); + void SetBatteryPercentageFlag(HLERequestContext& ctx); + void SetExternalSteadyClockInternalOffset(HLERequestContext& ctx); + void GetExternalSteadyClockInternalOffset(HLERequestContext& ctx); + void GetPushNotificationActivityModeOnSleep(HLERequestContext& ctx); + void SetPushNotificationActivityModeOnSleep(HLERequestContext& ctx); + void GetErrorReportSharePermission(HLERequestContext& ctx); + void SetErrorReportSharePermission(HLERequestContext& ctx); + void GetAppletLaunchFlags(HLERequestContext& ctx); + void SetAppletLaunchFlags(HLERequestContext& ctx); + void GetKeyboardLayout(HLERequestContext& ctx); + void SetKeyboardLayout(HLERequestContext& ctx); + void GetDeviceTimeZoneLocationUpdatedTime(HLERequestContext& ctx); + void SetDeviceTimeZoneLocationUpdatedTime(HLERequestContext& ctx); + void GetUserSystemClockAutomaticCorrectionUpdatedTime(HLERequestContext& ctx); + void SetUserSystemClockAutomaticCorrectionUpdatedTime(HLERequestContext& ctx); + void GetChineseTraditionalInputMethod(HLERequestContext& ctx); + void GetHomeMenuScheme(HLERequestContext& ctx); + void GetHomeMenuSchemeModel(HLERequestContext& ctx); + void GetFieldTestingFlag(HLERequestContext& ctx); + void GetPanelCrcMode(HLERequestContext& ctx); + void SetPanelCrcMode(HLERequestContext& ctx); + + bool LoadSettingsFile(std::filesystem::path& path, auto&& default_func); + bool StoreSettingsFile(std::filesystem::path& path, auto& settings); + void SetupSettings(); + void StoreSettings(); + void StoreSettingsThreadFunc(std::stop_token stop_token); + void SetSaveNeeded(); + + Core::System& m_system; + SystemSettings m_system_settings{}; + PrivateSettings m_private_settings{}; + DeviceSettings m_device_settings{}; + ApplnSettings m_appln_settings{}; + std::mutex m_save_needed_mutex; + std::jthread m_save_thread; + bool m_save_needed{false}; +}; + +} // namespace Service::Set |