diff options
Diffstat (limited to 'src/core')
30 files changed, 1223 insertions, 818 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 0f713ead1..4ff2c1bb7 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -716,22 +716,23 @@ add_library(core STATIC hle/service/server_manager.h hle/service/service.cpp hle/service/service.h - hle/service/set/appln_settings.cpp - hle/service/set/appln_settings.h - hle/service/set/device_settings.cpp - hle/service/set/device_settings.h + hle/service/set/setting_formats/appln_settings.cpp + hle/service/set/setting_formats/appln_settings.h + hle/service/set/setting_formats/device_settings.cpp + hle/service/set/setting_formats/device_settings.h + hle/service/set/setting_formats/system_settings.cpp + hle/service/set/setting_formats/system_settings.h + hle/service/set/setting_formats/private_settings.cpp + hle/service/set/setting_formats/private_settings.h hle/service/set/factory_settings_server.cpp hle/service/set/factory_settings_server.h hle/service/set/firmware_debug_settings_server.cpp hle/service/set/firmware_debug_settings_server.h - hle/service/set/private_settings.cpp - hle/service/set/private_settings.h hle/service/set/settings.cpp hle/service/set/settings.h hle/service/set/settings_server.cpp hle/service/set/settings_server.h - hle/service/set/system_settings.cpp - hle/service/set/system_settings.h + hle/service/set/settings_types.h hle/service/set/system_settings_server.cpp hle/service/set/system_settings_server.h hle/service/sm/sm.cpp diff --git a/src/core/file_sys/patch_manager.cpp b/src/core/file_sys/patch_manager.cpp index 4a3dbc6a3..612122224 100644 --- a/src/core/file_sys/patch_manager.cpp +++ b/src/core/file_sys/patch_manager.cpp @@ -466,12 +466,12 @@ VirtualFile PatchManager::PatchRomFS(const NCA* base_nca, VirtualFile base_romfs return romfs; } -PatchManager::PatchVersionNames PatchManager::GetPatchVersionNames(VirtualFile update_raw) const { +std::vector<Patch> PatchManager::GetPatches(VirtualFile update_raw) const { if (title_id == 0) { return {}; } - std::map<std::string, std::string, std::less<>> out; + std::vector<Patch> out; const auto& disabled = Settings::values.disabled_addons[title_id]; // Game Updates @@ -482,20 +482,28 @@ PatchManager::PatchVersionNames PatchManager::GetPatchVersionNames(VirtualFile u const auto update_disabled = std::find(disabled.cbegin(), disabled.cend(), "Update") != disabled.cend(); - const auto update_label = update_disabled ? "[D] Update" : "Update"; + Patch update_patch = {.enabled = !update_disabled, + .name = "Update", + .version = "", + .type = PatchType::Update, + .program_id = title_id, + .title_id = title_id}; if (nacp != nullptr) { - out.insert_or_assign(update_label, nacp->GetVersionString()); + update_patch.version = nacp->GetVersionString(); + out.push_back(update_patch); } else { if (content_provider.HasEntry(update_tid, ContentRecordType::Program)) { const auto meta_ver = content_provider.GetEntryVersion(update_tid); if (meta_ver.value_or(0) == 0) { - out.insert_or_assign(update_label, ""); + out.push_back(update_patch); } else { - out.insert_or_assign(update_label, FormatTitleVersion(*meta_ver)); + update_patch.version = FormatTitleVersion(*meta_ver); + out.push_back(update_patch); } } else if (update_raw != nullptr) { - out.insert_or_assign(update_label, "PACKED"); + update_patch.version = "PACKED"; + out.push_back(update_patch); } } @@ -539,7 +547,12 @@ PatchManager::PatchVersionNames PatchManager::GetPatchVersionNames(VirtualFile u const auto mod_disabled = std::find(disabled.begin(), disabled.end(), mod->GetName()) != disabled.end(); - out.insert_or_assign(mod_disabled ? "[D] " + mod->GetName() : mod->GetName(), types); + out.push_back({.enabled = !mod_disabled, + .name = mod->GetName(), + .version = types, + .type = PatchType::Mod, + .program_id = title_id, + .title_id = title_id}); } } @@ -557,7 +570,12 @@ PatchManager::PatchVersionNames PatchManager::GetPatchVersionNames(VirtualFile u if (!types.empty()) { const auto mod_disabled = std::find(disabled.begin(), disabled.end(), "SDMC") != disabled.end(); - out.insert_or_assign(mod_disabled ? "[D] SDMC" : "SDMC", types); + out.push_back({.enabled = !mod_disabled, + .name = "SDMC", + .version = types, + .type = PatchType::Mod, + .program_id = title_id, + .title_id = title_id}); } } @@ -584,7 +602,12 @@ PatchManager::PatchVersionNames PatchManager::GetPatchVersionNames(VirtualFile u const auto dlc_disabled = std::find(disabled.begin(), disabled.end(), "DLC") != disabled.end(); - out.insert_or_assign(dlc_disabled ? "[D] DLC" : "DLC", std::move(list)); + out.push_back({.enabled = !dlc_disabled, + .name = "DLC", + .version = std::move(list), + .type = PatchType::DLC, + .program_id = title_id, + .title_id = dlc_match.back().title_id}); } return out; diff --git a/src/core/file_sys/patch_manager.h b/src/core/file_sys/patch_manager.h index 03e9c7301..2601b8217 100644 --- a/src/core/file_sys/patch_manager.h +++ b/src/core/file_sys/patch_manager.h @@ -26,12 +26,22 @@ class ContentProvider; class NCA; class NACP; +enum class PatchType { Update, DLC, Mod }; + +struct Patch { + bool enabled; + std::string name; + std::string version; + PatchType type; + u64 program_id; + u64 title_id; +}; + // A centralized class to manage patches to games. class PatchManager { public: using BuildID = std::array<u8, 0x20>; using Metadata = std::pair<std::unique_ptr<NACP>, VirtualFile>; - using PatchVersionNames = std::map<std::string, std::string, std::less<>>; explicit PatchManager(u64 title_id_, const Service::FileSystem::FileSystemController& fs_controller_, @@ -66,9 +76,8 @@ public: VirtualFile packed_update_raw = nullptr, bool apply_layeredfs = true) const; - // Returns a vector of pairs between patch names and patch versions. - // i.e. Update 3.2.2 will return {"Update", "3.2.2"} - [[nodiscard]] PatchVersionNames GetPatchVersionNames(VirtualFile update_raw = nullptr) const; + // Returns a vector of patches + [[nodiscard]] std::vector<Patch> GetPatches(VirtualFile update_raw = nullptr) const; // If the game update exists, returns the u32 version field in its Meta-type NCA. If that fails, // it will fallback to the Meta-type NCA of the base game. If that fails, the result will be diff --git a/src/core/hle/service/acc/profile_manager.cpp b/src/core/hle/service/acc/profile_manager.cpp index 683f44e27..29a10ad13 100644 --- a/src/core/hle/service/acc/profile_manager.cpp +++ b/src/core/hle/service/acc/profile_manager.cpp @@ -11,6 +11,7 @@ #include "common/fs/path_util.h" #include "common/polyfill_ranges.h" #include "common/settings.h" +#include "common/string_util.h" #include "core/hle/service/acc/profile_manager.h" namespace Service::Account { @@ -164,6 +165,22 @@ std::optional<std::size_t> ProfileManager::GetUserIndex(const ProfileInfo& user) return GetUserIndex(user.user_uuid); } +/// Returns the first user profile seen based on username (which does not enforce uniqueness) +std::optional<std::size_t> ProfileManager::GetUserIndex(const std::string& username) const { + const auto iter = + std::find_if(profiles.begin(), profiles.end(), [&username](const ProfileInfo& p) { + const std::string profile_username = Common::StringFromFixedZeroTerminatedBuffer( + reinterpret_cast<const char*>(p.username.data()), p.username.size()); + + return username.compare(profile_username) == 0; + }); + if (iter == profiles.end()) { + return std::nullopt; + } + + return static_cast<std::size_t>(std::distance(profiles.begin(), iter)); +} + /// Returns the data structure used by the switch when GetProfileBase is called on acc:* bool ProfileManager::GetProfileBase(std::optional<std::size_t> index, ProfileBase& profile) const { if (!index || index >= MAX_USERS) { diff --git a/src/core/hle/service/acc/profile_manager.h b/src/core/hle/service/acc/profile_manager.h index e21863e64..f94157300 100644 --- a/src/core/hle/service/acc/profile_manager.h +++ b/src/core/hle/service/acc/profile_manager.h @@ -70,6 +70,7 @@ public: std::optional<Common::UUID> GetUser(std::size_t index) const; std::optional<std::size_t> GetUserIndex(const Common::UUID& uuid) const; std::optional<std::size_t> GetUserIndex(const ProfileInfo& user) const; + std::optional<std::size_t> GetUserIndex(const std::string& username) const; bool GetProfileBase(std::optional<std::size_t> index, ProfileBase& profile) const; bool GetProfileBase(Common::UUID uuid, ProfileBase& profile) const; bool GetProfileBase(const ProfileInfo& user, ProfileBase& profile) const; diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index 4ce0a9834..595a3372e 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp @@ -20,12 +20,13 @@ void LoopProcess(Core::System& system) { auto server_manager = std::make_unique<ServerManager>(system); std::shared_ptr<ResourceManager> resource_manager = std::make_shared<ResourceManager>(system); std::shared_ptr<HidFirmwareSettings> firmware_settings = - std::make_shared<HidFirmwareSettings>(); + std::make_shared<HidFirmwareSettings>(system); // TODO: Remove this hack when am is emulated properly. resource_manager->Initialize(); resource_manager->RegisterAppletResourceUserId(system.ApplicationProcess()->GetProcessId(), true); + resource_manager->SetAruidValidForVibration(system.ApplicationProcess()->GetProcessId(), true); server_manager->RegisterNamedService( "hid", std::make_shared<IHidServer>(system, resource_manager, firmware_settings)); diff --git a/src/core/hle/service/hid/hid_server.cpp b/src/core/hle/service/hid/hid_server.cpp index 1951da33b..30afed812 100644 --- a/src/core/hle/service/hid/hid_server.cpp +++ b/src/core/hle/service/hid/hid_server.cpp @@ -22,12 +22,16 @@ #include "hid_core/resources/mouse/mouse.h" #include "hid_core/resources/npad/npad.h" #include "hid_core/resources/npad/npad_types.h" +#include "hid_core/resources/npad/npad_vibration.h" #include "hid_core/resources/palma/palma.h" #include "hid_core/resources/six_axis/console_six_axis.h" #include "hid_core/resources/six_axis/seven_six_axis.h" #include "hid_core/resources/six_axis/six_axis.h" #include "hid_core/resources/touch_screen/gesture.h" #include "hid_core/resources/touch_screen/touch_screen.h" +#include "hid_core/resources/vibration/gc_vibration_device.h" +#include "hid_core/resources/vibration/n64_vibration_device.h" +#include "hid_core/resources/vibration/vibration_device.h" namespace Service::HID { @@ -38,7 +42,7 @@ public: : ServiceFramework{system_, "IActiveVibrationDeviceList"}, resource_manager(resource) { // clang-format off static const FunctionInfo functions[] = { - {0, &IActiveVibrationDeviceList::InitializeVibrationDevice, "InitializeVibrationDevice"}, + {0, &IActiveVibrationDeviceList::ActivateVibrationDevice, "ActivateVibrationDevice"}, }; // clang-format on @@ -46,22 +50,49 @@ public: } private: - void InitializeVibrationDevice(HLERequestContext& ctx) { + void ActivateVibrationDevice(HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const auto vibration_device_handle{rp.PopRaw<Core::HID::VibrationDeviceHandle>()}; - if (resource_manager != nullptr && resource_manager->GetNpad()) { - resource_manager->GetNpad()->InitializeVibrationDevice(vibration_device_handle); - } - LOG_DEBUG(Service_HID, "called, npad_type={}, npad_id={}, device_index={}", vibration_device_handle.npad_type, vibration_device_handle.npad_id, vibration_device_handle.device_index); + const auto result = ActivateVibrationDeviceImpl(vibration_device_handle); + IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); + rb.Push(result); } + Result ActivateVibrationDeviceImpl(const Core::HID::VibrationDeviceHandle& handle) { + std::scoped_lock lock{mutex}; + + const Result is_valid = IsVibrationHandleValid(handle); + if (is_valid.IsError()) { + return is_valid; + } + + for (std::size_t i = 0; i < list_size; i++) { + if (handle.device_index == vibration_device_list[i].device_index && + handle.npad_id == vibration_device_list[i].npad_id && + handle.npad_type == vibration_device_list[i].npad_type) { + return ResultSuccess; + } + } + if (list_size == vibration_device_list.size()) { + return ResultVibrationDeviceIndexOutOfRange; + } + const Result result = resource_manager->GetVibrationDevice(handle)->Activate(); + if (result.IsError()) { + return result; + } + vibration_device_list[list_size++] = handle; + return ResultSuccess; + } + + mutable std::mutex mutex; + std::size_t list_size{}; + std::array<Core::HID::VibrationDeviceHandle, 0x100> vibration_device_list{}; std::shared_ptr<ResourceManager> resource_manager; }; @@ -153,7 +184,7 @@ IHidServer::IHidServer(Core::System& system_, std::shared_ptr<ResourceManager> r {209, &IHidServer::BeginPermitVibrationSession, "BeginPermitVibrationSession"}, {210, &IHidServer::EndPermitVibrationSession, "EndPermitVibrationSession"}, {211, &IHidServer::IsVibrationDeviceMounted, "IsVibrationDeviceMounted"}, - {212, nullptr, "SendVibrationValueInBool"}, + {212, &IHidServer::SendVibrationValueInBool, "SendVibrationValueInBool"}, {300, &IHidServer::ActivateConsoleSixAxisSensor, "ActivateConsoleSixAxisSensor"}, {301, &IHidServer::StartConsoleSixAxisSensor, "StartConsoleSixAxisSensor"}, {302, &IHidServer::StopConsoleSixAxisSensor, "StopConsoleSixAxisSensor"}, @@ -1492,59 +1523,13 @@ void IHidServer::ClearNpadCaptureButtonAssignment(HLERequestContext& ctx) { void IHidServer::GetVibrationDeviceInfo(HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const auto vibration_device_handle{rp.PopRaw<Core::HID::VibrationDeviceHandle>()}; - const auto controller = GetResourceManager()->GetNpad(); - - Core::HID::VibrationDeviceInfo vibration_device_info; - bool check_device_index = false; - - switch (vibration_device_handle.npad_type) { - case Core::HID::NpadStyleIndex::Fullkey: - case Core::HID::NpadStyleIndex::Handheld: - case Core::HID::NpadStyleIndex::JoyconDual: - case Core::HID::NpadStyleIndex::JoyconLeft: - case Core::HID::NpadStyleIndex::JoyconRight: - vibration_device_info.type = Core::HID::VibrationDeviceType::LinearResonantActuator; - check_device_index = true; - break; - case Core::HID::NpadStyleIndex::GameCube: - vibration_device_info.type = Core::HID::VibrationDeviceType::GcErm; - break; - case Core::HID::NpadStyleIndex::N64: - vibration_device_info.type = Core::HID::VibrationDeviceType::N64; - break; - default: - vibration_device_info.type = Core::HID::VibrationDeviceType::Unknown; - break; - } - - vibration_device_info.position = Core::HID::VibrationDevicePosition::None; - if (check_device_index) { - switch (vibration_device_handle.device_index) { - case Core::HID::DeviceIndex::Left: - vibration_device_info.position = Core::HID::VibrationDevicePosition::Left; - break; - case Core::HID::DeviceIndex::Right: - vibration_device_info.position = Core::HID::VibrationDevicePosition::Right; - break; - case Core::HID::DeviceIndex::None: - default: - ASSERT_MSG(false, "DeviceIndex should never be None!"); - break; - } - } - LOG_DEBUG(Service_HID, "called, vibration_device_type={}, vibration_device_position={}", - vibration_device_info.type, vibration_device_info.position); - - const auto result = IsVibrationHandleValid(vibration_device_handle); - if (result.IsError()) { - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(result); - return; - } + Core::HID::VibrationDeviceInfo vibration_device_info{}; + const auto result = GetResourceManager()->GetVibrationDeviceInfo(vibration_device_info, + vibration_device_handle); IPC::ResponseBuilder rb{ctx, 4}; - rb.Push(ResultSuccess); + rb.Push(result); rb.PushRaw(vibration_device_info); } @@ -1560,16 +1545,16 @@ void IHidServer::SendVibrationValue(HLERequestContext& ctx) { const auto parameters{rp.PopRaw<Parameters>()}; - GetResourceManager()->GetNpad()->VibrateController(parameters.applet_resource_user_id, - parameters.vibration_device_handle, - parameters.vibration_value); - LOG_DEBUG(Service_HID, "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}", parameters.vibration_device_handle.npad_type, parameters.vibration_device_handle.npad_id, parameters.vibration_device_handle.device_index, parameters.applet_resource_user_id); + GetResourceManager()->SendVibrationValue(parameters.applet_resource_user_id, + parameters.vibration_device_handle, + parameters.vibration_value); + IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); } @@ -1591,10 +1576,28 @@ void IHidServer::GetActualVibrationValue(HLERequestContext& ctx) { parameters.vibration_device_handle.npad_id, parameters.vibration_device_handle.device_index, parameters.applet_resource_user_id); + bool has_active_aruid{}; + NpadVibrationDevice* device{nullptr}; + Core::HID::VibrationValue vibration_value{}; + Result result = GetResourceManager()->IsVibrationAruidActive(parameters.applet_resource_user_id, + has_active_aruid); + + if (result.IsSuccess() && has_active_aruid) { + result = IsVibrationHandleValid(parameters.vibration_device_handle); + } + if (result.IsSuccess() && has_active_aruid) { + device = GetResourceManager()->GetNSVibrationDevice(parameters.vibration_device_handle); + } + if (device != nullptr) { + result = device->GetActualVibrationValue(vibration_value); + } + if (result.IsError()) { + vibration_value = Core::HID::DEFAULT_VIBRATION_VALUE; + } + IPC::ResponseBuilder rb{ctx, 6}; rb.Push(ResultSuccess); - rb.PushRaw(GetResourceManager()->GetNpad()->GetLastVibration( - parameters.applet_resource_user_id, parameters.vibration_device_handle)); + rb.PushRaw(vibration_value); } void IHidServer::CreateActiveVibrationDeviceList(HLERequestContext& ctx) { @@ -1609,25 +1612,27 @@ void IHidServer::PermitVibration(HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const auto can_vibrate{rp.Pop<bool>()}; - // nnSDK saves this value as a float. Since it can only be 1.0f or 0.0f we simplify this value - // by converting it to a bool - Settings::values.vibration_enabled.SetValue(can_vibrate); - LOG_DEBUG(Service_HID, "called, can_vibrate={}", can_vibrate); + const auto result = + GetResourceManager()->GetNpad()->GetVibrationHandler()->SetVibrationMasterVolume( + can_vibrate ? 1.0f : 0.0f); + IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); + rb.Push(result); } void IHidServer::IsVibrationPermitted(HLERequestContext& ctx) { LOG_DEBUG(Service_HID, "called"); - // nnSDK checks if a float is greater than zero. We return the bool we stored earlier - const auto is_enabled = Settings::values.vibration_enabled.GetValue(); + f32 master_volume{}; + const auto result = + GetResourceManager()->GetNpad()->GetVibrationHandler()->GetVibrationMasterVolume( + master_volume); IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(ResultSuccess); - rb.Push(is_enabled); + rb.Push(result); + rb.Push(master_volume > 0.0f); } void IHidServer::SendVibrationValues(HLERequestContext& ctx) { @@ -1645,13 +1650,22 @@ void IHidServer::SendVibrationValues(HLERequestContext& ctx) { auto vibration_values = std::span( reinterpret_cast<const Core::HID::VibrationValue*>(vibration_data.data()), vibration_count); - GetResourceManager()->GetNpad()->VibrateControllers(applet_resource_user_id, - vibration_device_handles, vibration_values); - LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); + Result result = ResultSuccess; + if (handle_count != vibration_count) { + result = ResultVibrationArraySizeMismatch; + } + + for (std::size_t i = 0; i < handle_count; i++) { + if (result.IsSuccess()) { + result = GetResourceManager()->SendVibrationValue( + applet_resource_user_id, vibration_device_handles[i], vibration_values[i]); + } + } + IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); + rb.Push(result); } void IHidServer::SendVibrationGcErmCommand(HLERequestContext& ctx) { @@ -1666,43 +1680,6 @@ void IHidServer::SendVibrationGcErmCommand(HLERequestContext& ctx) { const auto parameters{rp.PopRaw<Parameters>()}; - /** - * Note: This uses yuzu-specific behavior such that the StopHard command produces - * vibrations where freq_low == 0.0f and freq_high == 0.0f, as defined below, - * in order to differentiate between Stop and StopHard commands. - * This is done to reuse the controller vibration functions made for regular controllers. - */ - const auto vibration_value = [parameters] { - switch (parameters.gc_erm_command) { - case Core::HID::VibrationGcErmCommand::Stop: - return Core::HID::VibrationValue{ - .low_amplitude = 0.0f, - .low_frequency = 160.0f, - .high_amplitude = 0.0f, - .high_frequency = 320.0f, - }; - case Core::HID::VibrationGcErmCommand::Start: - return Core::HID::VibrationValue{ - .low_amplitude = 1.0f, - .low_frequency = 160.0f, - .high_amplitude = 1.0f, - .high_frequency = 320.0f, - }; - case Core::HID::VibrationGcErmCommand::StopHard: - return Core::HID::VibrationValue{ - .low_amplitude = 0.0f, - .low_frequency = 0.0f, - .high_amplitude = 0.0f, - .high_frequency = 0.0f, - }; - default: - return Core::HID::DEFAULT_VIBRATION_VALUE; - } - }(); - - GetResourceManager()->GetNpad()->VibrateController( - parameters.applet_resource_user_id, parameters.vibration_device_handle, vibration_value); - LOG_DEBUG(Service_HID, "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}, " "gc_erm_command={}", @@ -1711,8 +1688,23 @@ void IHidServer::SendVibrationGcErmCommand(HLERequestContext& ctx) { parameters.vibration_device_handle.device_index, parameters.applet_resource_user_id, parameters.gc_erm_command); + bool has_active_aruid{}; + NpadGcVibrationDevice* gc_device{nullptr}; + Result result = GetResourceManager()->IsVibrationAruidActive(parameters.applet_resource_user_id, + has_active_aruid); + + if (result.IsSuccess() && has_active_aruid) { + result = IsVibrationHandleValid(parameters.vibration_device_handle); + } + if (result.IsSuccess() && has_active_aruid) { + gc_device = GetResourceManager()->GetGcVibrationDevice(parameters.vibration_device_handle); + } + if (gc_device != nullptr) { + result = gc_device->SendVibrationGcErmCommand(parameters.gc_erm_command); + } + IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); + rb.Push(result); } void IHidServer::GetActualVibrationGcErmCommand(HLERequestContext& ctx) { @@ -1725,33 +1717,31 @@ void IHidServer::GetActualVibrationGcErmCommand(HLERequestContext& ctx) { const auto parameters{rp.PopRaw<Parameters>()}; - const auto last_vibration = GetResourceManager()->GetNpad()->GetLastVibration( - parameters.applet_resource_user_id, parameters.vibration_device_handle); - - const auto gc_erm_command = [last_vibration] { - if (last_vibration.low_amplitude != 0.0f || last_vibration.high_amplitude != 0.0f) { - return Core::HID::VibrationGcErmCommand::Start; - } - - /** - * Note: This uses yuzu-specific behavior such that the StopHard command produces - * vibrations where freq_low == 0.0f and freq_high == 0.0f, as defined in the HID function - * SendVibrationGcErmCommand, in order to differentiate between Stop and StopHard commands. - * This is done to reuse the controller vibration functions made for regular controllers. - */ - if (last_vibration.low_frequency == 0.0f && last_vibration.high_frequency == 0.0f) { - return Core::HID::VibrationGcErmCommand::StopHard; - } - - return Core::HID::VibrationGcErmCommand::Stop; - }(); - LOG_DEBUG(Service_HID, "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}", parameters.vibration_device_handle.npad_type, parameters.vibration_device_handle.npad_id, parameters.vibration_device_handle.device_index, parameters.applet_resource_user_id); + bool has_active_aruid{}; + NpadGcVibrationDevice* gc_device{nullptr}; + Core::HID::VibrationGcErmCommand gc_erm_command{}; + Result result = GetResourceManager()->IsVibrationAruidActive(parameters.applet_resource_user_id, + has_active_aruid); + + if (result.IsSuccess() && has_active_aruid) { + result = IsVibrationHandleValid(parameters.vibration_device_handle); + } + if (result.IsSuccess() && has_active_aruid) { + gc_device = GetResourceManager()->GetGcVibrationDevice(parameters.vibration_device_handle); + } + if (gc_device != nullptr) { + result = gc_device->GetActualVibrationGcErmCommand(gc_erm_command); + } + if (result.IsError()) { + gc_erm_command = Core::HID::VibrationGcErmCommand::Stop; + } + IPC::ResponseBuilder rb{ctx, 4}; rb.Push(ResultSuccess); rb.PushEnum(gc_erm_command); @@ -1761,21 +1751,24 @@ void IHidServer::BeginPermitVibrationSession(HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const auto applet_resource_user_id{rp.Pop<u64>()}; - GetResourceManager()->GetNpad()->SetPermitVibrationSession(true); - LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); + const auto result = + GetResourceManager()->GetNpad()->GetVibrationHandler()->BeginPermitVibrationSession( + applet_resource_user_id); + IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); + rb.Push(result); } void IHidServer::EndPermitVibrationSession(HLERequestContext& ctx) { - GetResourceManager()->GetNpad()->SetPermitVibrationSession(false); - LOG_DEBUG(Service_HID, "called"); + const auto result = + GetResourceManager()->GetNpad()->GetVibrationHandler()->EndPermitVibrationSession(); + IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); + rb.Push(result); } void IHidServer::IsVibrationDeviceMounted(HLERequestContext& ctx) { @@ -1795,10 +1788,61 @@ void IHidServer::IsVibrationDeviceMounted(HLERequestContext& ctx) { parameters.vibration_device_handle.npad_id, parameters.vibration_device_handle.device_index, parameters.applet_resource_user_id); + bool is_mounted{}; + NpadVibrationBase* device{nullptr}; + Result result = IsVibrationHandleValid(parameters.vibration_device_handle); + + if (result.IsSuccess()) { + device = GetResourceManager()->GetVibrationDevice(parameters.vibration_device_handle); + } + + if (device != nullptr) { + is_mounted = device->IsVibrationMounted(); + } + IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(ResultSuccess); - rb.Push(GetResourceManager()->GetNpad()->IsVibrationDeviceMounted( - parameters.applet_resource_user_id, parameters.vibration_device_handle)); + rb.Push(result); + rb.Push(is_mounted); +} + +void IHidServer::SendVibrationValueInBool(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + struct Parameters { + Core::HID::VibrationDeviceHandle vibration_device_handle; + INSERT_PADDING_WORDS_NOINIT(1); + u64 applet_resource_user_id; + bool is_vibrating; + }; + static_assert(sizeof(Parameters) == 0x18, "Parameters has incorrect size."); + + const auto parameters{rp.PopRaw<Parameters>()}; + + LOG_DEBUG(Service_HID, + "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}, " + "is_vibrating={}", + parameters.vibration_device_handle.npad_type, + parameters.vibration_device_handle.npad_id, + parameters.vibration_device_handle.device_index, parameters.applet_resource_user_id, + parameters.is_vibrating); + + bool has_active_aruid{}; + NpadN64VibrationDevice* n64_device{nullptr}; + Result result = GetResourceManager()->IsVibrationAruidActive(parameters.applet_resource_user_id, + has_active_aruid); + + if (result.IsSuccess() && has_active_aruid) { + result = IsVibrationHandleValid(parameters.vibration_device_handle); + } + if (result.IsSuccess() && has_active_aruid) { + n64_device = + GetResourceManager()->GetN64VibrationDevice(parameters.vibration_device_handle); + } + if (n64_device != nullptr) { + result = n64_device->SendValueInBool(parameters.is_vibrating); + } + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(result); } void IHidServer::ActivateConsoleSixAxisSensor(HLERequestContext& ctx) { diff --git a/src/core/hle/service/hid/hid_server.h b/src/core/hle/service/hid/hid_server.h index cc7c4ebdd..3a2e0a230 100644 --- a/src/core/hle/service/hid/hid_server.h +++ b/src/core/hle/service/hid/hid_server.h @@ -97,6 +97,7 @@ private: void BeginPermitVibrationSession(HLERequestContext& ctx); void EndPermitVibrationSession(HLERequestContext& ctx); void IsVibrationDeviceMounted(HLERequestContext& ctx); + void SendVibrationValueInBool(HLERequestContext& ctx); void ActivateConsoleSixAxisSensor(HLERequestContext& ctx); void StartConsoleSixAxisSensor(HLERequestContext& ctx); void StopConsoleSixAxisSensor(HLERequestContext& ctx); diff --git a/src/core/hle/service/hid/hid_system_server.cpp b/src/core/hle/service/hid/hid_system_server.cpp index 3a0cb3cb1..bf27ddfbf 100644 --- a/src/core/hle/service/hid/hid_system_server.cpp +++ b/src/core/hle/service/hid/hid_system_server.cpp @@ -7,6 +7,7 @@ #include "hid_core/resource_manager.h" #include "hid_core/resources/npad/npad.h" #include "hid_core/resources/npad/npad_types.h" +#include "hid_core/resources/npad/npad_vibration.h" #include "hid_core/resources/palma/palma.h" #include "hid_core/resources/touch_screen/touch_screen.h" @@ -67,14 +68,14 @@ IHidSystemServer::IHidSystemServer(Core::System& system_, std::shared_ptr<Resour {501, &IHidSystemServer::RegisterAppletResourceUserId, "RegisterAppletResourceUserId"}, {502, &IHidSystemServer::UnregisterAppletResourceUserId, "UnregisterAppletResourceUserId"}, {503, &IHidSystemServer::EnableAppletToGetInput, "EnableAppletToGetInput"}, - {504, nullptr, "SetAruidValidForVibration"}, + {504, &IHidSystemServer::SetAruidValidForVibration, "SetAruidValidForVibration"}, {505, &IHidSystemServer::EnableAppletToGetSixAxisSensor, "EnableAppletToGetSixAxisSensor"}, {506, &IHidSystemServer::EnableAppletToGetPadInput, "EnableAppletToGetPadInput"}, {507, &IHidSystemServer::EnableAppletToGetTouchScreen, "EnableAppletToGetTouchScreen"}, - {510, nullptr, "SetVibrationMasterVolume"}, - {511, nullptr, "GetVibrationMasterVolume"}, - {512, nullptr, "BeginPermitVibrationSession"}, - {513, nullptr, "EndPermitVibrationSession"}, + {510, &IHidSystemServer::SetVibrationMasterVolume, "SetVibrationMasterVolume"}, + {511, &IHidSystemServer::GetVibrationMasterVolume, "GetVibrationMasterVolume"}, + {512, &IHidSystemServer::BeginPermitVibrationSession, "BeginPermitVibrationSession"}, + {513, &IHidSystemServer::EndPermitVibrationSession, "EndPermitVibrationSession"}, {514, nullptr, "Unknown514"}, {520, nullptr, "EnableHandheldHids"}, {521, nullptr, "DisableHandheldHids"}, @@ -156,7 +157,7 @@ IHidSystemServer::IHidSystemServer(Core::System& system_, std::shared_ptr<Resour {1152, nullptr, "SetTouchScreenDefaultConfiguration"}, {1153, &IHidSystemServer::GetTouchScreenDefaultConfiguration, "GetTouchScreenDefaultConfiguration"}, {1154, nullptr, "IsFirmwareAvailableForNotification"}, - {1155, nullptr, "SetForceHandheldStyleVibration"}, + {1155, &IHidSystemServer::SetForceHandheldStyleVibration, "SetForceHandheldStyleVibration"}, {1156, nullptr, "SendConnectionTriggerWithoutTimeoutEvent"}, {1157, nullptr, "CancelConnectionTrigger"}, {1200, nullptr, "IsButtonConfigSupported"}, @@ -532,7 +533,28 @@ void IHidSystemServer::EnableAppletToGetInput(HLERequestContext& ctx) { parameters.is_enabled, parameters.applet_resource_user_id); GetResourceManager()->EnableInput(parameters.applet_resource_user_id, parameters.is_enabled); - // GetResourceManager()->GetNpad()->EnableInput(parameters.applet_resource_user_id); + GetResourceManager()->GetNpad()->EnableAppletToGetInput(parameters.applet_resource_user_id); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); +} + +void IHidSystemServer::SetAruidValidForVibration(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + struct Parameters { + bool is_enabled; + INSERT_PADDING_WORDS_NOINIT(1); + u64 applet_resource_user_id; + }; + static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); + + const auto parameters{rp.PopRaw<Parameters>()}; + + LOG_INFO(Service_HID, "called, is_enabled={}, applet_resource_user_id={}", + parameters.is_enabled, parameters.applet_resource_user_id); + + GetResourceManager()->SetAruidValidForVibration(parameters.applet_resource_user_id, + parameters.is_enabled); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); @@ -574,7 +596,7 @@ void IHidSystemServer::EnableAppletToGetPadInput(HLERequestContext& ctx) { parameters.is_enabled, parameters.applet_resource_user_id); GetResourceManager()->EnablePadInput(parameters.applet_resource_user_id, parameters.is_enabled); - // GetResourceManager()->GetNpad()->EnableInput(parameters.applet_resource_user_id); + GetResourceManager()->GetNpad()->EnableAppletToGetInput(parameters.applet_resource_user_id); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); @@ -601,6 +623,57 @@ void IHidSystemServer::EnableAppletToGetTouchScreen(HLERequestContext& ctx) { rb.Push(ResultSuccess); } +void IHidSystemServer::SetVibrationMasterVolume(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + const auto master_volume{rp.Pop<f32>()}; + + LOG_INFO(Service_HID, "called, volume={}", master_volume); + + const auto result = + GetResourceManager()->GetNpad()->GetVibrationHandler()->SetVibrationMasterVolume( + master_volume); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(result); +} + +void IHidSystemServer::GetVibrationMasterVolume(HLERequestContext& ctx) { + f32 master_volume{}; + const auto result = + GetResourceManager()->GetNpad()->GetVibrationHandler()->GetVibrationMasterVolume( + master_volume); + + LOG_INFO(Service_HID, "called, volume={}", master_volume); + + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(result); + rb.Push(master_volume); +} + +void IHidSystemServer::BeginPermitVibrationSession(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + const auto applet_resource_user_id{rp.Pop<u64>()}; + + LOG_INFO(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); + + const auto result = + GetResourceManager()->GetNpad()->GetVibrationHandler()->BeginPermitVibrationSession( + applet_resource_user_id); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(result); +} + +void IHidSystemServer::EndPermitVibrationSession(HLERequestContext& ctx) { + LOG_INFO(Service_HID, "called"); + + const auto result = + GetResourceManager()->GetNpad()->GetVibrationHandler()->EndPermitVibrationSession(); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(result); +} + void IHidSystemServer::IsJoyConAttachedOnAllRail(HLERequestContext& ctx) { const bool is_attached = true; @@ -749,6 +822,19 @@ void IHidSystemServer::GetTouchScreenDefaultConfiguration(HLERequestContext& ctx rb.PushRaw(touchscreen_config); } +void IHidSystemServer::SetForceHandheldStyleVibration(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + const auto is_forced{rp.Pop<bool>()}; + + LOG_INFO(Service_HID, "called, is_forced={}", is_forced); + + GetResourceManager()->SetForceHandheldStyleVibration(is_forced); + GetResourceManager()->GetNpad()->UpdateHandheldAbstractState(); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); +} + void IHidSystemServer::IsUsingCustomButtonConfig(HLERequestContext& ctx) { const bool is_enabled = false; diff --git a/src/core/hle/service/hid/hid_system_server.h b/src/core/hle/service/hid/hid_system_server.h index 0c2634e3f..90a719f02 100644 --- a/src/core/hle/service/hid/hid_system_server.h +++ b/src/core/hle/service/hid/hid_system_server.h @@ -42,9 +42,14 @@ private: void RegisterAppletResourceUserId(HLERequestContext& ctx); void UnregisterAppletResourceUserId(HLERequestContext& ctx); void EnableAppletToGetInput(HLERequestContext& ctx); + void SetAruidValidForVibration(HLERequestContext& ctx); void EnableAppletToGetSixAxisSensor(HLERequestContext& ctx); void EnableAppletToGetPadInput(HLERequestContext& ctx); void EnableAppletToGetTouchScreen(HLERequestContext& ctx); + void SetVibrationMasterVolume(HLERequestContext& ctx); + void GetVibrationMasterVolume(HLERequestContext& ctx); + void BeginPermitVibrationSession(HLERequestContext& ctx); + void EndPermitVibrationSession(HLERequestContext& ctx); void IsJoyConAttachedOnAllRail(HLERequestContext& ctx); void AcquireConnectionTriggerTimeoutEvent(HLERequestContext& ctx); void AcquireDeviceRegisteredEventForControllerSupport(HLERequestContext& ctx); @@ -61,6 +66,7 @@ private: void FinalizeUsbFirmwareUpdate(HLERequestContext& ctx); void InitializeUsbFirmwareUpdateWithoutMemory(HLERequestContext& ctx); void GetTouchScreenDefaultConfiguration(HLERequestContext& ctx); + void SetForceHandheldStyleVibration(HLERequestContext& ctx); void IsUsingCustomButtonConfig(HLERequestContext& ctx); std::shared_ptr<ResourceManager> GetResourceManager(); diff --git a/src/core/hle/service/nfc/common/device.cpp b/src/core/hle/service/nfc/common/device.cpp index 31cc87acc..cc7776efc 100644 --- a/src/core/hle/service/nfc/common/device.cpp +++ b/src/core/hle/service/nfc/common/device.cpp @@ -441,7 +441,10 @@ Result NfcDevice::Mount(NFP::ModelType model_type, NFP::MountTarget mount_target device_state = DeviceState::TagMounted; mount_target = mount_target_; - if (!is_corrupted && mount_target != NFP::MountTarget::Rom) { + const bool create_backup = + mount_target == NFP::MountTarget::All || mount_target == NFP::MountTarget::Ram || + (mount_target == NFP::MountTarget::Rom && HasBackup(encrypted_tag_data.uuid).IsError()); + if (!is_corrupted && create_backup) { std::vector<u8> data(sizeof(NFP::EncryptedNTAG215File)); memcpy(data.data(), &encrypted_tag_data, sizeof(encrypted_tag_data)); WriteBackupData(encrypted_tag_data.uuid, data); diff --git a/src/core/hle/service/nvnflinger/nvnflinger.cpp b/src/core/hle/service/nvnflinger/nvnflinger.cpp index 423b9aef1..71d6fdb0c 100644 --- a/src/core/hle/service/nvnflinger/nvnflinger.cpp +++ b/src/core/hle/service/nvnflinger/nvnflinger.cpp @@ -112,9 +112,7 @@ void Nvnflinger::ShutdownLayers() { { const auto lock_guard = Lock(); for (auto& display : displays) { - for (size_t layer = 0; layer < display.GetNumLayers(); ++layer) { - display.GetLayer(layer).GetConsumer().Abandon(); - } + display.Abandon(); } is_abandoned = true; @@ -176,24 +174,28 @@ void Nvnflinger::CreateLayerAtId(VI::Display& display, u64 layer_id) { display.CreateLayer(layer_id, buffer_id, nvdrv->container); } -void Nvnflinger::OpenLayer(u64 layer_id) { +bool Nvnflinger::OpenLayer(u64 layer_id) { const auto lock_guard = Lock(); for (auto& display : displays) { if (auto* layer = display.FindLayer(layer_id); layer) { - layer->Open(); + return layer->Open(); } } + + return false; } -void Nvnflinger::CloseLayer(u64 layer_id) { +bool Nvnflinger::CloseLayer(u64 layer_id) { const auto lock_guard = Lock(); for (auto& display : displays) { if (auto* layer = display.FindLayer(layer_id); layer) { - layer->Close(); + return layer->Close(); } } + + return false; } void Nvnflinger::DestroyLayer(u64 layer_id) { diff --git a/src/core/hle/service/nvnflinger/nvnflinger.h b/src/core/hle/service/nvnflinger/nvnflinger.h index 871285764..a60e0ae6b 100644 --- a/src/core/hle/service/nvnflinger/nvnflinger.h +++ b/src/core/hle/service/nvnflinger/nvnflinger.h @@ -74,10 +74,10 @@ public: [[nodiscard]] std::optional<u64> CreateLayer(u64 display_id); /// Opens a layer on all displays for the given layer ID. - void OpenLayer(u64 layer_id); + bool OpenLayer(u64 layer_id); /// Closes a layer on all displays for the given layer ID. - void CloseLayer(u64 layer_id); + bool CloseLayer(u64 layer_id); /// Destroys the given layer ID. void DestroyLayer(u64 layer_id); diff --git a/src/core/hle/service/set/private_settings.h b/src/core/hle/service/set/private_settings.h deleted file mode 100644 index b63eaf45c..000000000 --- a/src/core/hle/service/set/private_settings.h +++ /dev/null @@ -1,72 +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 "common/uuid.h" -#include "core/hle/service/time/clock_types.h" - -namespace Service::Set { - -/// This is nn::settings::system::InitialLaunchFlag -struct InitialLaunchFlag { - union { - u32 raw{}; - - BitField<0, 1, u32> InitialLaunchCompletionFlag; - BitField<8, 1, u32> InitialLaunchUserAdditionFlag; - BitField<16, 1, u32> InitialLaunchTimestampFlag; - }; -}; -static_assert(sizeof(InitialLaunchFlag) == 4, "InitialLaunchFlag is an invalid size"); - -/// This is nn::settings::system::InitialLaunchSettings -struct InitialLaunchSettings { - InitialLaunchFlag flags; - INSERT_PADDING_BYTES(0x4); - Service::Time::Clock::SteadyClockTimePoint timestamp; -}; -static_assert(sizeof(InitialLaunchSettings) == 0x20, "InitialLaunchSettings is incorrect size"); - -#pragma pack(push, 4) -struct InitialLaunchSettingsPacked { - InitialLaunchFlag flags; - Service::Time::Clock::SteadyClockTimePoint timestamp; -}; -#pragma pack(pop) -static_assert(sizeof(InitialLaunchSettingsPacked) == 0x1C, - "InitialLaunchSettingsPacked is incorrect size"); - -struct PrivateSettings { - std::array<u8, 0x10> reserved_00; - - // nn::settings::system::InitialLaunchSettings - InitialLaunchSettings initial_launch_settings; - - std::array<u8, 0x20> reserved_30; - - Common::UUID external_clock_source_id; - s64 shutdown_rtc_value; - s64 external_steady_clock_internal_offset; - - std::array<u8, 0x60> reserved_70; - - // nn::settings::system::PlatformRegion - std::array<u8, 0x4> platform_region; - - std::array<u8, 0x4> reserved_D4; -}; -static_assert(offsetof(PrivateSettings, initial_launch_settings) == 0x10); -static_assert(offsetof(PrivateSettings, external_clock_source_id) == 0x50); -static_assert(offsetof(PrivateSettings, reserved_70) == 0x70); -static_assert(offsetof(PrivateSettings, platform_region) == 0xD0); -static_assert(sizeof(PrivateSettings) == 0xD8, "PrivateSettings has the wrong size!"); - -PrivateSettings DefaultPrivateSettings(); - -} // namespace Service::Set diff --git a/src/core/hle/service/set/appln_settings.cpp b/src/core/hle/service/set/setting_formats/appln_settings.cpp index a5d802757..f7c7d5b91 100644 --- a/src/core/hle/service/set/appln_settings.cpp +++ b/src/core/hle/service/set/setting_formats/appln_settings.cpp @@ -1,12 +1,16 @@ // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later -#include "core/hle/service/set/appln_settings.h" +#include "core/hle/service/set/setting_formats/appln_settings.h" namespace Service::Set { ApplnSettings DefaultApplnSettings() { - return {}; + ApplnSettings settings{}; + + settings.mii_author_id = Common::UUID::MakeDefault(); + + return settings; } } // namespace Service::Set diff --git a/src/core/hle/service/set/appln_settings.h b/src/core/hle/service/set/setting_formats/appln_settings.h index 126375860..ba9af998a 100644 --- a/src/core/hle/service/set/appln_settings.h +++ b/src/core/hle/service/set/setting_formats/appln_settings.h @@ -7,24 +7,23 @@ #include <cstddef> #include "common/common_types.h" +#include "common/uuid.h" +#include "core/hle/service/set/settings_types.h" namespace Service::Set { struct ApplnSettings { - std::array<u8, 0x10> reserved_000; + INSERT_PADDING_BYTES(0x10); // Reserved // nn::util::Uuid MiiAuthorId, copied from system settings 0x94B0 - std::array<u8, 0x10> mii_author_id; - - std::array<u8, 0x30> reserved_020; + Common::UUID mii_author_id; + INSERT_PADDING_BYTES(0x30); // Reserved // nn::settings::system::ServiceDiscoveryControlSettings - std::array<u8, 0x4> service_discovery_control_settings; - - std::array<u8, 0x20> reserved_054; + u32 service_discovery_control_settings; + INSERT_PADDING_BYTES(0x20); // Reserved bool in_repair_process_enable_flag; - - std::array<u8, 0x3> pad_075; + INSERT_PADDING_BYTES(0x3); }; static_assert(offsetof(ApplnSettings, mii_author_id) == 0x10); static_assert(offsetof(ApplnSettings, service_discovery_control_settings) == 0x50); diff --git a/src/core/hle/service/set/device_settings.cpp b/src/core/hle/service/set/setting_formats/device_settings.cpp index e423ce38a..5f295404d 100644 --- a/src/core/hle/service/set/device_settings.cpp +++ b/src/core/hle/service/set/setting_formats/device_settings.cpp @@ -1,7 +1,7 @@ // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later -#include "core/hle/service/set/device_settings.h" +#include "core/hle/service/set/setting_formats/device_settings.h" namespace Service::Set { diff --git a/src/core/hle/service/set/device_settings.h b/src/core/hle/service/set/setting_formats/device_settings.h index f291d0ebe..2827756f6 100644 --- a/src/core/hle/service/set/device_settings.h +++ b/src/core/hle/service/set/setting_formats/device_settings.h @@ -7,10 +7,12 @@ #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 { - std::array<u8, 0x10> reserved_000; + INSERT_PADDING_BYTES(0x10); // Reserved // nn::settings::BatteryLot std::array<u8, 0x18> ptm_battery_lot; @@ -19,26 +21,24 @@ struct DeviceSettings { u8 ptm_battery_version; // nn::settings::system::PtmCycleCountReliability u32 ptm_cycle_count_reliability; - - std::array<u8, 0x48> reserved_048; + 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; - - std::array<u8, 0x20> reserved_0B0; + INSERT_PADDING_BYTES(0x20); // Reserved // nn::settings::system::ConsoleSixAxisSensorAccelerationBias - std::array<u8, 0xC> console_six_axis_sensor_acceleration_bias; + Common::Vec3<f32> console_six_axis_sensor_acceleration_bias; // nn::settings::system::ConsoleSixAxisSensorAngularVelocityBias - std::array<u8, 0xC> console_six_axis_sensor_angular_velocity_bias; + 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 - std::array<u8, 0xC> console_six_axis_sensor_angular_velocity_time_bias; + 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; }; diff --git a/src/core/hle/service/set/private_settings.cpp b/src/core/hle/service/set/setting_formats/private_settings.cpp index 70bf65727..81c362482 100644 --- a/src/core/hle/service/set/private_settings.cpp +++ b/src/core/hle/service/set/setting_formats/private_settings.cpp @@ -1,7 +1,7 @@ // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later -#include "core/hle/service/set/private_settings.h" +#include "core/hle/service/set/setting_formats/private_settings.h" 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..6c40f62e1 --- /dev/null +++ b/src/core/hle/service/set/setting_formats/private_settings.h @@ -0,0 +1,39 @@ +// 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" +#include "core/hle/service/time/clock_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/system_settings.cpp b/src/core/hle/service/set/setting_formats/system_settings.cpp index 5977429b2..66e57651e 100644 --- a/src/core/hle/service/set/system_settings.cpp +++ b/src/core/hle/service/set/setting_formats/system_settings.cpp @@ -1,7 +1,7 @@ // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later -#include "core/hle/service/set/system_settings.h" +#include "core/hle/service/set/setting_formats/system_settings.h" namespace Service::Set { @@ -11,6 +11,8 @@ SystemSettings DefaultSystemSettings() { settings.version = 0x140000; settings.flags = 7; + settings.mii_author_id = Common::UUID::MakeDefault(); + settings.color_set_id = ColorSet::BasicWhite; settings.notification_settings = { @@ -45,6 +47,10 @@ SystemSettings DefaultSystemSettings() { settings.device_time_zone_location_name = {"UTC"}; settings.user_system_clock_automatic_correction_enabled = false; + settings.primary_album_storage = PrimaryAlbumStorage::SdCard; + settings.battery_percentage_flag = true; + settings.chinese_traditional_input_method = ChineseTraditionalInputMethod::Unknown0; + return settings; } diff --git a/src/core/hle/service/set/system_settings.h b/src/core/hle/service/set/setting_formats/system_settings.h index 6ec9e71e7..14654f8b1 100644 --- a/src/core/hle/service/set/system_settings.h +++ b/src/core/hle/service/set/setting_formats/system_settings.h @@ -8,272 +8,14 @@ #include "common/bit_field.h" #include "common/common_funcs.h" #include "common/common_types.h" -#include "core/hle/service/set/private_settings.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" #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 contrast_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 @@ -283,20 +25,16 @@ struct SystemSettings { // 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 - std::array<u8, 0x8> reserved_00008; - - // nn::settings::LanguageCode LanguageCode language_code; - - std::array<u8, 0x38> reserved_00018; + INSERT_PADDING_BYTES(0x38); // Reserved // 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; + INSERT_PADDING_BYTES(0x3); + INSERT_PADDING_BYTES(0x8); // Reserved // nn::settings::system::NetworkSettings std::array<std::array<u8, 0x400>, 32> network_settings_1B0; @@ -304,161 +42,142 @@ struct SystemSettings { // nn::settings::system::BluetoothDevicesSettings std::array<u8, 0x4> bluetooth_device_settings_count; bool bluetooth_enable_flag; - std::array<u8, 0x3> pad_08065; + INSERT_PADDING_BYTES(0x3); bool bluetooth_afh_enable_flag; - std::array<u8, 0x3> pad_08069; + INSERT_PADDING_BYTES(0x3); bool bluetooth_boost_enable_flag; - std::array<u8, 0x3> pad_0806D; + INSERT_PADDING_BYTES(0x3); std::array<std::array<u8, 0x200>, 10> bluetooth_device_settings_first_10; s32 ldn_channel; - - std::array<u8, 0x3C> reserved_09474; + INSERT_PADDING_BYTES(0x3C); // Reserved // nn::util::Uuid MiiAuthorId - std::array<u8, 0x10> mii_author_id; + Common::UUID mii_author_id; - std::array<u8, 0x30> reserved_094C0; + INSERT_PADDING_BYTES(0x30); // Reserved // nn::settings::system::NxControllerSettings u32 nx_controller_settings_count; - std::array<u8, 0xC> reserved_094F4; + 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; - - std::array<u8, 0x170> reserved_09780; + INSERT_PADDING_BYTES(0x170); // Reserved bool external_rtc_reset_flag; - std::array<u8, 0x3> pad_098F1; - - std::array<u8, 0x3C> reserved_098F4; + INSERT_PADDING_BYTES(0x3); + INSERT_PADDING_BYTES(0x3C); // Reserved s32 push_notification_activity_mode_on_sleep; + INSERT_PADDING_BYTES(0x3C); // Reserved - std::array<u8, 0x3C> reserved_09934; - - // nn::settings::system::ErrorReportSharePermission ErrorReportSharePermission error_report_share_permission; + INSERT_PADDING_BYTES(0x3C); // Reserved - std::array<u8, 0x3C> reserved_09974; - - // nn::settings::KeyboardLayout - std::array<u8, 0x4> keyboard_layout; - - std::array<u8, 0x3C> reserved_099B4; + KeyboardLayout keyboard_layout; + INSERT_PADDING_BYTES(0x3C); // Reserved bool web_inspector_flag; - std::array<u8, 0x3> pad_099F1; + INSERT_PADDING_BYTES(0x3); // 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; + 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; - - std::array<u8, 0x6C0> reserved_0A330; + INSERT_PADDING_BYTES(0x6C0); // Reserved // nn::settings::system::BlePairingSettings u32 ble_pairing_settings_count; - std::array<u8, 0xC> reserved_0A9F4; + 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; - std::array<u8, 0xC> reserved_0AF04; + INSERT_PADDING_BYTES(0xC); // Reserved 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; + 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 - std::array<u8, 0x100> reserved_0B250; - - // nn::settings::ChineseTraditionalInputMethod ChineseTraditionalInputMethod chinese_traditional_input_method; - - std::array<u8, 0x3C> reserved_0B354; + INSERT_PADDING_BYTES(0x3C); // Reserved bool zoom_flag; - std::array<u8, 0x3> pad_0B391; - - std::array<u8, 0x3C> reserved_0B394; + INSERT_PADDING_BYTES(0x3); + INSERT_PADDING_BYTES(0x3C); // Reserved // nn::settings::system::ButtonConfigRegisteredSettings u32 button_config_registered_settings_count; - std::array<u8, 0xC> reserved_0B3D4; + INSERT_PADDING_BYTES(0xC); // Reserved // nn::settings::system::ButtonConfigSettings u32 button_config_settings_count; - std::array<u8, 0x4> reserved_0B3E4; + INSERT_PADDING_BYTES(0x4); // Reserved std::array<std::array<u8, 0x5A8>, 5> button_config_settings; - std::array<u8, 0x13B0> reserved_0D030; + INSERT_PADDING_BYTES(0x13B0); // Reserved u32 button_config_settings_embedded_count; - std::array<u8, 0x4> reserved_0E3E4; + INSERT_PADDING_BYTES(0x4); // Reserved std::array<std::array<u8, 0x5A8>, 5> button_config_settings_embedded; - std::array<u8, 0x13B0> reserved_10030; + INSERT_PADDING_BYTES(0x13B0); // Reserved u32 button_config_settings_left_count; - std::array<u8, 0x4> reserved_113E4; + INSERT_PADDING_BYTES(0x4); // Reserved std::array<std::array<u8, 0x5A8>, 5> button_config_settings_left; - std::array<u8, 0x13B0> reserved_13030; + INSERT_PADDING_BYTES(0x13B0); // Reserved u32 button_config_settings_right_count; - std::array<u8, 0x4> reserved_143E4; + INSERT_PADDING_BYTES(0x4); // Reserved std::array<std::array<u8, 0x5A8>, 5> button_config_settings_right; - std::array<u8, 0x73B0> reserved_16030; + 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; - - std::array<u8, 0x7FF8> reserved_21378; + INSERT_PADDING_BYTES(0x7FF8); // Reserved // nn::settings::system::ConsoleSixAxisSensorAccelerationBias - std::array<u8, 0xC> console_six_axis_sensor_acceleration_bias; + Common::Vec3<f32> console_six_axis_sensor_acceleration_bias; // nn::settings::system::ConsoleSixAxisSensorAngularVelocityBias - std::array<u8, 0xC> console_six_axis_sensor_angular_velocity_bias; + 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 - std::array<u8, 0xC> console_six_axis_sensor_angular_velocity_time_bias; + 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; - - std::array<u8, 0x70> reserved_29400; + INSERT_PADDING_BYTES(0x70); // Reserved bool lock_screen_flag; - std::array<u8, 0x3> pad_29471; - - std::array<u8, 0x4> reserved_249274; + INSERT_PADDING_BYTES(0x3); + INSERT_PADDING_BYTES(0x4); // Reserved ColorSet color_set_id; QuestFlag quest_flag; - // nn::settings::system::RegionCode - RegionCode region_code; + SystemRegionCode region_code; // Different to nn::settings::system::InitialLaunchSettings? InitialLaunchSettingsPacked initial_launch_settings_packed; bool battery_percentage_flag; - std::array<u8, 0x3> pad_294A1; + INSERT_PADDING_BYTES(0x3); // BitFlagSet<32, nn::settings::system::AppletLaunchFlag> u32 applet_launch_flag; @@ -469,33 +188,26 @@ struct SystemSettings { std::array<u8, 0x10> theme_key; bool field_testing_flag; - std::array<u8, 0x3> pad_294C1; + INSERT_PADDING_BYTES(0x3); s32 panel_crc_mode; - - std::array<u8, 0x28> reserved_294C8; + INSERT_PADDING_BYTES(0x28); // Reserved // nn::settings::system::BacklightSettings std::array<u8, 0x2C> backlight_settings_mixed_up; + INSERT_PADDING_BYTES(0x64); // Reserved - 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 + INSERT_PADDING_BYTES(0x3); + INSERT_PADDING_BYTES(0x4); // Reserved Service::Time::Clock::SteadyClockTimePoint user_system_clock_automatic_correction_updated_time_point; + INSERT_PADDING_BYTES(0x10); // Reserved - std::array<u8, 0x10> reserved_295E0; - - // nn::settings::system::AccountSettings AccountSettings account_settings; - - std::array<u8, 0xFC> reserved_295F4; + INSERT_PADDING_BYTES(0xFC); // Reserved // nn::settings::system::AudioVolume std::array<u8, 0x8> audio_volume_type0; @@ -505,47 +217,42 @@ struct SystemSettings { s32 audio_output_mode_type1; s32 audio_output_mode_type2; bool force_mute_on_headphone_removed; - std::array<u8, 0x3> pad_2970D; + INSERT_PADDING_BYTES(0x3); s32 headphone_volume_warning_count; bool heaphone_volume_update_flag; - std::array<u8, 0x3> pad_29715; + INSERT_PADDING_BYTES(0x3); // 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; + INSERT_PADDING_BYTES(0x3); + INSERT_PADDING_BYTES(0x4); // Reserved s64 hearing_protection_safeguard_remaining_time; - std::array<u8, 0x38> reserved_29738; + INSERT_PADDING_BYTES(0x38); // Reserved bool console_information_upload_flag; - std::array<u8, 0x3> pad_29771; - - std::array<u8, 0x3C> reserved_29774; + INSERT_PADDING_BYTES(0x3); + INSERT_PADDING_BYTES(0x3C); // Reserved bool automatic_application_download_flag; - std::array<u8, 0x3> pad_297B1; - - std::array<u8, 0x4> reserved_297B4; + INSERT_PADDING_BYTES(0x3); + INSERT_PADDING_BYTES(0x4); // Reserved - // nn::settings::system::NotificationSettings NotificationSettings notification_settings; - - std::array<u8, 0x60> reserved_297D0; + INSERT_PADDING_BYTES(0x60); // Reserved // nn::settings::system::AccountNotificationSettings u32 account_notification_settings_count; - std::array<u8, 0xC> reserved_29834; + INSERT_PADDING_BYTES(0xC); // Reserved std::array<AccountNotificationSettings, 8> account_notification_settings; - - std::array<u8, 0x140> reserved_29900; + INSERT_PADDING_BYTES(0x140); // Reserved f32 vibration_master_volume; bool usb_full_key_enable_flag; - std::array<u8, 0x3> pad_29A45; + INSERT_PADDING_BYTES(0x3); // nn::settings::system::AnalogStickUserCalibration std::array<u8, 0x10> analog_stick_user_calibration_left; @@ -553,85 +260,68 @@ struct SystemSettings { // nn::settings::system::TouchScreenMode s32 touch_screen_mode; + INSERT_PADDING_BYTES(0x14); // Reserved - 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; + INSERT_PADDING_BYTES(0x2E0); // Reserved // nn::settings::system::DataDeletionSettings std::array<u8, 0x8> data_deletion_settings; - - std::array<u8, 0x38> reserved_29E88; + 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; - - std::array<u8, 0x4> reserved_29ED0; + INSERT_PADDING_BYTES(0x4); // Reserved bool requires_run_repair_time_reviser; + INSERT_PADDING_BYTES(0x6B); // Reserved - 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 + INSERT_PADDING_BYTES(0x4); // Reserved Service::Time::Clock::SteadyClockTimePoint device_time_zone_location_updated_time; - - std::array<u8, 0xC0> reserved_29F80; + INSERT_PADDING_BYTES(0xC0); // Reserved // nn::settings::system::PrimaryAlbumStorage PrimaryAlbumStorage primary_album_storage; - - std::array<u8, 0x3C> reserved_2A044; + INSERT_PADDING_BYTES(0x3C); // Reserved bool usb_30_enable_flag; - std::array<u8, 0x3> pad_2A081; + INSERT_PADDING_BYTES(0x3); bool usb_30_host_enable_flag; - std::array<u8, 0x3> pad_2A085; + INSERT_PADDING_BYTES(0x3); bool usb_30_device_enable_flag; - std::array<u8, 0x3> pad_2A089; - - std::array<u8, 0x34> reserved_2A08C; + INSERT_PADDING_BYTES(0x3); + INSERT_PADDING_BYTES(0x34); // Reserved bool nfc_enable_flag; - std::array<u8, 0x3> pad_2A0C1; - - std::array<u8, 0x3C> reserved_2A0C4; + INSERT_PADDING_BYTES(0x3); + INSERT_PADDING_BYTES(0x3C); // Reserved // nn::settings::system::SleepSettings SleepSettings sleep_settings; - - std::array<u8, 0x34> reserved_2A10C; + INSERT_PADDING_BYTES(0x34); // Reserved // nn::settings::system::EulaVersion u32 eula_version_count; - std::array<u8, 0xC> reserved_2A144; + INSERT_PADDING_BYTES(0xC); // Reserved std::array<EulaVersion, 32> eula_versions; - - std::array<u8, 0x200> reserved_2A750; + INSERT_PADDING_BYTES(0x200); // Reserved // nn::settings::system::DeviceNickName std::array<u8, 0x80> device_nick_name; - - std::array<u8, 0x80> reserved_2A9D0; + INSERT_PADDING_BYTES(0x80); // Reserved bool auto_update_enable_flag; - std::array<u8, 0x3> pad_2AA51; - - std::array<u8, 0x4C> reserved_2AA54; + 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; - - std::array<u8, 0x2000> reserved_2C6A0; + INSERT_PADDING_BYTES(0x2000); // Reserved // nn::settings::system::NxControllerSettings std::array<std::array<u8, 0x800>, 10> nx_controller_settings_data_from_offset_30; diff --git a/src/core/hle/service/set/settings_server.h b/src/core/hle/service/set/settings_server.h index a4e78db6c..8304e8424 100644 --- a/src/core/hle/service/set/settings_server.h +++ b/src/core/hle/service/set/settings_server.h @@ -4,72 +4,13 @@ #pragma once #include "core/hle/service/service.h" -#include "core/hle/service/set/system_settings.h" +#include "core/hle/service/set/settings_types.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); 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..4dee202d7 --- /dev/null +++ b/src/core/hle/service/set/settings_types.h @@ -0,0 +1,451 @@ +// 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/time/clock_types.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 { + Hdmi, + Speaker, + Headphone, +}; + +/// 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"); + +/// 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::system::EulaVersion +struct EulaVersion { + u32 version; + SystemRegionCode 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 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::Time::Clock::SteadyClockTimePoint timestamp; +}; +static_assert(sizeof(InitialLaunchSettings) == 0x20, "InitialLaunchSettings is incorrect size"); + +#pragma pack(push, 4) +struct InitialLaunchSettingsPacked { + InitialLaunchFlag flags; + Service::Time::Clock::SteadyClockTimePoint timestamp; +}; +#pragma pack(pop) +static_assert(sizeof(InitialLaunchSettingsPacked) == 0x1C, + "InitialLaunchSettingsPacked is incorrect size"); + +/// 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::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_server.cpp b/src/core/hle/service/set/system_settings_server.cpp index af9348522..2e5785fed 100644 --- a/src/core/hle/service/set/system_settings_server.cpp +++ b/src/core/hle/service/set/system_settings_server.cpp @@ -97,8 +97,8 @@ ISystemSettingsServer::ISystemSettingsServer(Core::System& system_) {3, &ISystemSettingsServer::GetFirmwareVersion, "GetFirmwareVersion"}, {4, &ISystemSettingsServer::GetFirmwareVersion2, "GetFirmwareVersion2"}, {5, nullptr, "GetFirmwareVersionDigest"}, - {7, nullptr, "GetLockScreenFlag"}, - {8, nullptr, "SetLockScreenFlag"}, + {7, &ISystemSettingsServer::GetLockScreenFlag, "GetLockScreenFlag"}, + {8, &ISystemSettingsServer::SetLockScreenFlag, "SetLockScreenFlag"}, {9, nullptr, "GetBacklightSettings"}, {10, nullptr, "SetBacklightSettings"}, {11, nullptr, "SetBluetoothDevicesSettings"}, @@ -157,12 +157,12 @@ ISystemSettingsServer::ISystemSettingsServer(Core::System& system_) {66, nullptr, "SetUsb30EnableFlag"}, {67, nullptr, "GetBatteryLot"}, {68, nullptr, "GetSerialNumber"}, - {69, nullptr, "GetNfcEnableFlag"}, - {70, nullptr, "SetNfcEnableFlag"}, + {69, &ISystemSettingsServer::GetNfcEnableFlag, "GetNfcEnableFlag"}, + {70, &ISystemSettingsServer::SetNfcEnableFlag, "SetNfcEnableFlag"}, {71, &ISystemSettingsServer::GetSleepSettings, "GetSleepSettings"}, {72, &ISystemSettingsServer::SetSleepSettings, "SetSleepSettings"}, - {73, nullptr, "GetWirelessLanEnableFlag"}, - {74, nullptr, "SetWirelessLanEnableFlag"}, + {73, &ISystemSettingsServer::GetWirelessLanEnableFlag, "GetWirelessLanEnableFlag"}, + {74, &ISystemSettingsServer::SetWirelessLanEnableFlag, "SetWirelessLanEnableFlag"}, {75, &ISystemSettingsServer::GetInitialLaunchSettings, "GetInitialLaunchSettings"}, {76, &ISystemSettingsServer::SetInitialLaunchSettings, "SetInitialLaunchSettings"}, {77, &ISystemSettingsServer::GetDeviceNickName, "GetDeviceNickName"}, @@ -176,8 +176,8 @@ ISystemSettingsServer::ISystemSettingsServer(Core::System& system_) {85, nullptr, "SetPtmBatteryLot"}, {86, nullptr, "GetPtmFuelGaugeParameter"}, {87, nullptr, "SetPtmFuelGaugeParameter"}, - {88, nullptr, "GetBluetoothEnableFlag"}, - {89, nullptr, "SetBluetoothEnableFlag"}, + {88, &ISystemSettingsServer::GetBluetoothEnableFlag, "GetBluetoothEnableFlag"}, + {89, &ISystemSettingsServer::SetBluetoothEnableFlag, "SetBluetoothEnableFlag"}, {90, &ISystemSettingsServer::GetMiiAuthorId, "GetMiiAuthorId"}, {91, nullptr, "SetShutdownRtcValue"}, {92, nullptr, "GetShutdownRtcValue"}, @@ -510,6 +510,25 @@ void ISystemSettingsServer::SetUserSystemClockContext(HLERequestContext& ctx) { 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"); @@ -531,7 +550,7 @@ void ISystemSettingsServer::SetAccountSettings(HLERequestContext& ctx) { } void ISystemSettingsServer::GetEulaVersions(HLERequestContext& ctx) { - LOG_INFO(Service_SET, "called"); + LOG_INFO(Service_SET, "called, elements={}", m_system_settings.eula_version_count); ctx.WriteBuffer(m_system_settings.eula_versions); @@ -557,7 +576,7 @@ void ISystemSettingsServer::SetEulaVersions(HLERequestContext& ctx) { } void ISystemSettingsServer::GetColorSetId(HLERequestContext& ctx) { - LOG_DEBUG(Service_SET, "called"); + LOG_DEBUG(Service_SET, "called, color_set=", m_system_settings.color_set_id); IPC::ResponseBuilder rb{ctx, 3}; rb.Push(ResultSuccess); @@ -576,7 +595,13 @@ void ISystemSettingsServer::SetColorSetId(HLERequestContext& ctx) { } void ISystemSettingsServer::GetNotificationSettings(HLERequestContext& ctx) { - LOG_INFO(Service_SET, "called"); + 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); @@ -601,7 +626,8 @@ void ISystemSettingsServer::SetNotificationSettings(HLERequestContext& ctx) { } void ISystemSettingsServer::GetAccountNotificationSettings(HLERequestContext& ctx) { - LOG_INFO(Service_SET, "called"); + LOG_INFO(Service_SET, "called, elements={}", + m_system_settings.account_notification_settings_count); ctx.WriteBuffer(m_system_settings.account_notification_settings); @@ -645,6 +671,7 @@ using Settings = static Settings GetSettings() { Settings ret; + // AM ret["hbloader"]["applet_heap_size"] = ToBytes(u64{0x0}); ret["hbloader"]["applet_heap_reservation_size"] = ToBytes(u64{0x8600000}); @@ -656,6 +683,24 @@ static Settings GetSettings() { ret["time"]["standard_steady_clock_test_offset_minutes"] = ToBytes(s32{0}); ret["time"]["standard_user_clock_initial_year"] = ToBytes(s32{2023}); + // HID + 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}); + + // Settings + ret["settings_debug"]["is_debug_mode_enabled"] = ToBytes(bool{false}); + return ret; } @@ -708,7 +753,15 @@ void ISystemSettingsServer::GetSettingsItemValue(HLERequestContext& ctx) { } void ISystemSettingsServer::GetTvSettings(HLERequestContext& ctx) { - LOG_INFO(Service_SET, "called"); + 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); @@ -735,23 +788,26 @@ void ISystemSettingsServer::SetTvSettings(HLERequestContext& ctx) { } void ISystemSettingsServer::GetDebugModeFlag(HLERequestContext& ctx) { - LOG_DEBUG(Service_SET, "called"); + 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<u32>(0); + rb.Push(is_debug_mode_enabled); } void ISystemSettingsServer::GetQuestFlag(HLERequestContext& ctx) { - LOG_WARNING(Service_SET, "(STUBBED) called"); + LOG_INFO(Service_SET, "called, quest_flag={}", m_system_settings.quest_flag); IPC::ResponseBuilder rb{ctx, 3}; rb.Push(ResultSuccess); - rb.PushEnum(QuestFlag::Retail); + rb.PushEnum(m_system_settings.quest_flag); } void ISystemSettingsServer::GetDeviceTimeZoneLocationName(HLERequestContext& ctx) { - LOG_WARNING(Service_SET, "called"); + LOG_INFO(Service_SET, "called"); Service::Time::TimeZone::LocationName name{}; auto res = GetDeviceTimeZoneLocationName(name); @@ -762,7 +818,7 @@ void ISystemSettingsServer::GetDeviceTimeZoneLocationName(HLERequestContext& ctx } void ISystemSettingsServer::SetDeviceTimeZoneLocationName(HLERequestContext& ctx) { - LOG_WARNING(Service_SET, "called"); + LOG_INFO(Service_SET, "called"); IPC::RequestParser rp{ctx}; auto name{rp.PopRaw<Service::Time::TimeZone::LocationName>()}; @@ -775,7 +831,7 @@ void ISystemSettingsServer::SetDeviceTimeZoneLocationName(HLERequestContext& ctx void ISystemSettingsServer::SetRegionCode(HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; - m_system_settings.region_code = rp.PopEnum<RegionCode>(); + m_system_settings.region_code = rp.PopEnum<SystemRegionCode>(); SetSaveNeeded(); LOG_INFO(Service_SET, "called, region_code={}", m_system_settings.region_code); @@ -832,15 +888,38 @@ void ISystemSettingsServer::SetUserSystemClockAutomaticCorrectionEnabled(HLERequ } void ISystemSettingsServer::GetPrimaryAlbumStorage(HLERequestContext& ctx) { - LOG_WARNING(Service_SET, "(STUBBED) called"); + 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::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.PushEnum(PrimaryAlbumStorage::SdCard); + 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"); + 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); @@ -861,8 +940,32 @@ void ISystemSettingsServer::SetSleepSettings(HLERequestContext& ctx) { 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"); + 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); @@ -913,35 +1016,56 @@ void ISystemSettingsServer::GetProductModel(HLERequestContext& ctx) { 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) { - const auto author_id = Common::UUID::MakeDefault(); + if (m_system_settings.mii_author_id.IsInvalid()) { + m_system_settings.mii_author_id = Common::UUID::MakeDefault(); + SetSaveNeeded(); + } - LOG_WARNING(Service_SET, "(STUBBED) called, author_id={}", author_id.FormattedString()); + LOG_INFO(Service_SET, "called, author_id={}", + m_system_settings.mii_author_id.FormattedString()); IPC::ResponseBuilder rb{ctx, 6}; rb.Push(ResultSuccess); - rb.PushRaw(author_id); + rb.PushRaw(m_system_settings.mii_author_id); } void ISystemSettingsServer::GetAutoUpdateEnableFlag(HLERequestContext& ctx) { - u8 auto_update_flag{}; - - LOG_WARNING(Service_SET, "(STUBBED) called, auto_update_flag={}", auto_update_flag); + 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(auto_update_flag); + rb.Push(m_system_settings.auto_update_enable_flag); } void ISystemSettingsServer::GetBatteryPercentageFlag(HLERequestContext& ctx) { - u8 battery_percentage_flag{1}; - - LOG_WARNING(Service_SET, "(STUBBED) called, battery_percentage_flag={}", - battery_percentage_flag); + LOG_DEBUG(Service_SET, "called, battery_percentage_flag={}", + m_system_settings.battery_percentage_flag); IPC::ResponseBuilder rb{ctx, 3}; rb.Push(ResultSuccess); - rb.Push(battery_percentage_flag); + rb.Push(m_system_settings.battery_percentage_flag); } void ISystemSettingsServer::SetExternalSteadyClockInternalOffset(HLERequestContext& ctx) { @@ -968,11 +1092,12 @@ void ISystemSettingsServer::GetExternalSteadyClockInternalOffset(HLERequestConte } void ISystemSettingsServer::GetErrorReportSharePermission(HLERequestContext& ctx) { - LOG_WARNING(Service_SET, "(STUBBED) called"); + 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(ErrorReportSharePermission::Denied); + rb.PushEnum(m_system_settings.error_report_share_permission); } void ISystemSettingsServer::GetAppletLaunchFlags(HLERequestContext& ctx) { @@ -1014,7 +1139,7 @@ void ISystemSettingsServer::GetKeyboardLayout(HLERequestContext& ctx) { } void ISystemSettingsServer::GetDeviceTimeZoneLocationUpdatedTime(HLERequestContext& ctx) { - LOG_WARNING(Service_SET, "called."); + LOG_INFO(Service_SET, "called"); Service::Time::Clock::SteadyClockTimePoint time_point{}; auto res = GetDeviceTimeZoneLocationUpdatedTime(time_point); @@ -1025,7 +1150,7 @@ void ISystemSettingsServer::GetDeviceTimeZoneLocationUpdatedTime(HLERequestConte } void ISystemSettingsServer::SetDeviceTimeZoneLocationUpdatedTime(HLERequestContext& ctx) { - LOG_WARNING(Service_SET, "called."); + LOG_INFO(Service_SET, "called"); IPC::RequestParser rp{ctx}; auto time_point{rp.PopRaw<Service::Time::Clock::SteadyClockTimePoint>()}; @@ -1038,7 +1163,7 @@ void ISystemSettingsServer::SetDeviceTimeZoneLocationUpdatedTime(HLERequestConte void ISystemSettingsServer::GetUserSystemClockAutomaticCorrectionUpdatedTime( HLERequestContext& ctx) { - LOG_WARNING(Service_SET, "called."); + LOG_INFO(Service_SET, "called"); Service::Time::Clock::SteadyClockTimePoint time_point{}; auto res = GetUserSystemClockAutomaticCorrectionUpdatedTime(time_point); @@ -1050,7 +1175,7 @@ void ISystemSettingsServer::GetUserSystemClockAutomaticCorrectionUpdatedTime( void ISystemSettingsServer::SetUserSystemClockAutomaticCorrectionUpdatedTime( HLERequestContext& ctx) { - LOG_WARNING(Service_SET, "called."); + LOG_INFO(Service_SET, "called"); IPC::RequestParser rp{ctx}; auto time_point{rp.PopRaw<Service::Time::Clock::SteadyClockTimePoint>()}; @@ -1062,11 +1187,12 @@ void ISystemSettingsServer::SetUserSystemClockAutomaticCorrectionUpdatedTime( } void ISystemSettingsServer::GetChineseTraditionalInputMethod(HLERequestContext& ctx) { - LOG_WARNING(Service_SET, "(STUBBED) called"); + 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(ChineseTraditionalInputMethod::Unknown0); + rb.PushEnum(m_system_settings.chinese_traditional_input_method); } void ISystemSettingsServer::GetHomeMenuScheme(HLERequestContext& ctx) { @@ -1094,11 +1220,11 @@ void ISystemSettingsServer::GetHomeMenuSchemeModel(HLERequestContext& ctx) { } void ISystemSettingsServer::GetFieldTestingFlag(HLERequestContext& ctx) { - LOG_WARNING(Service_SET, "(STUBBED) called"); + LOG_INFO(Service_SET, "called, field_testing_flag={}", m_system_settings.field_testing_flag); IPC::ResponseBuilder rb{ctx, 3}; rb.Push(ResultSuccess); - rb.Push<u8>(false); + rb.Push(m_system_settings.field_testing_flag); } void ISystemSettingsServer::SetupSettings() { diff --git a/src/core/hle/service/set/system_settings_server.h b/src/core/hle/service/set/system_settings_server.h index 6f587e0b3..32716f567 100644 --- a/src/core/hle/service/set/system_settings_server.h +++ b/src/core/hle/service/set/system_settings_server.h @@ -12,10 +12,11 @@ #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/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" #include "core/hle/service/time/clock_types.h" #include "core/hle/service/time/time_zone_types.h" @@ -24,25 +25,6 @@ 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); @@ -55,6 +37,18 @@ public: 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 GetExternalSteadyClockSourceId(Common::UUID& out_id); Result SetExternalSteadyClockSourceId(Common::UUID id); Result GetUserSystemClockContext(Service::Time::Clock::SystemClockContext& out_context); @@ -80,6 +74,8 @@ 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); @@ -108,13 +104,19 @@ private: void IsUserSystemClockAutomaticCorrectionEnabled(HLERequestContext& ctx); void SetUserSystemClockAutomaticCorrectionEnabled(HLERequestContext& ctx); void GetPrimaryAlbumStorage(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 GetBatteryPercentageFlag(HLERequestContext& ctx); diff --git a/src/core/hle/service/vi/display/vi_display.cpp b/src/core/hle/service/vi/display/vi_display.cpp index e2d9cd98a..725311c53 100644 --- a/src/core/hle/service/vi/display/vi_display.cpp +++ b/src/core/hle/service/vi/display/vi_display.cpp @@ -91,6 +91,10 @@ void Display::CreateLayer(u64 layer_id, u32 binder_id, layers.emplace_back(std::make_unique<Layer>(layer_id, binder_id, *core, *producer, std::move(buffer_item_consumer))); + if (is_abandoned) { + this->FindLayer(layer_id)->GetConsumer().Abandon(); + } + hos_binder_driver_server.RegisterProducer(std::move(producer)); } @@ -103,6 +107,13 @@ void Display::DestroyLayer(u64 layer_id) { [layer_id](const auto& layer) { return layer->GetLayerId() == layer_id; }); } +void Display::Abandon() { + for (auto& layer : layers) { + layer->GetConsumer().Abandon(); + } + is_abandoned = true; +} + Layer* Display::FindLayer(u64 layer_id) { const auto itr = std::find_if(layers.begin(), layers.end(), [layer_id](const std::unique_ptr<Layer>& layer) { diff --git a/src/core/hle/service/vi/display/vi_display.h b/src/core/hle/service/vi/display/vi_display.h index 7e68ee79b..8eb8a5155 100644 --- a/src/core/hle/service/vi/display/vi_display.h +++ b/src/core/hle/service/vi/display/vi_display.h @@ -98,6 +98,8 @@ public: layers.clear(); } + void Abandon(); + /// Attempts to find a layer with the given ID. /// /// @param layer_id The layer ID. @@ -124,6 +126,7 @@ private: std::vector<std::unique_ptr<Layer>> layers; Kernel::KEvent* vsync_event{}; + bool is_abandoned{}; }; } // namespace Service::VI diff --git a/src/core/hle/service/vi/layer/vi_layer.h b/src/core/hle/service/vi/layer/vi_layer.h index 295005e23..f95e2dc71 100644 --- a/src/core/hle/service/vi/layer/vi_layer.h +++ b/src/core/hle/service/vi/layer/vi_layer.h @@ -4,6 +4,7 @@ #pragma once #include <memory> +#include <utility> #include "common/common_types.h" @@ -75,12 +76,12 @@ public: return open; } - void Close() { - open = false; + bool Close() { + return std::exchange(open, false); } - void Open() { - open = true; + bool Open() { + return !std::exchange(open, true); } private: diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp index 39d5be90d..bfcc27ddc 100644 --- a/src/core/hle/service/vi/vi.cpp +++ b/src/core/hle/service/vi/vi.cpp @@ -719,7 +719,12 @@ private: return; } - nvnflinger.OpenLayer(layer_id); + if (!nvnflinger.OpenLayer(layer_id)) { + LOG_WARNING(Service_VI, "Tried to open layer which was already open"); + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultOperationFailed); + return; + } android::OutputParcel parcel; parcel.WriteInterface(NativeWindow{*buffer_queue_id}); @@ -737,7 +742,12 @@ private: LOG_DEBUG(Service_VI, "called. layer_id=0x{:016X}", layer_id); - nvnflinger.CloseLayer(layer_id); + if (!nvnflinger.CloseLayer(layer_id)) { + LOG_WARNING(Service_VI, "Tried to close layer which was not open"); + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultOperationFailed); + return; + } IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); |