general: preliminary support for hbl
This commit is contained in:
		| @@ -8,6 +8,7 @@ | ||||
| #include "core/file_sys/patch_manager.h" | ||||
| #include "core/file_sys/vfs.h" | ||||
| #include "core/hle/ipc_helpers.h" | ||||
| #include "core/hle/service/glue/glue_manager.h" | ||||
| #include "core/hle/service/ns/errors.h" | ||||
| #include "core/hle/service/ns/iplatform_service_manager.h" | ||||
| #include "core/hle/service/ns/language.h" | ||||
| @@ -581,7 +582,7 @@ IReadOnlyApplicationControlDataInterface::IReadOnlyApplicationControlDataInterfa | ||||
|     : ServiceFramework{system_, "IReadOnlyApplicationControlDataInterface"} { | ||||
|     // clang-format off | ||||
|     static const FunctionInfo functions[] = { | ||||
|         {0, nullptr, "GetApplicationControlData"}, | ||||
|         {0, &IReadOnlyApplicationControlDataInterface::GetApplicationControlData, "GetApplicationControlData"}, | ||||
|         {1, nullptr, "GetApplicationDesiredLanguage"}, | ||||
|         {2, nullptr, "ConvertApplicationLanguageToLanguageCode"}, | ||||
|         {3, nullptr, "ConvertLanguageCodeToApplicationLanguage"}, | ||||
| @@ -594,6 +595,33 @@ IReadOnlyApplicationControlDataInterface::IReadOnlyApplicationControlDataInterfa | ||||
|  | ||||
| IReadOnlyApplicationControlDataInterface::~IReadOnlyApplicationControlDataInterface() = default; | ||||
|  | ||||
| void IReadOnlyApplicationControlDataInterface::GetApplicationControlData( | ||||
|     Kernel::HLERequestContext& ctx) { | ||||
|     enum class ApplicationControlSource : u8 { | ||||
|         CacheOnly, | ||||
|         Storage, | ||||
|         StorageOnly, | ||||
|     }; | ||||
|  | ||||
|     struct RequestParameters { | ||||
|         ApplicationControlSource source; | ||||
|         u64 application_id; | ||||
|     }; | ||||
|     static_assert(sizeof(RequestParameters) == 0x10, "RequestParameters has incorrect size."); | ||||
|  | ||||
|     IPC::RequestParser rp{ctx}; | ||||
|     const auto parameters{rp.PopRaw<RequestParameters>()}; | ||||
|     const auto nacp_data{system.GetARPManager().GetControlProperty(parameters.application_id)}; | ||||
|     const auto result = nacp_data ? ResultSuccess : ResultUnknown; | ||||
|  | ||||
|     if (nacp_data) { | ||||
|         ctx.WriteBuffer(nacp_data->data(), nacp_data->size()); | ||||
|     } | ||||
|  | ||||
|     IPC::ResponseBuilder rb{ctx, 2}; | ||||
|     rb.Push(result); | ||||
| } | ||||
|  | ||||
| NS::NS(const char* name, Core::System& system_) : ServiceFramework{system_, name} { | ||||
|     // clang-format off | ||||
|     static const FunctionInfo functions[] = { | ||||
|   | ||||
| @@ -78,6 +78,9 @@ class IReadOnlyApplicationControlDataInterface final | ||||
| public: | ||||
|     explicit IReadOnlyApplicationControlDataInterface(Core::System& system_); | ||||
|     ~IReadOnlyApplicationControlDataInterface() override; | ||||
|  | ||||
| private: | ||||
|     void GetApplicationControlData(Kernel::HLERequestContext& ctx); | ||||
| }; | ||||
|  | ||||
| class NS final : public ServiceFramework<NS> { | ||||
|   | ||||
| @@ -15,7 +15,7 @@ TS::TS(Core::System& system_) : ServiceFramework{system_, "ts"} { | ||||
|         {0, nullptr, "GetTemperatureRange"}, | ||||
|         {1, &TS::GetTemperature, "GetTemperature"}, | ||||
|         {2, nullptr, "SetMeasurementMode"}, | ||||
|         {3, nullptr, "GetTemperatureMilliC"}, | ||||
|         {3, &TS::GetTemperatureMilliC, "GetTemperatureMilliC"}, | ||||
|         {4, nullptr, "OpenSession"}, | ||||
|     }; | ||||
|     // clang-format on | ||||
| @@ -29,8 +29,6 @@ void TS::GetTemperature(Kernel::HLERequestContext& ctx) { | ||||
|     IPC::RequestParser rp{ctx}; | ||||
|     const auto location{rp.PopEnum<Location>()}; | ||||
|  | ||||
|     LOG_WARNING(Service_HID, "(STUBBED) called. location={}", location); | ||||
|  | ||||
|     const s32 temperature = location == Location::Internal ? 35 : 20; | ||||
|  | ||||
|     IPC::ResponseBuilder rb{ctx, 3}; | ||||
| @@ -38,4 +36,15 @@ void TS::GetTemperature(Kernel::HLERequestContext& ctx) { | ||||
|     rb.Push(temperature); | ||||
| } | ||||
|  | ||||
| void TS::GetTemperatureMilliC(Kernel::HLERequestContext& ctx) { | ||||
|     IPC::RequestParser rp{ctx}; | ||||
|     const auto location{rp.PopEnum<Location>()}; | ||||
|  | ||||
|     const s32 temperature = location == Location::Internal ? 35000 : 20000; | ||||
|  | ||||
|     IPC::ResponseBuilder rb{ctx, 3}; | ||||
|     rb.Push(ResultSuccess); | ||||
|     rb.Push(temperature); | ||||
| } | ||||
|  | ||||
| } // namespace Service::PTM | ||||
|   | ||||
| @@ -20,6 +20,7 @@ private: | ||||
|     }; | ||||
|  | ||||
|     void GetTemperature(Kernel::HLERequestContext& ctx); | ||||
|     void GetTemperatureMilliC(Kernel::HLERequestContext& ctx); | ||||
| }; | ||||
|  | ||||
| } // namespace Service::PTM | ||||
|   | ||||
| @@ -101,6 +101,81 @@ void SET_SYS::SetColorSetId(Kernel::HLERequestContext& ctx) { | ||||
|     rb.Push(ResultSuccess); | ||||
| } | ||||
|  | ||||
| // FIXME: implement support for the real system_settings.ini | ||||
|  | ||||
| template <typename T> | ||||
| static std::vector<u8> ToBytes(const T& value) { | ||||
|     static_assert(std::is_trivially_copyable_v<T>); | ||||
|  | ||||
|     const auto* begin = reinterpret_cast<const u8*>(&value); | ||||
|     const auto* end = begin + sizeof(T); | ||||
|  | ||||
|     return std::vector<u8>(begin, end); | ||||
| } | ||||
|  | ||||
| using Settings = | ||||
|     std::map<std::string, std::map<std::string, std::vector<u8>, std::less<>>, std::less<>>; | ||||
|  | ||||
| static Settings GetSettings() { | ||||
|     Settings ret; | ||||
|  | ||||
|     ret["hbloader"]["applet_heap_size"] = ToBytes(u64{0x0}); | ||||
|     ret["hbloader"]["applet_heap_reservation_size"] = ToBytes(u64{0x8600000}); | ||||
|  | ||||
|     return ret; | ||||
| } | ||||
|  | ||||
| void SET_SYS::GetSettingsItemValueSize(Kernel::HLERequestContext& ctx) { | ||||
|     LOG_DEBUG(Service_SET, "called"); | ||||
|  | ||||
|     // The category of the setting. This corresponds to the top-level keys of | ||||
|     // system_settings.ini. | ||||
|     const auto setting_category_buf{ctx.ReadBuffer(0)}; | ||||
|     const std::string setting_category{setting_category_buf.begin(), setting_category_buf.end()}; | ||||
|  | ||||
|     // The name of the setting. This corresponds to the second-level keys of | ||||
|     // system_settings.ini. | ||||
|     const auto setting_name_buf{ctx.ReadBuffer(1)}; | ||||
|     const std::string setting_name{setting_name_buf.begin(), setting_name_buf.end()}; | ||||
|  | ||||
|     auto settings{GetSettings()}; | ||||
|     u64 response_size{0}; | ||||
|  | ||||
|     if (settings.contains(setting_category) && settings[setting_category].contains(setting_name)) { | ||||
|         response_size = settings[setting_category][setting_name].size(); | ||||
|     } | ||||
|  | ||||
|     IPC::ResponseBuilder rb{ctx, 4}; | ||||
|     rb.Push(response_size == 0 ? ResultUnknown : ResultSuccess); | ||||
|     rb.Push(response_size); | ||||
| } | ||||
|  | ||||
| void SET_SYS::GetSettingsItemValue(Kernel::HLERequestContext& ctx) { | ||||
|     LOG_DEBUG(Service_SET, "called"); | ||||
|  | ||||
|     // The category of the setting. This corresponds to the top-level keys of | ||||
|     // system_settings.ini. | ||||
|     const auto setting_category_buf{ctx.ReadBuffer(0)}; | ||||
|     const std::string setting_category{setting_category_buf.begin(), setting_category_buf.end()}; | ||||
|  | ||||
|     // The name of the setting. This corresponds to the second-level keys of | ||||
|     // system_settings.ini. | ||||
|     const auto setting_name_buf{ctx.ReadBuffer(1)}; | ||||
|     const std::string setting_name{setting_name_buf.begin(), setting_name_buf.end()}; | ||||
|  | ||||
|     auto settings{GetSettings()}; | ||||
|     Result response{ResultUnknown}; | ||||
|  | ||||
|     if (settings.contains(setting_category) && settings[setting_category].contains(setting_name)) { | ||||
|         auto setting_value = settings[setting_category][setting_name]; | ||||
|         ctx.WriteBuffer(setting_value.data(), setting_value.size()); | ||||
|         response = ResultSuccess; | ||||
|     } | ||||
|  | ||||
|     IPC::ResponseBuilder rb{ctx, 2}; | ||||
|     rb.Push(response); | ||||
| } | ||||
|  | ||||
| SET_SYS::SET_SYS(Core::System& system_) : ServiceFramework{system_, "set:sys"} { | ||||
|     // clang-format off | ||||
|     static const FunctionInfo functions[] = { | ||||
| @@ -138,8 +213,8 @@ SET_SYS::SET_SYS(Core::System& system_) : ServiceFramework{system_, "set:sys"} { | ||||
|         {32, nullptr, "SetAccountNotificationSettings"}, | ||||
|         {35, nullptr, "GetVibrationMasterVolume"}, | ||||
|         {36, nullptr, "SetVibrationMasterVolume"}, | ||||
|         {37, nullptr, "GetSettingsItemValueSize"}, | ||||
|         {38, nullptr, "GetSettingsItemValue"}, | ||||
|         {37, &SET_SYS::GetSettingsItemValueSize, "GetSettingsItemValueSize"}, | ||||
|         {38, &SET_SYS::GetSettingsItemValue, "GetSettingsItemValue"}, | ||||
|         {39, nullptr, "GetTvSettings"}, | ||||
|         {40, nullptr, "SetTvSettings"}, | ||||
|         {41, nullptr, "GetEdid"}, | ||||
|   | ||||
| @@ -23,6 +23,8 @@ private: | ||||
|         BasicBlack = 1, | ||||
|     }; | ||||
|  | ||||
|     void GetSettingsItemValueSize(Kernel::HLERequestContext& ctx); | ||||
|     void GetSettingsItemValue(Kernel::HLERequestContext& ctx); | ||||
|     void GetFirmwareVersion(Kernel::HLERequestContext& ctx); | ||||
|     void GetFirmwareVersion2(Kernel::HLERequestContext& ctx); | ||||
|     void GetColorSetId(Kernel::HLERequestContext& ctx); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user