forked from eden-emu/eden
		
	Implement IApplicationFunctions::GetDesiredLanguage
This commit is contained in:
		
							parent
							
								
									d9b4b49538
								
							
						
					
					
						commit
						e417da5070
					
				
					 9 changed files with 1004 additions and 397 deletions
				
			
		|  | @ -326,8 +326,11 @@ add_library(core STATIC | ||||||
|     hle/service/nim/nim.h |     hle/service/nim/nim.h | ||||||
|     hle/service/npns/npns.cpp |     hle/service/npns/npns.cpp | ||||||
|     hle/service/npns/npns.h |     hle/service/npns/npns.h | ||||||
|  |     hle/service/ns/errors.h | ||||||
|     hle/service/ns/ns.cpp |     hle/service/ns/ns.cpp | ||||||
|     hle/service/ns/ns.h |     hle/service/ns/ns.h | ||||||
|  |     hle/service/ns/ns_language.cpp | ||||||
|  |     hle/service/ns/ns_language.h | ||||||
|     hle/service/ns/pl_u.cpp |     hle/service/ns/pl_u.cpp | ||||||
|     hle/service/ns/pl_u.h |     hle/service/ns/pl_u.h | ||||||
|     hle/service/nvdrv/devices/nvdevice.h |     hle/service/nvdrv/devices/nvdevice.h | ||||||
|  |  | ||||||
|  | @ -87,6 +87,10 @@ u64 NACP::GetDefaultJournalSaveSize() const { | ||||||
|     return raw.user_account_save_data_journal_size; |     return raw.user_account_save_data_journal_size; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | u32 NACP::GetSupportedLanguages() const { | ||||||
|  |     return raw.supported_languages; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| std::vector<u8> NACP::GetRawBytes() const { | std::vector<u8> NACP::GetRawBytes() const { | ||||||
|     std::vector<u8> out(sizeof(RawNACP)); |     std::vector<u8> out(sizeof(RawNACP)); | ||||||
|     std::memcpy(out.data(), &raw, sizeof(RawNACP)); |     std::memcpy(out.data(), &raw, sizeof(RawNACP)); | ||||||
|  |  | ||||||
|  | @ -109,6 +109,7 @@ public: | ||||||
|     std::string GetVersionString() const; |     std::string GetVersionString() const; | ||||||
|     u64 GetDefaultNormalSaveSize() const; |     u64 GetDefaultNormalSaveSize() const; | ||||||
|     u64 GetDefaultJournalSaveSize() const; |     u64 GetDefaultJournalSaveSize() const; | ||||||
|  |     u32 GetSupportedLanguages() const; | ||||||
|     std::vector<u8> GetRawBytes() const; |     std::vector<u8> GetRawBytes() const; | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|  |  | ||||||
|  | @ -8,6 +8,8 @@ | ||||||
| #include <cstring> | #include <cstring> | ||||||
| #include "audio_core/audio_renderer.h" | #include "audio_core/audio_renderer.h" | ||||||
| #include "core/core.h" | #include "core/core.h" | ||||||
|  | #include "core/file_sys/control_metadata.h" | ||||||
|  | #include "core/file_sys/patch_manager.h" | ||||||
| #include "core/file_sys/savedata_factory.h" | #include "core/file_sys/savedata_factory.h" | ||||||
| #include "core/hle/ipc_helpers.h" | #include "core/hle/ipc_helpers.h" | ||||||
| #include "core/hle/kernel/kernel.h" | #include "core/hle/kernel/kernel.h" | ||||||
|  | @ -29,9 +31,11 @@ | ||||||
| #include "core/hle/service/am/tcap.h" | #include "core/hle/service/am/tcap.h" | ||||||
| #include "core/hle/service/apm/apm.h" | #include "core/hle/service/apm/apm.h" | ||||||
| #include "core/hle/service/filesystem/filesystem.h" | #include "core/hle/service/filesystem/filesystem.h" | ||||||
|  | #include "core/hle/service/ns/ns.h" | ||||||
| #include "core/hle/service/nvflinger/nvflinger.h" | #include "core/hle/service/nvflinger/nvflinger.h" | ||||||
| #include "core/hle/service/pm/pm.h" | #include "core/hle/service/pm/pm.h" | ||||||
| #include "core/hle/service/set/set.h" | #include "core/hle/service/set/set.h" | ||||||
|  | #include "core/hle/service/sm/sm.h" | ||||||
| #include "core/hle/service/vi/vi.h" | #include "core/hle/service/vi/vi.h" | ||||||
| #include "core/settings.h" | #include "core/settings.h" | ||||||
| 
 | 
 | ||||||
|  | @ -1100,10 +1104,42 @@ void IApplicationFunctions::GetDesiredLanguage(Kernel::HLERequestContext& ctx) { | ||||||
|     // TODO(bunnei): This should be configurable
 |     // TODO(bunnei): This should be configurable
 | ||||||
|     LOG_DEBUG(Service_AM, "called"); |     LOG_DEBUG(Service_AM, "called"); | ||||||
| 
 | 
 | ||||||
|  |     // Get supported languages from NACP, if possible
 | ||||||
|  |     // Default to 0 (all languages supported)
 | ||||||
|  |     u32 supported_languages = 0; | ||||||
|  |     FileSys::PatchManager pm{Core::System::GetInstance().CurrentProcess()->GetTitleID()}; | ||||||
|  | 
 | ||||||
|  |     const auto res = pm.GetControlMetadata(); | ||||||
|  |     if (res.first != nullptr) { | ||||||
|  |         supported_languages = res.first->GetSupportedLanguages(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // Call IApplicationManagerInterface implementation.
 | ||||||
|  |     auto& service_manager = Core::System::GetInstance().ServiceManager(); | ||||||
|  |     auto ns_am2 = service_manager.GetService<Service::NS::NS>("ns:am2"); | ||||||
|  |     auto app_man = ns_am2->GetApplicationManagerInterface(); | ||||||
|  | 
 | ||||||
|  |     // Get desired application language
 | ||||||
|  |     const auto res_lang = app_man->GetApplicationDesiredLanguage(supported_languages); | ||||||
|  |     if (res_lang.Failed()) { | ||||||
|  |         IPC::ResponseBuilder rb{ctx, 2}; | ||||||
|  |         rb.Push(res_lang.Code()); | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // Convert to settings language code.
 | ||||||
|  |     const auto res_code = app_man->ConvertApplicationLanguageToLanguageCode(*res_lang); | ||||||
|  |     if (res_code.Failed()) { | ||||||
|  |         IPC::ResponseBuilder rb{ctx, 2}; | ||||||
|  |         rb.Push(res_code.Code()); | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     LOG_DEBUG(Service_AM, "got desired_language={:016X}", *res_code); | ||||||
|  | 
 | ||||||
|     IPC::ResponseBuilder rb{ctx, 4}; |     IPC::ResponseBuilder rb{ctx, 4}; | ||||||
|     rb.Push(RESULT_SUCCESS); |     rb.Push(RESULT_SUCCESS); | ||||||
|     rb.Push( |     rb.Push(*res_code); | ||||||
|         static_cast<u64>(Service::Set::GetLanguageCodeFromIndex(Settings::values.language_index))); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void IApplicationFunctions::InitializeGamePlayRecording(Kernel::HLERequestContext& ctx) { | void IApplicationFunctions::InitializeGamePlayRecording(Kernel::HLERequestContext& ctx) { | ||||||
|  |  | ||||||
							
								
								
									
										13
									
								
								src/core/hle/service/ns/errors.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								src/core/hle/service/ns/errors.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,13 @@ | ||||||
|  | // Copyright 2019 yuzu emulator team
 | ||||||
|  | // Licensed under GPLv2 or any later version
 | ||||||
|  | // Refer to the license.txt file included.
 | ||||||
|  | 
 | ||||||
|  | #pragma once | ||||||
|  | 
 | ||||||
|  | #include "core/hle/result.h" | ||||||
|  | 
 | ||||||
|  | namespace Service::NS { | ||||||
|  | 
 | ||||||
|  | constexpr ResultCode ERR_APPLICATION_LANGUAGE_NOT_FOUND{ErrorModule::NS, 300}; | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | @ -7,445 +7,490 @@ | ||||||
| #include "core/file_sys/patch_manager.h" | #include "core/file_sys/patch_manager.h" | ||||||
| #include "core/hle/ipc_helpers.h" | #include "core/hle/ipc_helpers.h" | ||||||
| #include "core/hle/kernel/hle_ipc.h" | #include "core/hle/kernel/hle_ipc.h" | ||||||
|  | #include "core/hle/service/ns/errors.h" | ||||||
| #include "core/hle/service/ns/ns.h" | #include "core/hle/service/ns/ns.h" | ||||||
|  | #include "core/hle/service/ns/ns_language.h" | ||||||
| #include "core/hle/service/ns/pl_u.h" | #include "core/hle/service/ns/pl_u.h" | ||||||
|  | #include "core/settings.h" | ||||||
| 
 | 
 | ||||||
| namespace Service::NS { | namespace Service::NS { | ||||||
| 
 | 
 | ||||||
| class IAccountProxyInterface final : public ServiceFramework<IAccountProxyInterface> { | IAccountProxyInterface::IAccountProxyInterface() : ServiceFramework{"IAccountProxyInterface"} { | ||||||
| public: |     // clang-format off
 | ||||||
|     explicit IAccountProxyInterface() : ServiceFramework{"IAccountProxyInterface"} { |     static const FunctionInfo functions[] = { | ||||||
|         // clang-format off
 |         {0, nullptr, "CreateUserAccount"}, | ||||||
|         static const FunctionInfo functions[] = { |     }; | ||||||
|             {0, nullptr, "CreateUserAccount"}, |     // clang-format on
 | ||||||
|         }; |  | ||||||
|         // clang-format on
 |  | ||||||
| 
 | 
 | ||||||
|         RegisterHandlers(functions); |     RegisterHandlers(functions); | ||||||
|     } | } | ||||||
| }; |  | ||||||
| 
 | 
 | ||||||
| class IApplicationManagerInterface final : public ServiceFramework<IApplicationManagerInterface> { | IApplicationManagerInterface::IApplicationManagerInterface() | ||||||
| public: |     : ServiceFramework{"IApplicationManagerInterface"} { | ||||||
|     explicit IApplicationManagerInterface() : ServiceFramework{"IApplicationManagerInterface"} { |     // clang-format off
 | ||||||
|         // clang-format off
 |     static const FunctionInfo functions[] = { | ||||||
|         static const FunctionInfo functions[] = { |         {0, nullptr, "ListApplicationRecord"}, | ||||||
|             {0, nullptr, "ListApplicationRecord"}, |         {1, nullptr, "GenerateApplicationRecordCount"}, | ||||||
|             {1, nullptr, "GenerateApplicationRecordCount"}, |         {2, nullptr, "GetApplicationRecordUpdateSystemEvent"}, | ||||||
|             {2, nullptr, "GetApplicationRecordUpdateSystemEvent"}, |         {3, nullptr, "GetApplicationViewDeprecated"}, | ||||||
|             {3, nullptr, "GetApplicationViewDeprecated"}, |         {4, nullptr, "DeleteApplicationEntity"}, | ||||||
|             {4, nullptr, "DeleteApplicationEntity"}, |         {5, nullptr, "DeleteApplicationCompletely"}, | ||||||
|             {5, nullptr, "DeleteApplicationCompletely"}, |         {6, nullptr, "IsAnyApplicationEntityRedundant"}, | ||||||
|             {6, nullptr, "IsAnyApplicationEntityRedundant"}, |         {7, nullptr, "DeleteRedundantApplicationEntity"}, | ||||||
|             {7, nullptr, "DeleteRedundantApplicationEntity"}, |         {8, nullptr, "IsApplicationEntityMovable"}, | ||||||
|             {8, nullptr, "IsApplicationEntityMovable"}, |         {9, nullptr, "MoveApplicationEntity"}, | ||||||
|             {9, nullptr, "MoveApplicationEntity"}, |         {11, nullptr, "CalculateApplicationOccupiedSize"}, | ||||||
|             {11, nullptr, "CalculateApplicationOccupiedSize"}, |         {16, nullptr, "PushApplicationRecord"}, | ||||||
|             {16, nullptr, "PushApplicationRecord"}, |         {17, nullptr, "ListApplicationRecordContentMeta"}, | ||||||
|             {17, nullptr, "ListApplicationRecordContentMeta"}, |         {19, nullptr, "LaunchApplicationOld"}, | ||||||
|             {19, nullptr, "LaunchApplicationOld"}, |         {21, nullptr, "GetApplicationContentPath"}, | ||||||
|             {21, nullptr, "GetApplicationContentPath"}, |         {22, nullptr, "TerminateApplication"}, | ||||||
|             {22, nullptr, "TerminateApplication"}, |         {23, nullptr, "ResolveApplicationContentPath"}, | ||||||
|             {23, nullptr, "ResolveApplicationContentPath"}, |         {26, nullptr, "BeginInstallApplication"}, | ||||||
|             {26, nullptr, "BeginInstallApplication"}, |         {27, nullptr, "DeleteApplicationRecord"}, | ||||||
|             {27, nullptr, "DeleteApplicationRecord"}, |         {30, nullptr, "RequestApplicationUpdateInfo"}, | ||||||
|             {30, nullptr, "RequestApplicationUpdateInfo"}, |         {32, nullptr, "CancelApplicationDownload"}, | ||||||
|             {32, nullptr, "CancelApplicationDownload"}, |         {33, nullptr, "ResumeApplicationDownload"}, | ||||||
|             {33, nullptr, "ResumeApplicationDownload"}, |         {35, nullptr, "UpdateVersionList"}, | ||||||
|             {35, nullptr, "UpdateVersionList"}, |         {36, nullptr, "PushLaunchVersion"}, | ||||||
|             {36, nullptr, "PushLaunchVersion"}, |         {37, nullptr, "ListRequiredVersion"}, | ||||||
|             {37, nullptr, "ListRequiredVersion"}, |         {38, nullptr, "CheckApplicationLaunchVersion"}, | ||||||
|             {38, nullptr, "CheckApplicationLaunchVersion"}, |         {39, nullptr, "CheckApplicationLaunchRights"}, | ||||||
|             {39, nullptr, "CheckApplicationLaunchRights"}, |         {40, nullptr, "GetApplicationLogoData"}, | ||||||
|             {40, nullptr, "GetApplicationLogoData"}, |         {41, nullptr, "CalculateApplicationDownloadRequiredSize"}, | ||||||
|             {41, nullptr, "CalculateApplicationDownloadRequiredSize"}, |         {42, nullptr, "CleanupSdCard"}, | ||||||
|             {42, nullptr, "CleanupSdCard"}, |         {43, nullptr, "CheckSdCardMountStatus"}, | ||||||
|             {43, nullptr, "CheckSdCardMountStatus"}, |         {44, nullptr, "GetSdCardMountStatusChangedEvent"}, | ||||||
|             {44, nullptr, "GetSdCardMountStatusChangedEvent"}, |         {45, nullptr, "GetGameCardAttachmentEvent"}, | ||||||
|             {45, nullptr, "GetGameCardAttachmentEvent"}, |         {46, nullptr, "GetGameCardAttachmentInfo"}, | ||||||
|             {46, nullptr, "GetGameCardAttachmentInfo"}, |         {47, nullptr, "GetTotalSpaceSize"}, | ||||||
|             {47, nullptr, "GetTotalSpaceSize"}, |         {48, nullptr, "GetFreeSpaceSize"}, | ||||||
|             {48, nullptr, "GetFreeSpaceSize"}, |         {49, nullptr, "GetSdCardRemovedEvent"}, | ||||||
|             {49, nullptr, "GetSdCardRemovedEvent"}, |         {52, nullptr, "GetGameCardUpdateDetectionEvent"}, | ||||||
|             {52, nullptr, "GetGameCardUpdateDetectionEvent"}, |         {53, nullptr, "DisableApplicationAutoDelete"}, | ||||||
|             {53, nullptr, "DisableApplicationAutoDelete"}, |         {54, nullptr, "EnableApplicationAutoDelete"}, | ||||||
|             {54, nullptr, "EnableApplicationAutoDelete"}, |         {55, &IApplicationManagerInterface::GetApplicationDesiredLanguage, "GetApplicationDesiredLanguage"}, | ||||||
|             {55, nullptr, "GetApplicationDesiredLanguage"}, |         {56, nullptr, "SetApplicationTerminateResult"}, | ||||||
|             {56, nullptr, "SetApplicationTerminateResult"}, |         {57, nullptr, "ClearApplicationTerminateResult"}, | ||||||
|             {57, nullptr, "ClearApplicationTerminateResult"}, |         {58, nullptr, "GetLastSdCardMountUnexpectedResult"}, | ||||||
|             {58, nullptr, "GetLastSdCardMountUnexpectedResult"}, |         {59, &IApplicationManagerInterface::ConvertApplicationLanguageToLanguageCode, "ConvertApplicationLanguageToLanguageCode"}, | ||||||
|             {59, nullptr, "ConvertApplicationLanguageToLanguageCode"}, |         {60, nullptr, "ConvertLanguageCodeToApplicationLanguage"}, | ||||||
|             {60, nullptr, "ConvertLanguageCodeToApplicationLanguage"}, |         {61, nullptr, "GetBackgroundDownloadStressTaskInfo"}, | ||||||
|             {61, nullptr, "GetBackgroundDownloadStressTaskInfo"}, |         {62, nullptr, "GetGameCardStopper"}, | ||||||
|             {62, nullptr, "GetGameCardStopper"}, |         {63, nullptr, "IsSystemProgramInstalled"}, | ||||||
|             {63, nullptr, "IsSystemProgramInstalled"}, |         {64, nullptr, "StartApplyDeltaTask"}, | ||||||
|             {64, nullptr, "StartApplyDeltaTask"}, |         {65, nullptr, "GetRequestServerStopper"}, | ||||||
|             {65, nullptr, "GetRequestServerStopper"}, |         {66, nullptr, "GetBackgroundApplyDeltaStressTaskInfo"}, | ||||||
|             {66, nullptr, "GetBackgroundApplyDeltaStressTaskInfo"}, |         {67, nullptr, "CancelApplicationApplyDelta"}, | ||||||
|             {67, nullptr, "CancelApplicationApplyDelta"}, |         {68, nullptr, "ResumeApplicationApplyDelta"}, | ||||||
|             {68, nullptr, "ResumeApplicationApplyDelta"}, |         {69, nullptr, "CalculateApplicationApplyDeltaRequiredSize"}, | ||||||
|             {69, nullptr, "CalculateApplicationApplyDeltaRequiredSize"}, |         {70, nullptr, "ResumeAll"}, | ||||||
|             {70, nullptr, "ResumeAll"}, |         {71, nullptr, "GetStorageSize"}, | ||||||
|             {71, nullptr, "GetStorageSize"}, |         {80, nullptr, "RequestDownloadApplication"}, | ||||||
|             {80, nullptr, "RequestDownloadApplication"}, |         {81, nullptr, "RequestDownloadAddOnContent"}, | ||||||
|             {81, nullptr, "RequestDownloadAddOnContent"}, |         {82, nullptr, "DownloadApplication"}, | ||||||
|             {82, nullptr, "DownloadApplication"}, |         {83, nullptr, "CheckApplicationResumeRights"}, | ||||||
|             {83, nullptr, "CheckApplicationResumeRights"}, |         {84, nullptr, "GetDynamicCommitEvent"}, | ||||||
|             {84, nullptr, "GetDynamicCommitEvent"}, |         {85, nullptr, "RequestUpdateApplication2"}, | ||||||
|             {85, nullptr, "RequestUpdateApplication2"}, |         {86, nullptr, "EnableApplicationCrashReport"}, | ||||||
|             {86, nullptr, "EnableApplicationCrashReport"}, |         {87, nullptr, "IsApplicationCrashReportEnabled"}, | ||||||
|             {87, nullptr, "IsApplicationCrashReportEnabled"}, |         {90, nullptr, "BoostSystemMemoryResourceLimit"}, | ||||||
|             {90, nullptr, "BoostSystemMemoryResourceLimit"}, |         {91, nullptr, "DeprecatedLaunchApplication"}, | ||||||
|             {91, nullptr, "DeprecatedLaunchApplication"}, |         {92, nullptr, "GetRunningApplicationProgramId"}, | ||||||
|             {92, nullptr, "GetRunningApplicationProgramId"}, |         {93, nullptr, "GetMainApplicationProgramIndex"}, | ||||||
|             {93, nullptr, "GetMainApplicationProgramIndex"}, |         {94, nullptr, "LaunchApplication"}, | ||||||
|             {94, nullptr, "LaunchApplication"}, |         {95, nullptr, "GetApplicationLaunchInfo"}, | ||||||
|             {95, nullptr, "GetApplicationLaunchInfo"}, |         {96, nullptr, "AcquireApplicationLaunchInfo"}, | ||||||
|             {96, nullptr, "AcquireApplicationLaunchInfo"}, |         {97, nullptr, "GetMainApplicationProgramIndex2"}, | ||||||
|             {97, nullptr, "GetMainApplicationProgramIndex2"}, |         {98, nullptr, "EnableApplicationAllThreadDumpOnCrash"}, | ||||||
|             {98, nullptr, "EnableApplicationAllThreadDumpOnCrash"}, |         {100, nullptr, "ResetToFactorySettings"}, | ||||||
|             {100, nullptr, "ResetToFactorySettings"}, |         {101, nullptr, "ResetToFactorySettingsWithoutUserSaveData"}, | ||||||
|             {101, nullptr, "ResetToFactorySettingsWithoutUserSaveData"}, |         {102, nullptr, "ResetToFactorySettingsForRefurbishment"}, | ||||||
|             {102, nullptr, "ResetToFactorySettingsForRefurbishment"}, |         {200, nullptr, "CalculateUserSaveDataStatistics"}, | ||||||
|             {200, nullptr, "CalculateUserSaveDataStatistics"}, |         {201, nullptr, "DeleteUserSaveDataAll"}, | ||||||
|             {201, nullptr, "DeleteUserSaveDataAll"}, |         {210, nullptr, "DeleteUserSystemSaveData"}, | ||||||
|             {210, nullptr, "DeleteUserSystemSaveData"}, |         {211, nullptr, "DeleteSaveData"}, | ||||||
|             {211, nullptr, "DeleteSaveData"}, |         {220, nullptr, "UnregisterNetworkServiceAccount"}, | ||||||
|             {220, nullptr, "UnregisterNetworkServiceAccount"}, |         {221, nullptr, "UnregisterNetworkServiceAccountWithUserSaveDataDeletion"}, | ||||||
|             {221, nullptr, "UnregisterNetworkServiceAccountWithUserSaveDataDeletion"}, |         {300, nullptr, "GetApplicationShellEvent"}, | ||||||
|             {300, nullptr, "GetApplicationShellEvent"}, |         {301, nullptr, "PopApplicationShellEventInfo"}, | ||||||
|             {301, nullptr, "PopApplicationShellEventInfo"}, |         {302, nullptr, "LaunchLibraryApplet"}, | ||||||
|             {302, nullptr, "LaunchLibraryApplet"}, |         {303, nullptr, "TerminateLibraryApplet"}, | ||||||
|             {303, nullptr, "TerminateLibraryApplet"}, |         {304, nullptr, "LaunchSystemApplet"}, | ||||||
|             {304, nullptr, "LaunchSystemApplet"}, |         {305, nullptr, "TerminateSystemApplet"}, | ||||||
|             {305, nullptr, "TerminateSystemApplet"}, |         {306, nullptr, "LaunchOverlayApplet"}, | ||||||
|             {306, nullptr, "LaunchOverlayApplet"}, |         {307, nullptr, "TerminateOverlayApplet"}, | ||||||
|             {307, nullptr, "TerminateOverlayApplet"}, |         {400, &IApplicationManagerInterface::GetApplicationControlData, "GetApplicationControlData"}, | ||||||
|             {400, &IApplicationManagerInterface::GetApplicationControlData, "GetApplicationControlData"}, |         {401, nullptr, "InvalidateAllApplicationControlCache"}, | ||||||
|             {401, nullptr, "InvalidateAllApplicationControlCache"}, |         {402, nullptr, "RequestDownloadApplicationControlData"}, | ||||||
|             {402, nullptr, "RequestDownloadApplicationControlData"}, |         {403, nullptr, "GetMaxApplicationControlCacheCount"}, | ||||||
|             {403, nullptr, "GetMaxApplicationControlCacheCount"}, |         {404, nullptr, "InvalidateApplicationControlCache"}, | ||||||
|             {404, nullptr, "InvalidateApplicationControlCache"}, |         {405, nullptr, "ListApplicationControlCacheEntryInfo"}, | ||||||
|             {405, nullptr, "ListApplicationControlCacheEntryInfo"}, |         {406, nullptr, "GetApplicationControlProperty"}, | ||||||
|             {406, nullptr, "GetApplicationControlProperty"}, |         {502, nullptr, "RequestCheckGameCardRegistration"}, | ||||||
|             {502, nullptr, "RequestCheckGameCardRegistration"}, |         {503, nullptr, "RequestGameCardRegistrationGoldPoint"}, | ||||||
|             {503, nullptr, "RequestGameCardRegistrationGoldPoint"}, |         {504, nullptr, "RequestRegisterGameCard"}, | ||||||
|             {504, nullptr, "RequestRegisterGameCard"}, |         {505, nullptr, "GetGameCardMountFailureEvent"}, | ||||||
|             {505, nullptr, "GetGameCardMountFailureEvent"}, |         {506, nullptr, "IsGameCardInserted"}, | ||||||
|             {506, nullptr, "IsGameCardInserted"}, |         {507, nullptr, "EnsureGameCardAccess"}, | ||||||
|             {507, nullptr, "EnsureGameCardAccess"}, |         {508, nullptr, "GetLastGameCardMountFailureResult"}, | ||||||
|             {508, nullptr, "GetLastGameCardMountFailureResult"}, |         {509, nullptr, "ListApplicationIdOnGameCard"}, | ||||||
|             {509, nullptr, "ListApplicationIdOnGameCard"}, |         {600, nullptr, "CountApplicationContentMeta"}, | ||||||
|             {600, nullptr, "CountApplicationContentMeta"}, |         {601, nullptr, "ListApplicationContentMetaStatus"}, | ||||||
|             {601, nullptr, "ListApplicationContentMetaStatus"}, |         {602, nullptr, "ListAvailableAddOnContent"}, | ||||||
|             {602, nullptr, "ListAvailableAddOnContent"}, |         {603, nullptr, "GetOwnedApplicationContentMetaStatus"}, | ||||||
|             {603, nullptr, "GetOwnedApplicationContentMetaStatus"}, |         {604, nullptr, "RegisterContentsExternalKey"}, | ||||||
|             {604, nullptr, "RegisterContentsExternalKey"}, |         {605, nullptr, "ListApplicationContentMetaStatusWithRightsCheck"}, | ||||||
|             {605, nullptr, "ListApplicationContentMetaStatusWithRightsCheck"}, |         {606, nullptr, "GetContentMetaStorage"}, | ||||||
|             {606, nullptr, "GetContentMetaStorage"}, |         {607, nullptr, "ListAvailableAddOnContent"}, | ||||||
|             {607, nullptr, "ListAvailableAddOnContent"}, |         {700, nullptr, "PushDownloadTaskList"}, | ||||||
|             {700, nullptr, "PushDownloadTaskList"}, |         {701, nullptr, "ClearTaskStatusList"}, | ||||||
|             {701, nullptr, "ClearTaskStatusList"}, |         {702, nullptr, "RequestDownloadTaskList"}, | ||||||
|             {702, nullptr, "RequestDownloadTaskList"}, |         {703, nullptr, "RequestEnsureDownloadTask"}, | ||||||
|             {703, nullptr, "RequestEnsureDownloadTask"}, |         {704, nullptr, "ListDownloadTaskStatus"}, | ||||||
|             {704, nullptr, "ListDownloadTaskStatus"}, |         {705, nullptr, "RequestDownloadTaskListData"}, | ||||||
|             {705, nullptr, "RequestDownloadTaskListData"}, |         {800, nullptr, "RequestVersionList"}, | ||||||
|             {800, nullptr, "RequestVersionList"}, |         {801, nullptr, "ListVersionList"}, | ||||||
|             {801, nullptr, "ListVersionList"}, |         {802, nullptr, "RequestVersionListData"}, | ||||||
|             {802, nullptr, "RequestVersionListData"}, |         {900, nullptr, "GetApplicationRecord"}, | ||||||
|             {900, nullptr, "GetApplicationRecord"}, |         {901, nullptr, "GetApplicationRecordProperty"}, | ||||||
|             {901, nullptr, "GetApplicationRecordProperty"}, |         {902, nullptr, "EnableApplicationAutoUpdate"}, | ||||||
|             {902, nullptr, "EnableApplicationAutoUpdate"}, |         {903, nullptr, "DisableApplicationAutoUpdate"}, | ||||||
|             {903, nullptr, "DisableApplicationAutoUpdate"}, |         {904, nullptr, "TouchApplication"}, | ||||||
|             {904, nullptr, "TouchApplication"}, |         {905, nullptr, "RequestApplicationUpdate"}, | ||||||
|             {905, nullptr, "RequestApplicationUpdate"}, |         {906, nullptr, "IsApplicationUpdateRequested"}, | ||||||
|             {906, nullptr, "IsApplicationUpdateRequested"}, |         {907, nullptr, "WithdrawApplicationUpdateRequest"}, | ||||||
|             {907, nullptr, "WithdrawApplicationUpdateRequest"}, |         {908, nullptr, "ListApplicationRecordInstalledContentMeta"}, | ||||||
|             {908, nullptr, "ListApplicationRecordInstalledContentMeta"}, |         {909, nullptr, "WithdrawCleanupAddOnContentsWithNoRightsRecommendation"}, | ||||||
|             {909, nullptr, "WithdrawCleanupAddOnContentsWithNoRightsRecommendation"}, |         {910, nullptr, "HasApplicationRecord"}, | ||||||
|             {910, nullptr, "HasApplicationRecord"}, |         {911, nullptr, "SetPreInstalledApplication"}, | ||||||
|             {911, nullptr, "SetPreInstalledApplication"}, |         {912, nullptr, "ClearPreInstalledApplicationFlag"}, | ||||||
|             {912, nullptr, "ClearPreInstalledApplicationFlag"}, |         {1000, nullptr, "RequestVerifyApplicationDeprecated"}, | ||||||
|             {1000, nullptr, "RequestVerifyApplicationDeprecated"}, |         {1001, nullptr, "CorruptApplicationForDebug"}, | ||||||
|             {1001, nullptr, "CorruptApplicationForDebug"}, |         {1002, nullptr, "RequestVerifyAddOnContentsRights"}, | ||||||
|             {1002, nullptr, "RequestVerifyAddOnContentsRights"}, |         {1003, nullptr, "RequestVerifyApplication"}, | ||||||
|             {1003, nullptr, "RequestVerifyApplication"}, |         {1004, nullptr, "CorruptContentForDebug"}, | ||||||
|             {1004, nullptr, "CorruptContentForDebug"}, |         {1200, nullptr, "NeedsUpdateVulnerability"}, | ||||||
|             {1200, nullptr, "NeedsUpdateVulnerability"}, |         {1300, nullptr, "IsAnyApplicationEntityInstalled"}, | ||||||
|             {1300, nullptr, "IsAnyApplicationEntityInstalled"}, |         {1301, nullptr, "DeleteApplicationContentEntities"}, | ||||||
|             {1301, nullptr, "DeleteApplicationContentEntities"}, |         {1302, nullptr, "CleanupUnrecordedApplicationEntity"}, | ||||||
|             {1302, nullptr, "CleanupUnrecordedApplicationEntity"}, |         {1303, nullptr, "CleanupAddOnContentsWithNoRights"}, | ||||||
|             {1303, nullptr, "CleanupAddOnContentsWithNoRights"}, |         {1304, nullptr, "DeleteApplicationContentEntity"}, | ||||||
|             {1304, nullptr, "DeleteApplicationContentEntity"}, |         {1305, nullptr, "TryDeleteRunningApplicationEntity"}, | ||||||
|             {1305, nullptr, "TryDeleteRunningApplicationEntity"}, |         {1306, nullptr, "TryDeleteRunningApplicationCompletely"}, | ||||||
|             {1306, nullptr, "TryDeleteRunningApplicationCompletely"}, |         {1307, nullptr, "TryDeleteRunningApplicationContentEntities"}, | ||||||
|             {1307, nullptr, "TryDeleteRunningApplicationContentEntities"}, |         {1308, nullptr, "DeleteApplicationCompletelyForDebug"}, | ||||||
|             {1308, nullptr, "DeleteApplicationCompletelyForDebug"}, |         {1309, nullptr, "CleanupUnavailableAddOnContents"}, | ||||||
|             {1309, nullptr, "CleanupUnavailableAddOnContents"}, |         {1400, nullptr, "PrepareShutdown"}, | ||||||
|             {1400, nullptr, "PrepareShutdown"}, |         {1500, nullptr, "FormatSdCard"}, | ||||||
|             {1500, nullptr, "FormatSdCard"}, |         {1501, nullptr, "NeedsSystemUpdateToFormatSdCard"}, | ||||||
|             {1501, nullptr, "NeedsSystemUpdateToFormatSdCard"}, |         {1502, nullptr, "GetLastSdCardFormatUnexpectedResult"}, | ||||||
|             {1502, nullptr, "GetLastSdCardFormatUnexpectedResult"}, |         {1504, nullptr, "InsertSdCard"}, | ||||||
|             {1504, nullptr, "InsertSdCard"}, |         {1505, nullptr, "RemoveSdCard"}, | ||||||
|             {1505, nullptr, "RemoveSdCard"}, |         {1600, nullptr, "GetSystemSeedForPseudoDeviceId"}, | ||||||
|             {1600, nullptr, "GetSystemSeedForPseudoDeviceId"}, |         {1601, nullptr, "ResetSystemSeedForPseudoDeviceId"}, | ||||||
|             {1601, nullptr, "ResetSystemSeedForPseudoDeviceId"}, |         {1700, nullptr, "ListApplicationDownloadingContentMeta"}, | ||||||
|             {1700, nullptr, "ListApplicationDownloadingContentMeta"}, |         {1701, nullptr, "GetApplicationView"}, | ||||||
|             {1701, nullptr, "GetApplicationView"}, |         {1702, nullptr, "GetApplicationDownloadTaskStatus"}, | ||||||
|             {1702, nullptr, "GetApplicationDownloadTaskStatus"}, |         {1703, nullptr, "GetApplicationViewDownloadErrorContext"}, | ||||||
|             {1703, nullptr, "GetApplicationViewDownloadErrorContext"}, |         {1800, nullptr, "IsNotificationSetupCompleted"}, | ||||||
|             {1800, nullptr, "IsNotificationSetupCompleted"}, |         {1801, nullptr, "GetLastNotificationInfoCount"}, | ||||||
|             {1801, nullptr, "GetLastNotificationInfoCount"}, |         {1802, nullptr, "ListLastNotificationInfo"}, | ||||||
|             {1802, nullptr, "ListLastNotificationInfo"}, |         {1803, nullptr, "ListNotificationTask"}, | ||||||
|             {1803, nullptr, "ListNotificationTask"}, |         {1900, nullptr, "IsActiveAccount"}, | ||||||
|             {1900, nullptr, "IsActiveAccount"}, |         {1901, nullptr, "RequestDownloadApplicationPrepurchasedRights"}, | ||||||
|             {1901, nullptr, "RequestDownloadApplicationPrepurchasedRights"}, |         {1902, nullptr, "GetApplicationTicketInfo"}, | ||||||
|             {1902, nullptr, "GetApplicationTicketInfo"}, |         {2000, nullptr, "GetSystemDeliveryInfo"}, | ||||||
|             {2000, nullptr, "GetSystemDeliveryInfo"}, |         {2001, nullptr, "SelectLatestSystemDeliveryInfo"}, | ||||||
|             {2001, nullptr, "SelectLatestSystemDeliveryInfo"}, |         {2002, nullptr, "VerifyDeliveryProtocolVersion"}, | ||||||
|             {2002, nullptr, "VerifyDeliveryProtocolVersion"}, |         {2003, nullptr, "GetApplicationDeliveryInfo"}, | ||||||
|             {2003, nullptr, "GetApplicationDeliveryInfo"}, |         {2004, nullptr, "HasAllContentsToDeliver"}, | ||||||
|             {2004, nullptr, "HasAllContentsToDeliver"}, |         {2005, nullptr, "CompareApplicationDeliveryInfo"}, | ||||||
|             {2005, nullptr, "CompareApplicationDeliveryInfo"}, |         {2006, nullptr, "CanDeliverApplication"}, | ||||||
|             {2006, nullptr, "CanDeliverApplication"}, |         {2007, nullptr, "ListContentMetaKeyToDeliverApplication"}, | ||||||
|             {2007, nullptr, "ListContentMetaKeyToDeliverApplication"}, |         {2008, nullptr, "NeedsSystemUpdateToDeliverApplication"}, | ||||||
|             {2008, nullptr, "NeedsSystemUpdateToDeliverApplication"}, |         {2009, nullptr, "EstimateRequiredSize"}, | ||||||
|             {2009, nullptr, "EstimateRequiredSize"}, |         {2010, nullptr, "RequestReceiveApplication"}, | ||||||
|             {2010, nullptr, "RequestReceiveApplication"}, |         {2011, nullptr, "CommitReceiveApplication"}, | ||||||
|             {2011, nullptr, "CommitReceiveApplication"}, |         {2012, nullptr, "GetReceiveApplicationProgress"}, | ||||||
|             {2012, nullptr, "GetReceiveApplicationProgress"}, |         {2013, nullptr, "RequestSendApplication"}, | ||||||
|             {2013, nullptr, "RequestSendApplication"}, |         {2014, nullptr, "GetSendApplicationProgress"}, | ||||||
|             {2014, nullptr, "GetSendApplicationProgress"}, |         {2015, nullptr, "CompareSystemDeliveryInfo"}, | ||||||
|             {2015, nullptr, "CompareSystemDeliveryInfo"}, |         {2016, nullptr, "ListNotCommittedContentMeta"}, | ||||||
|             {2016, nullptr, "ListNotCommittedContentMeta"}, |         {2017, nullptr, "CreateDownloadTask"}, | ||||||
|             {2017, nullptr, "CreateDownloadTask"}, |         {2018, nullptr, "GetApplicationDeliveryInfoHash"}, | ||||||
|             {2018, nullptr, "GetApplicationDeliveryInfoHash"}, |         {2050, nullptr, "GetApplicationRightsOnClient"}, | ||||||
|             {2050, nullptr, "GetApplicationRightsOnClient"}, |         {2100, nullptr, "GetApplicationTerminateResult"}, | ||||||
|             {2100, nullptr, "GetApplicationTerminateResult"}, |         {2101, nullptr, "GetRawApplicationTerminateResult"}, | ||||||
|             {2101, nullptr, "GetRawApplicationTerminateResult"}, |         {2150, nullptr, "CreateRightsEnvironment"}, | ||||||
|             {2150, nullptr, "CreateRightsEnvironment"}, |         {2151, nullptr, "DestroyRightsEnvironment"}, | ||||||
|             {2151, nullptr, "DestroyRightsEnvironment"}, |         {2152, nullptr, "ActivateRightsEnvironment"}, | ||||||
|             {2152, nullptr, "ActivateRightsEnvironment"}, |         {2153, nullptr, "DeactivateRightsEnvironment"}, | ||||||
|             {2153, nullptr, "DeactivateRightsEnvironment"}, |         {2154, nullptr, "ForceActivateRightsContextForExit"}, | ||||||
|             {2154, nullptr, "ForceActivateRightsContextForExit"}, |         {2160, nullptr, "AddTargetApplicationToRightsEnvironment"}, | ||||||
|             {2160, nullptr, "AddTargetApplicationToRightsEnvironment"}, |         {2161, nullptr, "SetUsersToRightsEnvironment"}, | ||||||
|             {2161, nullptr, "SetUsersToRightsEnvironment"}, |         {2170, nullptr, "GetRightsEnvironmentStatus"}, | ||||||
|             {2170, nullptr, "GetRightsEnvironmentStatus"}, |         {2171, nullptr, "GetRightsEnvironmentStatusChangedEvent"}, | ||||||
|             {2171, nullptr, "GetRightsEnvironmentStatusChangedEvent"}, |         {2180, nullptr, "RequestExtendRightsInRightsEnvironment"}, | ||||||
|             {2180, nullptr, "RequestExtendRightsInRightsEnvironment"}, |         {2181, nullptr, "GetLastResultOfExtendRightsInRightsEnvironment"}, | ||||||
|             {2181, nullptr, "GetLastResultOfExtendRightsInRightsEnvironment"}, |         {2182, nullptr, "SetActiveRightsContextUsingStateToRightsEnvironment"}, | ||||||
|             {2182, nullptr, "SetActiveRightsContextUsingStateToRightsEnvironment"}, |         {2190, nullptr, "GetRightsEnvironmentHandleForApplication"}, | ||||||
|             {2190, nullptr, "GetRightsEnvironmentHandleForApplication"}, |         {2199, nullptr, "GetRightsEnvironmentCountForDebug"}, | ||||||
|             {2199, nullptr, "GetRightsEnvironmentCountForDebug"}, |         {2200, nullptr, "GetGameCardApplicationCopyIdentifier"}, | ||||||
|             {2200, nullptr, "GetGameCardApplicationCopyIdentifier"}, |         {2201, nullptr, "GetInstalledApplicationCopyIdentifier"}, | ||||||
|             {2201, nullptr, "GetInstalledApplicationCopyIdentifier"}, |         {2250, nullptr, "RequestReportActiveELicence"}, | ||||||
|             {2250, nullptr, "RequestReportActiveELicence"}, |         {2300, nullptr, "ListEventLog"}, | ||||||
|             {2300, nullptr, "ListEventLog"}, |     }; | ||||||
|         }; |     // clang-format on
 | ||||||
|         // clang-format on
 |  | ||||||
| 
 | 
 | ||||||
|         RegisterHandlers(functions); |     RegisterHandlers(functions); | ||||||
|     } | } | ||||||
| 
 | 
 | ||||||
|     void GetApplicationControlData(Kernel::HLERequestContext& ctx) { | void IApplicationManagerInterface::GetApplicationControlData(Kernel::HLERequestContext& ctx) { | ||||||
|         IPC::RequestParser rp{ctx}; |     IPC::RequestParser rp{ctx}; | ||||||
|         const auto flag = rp.PopRaw<u64>(); |     const auto flag = rp.PopRaw<u64>(); | ||||||
|         LOG_DEBUG(Service_NS, "called with flag={:016X}", flag); |     LOG_DEBUG(Service_NS, "called with flag={:016X}", flag); | ||||||
| 
 | 
 | ||||||
|         const auto title_id = rp.PopRaw<u64>(); |     const auto title_id = rp.PopRaw<u64>(); | ||||||
| 
 | 
 | ||||||
|         const auto size = ctx.GetWriteBufferSize(); |     const auto size = ctx.GetWriteBufferSize(); | ||||||
| 
 | 
 | ||||||
|         const FileSys::PatchManager pm{title_id}; |     const FileSys::PatchManager pm{title_id}; | ||||||
|         const auto control = pm.GetControlMetadata(); |     const auto control = pm.GetControlMetadata(); | ||||||
| 
 | 
 | ||||||
|         std::vector<u8> out; |     std::vector<u8> out; | ||||||
| 
 | 
 | ||||||
|         if (control.first != nullptr) { |     if (control.first != nullptr) { | ||||||
|             if (size < 0x4000) { |         if (size < 0x4000) { | ||||||
|                 LOG_ERROR(Service_NS, |             LOG_ERROR(Service_NS, | ||||||
|                           "output buffer is too small! (actual={:016X}, expected_min=0x4000)", |                       "output buffer is too small! (actual={:016X}, expected_min=0x4000)", size); | ||||||
|                           size); |             IPC::ResponseBuilder rb{ctx, 2}; | ||||||
|                 IPC::ResponseBuilder rb{ctx, 2}; |             // TODO(DarkLordZach): Find a better error code for this.
 | ||||||
|                 // TODO(DarkLordZach): Find a better error code for this.
 |             rb.Push(ResultCode(-1)); | ||||||
|                 rb.Push(ResultCode(-1)); |             return; | ||||||
|                 return; |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             out.resize(0x4000); |  | ||||||
|             const auto bytes = control.first->GetRawBytes(); |  | ||||||
|             std::memcpy(out.data(), bytes.data(), bytes.size()); |  | ||||||
|         } else { |  | ||||||
|             LOG_WARNING(Service_NS, "missing NACP data for title_id={:016X}, defaulting to zeros.", |  | ||||||
|                         title_id); |  | ||||||
|             out.resize(std::min<u64>(0x4000, size)); |  | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         if (control.second != nullptr) { |         out.resize(0x4000); | ||||||
|             if (size < 0x4000 + control.second->GetSize()) { |         const auto bytes = control.first->GetRawBytes(); | ||||||
|                 LOG_ERROR(Service_NS, |         std::memcpy(out.data(), bytes.data(), bytes.size()); | ||||||
|                           "output buffer is too small! (actual={:016X}, expected_min={:016X})", |     } else { | ||||||
|                           size, 0x4000 + control.second->GetSize()); |         LOG_WARNING(Service_NS, "missing NACP data for title_id={:016X}, defaulting to zeros.", | ||||||
|                 IPC::ResponseBuilder rb{ctx, 2}; |                     title_id); | ||||||
|                 // TODO(DarkLordZach): Find a better error code for this.
 |         out.resize(std::min<u64>(0x4000, size)); | ||||||
|                 rb.Push(ResultCode(-1)); |     } | ||||||
|                 return; |  | ||||||
|             } |  | ||||||
| 
 | 
 | ||||||
|             out.resize(0x4000 + control.second->GetSize()); |     if (control.second != nullptr) { | ||||||
|             control.second->Read(out.data() + 0x4000, control.second->GetSize()); |         if (size < 0x4000 + control.second->GetSize()) { | ||||||
|         } else { |             LOG_ERROR(Service_NS, | ||||||
|             LOG_WARNING(Service_NS, "missing icon data for title_id={:016X}, defaulting to zeros.", |                       "output buffer is too small! (actual={:016X}, expected_min={:016X})", size, | ||||||
|                         title_id); |                       0x4000 + control.second->GetSize()); | ||||||
|  |             IPC::ResponseBuilder rb{ctx, 2}; | ||||||
|  |             // TODO(DarkLordZach): Find a better error code for this.
 | ||||||
|  |             rb.Push(ResultCode(-1)); | ||||||
|  |             return; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         ctx.WriteBuffer(out); |         out.resize(0x4000 + control.second->GetSize()); | ||||||
|  |         control.second->Read(out.data() + 0x4000, control.second->GetSize()); | ||||||
|  |     } else { | ||||||
|  |         LOG_WARNING(Service_NS, "missing icon data for title_id={:016X}, defaulting to zeros.", | ||||||
|  |                     title_id); | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|  |     ctx.WriteBuffer(out); | ||||||
|  | 
 | ||||||
|  |     IPC::ResponseBuilder rb{ctx, 3}; | ||||||
|  |     rb.Push(RESULT_SUCCESS); | ||||||
|  |     rb.Push<u32>(static_cast<u32>(out.size())); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void IApplicationManagerInterface::GetApplicationDesiredLanguage(Kernel::HLERequestContext& ctx) { | ||||||
|  |     IPC::RequestParser rp{ctx}; | ||||||
|  |     const auto supported_languages = rp.Pop<u32>(); | ||||||
|  | 
 | ||||||
|  |     const auto res = GetApplicationDesiredLanguage(supported_languages); | ||||||
|  |     if (res.Succeeded()) { | ||||||
|         IPC::ResponseBuilder rb{ctx, 3}; |         IPC::ResponseBuilder rb{ctx, 3}; | ||||||
|         rb.Push(RESULT_SUCCESS); |         rb.Push(RESULT_SUCCESS); | ||||||
|         rb.Push<u32>(static_cast<u32>(out.size())); |         rb.Push<u32>(*res); | ||||||
|  |     } else { | ||||||
|  |         IPC::ResponseBuilder rb{ctx, 2}; | ||||||
|  |         rb.Push(res.Code()); | ||||||
|     } |     } | ||||||
| }; | } | ||||||
| 
 | 
 | ||||||
| class IApplicationVersionInterface final : public ServiceFramework<IApplicationVersionInterface> { | ResultVal<u8> IApplicationManagerInterface::GetApplicationDesiredLanguage( | ||||||
| public: |     const u32 supported_languages) { | ||||||
|     explicit IApplicationVersionInterface() : ServiceFramework{"IApplicationVersionInterface"} { |     LOG_DEBUG(Service_NS, "called with supported_languages={:08X}", supported_languages); | ||||||
|         // clang-format off
 |  | ||||||
|         static const FunctionInfo functions[] = { |  | ||||||
|             {0, nullptr, "GetLaunchRequiredVersion"}, |  | ||||||
|             {1, nullptr, "UpgradeLaunchRequiredVersion"}, |  | ||||||
|             {35, nullptr, "UpdateVersionList"}, |  | ||||||
|             {36, nullptr, "PushLaunchVersion"}, |  | ||||||
|             {37, nullptr, "ListRequiredVersion"}, |  | ||||||
|             {800, nullptr, "RequestVersionList"}, |  | ||||||
|             {801, nullptr, "ListVersionList"}, |  | ||||||
|             {802, nullptr, "RequestVersionListData"}, |  | ||||||
|             {1000, nullptr, "PerformAutoUpdate"}, |  | ||||||
|         }; |  | ||||||
|         // clang-format on
 |  | ||||||
| 
 | 
 | ||||||
|         RegisterHandlers(functions); |     // Get language code from settings
 | ||||||
|  |     const auto language_code = | ||||||
|  |         Service::Set::GetLanguageCodeFromIndex(Settings::values.language_index); | ||||||
|  | 
 | ||||||
|  |     // Convert to application language, get priority list
 | ||||||
|  |     const auto application_language = ConvertToApplicationLanguage(language_code); | ||||||
|  |     if (application_language == std::nullopt) { | ||||||
|  |         return ERR_APPLICATION_LANGUAGE_NOT_FOUND; | ||||||
|     } |     } | ||||||
| }; |     const auto priority_list = GetApplicationLanguagePriorityList(*application_language); | ||||||
| 
 |     if (!priority_list) { | ||||||
| class IContentManagerInterface final : public ServiceFramework<IContentManagerInterface> { |         return ERR_APPLICATION_LANGUAGE_NOT_FOUND; | ||||||
| public: |  | ||||||
|     explicit IContentManagerInterface() : ServiceFramework{"IContentManagerInterface"} { |  | ||||||
|         // clang-format off
 |  | ||||||
|         static const FunctionInfo functions[] = { |  | ||||||
|             {11, nullptr, "CalculateApplicationOccupiedSize"}, |  | ||||||
|             {43, nullptr, "CheckSdCardMountStatus"}, |  | ||||||
|             {47, nullptr, "GetTotalSpaceSize"}, |  | ||||||
|             {48, nullptr, "GetFreeSpaceSize"}, |  | ||||||
|             {600, nullptr, "CountApplicationContentMeta"}, |  | ||||||
|             {601, nullptr, "ListApplicationContentMetaStatus"}, |  | ||||||
|             {605, nullptr, "ListApplicationContentMetaStatusWithRightsCheck"}, |  | ||||||
|             {607, nullptr, "IsAnyApplicationRunning"}, |  | ||||||
|         }; |  | ||||||
|         // clang-format on
 |  | ||||||
| 
 |  | ||||||
|         RegisterHandlers(functions); |  | ||||||
|     } |     } | ||||||
| }; |  | ||||||
| 
 | 
 | ||||||
| class IDocumentInterface final : public ServiceFramework<IDocumentInterface> { |     // Try to find a valid language.
 | ||||||
| public: |     for (const auto lang : *priority_list) { | ||||||
|     explicit IDocumentInterface() : ServiceFramework{"IDocumentInterface"} { |         const auto supported_flag = GetSupportedLanguageFlag(lang); | ||||||
|         // clang-format off
 |         if (supported_languages == 0 || | ||||||
|         static const FunctionInfo functions[] = { |             (supported_languages & supported_flag) == supported_languages) { | ||||||
|             {21, nullptr, "GetApplicationContentPath"}, |             return ResultVal<u8>::WithCode(RESULT_SUCCESS, static_cast<u8>(lang)); | ||||||
|             {23, nullptr, "ResolveApplicationContentPath"}, |         } | ||||||
|             {93, nullptr, "GetRunningApplicationProgramId"}, |  | ||||||
|         }; |  | ||||||
|         // clang-format on
 |  | ||||||
| 
 |  | ||||||
|         RegisterHandlers(functions); |  | ||||||
|     } |     } | ||||||
| }; |  | ||||||
| 
 | 
 | ||||||
| class IDownloadTaskInterface final : public ServiceFramework<IDownloadTaskInterface> { |     return ERR_APPLICATION_LANGUAGE_NOT_FOUND; | ||||||
| public: | } | ||||||
|     explicit IDownloadTaskInterface() : ServiceFramework{"IDownloadTaskInterface"} { |  | ||||||
|         // clang-format off
 |  | ||||||
|         static const FunctionInfo functions[] = { |  | ||||||
|             {701, nullptr, "ClearTaskStatusList"}, |  | ||||||
|             {702, nullptr, "RequestDownloadTaskList"}, |  | ||||||
|             {703, nullptr, "RequestEnsureDownloadTask"}, |  | ||||||
|             {704, nullptr, "ListDownloadTaskStatus"}, |  | ||||||
|             {705, nullptr, "RequestDownloadTaskListData"}, |  | ||||||
|             {706, nullptr, "TryCommitCurrentApplicationDownloadTask"}, |  | ||||||
|             {707, nullptr, "EnableAutoCommit"}, |  | ||||||
|             {708, nullptr, "DisableAutoCommit"}, |  | ||||||
|             {709, nullptr, "TriggerDynamicCommitEvent"}, |  | ||||||
|         }; |  | ||||||
|         // clang-format on
 |  | ||||||
| 
 | 
 | ||||||
|         RegisterHandlers(functions); | void IApplicationManagerInterface::ConvertApplicationLanguageToLanguageCode( | ||||||
|  |     Kernel::HLERequestContext& ctx) { | ||||||
|  |     IPC::RequestParser rp{ctx}; | ||||||
|  |     const auto application_language = rp.Pop<u8>(); | ||||||
|  | 
 | ||||||
|  |     const auto res = ConvertApplicationLanguageToLanguageCode(application_language); | ||||||
|  |     if (res.Succeeded()) { | ||||||
|  |         IPC::ResponseBuilder rb{ctx, 4}; | ||||||
|  |         rb.Push(RESULT_SUCCESS); | ||||||
|  |         rb.Push(*res); | ||||||
|  |     } else { | ||||||
|  |         IPC::ResponseBuilder rb{ctx, 2}; | ||||||
|  |         rb.Push(res.Code()); | ||||||
|     } |     } | ||||||
| }; | } | ||||||
| 
 | 
 | ||||||
| class IECommerceInterface final : public ServiceFramework<IECommerceInterface> { | ResultVal<u64> IApplicationManagerInterface::ConvertApplicationLanguageToLanguageCode( | ||||||
| public: |     u8 application_language) { | ||||||
|     explicit IECommerceInterface() : ServiceFramework{"IECommerceInterface"} { |     const auto language_code = | ||||||
|         // clang-format off
 |         ConvertToLanguageCode(static_cast<ApplicationLanguage>(application_language)); | ||||||
|         static const FunctionInfo functions[] = { |     if (language_code == std::nullopt) { | ||||||
|             {0, nullptr, "RequestLinkDevice"}, |         return ERR_APPLICATION_LANGUAGE_NOT_FOUND; | ||||||
|             {1, nullptr, "RequestCleanupAllPreInstalledApplications"}, |  | ||||||
|             {2, nullptr, "RequestCleanupPreInstalledApplication"}, |  | ||||||
|             {3, nullptr, "RequestSyncRights"}, |  | ||||||
|             {4, nullptr, "RequestUnlinkDevice"}, |  | ||||||
|             {5, nullptr, "RequestRevokeAllELicense"}, |  | ||||||
|         }; |  | ||||||
|         // clang-format on
 |  | ||||||
| 
 |  | ||||||
|         RegisterHandlers(functions); |  | ||||||
|     } |     } | ||||||
| }; |  | ||||||
| 
 | 
 | ||||||
| class IFactoryResetInterface final : public ServiceFramework<IFactoryResetInterface> { |     return ResultVal<u64>::WithCode(RESULT_SUCCESS, static_cast<u64>(*language_code)); | ||||||
| public: | } | ||||||
|     explicit IFactoryResetInterface() : ServiceFramework{"IFactoryResetInterface"} { | 
 | ||||||
|         // clang-format off
 | IApplicationVersionInterface::IApplicationVersionInterface() | ||||||
|  |     : ServiceFramework{"IApplicationVersionInterface"} { | ||||||
|  |     // clang-format off
 | ||||||
|  |     static const FunctionInfo functions[] = { | ||||||
|  |         {0, nullptr, "GetLaunchRequiredVersion"}, | ||||||
|  |         {1, nullptr, "UpgradeLaunchRequiredVersion"}, | ||||||
|  |         {35, nullptr, "UpdateVersionList"}, | ||||||
|  |         {36, nullptr, "PushLaunchVersion"}, | ||||||
|  |         {37, nullptr, "ListRequiredVersion"}, | ||||||
|  |         {800, nullptr, "RequestVersionList"}, | ||||||
|  |         {801, nullptr, "ListVersionList"}, | ||||||
|  |         {802, nullptr, "RequestVersionListData"}, | ||||||
|  |         {1000, nullptr, "PerformAutoUpdate"}, | ||||||
|  |     }; | ||||||
|  |     // clang-format on
 | ||||||
|  | 
 | ||||||
|  |     RegisterHandlers(functions); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | IContentManagerInterface::IContentManagerInterface() | ||||||
|  |     : ServiceFramework{"IContentManagerInterface"} { | ||||||
|  |     // clang-format off
 | ||||||
|  |     static const FunctionInfo functions[] = { | ||||||
|  |         {11, nullptr, "CalculateApplicationOccupiedSize"}, | ||||||
|  |         {43, nullptr, "CheckSdCardMountStatus"}, | ||||||
|  |         {47, nullptr, "GetTotalSpaceSize"}, | ||||||
|  |         {48, nullptr, "GetFreeSpaceSize"}, | ||||||
|  |         {600, nullptr, "CountApplicationContentMeta"}, | ||||||
|  |         {601, nullptr, "ListApplicationContentMetaStatus"}, | ||||||
|  |         {605, nullptr, "ListApplicationContentMetaStatusWithRightsCheck"}, | ||||||
|  |         {607, nullptr, "IsAnyApplicationRunning"}, | ||||||
|  |     }; | ||||||
|  |     // clang-format on
 | ||||||
|  | 
 | ||||||
|  |     RegisterHandlers(functions); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | IDocumentInterface::IDocumentInterface() : ServiceFramework{"IDocumentInterface"} { | ||||||
|  |     // clang-format off
 | ||||||
|  |     static const FunctionInfo functions[] = { | ||||||
|  |         {21, nullptr, "GetApplicationContentPath"}, | ||||||
|  |         {23, nullptr, "ResolveApplicationContentPath"}, | ||||||
|  |         {93, nullptr, "GetRunningApplicationProgramId"}, | ||||||
|  |     }; | ||||||
|  |     // clang-format on
 | ||||||
|  | 
 | ||||||
|  |     RegisterHandlers(functions); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | IDownloadTaskInterface::IDownloadTaskInterface() : ServiceFramework{"IDownloadTaskInterface"} { | ||||||
|  |     // clang-format off
 | ||||||
|  |     static const FunctionInfo functions[] = { | ||||||
|  |         {701, nullptr, "ClearTaskStatusList"}, | ||||||
|  |         {702, nullptr, "RequestDownloadTaskList"}, | ||||||
|  |         {703, nullptr, "RequestEnsureDownloadTask"}, | ||||||
|  |         {704, nullptr, "ListDownloadTaskStatus"}, | ||||||
|  |         {705, nullptr, "RequestDownloadTaskListData"}, | ||||||
|  |         {706, nullptr, "TryCommitCurrentApplicationDownloadTask"}, | ||||||
|  |         {707, nullptr, "EnableAutoCommit"}, | ||||||
|  |         {708, nullptr, "DisableAutoCommit"}, | ||||||
|  |         {709, nullptr, "TriggerDynamicCommitEvent"}, | ||||||
|  |     }; | ||||||
|  |     // clang-format on
 | ||||||
|  | 
 | ||||||
|  |     RegisterHandlers(functions); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | IECommerceInterface::IECommerceInterface() : ServiceFramework{"IECommerceInterface"} { | ||||||
|  |     // clang-format off
 | ||||||
|  |     static const FunctionInfo functions[] = { | ||||||
|  |         {0, nullptr, "RequestLinkDevice"}, | ||||||
|  |         {1, nullptr, "RequestCleanupAllPreInstalledApplications"}, | ||||||
|  |         {2, nullptr, "RequestCleanupPreInstalledApplication"}, | ||||||
|  |         {3, nullptr, "RequestSyncRights"}, | ||||||
|  |         {4, nullptr, "RequestUnlinkDevice"}, | ||||||
|  |         {5, nullptr, "RequestRevokeAllELicense"}, | ||||||
|  |     }; | ||||||
|  |     // clang-format on
 | ||||||
|  | 
 | ||||||
|  |     RegisterHandlers(functions); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | IFactoryResetInterface::IFactoryResetInterface::IFactoryResetInterface() | ||||||
|  |     : ServiceFramework{"IFactoryResetInterface"} { | ||||||
|  |     // clang-format off
 | ||||||
|         static const FunctionInfo functions[] = { |         static const FunctionInfo functions[] = { | ||||||
|             {100, nullptr, "ResetToFactorySettings"}, |             {100, nullptr, "ResetToFactorySettings"}, | ||||||
|             {101, nullptr, "ResetToFactorySettingsWithoutUserSaveData"}, |             {101, nullptr, "ResetToFactorySettingsWithoutUserSaveData"}, | ||||||
|             {102, nullptr, "ResetToFactorySettingsForRefurbishment"}, |             {102, nullptr, "ResetToFactorySettingsForRefurbishment"}, | ||||||
|         }; |         }; | ||||||
|         // clang-format on
 |     // clang-format on
 | ||||||
| 
 | 
 | ||||||
|         RegisterHandlers(functions); |     RegisterHandlers(functions); | ||||||
|     } | } | ||||||
| }; |  | ||||||
| 
 | 
 | ||||||
| class NS final : public ServiceFramework<NS> { | NS::NS(const char* name) : ServiceFramework{name} { | ||||||
| public: |     // clang-format off
 | ||||||
|     explicit NS(const char* name) : ServiceFramework{name} { |     static const FunctionInfo functions[] = { | ||||||
|         // clang-format off
 |         {7992, &NS::PushInterface<IECommerceInterface>, "GetECommerceInterface"}, | ||||||
|         static const FunctionInfo functions[] = { |         {7993, &NS::PushInterface<IApplicationVersionInterface>, "GetApplicationVersionInterface"}, | ||||||
|             {7992, &NS::PushInterface<IECommerceInterface>, "GetECommerceInterface"}, |         {7994, &NS::PushInterface<IFactoryResetInterface>, "GetFactoryResetInterface"}, | ||||||
|             {7993, &NS::PushInterface<IApplicationVersionInterface>, "GetApplicationVersionInterface"}, |         {7995, &NS::PushInterface<IAccountProxyInterface>, "GetAccountProxyInterface"}, | ||||||
|             {7994, &NS::PushInterface<IFactoryResetInterface>, "GetFactoryResetInterface"}, |         {7996, &NS::PushInterface<IApplicationManagerInterface>, "GetApplicationManagerInterface"}, | ||||||
|             {7995, &NS::PushInterface<IAccountProxyInterface>, "GetAccountProxyInterface"}, |         {7997, &NS::PushInterface<IDownloadTaskInterface>, "GetDownloadTaskInterface"}, | ||||||
|             {7996, &NS::PushInterface<IApplicationManagerInterface>, "GetApplicationManagerInterface"}, |         {7998, &NS::PushInterface<IContentManagerInterface>, "GetContentManagementInterface"}, | ||||||
|             {7997, &NS::PushInterface<IDownloadTaskInterface>, "GetDownloadTaskInterface"}, |         {7999, &NS::PushInterface<IDocumentInterface>, "GetDocumentInterface"}, | ||||||
|             {7998, &NS::PushInterface<IContentManagerInterface>, "GetContentManagementInterface"}, |     }; | ||||||
|             {7999, &NS::PushInterface<IDocumentInterface>, "GetDocumentInterface"}, |     // clang-format on
 | ||||||
|         }; |  | ||||||
|         // clang-format on
 |  | ||||||
| 
 | 
 | ||||||
|         RegisterHandlers(functions); |     RegisterHandlers(functions); | ||||||
|     } | } | ||||||
| 
 | 
 | ||||||
| private: | std::shared_ptr<IApplicationManagerInterface> NS::GetApplicationManagerInterface() { | ||||||
|     template <typename T> |     return GetInterface<IApplicationManagerInterface>(); | ||||||
|     void PushInterface(Kernel::HLERequestContext& ctx) { | } | ||||||
|         LOG_DEBUG(Service_NS, "called"); |  | ||||||
| 
 |  | ||||||
|         IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |  | ||||||
|         rb.Push(RESULT_SUCCESS); |  | ||||||
|         rb.PushIpcInterface<T>(); |  | ||||||
|     } |  | ||||||
| }; |  | ||||||
| 
 | 
 | ||||||
| class NS_DEV final : public ServiceFramework<NS_DEV> { | class NS_DEV final : public ServiceFramework<NS_DEV> { | ||||||
| public: | public: | ||||||
|  |  | ||||||
|  | @ -5,9 +5,83 @@ | ||||||
| #pragma once | #pragma once | ||||||
| 
 | 
 | ||||||
| #include "core/hle/service/service.h" | #include "core/hle/service/service.h" | ||||||
|  | #include "core/hle/service/set/set.h" | ||||||
| 
 | 
 | ||||||
| namespace Service::NS { | namespace Service::NS { | ||||||
| 
 | 
 | ||||||
|  | class IAccountProxyInterface final : public ServiceFramework<IAccountProxyInterface> { | ||||||
|  | public: | ||||||
|  |     explicit IAccountProxyInterface(); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | class IApplicationManagerInterface final : public ServiceFramework<IApplicationManagerInterface> { | ||||||
|  | public: | ||||||
|  |     explicit IApplicationManagerInterface(); | ||||||
|  | 
 | ||||||
|  |     ResultVal<u8> GetApplicationDesiredLanguage(u32 supported_languages); | ||||||
|  |     ResultVal<u64> ConvertApplicationLanguageToLanguageCode(u8 application_language); | ||||||
|  | 
 | ||||||
|  | private: | ||||||
|  |     void GetApplicationControlData(Kernel::HLERequestContext& ctx); | ||||||
|  |     void GetApplicationDesiredLanguage(Kernel::HLERequestContext& ctx); | ||||||
|  |     void ConvertApplicationLanguageToLanguageCode(Kernel::HLERequestContext& ctx); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | class IApplicationVersionInterface final : public ServiceFramework<IApplicationVersionInterface> { | ||||||
|  | public: | ||||||
|  |     explicit IApplicationVersionInterface(); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | class IContentManagerInterface final : public ServiceFramework<IContentManagerInterface> { | ||||||
|  | public: | ||||||
|  |     explicit IContentManagerInterface(); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | class IDocumentInterface final : public ServiceFramework<IDocumentInterface> { | ||||||
|  | public: | ||||||
|  |     explicit IDocumentInterface(); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | class IDownloadTaskInterface final : public ServiceFramework<IDownloadTaskInterface> { | ||||||
|  | public: | ||||||
|  |     explicit IDownloadTaskInterface(); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | class IECommerceInterface final : public ServiceFramework<IECommerceInterface> { | ||||||
|  | public: | ||||||
|  |     explicit IECommerceInterface(); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | class IFactoryResetInterface final : public ServiceFramework<IFactoryResetInterface> { | ||||||
|  | public: | ||||||
|  |     explicit IFactoryResetInterface(); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | class NS final : public ServiceFramework<NS> { | ||||||
|  | public: | ||||||
|  |     explicit NS(const char* name); | ||||||
|  | 
 | ||||||
|  |     std::shared_ptr<IApplicationManagerInterface> GetApplicationManagerInterface(); | ||||||
|  | 
 | ||||||
|  | private: | ||||||
|  |     template <typename T> | ||||||
|  |     void PushInterface(Kernel::HLERequestContext& ctx) { | ||||||
|  |         LOG_DEBUG(Service_NS, "called"); | ||||||
|  | 
 | ||||||
|  |         IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||||||
|  |         rb.Push(RESULT_SUCCESS); | ||||||
|  |         rb.PushIpcInterface<T>(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     template<typename T> | ||||||
|  |     std::shared_ptr<T> GetInterface() { | ||||||
|  |         static_assert(std::is_base_of_v<Kernel::SessionRequestHandler, T>, | ||||||
|  |                       "Not a base of ServiceFrameworkBase"); | ||||||
|  | 
 | ||||||
|  |         return std::make_shared<T>(); | ||||||
|  |     } | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| /// Registers all NS services with the specified service manager.
 | /// Registers all NS services with the specified service manager.
 | ||||||
| void InstallInterfaces(SM::ServiceManager& service_manager); | void InstallInterfaces(SM::ServiceManager& service_manager); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
							
								
								
									
										390
									
								
								src/core/hle/service/ns/ns_language.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										390
									
								
								src/core/hle/service/ns/ns_language.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,390 @@ | ||||||
|  | // Copyright 2018 yuzu emulator team
 | ||||||
|  | // Licensed under GPLv2 or any later version
 | ||||||
|  | // Refer to the license.txt file included.
 | ||||||
|  | 
 | ||||||
|  | #include "core/hle/service/ns/ns_language.h" | ||||||
|  | 
 | ||||||
|  | namespace Service::NS { | ||||||
|  | 
 | ||||||
|  | constexpr ApplicationLanguagePriorityList priority_list_american_english = {{ | ||||||
|  |     ApplicationLanguage::AmericanEnglish, | ||||||
|  |     ApplicationLanguage::BritishEnglish, | ||||||
|  |     ApplicationLanguage::LatinAmericanSpanish, | ||||||
|  |     ApplicationLanguage::CanadianFrench, | ||||||
|  |     ApplicationLanguage::French, | ||||||
|  |     ApplicationLanguage::German, | ||||||
|  |     ApplicationLanguage::Spanish, | ||||||
|  |     ApplicationLanguage::Italian, | ||||||
|  |     ApplicationLanguage::Dutch, | ||||||
|  |     ApplicationLanguage::Portuguese, | ||||||
|  |     ApplicationLanguage::Russian, | ||||||
|  |     ApplicationLanguage::Japanese, | ||||||
|  |     ApplicationLanguage::SimplifiedChinese, | ||||||
|  |     ApplicationLanguage::TraditionalChinese, | ||||||
|  |     ApplicationLanguage::Korean, | ||||||
|  | }}; | ||||||
|  | 
 | ||||||
|  | constexpr ApplicationLanguagePriorityList priority_list_british_english = {{ | ||||||
|  |     ApplicationLanguage::BritishEnglish, | ||||||
|  |     ApplicationLanguage::AmericanEnglish, | ||||||
|  |     ApplicationLanguage::French, | ||||||
|  |     ApplicationLanguage::German, | ||||||
|  |     ApplicationLanguage::Spanish, | ||||||
|  |     ApplicationLanguage::Italian, | ||||||
|  |     ApplicationLanguage::Dutch, | ||||||
|  |     ApplicationLanguage::Portuguese, | ||||||
|  |     ApplicationLanguage::Russian, | ||||||
|  |     ApplicationLanguage::LatinAmericanSpanish, | ||||||
|  |     ApplicationLanguage::CanadianFrench, | ||||||
|  |     ApplicationLanguage::Japanese, | ||||||
|  |     ApplicationLanguage::SimplifiedChinese, | ||||||
|  |     ApplicationLanguage::TraditionalChinese, | ||||||
|  |     ApplicationLanguage::Korean, | ||||||
|  | }}; | ||||||
|  | 
 | ||||||
|  | constexpr ApplicationLanguagePriorityList priority_list_japanese = {{ | ||||||
|  |     ApplicationLanguage::Japanese, | ||||||
|  |     ApplicationLanguage::AmericanEnglish, | ||||||
|  |     ApplicationLanguage::BritishEnglish, | ||||||
|  |     ApplicationLanguage::LatinAmericanSpanish, | ||||||
|  |     ApplicationLanguage::CanadianFrench, | ||||||
|  |     ApplicationLanguage::French, | ||||||
|  |     ApplicationLanguage::German, | ||||||
|  |     ApplicationLanguage::Spanish, | ||||||
|  |     ApplicationLanguage::Italian, | ||||||
|  |     ApplicationLanguage::Dutch, | ||||||
|  |     ApplicationLanguage::Portuguese, | ||||||
|  |     ApplicationLanguage::Russian, | ||||||
|  |     ApplicationLanguage::SimplifiedChinese, | ||||||
|  |     ApplicationLanguage::TraditionalChinese, | ||||||
|  |     ApplicationLanguage::Korean, | ||||||
|  | }}; | ||||||
|  | 
 | ||||||
|  | constexpr ApplicationLanguagePriorityList priority_list_french = {{ | ||||||
|  |     ApplicationLanguage::French, | ||||||
|  |     ApplicationLanguage::CanadianFrench, | ||||||
|  |     ApplicationLanguage::BritishEnglish, | ||||||
|  |     ApplicationLanguage::AmericanEnglish, | ||||||
|  |     ApplicationLanguage::German, | ||||||
|  |     ApplicationLanguage::Spanish, | ||||||
|  |     ApplicationLanguage::Italian, | ||||||
|  |     ApplicationLanguage::Dutch, | ||||||
|  |     ApplicationLanguage::Portuguese, | ||||||
|  |     ApplicationLanguage::Russian, | ||||||
|  |     ApplicationLanguage::LatinAmericanSpanish, | ||||||
|  |     ApplicationLanguage::Japanese, | ||||||
|  |     ApplicationLanguage::SimplifiedChinese, | ||||||
|  |     ApplicationLanguage::TraditionalChinese, | ||||||
|  |     ApplicationLanguage::Korean, | ||||||
|  | }}; | ||||||
|  | 
 | ||||||
|  | constexpr ApplicationLanguagePriorityList priority_list_german = {{ | ||||||
|  |     ApplicationLanguage::German, | ||||||
|  |     ApplicationLanguage::BritishEnglish, | ||||||
|  |     ApplicationLanguage::AmericanEnglish, | ||||||
|  |     ApplicationLanguage::French, | ||||||
|  |     ApplicationLanguage::Spanish, | ||||||
|  |     ApplicationLanguage::Italian, | ||||||
|  |     ApplicationLanguage::Dutch, | ||||||
|  |     ApplicationLanguage::Portuguese, | ||||||
|  |     ApplicationLanguage::Russian, | ||||||
|  |     ApplicationLanguage::LatinAmericanSpanish, | ||||||
|  |     ApplicationLanguage::CanadianFrench, | ||||||
|  |     ApplicationLanguage::Japanese, | ||||||
|  |     ApplicationLanguage::SimplifiedChinese, | ||||||
|  |     ApplicationLanguage::TraditionalChinese, | ||||||
|  |     ApplicationLanguage::Korean, | ||||||
|  | }}; | ||||||
|  | 
 | ||||||
|  | constexpr ApplicationLanguagePriorityList priority_list_latin_american_spanish = {{ | ||||||
|  |     ApplicationLanguage::LatinAmericanSpanish, | ||||||
|  |     ApplicationLanguage::Spanish, | ||||||
|  |     ApplicationLanguage::AmericanEnglish, | ||||||
|  |     ApplicationLanguage::BritishEnglish, | ||||||
|  |     ApplicationLanguage::Portuguese, | ||||||
|  |     ApplicationLanguage::CanadianFrench, | ||||||
|  |     ApplicationLanguage::French, | ||||||
|  |     ApplicationLanguage::Italian, | ||||||
|  |     ApplicationLanguage::German, | ||||||
|  |     ApplicationLanguage::Dutch, | ||||||
|  |     ApplicationLanguage::Russian, | ||||||
|  |     ApplicationLanguage::Japanese, | ||||||
|  |     ApplicationLanguage::SimplifiedChinese, | ||||||
|  |     ApplicationLanguage::TraditionalChinese, | ||||||
|  |     ApplicationLanguage::Korean, | ||||||
|  | }}; | ||||||
|  | 
 | ||||||
|  | constexpr ApplicationLanguagePriorityList priority_list_spanish = {{ | ||||||
|  |     ApplicationLanguage::Spanish, | ||||||
|  |     ApplicationLanguage::LatinAmericanSpanish, | ||||||
|  |     ApplicationLanguage::BritishEnglish, | ||||||
|  |     ApplicationLanguage::AmericanEnglish, | ||||||
|  |     ApplicationLanguage::French, | ||||||
|  |     ApplicationLanguage::German, | ||||||
|  |     ApplicationLanguage::Italian, | ||||||
|  |     ApplicationLanguage::Dutch, | ||||||
|  |     ApplicationLanguage::Portuguese, | ||||||
|  |     ApplicationLanguage::Russian, | ||||||
|  |     ApplicationLanguage::CanadianFrench, | ||||||
|  |     ApplicationLanguage::Japanese, | ||||||
|  |     ApplicationLanguage::SimplifiedChinese, | ||||||
|  |     ApplicationLanguage::TraditionalChinese, | ||||||
|  |     ApplicationLanguage::Korean, | ||||||
|  | }}; | ||||||
|  | 
 | ||||||
|  | constexpr ApplicationLanguagePriorityList priority_list_italian = {{ | ||||||
|  |     ApplicationLanguage::Italian, | ||||||
|  |     ApplicationLanguage::BritishEnglish, | ||||||
|  |     ApplicationLanguage::AmericanEnglish, | ||||||
|  |     ApplicationLanguage::French, | ||||||
|  |     ApplicationLanguage::German, | ||||||
|  |     ApplicationLanguage::Spanish, | ||||||
|  |     ApplicationLanguage::Dutch, | ||||||
|  |     ApplicationLanguage::Portuguese, | ||||||
|  |     ApplicationLanguage::Russian, | ||||||
|  |     ApplicationLanguage::LatinAmericanSpanish, | ||||||
|  |     ApplicationLanguage::CanadianFrench, | ||||||
|  |     ApplicationLanguage::Japanese, | ||||||
|  |     ApplicationLanguage::SimplifiedChinese, | ||||||
|  |     ApplicationLanguage::TraditionalChinese, | ||||||
|  |     ApplicationLanguage::Korean, | ||||||
|  | }}; | ||||||
|  | 
 | ||||||
|  | constexpr ApplicationLanguagePriorityList priority_list_dutch = {{ | ||||||
|  |     ApplicationLanguage::Dutch, | ||||||
|  |     ApplicationLanguage::BritishEnglish, | ||||||
|  |     ApplicationLanguage::AmericanEnglish, | ||||||
|  |     ApplicationLanguage::French, | ||||||
|  |     ApplicationLanguage::German, | ||||||
|  |     ApplicationLanguage::Spanish, | ||||||
|  |     ApplicationLanguage::Italian, | ||||||
|  |     ApplicationLanguage::Portuguese, | ||||||
|  |     ApplicationLanguage::Russian, | ||||||
|  |     ApplicationLanguage::LatinAmericanSpanish, | ||||||
|  |     ApplicationLanguage::CanadianFrench, | ||||||
|  |     ApplicationLanguage::Japanese, | ||||||
|  |     ApplicationLanguage::SimplifiedChinese, | ||||||
|  |     ApplicationLanguage::TraditionalChinese, | ||||||
|  |     ApplicationLanguage::Korean, | ||||||
|  | }}; | ||||||
|  | 
 | ||||||
|  | constexpr ApplicationLanguagePriorityList priority_list_canadian_french = {{ | ||||||
|  |     ApplicationLanguage::CanadianFrench, | ||||||
|  |     ApplicationLanguage::French, | ||||||
|  |     ApplicationLanguage::AmericanEnglish, | ||||||
|  |     ApplicationLanguage::BritishEnglish, | ||||||
|  |     ApplicationLanguage::LatinAmericanSpanish, | ||||||
|  |     ApplicationLanguage::Spanish, | ||||||
|  |     ApplicationLanguage::German, | ||||||
|  |     ApplicationLanguage::Italian, | ||||||
|  |     ApplicationLanguage::Dutch, | ||||||
|  |     ApplicationLanguage::Portuguese, | ||||||
|  |     ApplicationLanguage::Russian, | ||||||
|  |     ApplicationLanguage::Japanese, | ||||||
|  |     ApplicationLanguage::SimplifiedChinese, | ||||||
|  |     ApplicationLanguage::TraditionalChinese, | ||||||
|  |     ApplicationLanguage::Korean, | ||||||
|  | }}; | ||||||
|  | 
 | ||||||
|  | constexpr ApplicationLanguagePriorityList priority_list_portuguese = {{ | ||||||
|  |     ApplicationLanguage::Portuguese, | ||||||
|  |     ApplicationLanguage::BritishEnglish, | ||||||
|  |     ApplicationLanguage::AmericanEnglish, | ||||||
|  |     ApplicationLanguage::French, | ||||||
|  |     ApplicationLanguage::German, | ||||||
|  |     ApplicationLanguage::Spanish, | ||||||
|  |     ApplicationLanguage::Italian, | ||||||
|  |     ApplicationLanguage::Dutch, | ||||||
|  |     ApplicationLanguage::Russian, | ||||||
|  |     ApplicationLanguage::LatinAmericanSpanish, | ||||||
|  |     ApplicationLanguage::CanadianFrench, | ||||||
|  |     ApplicationLanguage::Japanese, | ||||||
|  |     ApplicationLanguage::SimplifiedChinese, | ||||||
|  |     ApplicationLanguage::TraditionalChinese, | ||||||
|  |     ApplicationLanguage::Korean, | ||||||
|  | }}; | ||||||
|  | 
 | ||||||
|  | constexpr ApplicationLanguagePriorityList priority_list_russian = {{ | ||||||
|  |     ApplicationLanguage::Russian, | ||||||
|  |     ApplicationLanguage::BritishEnglish, | ||||||
|  |     ApplicationLanguage::AmericanEnglish, | ||||||
|  |     ApplicationLanguage::French, | ||||||
|  |     ApplicationLanguage::German, | ||||||
|  |     ApplicationLanguage::Spanish, | ||||||
|  |     ApplicationLanguage::Italian, | ||||||
|  |     ApplicationLanguage::Dutch, | ||||||
|  |     ApplicationLanguage::Portuguese, | ||||||
|  |     ApplicationLanguage::LatinAmericanSpanish, | ||||||
|  |     ApplicationLanguage::CanadianFrench, | ||||||
|  |     ApplicationLanguage::Japanese, | ||||||
|  |     ApplicationLanguage::SimplifiedChinese, | ||||||
|  |     ApplicationLanguage::TraditionalChinese, | ||||||
|  |     ApplicationLanguage::Korean, | ||||||
|  | }}; | ||||||
|  | 
 | ||||||
|  | constexpr ApplicationLanguagePriorityList priority_list_korean = {{ | ||||||
|  |     ApplicationLanguage::Korean, | ||||||
|  |     ApplicationLanguage::AmericanEnglish, | ||||||
|  |     ApplicationLanguage::BritishEnglish, | ||||||
|  |     ApplicationLanguage::LatinAmericanSpanish, | ||||||
|  |     ApplicationLanguage::CanadianFrench, | ||||||
|  |     ApplicationLanguage::French, | ||||||
|  |     ApplicationLanguage::German, | ||||||
|  |     ApplicationLanguage::Spanish, | ||||||
|  |     ApplicationLanguage::Italian, | ||||||
|  |     ApplicationLanguage::Dutch, | ||||||
|  |     ApplicationLanguage::Portuguese, | ||||||
|  |     ApplicationLanguage::Russian, | ||||||
|  |     ApplicationLanguage::Japanese, | ||||||
|  |     ApplicationLanguage::SimplifiedChinese, | ||||||
|  |     ApplicationLanguage::TraditionalChinese, | ||||||
|  | }}; | ||||||
|  | 
 | ||||||
|  | constexpr ApplicationLanguagePriorityList priority_list_traditional_chinese = {{ | ||||||
|  |     ApplicationLanguage::TraditionalChinese, | ||||||
|  |     ApplicationLanguage::SimplifiedChinese, | ||||||
|  |     ApplicationLanguage::AmericanEnglish, | ||||||
|  |     ApplicationLanguage::BritishEnglish, | ||||||
|  |     ApplicationLanguage::Japanese, | ||||||
|  |     ApplicationLanguage::LatinAmericanSpanish, | ||||||
|  |     ApplicationLanguage::CanadianFrench, | ||||||
|  |     ApplicationLanguage::French, | ||||||
|  |     ApplicationLanguage::German, | ||||||
|  |     ApplicationLanguage::Spanish, | ||||||
|  |     ApplicationLanguage::Italian, | ||||||
|  |     ApplicationLanguage::Dutch, | ||||||
|  |     ApplicationLanguage::Portuguese, | ||||||
|  |     ApplicationLanguage::Russian, | ||||||
|  |     ApplicationLanguage::Korean, | ||||||
|  | }}; | ||||||
|  | 
 | ||||||
|  | constexpr ApplicationLanguagePriorityList priority_list_simplified_chinese = {{ | ||||||
|  |     ApplicationLanguage::SimplifiedChinese, | ||||||
|  |     ApplicationLanguage::TraditionalChinese, | ||||||
|  |     ApplicationLanguage::AmericanEnglish, | ||||||
|  |     ApplicationLanguage::BritishEnglish, | ||||||
|  |     ApplicationLanguage::Japanese, | ||||||
|  |     ApplicationLanguage::LatinAmericanSpanish, | ||||||
|  |     ApplicationLanguage::CanadianFrench, | ||||||
|  |     ApplicationLanguage::French, | ||||||
|  |     ApplicationLanguage::German, | ||||||
|  |     ApplicationLanguage::Spanish, | ||||||
|  |     ApplicationLanguage::Italian, | ||||||
|  |     ApplicationLanguage::Dutch, | ||||||
|  |     ApplicationLanguage::Portuguese, | ||||||
|  |     ApplicationLanguage::Russian, | ||||||
|  |     ApplicationLanguage::Korean, | ||||||
|  | }}; | ||||||
|  | 
 | ||||||
|  | const ApplicationLanguagePriorityList* GetApplicationLanguagePriorityList(ApplicationLanguage lang) { | ||||||
|  |     switch (lang) { | ||||||
|  |     case ApplicationLanguage::AmericanEnglish: | ||||||
|  |         return &priority_list_american_english; | ||||||
|  |     case ApplicationLanguage::BritishEnglish: | ||||||
|  |         return &priority_list_british_english; | ||||||
|  |     case ApplicationLanguage::Japanese: | ||||||
|  |         return &priority_list_japanese; | ||||||
|  |     case ApplicationLanguage::French: | ||||||
|  |         return &priority_list_french; | ||||||
|  |     case ApplicationLanguage::German: | ||||||
|  |         return &priority_list_german; | ||||||
|  |     case ApplicationLanguage::LatinAmericanSpanish: | ||||||
|  |         return &priority_list_latin_american_spanish; | ||||||
|  |     case ApplicationLanguage::Spanish: | ||||||
|  |         return &priority_list_spanish; | ||||||
|  |     case ApplicationLanguage::Italian: | ||||||
|  |         return &priority_list_italian; | ||||||
|  |     case ApplicationLanguage::Dutch: | ||||||
|  |         return &priority_list_dutch; | ||||||
|  |     case ApplicationLanguage::CanadianFrench: | ||||||
|  |         return &priority_list_canadian_french; | ||||||
|  |     case ApplicationLanguage::Portuguese: | ||||||
|  |         return &priority_list_portuguese; | ||||||
|  |     case ApplicationLanguage::Russian: | ||||||
|  |         return &priority_list_russian; | ||||||
|  |     case ApplicationLanguage::Korean: | ||||||
|  |         return &priority_list_korean; | ||||||
|  |     case ApplicationLanguage::TraditionalChinese: | ||||||
|  |         return &priority_list_traditional_chinese; | ||||||
|  |     case ApplicationLanguage::SimplifiedChinese: | ||||||
|  |         return &priority_list_simplified_chinese; | ||||||
|  |     default: | ||||||
|  |         return nullptr; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | std::optional<ApplicationLanguage> ConvertToApplicationLanguage( | ||||||
|  |     const Service::Set::LanguageCode language_code) { | ||||||
|  |     switch (language_code) { | ||||||
|  |     case Service::Set::LanguageCode::EN_US: | ||||||
|  |         return ApplicationLanguage::AmericanEnglish; | ||||||
|  |     case Service::Set::LanguageCode::EN_GB: | ||||||
|  |         return ApplicationLanguage::BritishEnglish; | ||||||
|  |     case Service::Set::LanguageCode::JA: | ||||||
|  |         return ApplicationLanguage::Japanese; | ||||||
|  |     case Service::Set::LanguageCode::FR: | ||||||
|  |         return ApplicationLanguage::French; | ||||||
|  |     case Service::Set::LanguageCode::DE: | ||||||
|  |         return ApplicationLanguage::German; | ||||||
|  |     case Service::Set::LanguageCode::ES_419: | ||||||
|  |         return ApplicationLanguage::LatinAmericanSpanish; | ||||||
|  |     case Service::Set::LanguageCode::ES: | ||||||
|  |         return ApplicationLanguage::Spanish; | ||||||
|  |     case Service::Set::LanguageCode::IT: | ||||||
|  |         return ApplicationLanguage::Italian; | ||||||
|  |     case Service::Set::LanguageCode::NL: | ||||||
|  |         return ApplicationLanguage::Dutch; | ||||||
|  |     case Service::Set::LanguageCode::FR_CA: | ||||||
|  |         return ApplicationLanguage::CanadianFrench; | ||||||
|  |     case Service::Set::LanguageCode::PT: | ||||||
|  |         return ApplicationLanguage::Portuguese; | ||||||
|  |     case Service::Set::LanguageCode::RU: | ||||||
|  |         return ApplicationLanguage::Russian; | ||||||
|  |     case Service::Set::LanguageCode::KO: | ||||||
|  |         return ApplicationLanguage::Korean; | ||||||
|  |     case Service::Set::LanguageCode::ZH_HANT: | ||||||
|  |         return ApplicationLanguage::TraditionalChinese; | ||||||
|  |     case Service::Set::LanguageCode::ZH_HANS: | ||||||
|  |         return ApplicationLanguage::SimplifiedChinese; | ||||||
|  |     default: | ||||||
|  |         return std::nullopt; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | std::optional<Service::Set::LanguageCode> ConvertToLanguageCode(const ApplicationLanguage lang) { | ||||||
|  |     switch (lang) { | ||||||
|  |     case ApplicationLanguage::AmericanEnglish: | ||||||
|  |         return Service::Set::LanguageCode::EN_US; | ||||||
|  |     case ApplicationLanguage::BritishEnglish: | ||||||
|  |         return Service::Set::LanguageCode::EN_GB; | ||||||
|  |     case ApplicationLanguage::Japanese: | ||||||
|  |         return Service::Set::LanguageCode::JA; | ||||||
|  |     case ApplicationLanguage::French: | ||||||
|  |         return Service::Set::LanguageCode::FR; | ||||||
|  |     case ApplicationLanguage::German: | ||||||
|  |         return Service::Set::LanguageCode::DE; | ||||||
|  |     case ApplicationLanguage::LatinAmericanSpanish: | ||||||
|  |         return Service::Set::LanguageCode::ES_419; | ||||||
|  |     case ApplicationLanguage::Spanish: | ||||||
|  |         return Service::Set::LanguageCode::ES; | ||||||
|  |     case ApplicationLanguage::Italian: | ||||||
|  |         return Service::Set::LanguageCode::IT; | ||||||
|  |     case ApplicationLanguage::Dutch: | ||||||
|  |         return Service::Set::LanguageCode::NL; | ||||||
|  |     case ApplicationLanguage::CanadianFrench: | ||||||
|  |         return Service::Set::LanguageCode::FR_CA; | ||||||
|  |     case ApplicationLanguage::Portuguese: | ||||||
|  |         return Service::Set::LanguageCode::PT; | ||||||
|  |     case ApplicationLanguage::Russian: | ||||||
|  |         return Service::Set::LanguageCode::RU; | ||||||
|  |     case ApplicationLanguage::Korean: | ||||||
|  |         return Service::Set::LanguageCode::KO; | ||||||
|  |     case ApplicationLanguage::TraditionalChinese: | ||||||
|  |         return Service::Set::LanguageCode::ZH_HANT; | ||||||
|  |     case ApplicationLanguage::SimplifiedChinese: | ||||||
|  |         return Service::Set::LanguageCode::ZH_HANS; | ||||||
|  |     default: | ||||||
|  |         return std::nullopt; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | } // namespace Service::NS
 | ||||||
							
								
								
									
										41
									
								
								src/core/hle/service/ns/ns_language.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								src/core/hle/service/ns/ns_language.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,41 @@ | ||||||
|  | // Copyright 2018 yuzu emulator team
 | ||||||
|  | // Licensed under GPLv2 or any later version
 | ||||||
|  | // Refer to the license.txt file included.
 | ||||||
|  | 
 | ||||||
|  | #pragma once | ||||||
|  | #include <optional> | ||||||
|  | #include <string> | ||||||
|  | #include "common/common_types.h" | ||||||
|  | #include "core/hle/service/set/set.h" | ||||||
|  | 
 | ||||||
|  | namespace Service::NS { | ||||||
|  |     /// This is nn::ns::detail::ApplicationLanguage
 | ||||||
|  |     enum class ApplicationLanguage : u8 { | ||||||
|  |         AmericanEnglish = 0, | ||||||
|  |         BritishEnglish, | ||||||
|  |         Japanese, | ||||||
|  |         French, | ||||||
|  |         German, | ||||||
|  |         LatinAmericanSpanish, | ||||||
|  |         Spanish, | ||||||
|  |         Italian, | ||||||
|  |         Dutch, | ||||||
|  |         CanadianFrench, | ||||||
|  |         Portuguese, | ||||||
|  |         Russian, | ||||||
|  |         Korean, | ||||||
|  |         TraditionalChinese, | ||||||
|  |         SimplifiedChinese, | ||||||
|  |         Count | ||||||
|  |     }; | ||||||
|  |     using ApplicationLanguagePriorityList = const std::array<ApplicationLanguage, static_cast<std::size_t>(ApplicationLanguage::Count)>; | ||||||
|  | 
 | ||||||
|  |     constexpr u32 GetSupportedLanguageFlag(const ApplicationLanguage lang) { | ||||||
|  |         return 1u << static_cast<u32>(lang); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     const ApplicationLanguagePriorityList* GetApplicationLanguagePriorityList(ApplicationLanguage lang); | ||||||
|  |     std::optional<ApplicationLanguage> ConvertToApplicationLanguage(Service::Set::LanguageCode language_code); | ||||||
|  |     std::optional<Service::Set::LanguageCode> ConvertToLanguageCode(ApplicationLanguage lang); | ||||||
|  | } | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Michael Scire
						Michael Scire