Merge pull request #2510 from SciresM/desired_language
Implement/Fix IApplicationFunctions::GetDesiredLanguage
This commit is contained in:
commit
2beaaa35c5
|
@ -328,6 +328,9 @@ 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/language.cpp
|
||||||
|
hle/service/ns/language.h
|
||||||
hle/service/ns/ns.cpp
|
hle/service/ns/ns.cpp
|
||||||
hle/service/ns/ns.h
|
hle/service/ns/ns.h
|
||||||
hle/service/ns/pl_u.cpp
|
hle/service/ns/pl_u.cpp
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
// 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};
|
||||||
|
}
|
|
@ -0,0 +1,392 @@
|
||||||
|
// Copyright 2019 yuzu emulator team
|
||||||
|
// Licensed under GPLv2 or any later version
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#include "core/hle/service/ns/language.h"
|
||||||
|
#include "core/hle/service/set/set.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(
|
||||||
|
const 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 Set::LanguageCode language_code) {
|
||||||
|
switch (language_code) {
|
||||||
|
case Set::LanguageCode::EN_US:
|
||||||
|
return ApplicationLanguage::AmericanEnglish;
|
||||||
|
case Set::LanguageCode::EN_GB:
|
||||||
|
return ApplicationLanguage::BritishEnglish;
|
||||||
|
case Set::LanguageCode::JA:
|
||||||
|
return ApplicationLanguage::Japanese;
|
||||||
|
case Set::LanguageCode::FR:
|
||||||
|
return ApplicationLanguage::French;
|
||||||
|
case Set::LanguageCode::DE:
|
||||||
|
return ApplicationLanguage::German;
|
||||||
|
case Set::LanguageCode::ES_419:
|
||||||
|
return ApplicationLanguage::LatinAmericanSpanish;
|
||||||
|
case Set::LanguageCode::ES:
|
||||||
|
return ApplicationLanguage::Spanish;
|
||||||
|
case Set::LanguageCode::IT:
|
||||||
|
return ApplicationLanguage::Italian;
|
||||||
|
case Set::LanguageCode::NL:
|
||||||
|
return ApplicationLanguage::Dutch;
|
||||||
|
case Set::LanguageCode::FR_CA:
|
||||||
|
return ApplicationLanguage::CanadianFrench;
|
||||||
|
case Set::LanguageCode::PT:
|
||||||
|
return ApplicationLanguage::Portuguese;
|
||||||
|
case Set::LanguageCode::RU:
|
||||||
|
return ApplicationLanguage::Russian;
|
||||||
|
case Set::LanguageCode::KO:
|
||||||
|
return ApplicationLanguage::Korean;
|
||||||
|
case Set::LanguageCode::ZH_HANT:
|
||||||
|
return ApplicationLanguage::TraditionalChinese;
|
||||||
|
case Set::LanguageCode::ZH_HANS:
|
||||||
|
return ApplicationLanguage::SimplifiedChinese;
|
||||||
|
default:
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<Set::LanguageCode> ConvertToLanguageCode(const ApplicationLanguage lang) {
|
||||||
|
switch (lang) {
|
||||||
|
case ApplicationLanguage::AmericanEnglish:
|
||||||
|
return Set::LanguageCode::EN_US;
|
||||||
|
case ApplicationLanguage::BritishEnglish:
|
||||||
|
return Set::LanguageCode::EN_GB;
|
||||||
|
case ApplicationLanguage::Japanese:
|
||||||
|
return Set::LanguageCode::JA;
|
||||||
|
case ApplicationLanguage::French:
|
||||||
|
return Set::LanguageCode::FR;
|
||||||
|
case ApplicationLanguage::German:
|
||||||
|
return Set::LanguageCode::DE;
|
||||||
|
case ApplicationLanguage::LatinAmericanSpanish:
|
||||||
|
return Set::LanguageCode::ES_419;
|
||||||
|
case ApplicationLanguage::Spanish:
|
||||||
|
return Set::LanguageCode::ES;
|
||||||
|
case ApplicationLanguage::Italian:
|
||||||
|
return Set::LanguageCode::IT;
|
||||||
|
case ApplicationLanguage::Dutch:
|
||||||
|
return Set::LanguageCode::NL;
|
||||||
|
case ApplicationLanguage::CanadianFrench:
|
||||||
|
return Set::LanguageCode::FR_CA;
|
||||||
|
case ApplicationLanguage::Portuguese:
|
||||||
|
return Set::LanguageCode::PT;
|
||||||
|
case ApplicationLanguage::Russian:
|
||||||
|
return Set::LanguageCode::RU;
|
||||||
|
case ApplicationLanguage::Korean:
|
||||||
|
return Set::LanguageCode::KO;
|
||||||
|
case ApplicationLanguage::TraditionalChinese:
|
||||||
|
return Set::LanguageCode::ZH_HANT;
|
||||||
|
case ApplicationLanguage::SimplifiedChinese:
|
||||||
|
return Set::LanguageCode::ZH_HANS;
|
||||||
|
default:
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // namespace Service::NS
|
|
@ -0,0 +1,45 @@
|
||||||
|
// Copyright 2019 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"
|
||||||
|
|
||||||
|
namespace Service::Set {
|
||||||
|
enum class LanguageCode : u64;
|
||||||
|
}
|
||||||
|
|
||||||
|
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(Set::LanguageCode language_code);
|
||||||
|
std::optional<Set::LanguageCode> ConvertToLanguageCode(ApplicationLanguage lang);
|
||||||
|
} // namespace Service::NS
|
|
@ -7,445 +7,507 @@
|
||||||
#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/language.h"
|
||||||
#include "core/hle/service/ns/ns.h"
|
#include "core/hle/service/ns/ns.h"
|
||||||
#include "core/hle/service/ns/pl_u.h"
|
#include "core/hle/service/ns/pl_u.h"
|
||||||
|
#include "core/hle/service/set/set.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> {
|
IAccountProxyInterface::~IAccountProxyInterface() = default;
|
||||||
public:
|
|
||||||
explicit IApplicationManagerInterface() : ServiceFramework{"IApplicationManagerInterface"} {
|
|
||||||
// clang-format off
|
|
||||||
static const FunctionInfo functions[] = {
|
|
||||||
{0, nullptr, "ListApplicationRecord"},
|
|
||||||
{1, nullptr, "GenerateApplicationRecordCount"},
|
|
||||||
{2, nullptr, "GetApplicationRecordUpdateSystemEvent"},
|
|
||||||
{3, nullptr, "GetApplicationViewDeprecated"},
|
|
||||||
{4, nullptr, "DeleteApplicationEntity"},
|
|
||||||
{5, nullptr, "DeleteApplicationCompletely"},
|
|
||||||
{6, nullptr, "IsAnyApplicationEntityRedundant"},
|
|
||||||
{7, nullptr, "DeleteRedundantApplicationEntity"},
|
|
||||||
{8, nullptr, "IsApplicationEntityMovable"},
|
|
||||||
{9, nullptr, "MoveApplicationEntity"},
|
|
||||||
{11, nullptr, "CalculateApplicationOccupiedSize"},
|
|
||||||
{16, nullptr, "PushApplicationRecord"},
|
|
||||||
{17, nullptr, "ListApplicationRecordContentMeta"},
|
|
||||||
{19, nullptr, "LaunchApplicationOld"},
|
|
||||||
{21, nullptr, "GetApplicationContentPath"},
|
|
||||||
{22, nullptr, "TerminateApplication"},
|
|
||||||
{23, nullptr, "ResolveApplicationContentPath"},
|
|
||||||
{26, nullptr, "BeginInstallApplication"},
|
|
||||||
{27, nullptr, "DeleteApplicationRecord"},
|
|
||||||
{30, nullptr, "RequestApplicationUpdateInfo"},
|
|
||||||
{32, nullptr, "CancelApplicationDownload"},
|
|
||||||
{33, nullptr, "ResumeApplicationDownload"},
|
|
||||||
{35, nullptr, "UpdateVersionList"},
|
|
||||||
{36, nullptr, "PushLaunchVersion"},
|
|
||||||
{37, nullptr, "ListRequiredVersion"},
|
|
||||||
{38, nullptr, "CheckApplicationLaunchVersion"},
|
|
||||||
{39, nullptr, "CheckApplicationLaunchRights"},
|
|
||||||
{40, nullptr, "GetApplicationLogoData"},
|
|
||||||
{41, nullptr, "CalculateApplicationDownloadRequiredSize"},
|
|
||||||
{42, nullptr, "CleanupSdCard"},
|
|
||||||
{43, nullptr, "CheckSdCardMountStatus"},
|
|
||||||
{44, nullptr, "GetSdCardMountStatusChangedEvent"},
|
|
||||||
{45, nullptr, "GetGameCardAttachmentEvent"},
|
|
||||||
{46, nullptr, "GetGameCardAttachmentInfo"},
|
|
||||||
{47, nullptr, "GetTotalSpaceSize"},
|
|
||||||
{48, nullptr, "GetFreeSpaceSize"},
|
|
||||||
{49, nullptr, "GetSdCardRemovedEvent"},
|
|
||||||
{52, nullptr, "GetGameCardUpdateDetectionEvent"},
|
|
||||||
{53, nullptr, "DisableApplicationAutoDelete"},
|
|
||||||
{54, nullptr, "EnableApplicationAutoDelete"},
|
|
||||||
{55, nullptr, "GetApplicationDesiredLanguage"},
|
|
||||||
{56, nullptr, "SetApplicationTerminateResult"},
|
|
||||||
{57, nullptr, "ClearApplicationTerminateResult"},
|
|
||||||
{58, nullptr, "GetLastSdCardMountUnexpectedResult"},
|
|
||||||
{59, nullptr, "ConvertApplicationLanguageToLanguageCode"},
|
|
||||||
{60, nullptr, "ConvertLanguageCodeToApplicationLanguage"},
|
|
||||||
{61, nullptr, "GetBackgroundDownloadStressTaskInfo"},
|
|
||||||
{62, nullptr, "GetGameCardStopper"},
|
|
||||||
{63, nullptr, "IsSystemProgramInstalled"},
|
|
||||||
{64, nullptr, "StartApplyDeltaTask"},
|
|
||||||
{65, nullptr, "GetRequestServerStopper"},
|
|
||||||
{66, nullptr, "GetBackgroundApplyDeltaStressTaskInfo"},
|
|
||||||
{67, nullptr, "CancelApplicationApplyDelta"},
|
|
||||||
{68, nullptr, "ResumeApplicationApplyDelta"},
|
|
||||||
{69, nullptr, "CalculateApplicationApplyDeltaRequiredSize"},
|
|
||||||
{70, nullptr, "ResumeAll"},
|
|
||||||
{71, nullptr, "GetStorageSize"},
|
|
||||||
{80, nullptr, "RequestDownloadApplication"},
|
|
||||||
{81, nullptr, "RequestDownloadAddOnContent"},
|
|
||||||
{82, nullptr, "DownloadApplication"},
|
|
||||||
{83, nullptr, "CheckApplicationResumeRights"},
|
|
||||||
{84, nullptr, "GetDynamicCommitEvent"},
|
|
||||||
{85, nullptr, "RequestUpdateApplication2"},
|
|
||||||
{86, nullptr, "EnableApplicationCrashReport"},
|
|
||||||
{87, nullptr, "IsApplicationCrashReportEnabled"},
|
|
||||||
{90, nullptr, "BoostSystemMemoryResourceLimit"},
|
|
||||||
{91, nullptr, "DeprecatedLaunchApplication"},
|
|
||||||
{92, nullptr, "GetRunningApplicationProgramId"},
|
|
||||||
{93, nullptr, "GetMainApplicationProgramIndex"},
|
|
||||||
{94, nullptr, "LaunchApplication"},
|
|
||||||
{95, nullptr, "GetApplicationLaunchInfo"},
|
|
||||||
{96, nullptr, "AcquireApplicationLaunchInfo"},
|
|
||||||
{97, nullptr, "GetMainApplicationProgramIndex2"},
|
|
||||||
{98, nullptr, "EnableApplicationAllThreadDumpOnCrash"},
|
|
||||||
{100, nullptr, "ResetToFactorySettings"},
|
|
||||||
{101, nullptr, "ResetToFactorySettingsWithoutUserSaveData"},
|
|
||||||
{102, nullptr, "ResetToFactorySettingsForRefurbishment"},
|
|
||||||
{200, nullptr, "CalculateUserSaveDataStatistics"},
|
|
||||||
{201, nullptr, "DeleteUserSaveDataAll"},
|
|
||||||
{210, nullptr, "DeleteUserSystemSaveData"},
|
|
||||||
{211, nullptr, "DeleteSaveData"},
|
|
||||||
{220, nullptr, "UnregisterNetworkServiceAccount"},
|
|
||||||
{221, nullptr, "UnregisterNetworkServiceAccountWithUserSaveDataDeletion"},
|
|
||||||
{300, nullptr, "GetApplicationShellEvent"},
|
|
||||||
{301, nullptr, "PopApplicationShellEventInfo"},
|
|
||||||
{302, nullptr, "LaunchLibraryApplet"},
|
|
||||||
{303, nullptr, "TerminateLibraryApplet"},
|
|
||||||
{304, nullptr, "LaunchSystemApplet"},
|
|
||||||
{305, nullptr, "TerminateSystemApplet"},
|
|
||||||
{306, nullptr, "LaunchOverlayApplet"},
|
|
||||||
{307, nullptr, "TerminateOverlayApplet"},
|
|
||||||
{400, &IApplicationManagerInterface::GetApplicationControlData, "GetApplicationControlData"},
|
|
||||||
{401, nullptr, "InvalidateAllApplicationControlCache"},
|
|
||||||
{402, nullptr, "RequestDownloadApplicationControlData"},
|
|
||||||
{403, nullptr, "GetMaxApplicationControlCacheCount"},
|
|
||||||
{404, nullptr, "InvalidateApplicationControlCache"},
|
|
||||||
{405, nullptr, "ListApplicationControlCacheEntryInfo"},
|
|
||||||
{406, nullptr, "GetApplicationControlProperty"},
|
|
||||||
{502, nullptr, "RequestCheckGameCardRegistration"},
|
|
||||||
{503, nullptr, "RequestGameCardRegistrationGoldPoint"},
|
|
||||||
{504, nullptr, "RequestRegisterGameCard"},
|
|
||||||
{505, nullptr, "GetGameCardMountFailureEvent"},
|
|
||||||
{506, nullptr, "IsGameCardInserted"},
|
|
||||||
{507, nullptr, "EnsureGameCardAccess"},
|
|
||||||
{508, nullptr, "GetLastGameCardMountFailureResult"},
|
|
||||||
{509, nullptr, "ListApplicationIdOnGameCard"},
|
|
||||||
{600, nullptr, "CountApplicationContentMeta"},
|
|
||||||
{601, nullptr, "ListApplicationContentMetaStatus"},
|
|
||||||
{602, nullptr, "ListAvailableAddOnContent"},
|
|
||||||
{603, nullptr, "GetOwnedApplicationContentMetaStatus"},
|
|
||||||
{604, nullptr, "RegisterContentsExternalKey"},
|
|
||||||
{605, nullptr, "ListApplicationContentMetaStatusWithRightsCheck"},
|
|
||||||
{606, nullptr, "GetContentMetaStorage"},
|
|
||||||
{607, nullptr, "ListAvailableAddOnContent"},
|
|
||||||
{700, nullptr, "PushDownloadTaskList"},
|
|
||||||
{701, nullptr, "ClearTaskStatusList"},
|
|
||||||
{702, nullptr, "RequestDownloadTaskList"},
|
|
||||||
{703, nullptr, "RequestEnsureDownloadTask"},
|
|
||||||
{704, nullptr, "ListDownloadTaskStatus"},
|
|
||||||
{705, nullptr, "RequestDownloadTaskListData"},
|
|
||||||
{800, nullptr, "RequestVersionList"},
|
|
||||||
{801, nullptr, "ListVersionList"},
|
|
||||||
{802, nullptr, "RequestVersionListData"},
|
|
||||||
{900, nullptr, "GetApplicationRecord"},
|
|
||||||
{901, nullptr, "GetApplicationRecordProperty"},
|
|
||||||
{902, nullptr, "EnableApplicationAutoUpdate"},
|
|
||||||
{903, nullptr, "DisableApplicationAutoUpdate"},
|
|
||||||
{904, nullptr, "TouchApplication"},
|
|
||||||
{905, nullptr, "RequestApplicationUpdate"},
|
|
||||||
{906, nullptr, "IsApplicationUpdateRequested"},
|
|
||||||
{907, nullptr, "WithdrawApplicationUpdateRequest"},
|
|
||||||
{908, nullptr, "ListApplicationRecordInstalledContentMeta"},
|
|
||||||
{909, nullptr, "WithdrawCleanupAddOnContentsWithNoRightsRecommendation"},
|
|
||||||
{910, nullptr, "HasApplicationRecord"},
|
|
||||||
{911, nullptr, "SetPreInstalledApplication"},
|
|
||||||
{912, nullptr, "ClearPreInstalledApplicationFlag"},
|
|
||||||
{1000, nullptr, "RequestVerifyApplicationDeprecated"},
|
|
||||||
{1001, nullptr, "CorruptApplicationForDebug"},
|
|
||||||
{1002, nullptr, "RequestVerifyAddOnContentsRights"},
|
|
||||||
{1003, nullptr, "RequestVerifyApplication"},
|
|
||||||
{1004, nullptr, "CorruptContentForDebug"},
|
|
||||||
{1200, nullptr, "NeedsUpdateVulnerability"},
|
|
||||||
{1300, nullptr, "IsAnyApplicationEntityInstalled"},
|
|
||||||
{1301, nullptr, "DeleteApplicationContentEntities"},
|
|
||||||
{1302, nullptr, "CleanupUnrecordedApplicationEntity"},
|
|
||||||
{1303, nullptr, "CleanupAddOnContentsWithNoRights"},
|
|
||||||
{1304, nullptr, "DeleteApplicationContentEntity"},
|
|
||||||
{1305, nullptr, "TryDeleteRunningApplicationEntity"},
|
|
||||||
{1306, nullptr, "TryDeleteRunningApplicationCompletely"},
|
|
||||||
{1307, nullptr, "TryDeleteRunningApplicationContentEntities"},
|
|
||||||
{1308, nullptr, "DeleteApplicationCompletelyForDebug"},
|
|
||||||
{1309, nullptr, "CleanupUnavailableAddOnContents"},
|
|
||||||
{1400, nullptr, "PrepareShutdown"},
|
|
||||||
{1500, nullptr, "FormatSdCard"},
|
|
||||||
{1501, nullptr, "NeedsSystemUpdateToFormatSdCard"},
|
|
||||||
{1502, nullptr, "GetLastSdCardFormatUnexpectedResult"},
|
|
||||||
{1504, nullptr, "InsertSdCard"},
|
|
||||||
{1505, nullptr, "RemoveSdCard"},
|
|
||||||
{1600, nullptr, "GetSystemSeedForPseudoDeviceId"},
|
|
||||||
{1601, nullptr, "ResetSystemSeedForPseudoDeviceId"},
|
|
||||||
{1700, nullptr, "ListApplicationDownloadingContentMeta"},
|
|
||||||
{1701, nullptr, "GetApplicationView"},
|
|
||||||
{1702, nullptr, "GetApplicationDownloadTaskStatus"},
|
|
||||||
{1703, nullptr, "GetApplicationViewDownloadErrorContext"},
|
|
||||||
{1800, nullptr, "IsNotificationSetupCompleted"},
|
|
||||||
{1801, nullptr, "GetLastNotificationInfoCount"},
|
|
||||||
{1802, nullptr, "ListLastNotificationInfo"},
|
|
||||||
{1803, nullptr, "ListNotificationTask"},
|
|
||||||
{1900, nullptr, "IsActiveAccount"},
|
|
||||||
{1901, nullptr, "RequestDownloadApplicationPrepurchasedRights"},
|
|
||||||
{1902, nullptr, "GetApplicationTicketInfo"},
|
|
||||||
{2000, nullptr, "GetSystemDeliveryInfo"},
|
|
||||||
{2001, nullptr, "SelectLatestSystemDeliveryInfo"},
|
|
||||||
{2002, nullptr, "VerifyDeliveryProtocolVersion"},
|
|
||||||
{2003, nullptr, "GetApplicationDeliveryInfo"},
|
|
||||||
{2004, nullptr, "HasAllContentsToDeliver"},
|
|
||||||
{2005, nullptr, "CompareApplicationDeliveryInfo"},
|
|
||||||
{2006, nullptr, "CanDeliverApplication"},
|
|
||||||
{2007, nullptr, "ListContentMetaKeyToDeliverApplication"},
|
|
||||||
{2008, nullptr, "NeedsSystemUpdateToDeliverApplication"},
|
|
||||||
{2009, nullptr, "EstimateRequiredSize"},
|
|
||||||
{2010, nullptr, "RequestReceiveApplication"},
|
|
||||||
{2011, nullptr, "CommitReceiveApplication"},
|
|
||||||
{2012, nullptr, "GetReceiveApplicationProgress"},
|
|
||||||
{2013, nullptr, "RequestSendApplication"},
|
|
||||||
{2014, nullptr, "GetSendApplicationProgress"},
|
|
||||||
{2015, nullptr, "CompareSystemDeliveryInfo"},
|
|
||||||
{2016, nullptr, "ListNotCommittedContentMeta"},
|
|
||||||
{2017, nullptr, "CreateDownloadTask"},
|
|
||||||
{2018, nullptr, "GetApplicationDeliveryInfoHash"},
|
|
||||||
{2050, nullptr, "GetApplicationRightsOnClient"},
|
|
||||||
{2100, nullptr, "GetApplicationTerminateResult"},
|
|
||||||
{2101, nullptr, "GetRawApplicationTerminateResult"},
|
|
||||||
{2150, nullptr, "CreateRightsEnvironment"},
|
|
||||||
{2151, nullptr, "DestroyRightsEnvironment"},
|
|
||||||
{2152, nullptr, "ActivateRightsEnvironment"},
|
|
||||||
{2153, nullptr, "DeactivateRightsEnvironment"},
|
|
||||||
{2154, nullptr, "ForceActivateRightsContextForExit"},
|
|
||||||
{2160, nullptr, "AddTargetApplicationToRightsEnvironment"},
|
|
||||||
{2161, nullptr, "SetUsersToRightsEnvironment"},
|
|
||||||
{2170, nullptr, "GetRightsEnvironmentStatus"},
|
|
||||||
{2171, nullptr, "GetRightsEnvironmentStatusChangedEvent"},
|
|
||||||
{2180, nullptr, "RequestExtendRightsInRightsEnvironment"},
|
|
||||||
{2181, nullptr, "GetLastResultOfExtendRightsInRightsEnvironment"},
|
|
||||||
{2182, nullptr, "SetActiveRightsContextUsingStateToRightsEnvironment"},
|
|
||||||
{2190, nullptr, "GetRightsEnvironmentHandleForApplication"},
|
|
||||||
{2199, nullptr, "GetRightsEnvironmentCountForDebug"},
|
|
||||||
{2200, nullptr, "GetGameCardApplicationCopyIdentifier"},
|
|
||||||
{2201, nullptr, "GetInstalledApplicationCopyIdentifier"},
|
|
||||||
{2250, nullptr, "RequestReportActiveELicence"},
|
|
||||||
{2300, nullptr, "ListEventLog"},
|
|
||||||
};
|
|
||||||
// clang-format on
|
|
||||||
|
|
||||||
RegisterHandlers(functions);
|
IApplicationManagerInterface::IApplicationManagerInterface()
|
||||||
}
|
: ServiceFramework{"IApplicationManagerInterface"} {
|
||||||
|
// clang-format off
|
||||||
|
static const FunctionInfo functions[] = {
|
||||||
|
{0, nullptr, "ListApplicationRecord"},
|
||||||
|
{1, nullptr, "GenerateApplicationRecordCount"},
|
||||||
|
{2, nullptr, "GetApplicationRecordUpdateSystemEvent"},
|
||||||
|
{3, nullptr, "GetApplicationViewDeprecated"},
|
||||||
|
{4, nullptr, "DeleteApplicationEntity"},
|
||||||
|
{5, nullptr, "DeleteApplicationCompletely"},
|
||||||
|
{6, nullptr, "IsAnyApplicationEntityRedundant"},
|
||||||
|
{7, nullptr, "DeleteRedundantApplicationEntity"},
|
||||||
|
{8, nullptr, "IsApplicationEntityMovable"},
|
||||||
|
{9, nullptr, "MoveApplicationEntity"},
|
||||||
|
{11, nullptr, "CalculateApplicationOccupiedSize"},
|
||||||
|
{16, nullptr, "PushApplicationRecord"},
|
||||||
|
{17, nullptr, "ListApplicationRecordContentMeta"},
|
||||||
|
{19, nullptr, "LaunchApplicationOld"},
|
||||||
|
{21, nullptr, "GetApplicationContentPath"},
|
||||||
|
{22, nullptr, "TerminateApplication"},
|
||||||
|
{23, nullptr, "ResolveApplicationContentPath"},
|
||||||
|
{26, nullptr, "BeginInstallApplication"},
|
||||||
|
{27, nullptr, "DeleteApplicationRecord"},
|
||||||
|
{30, nullptr, "RequestApplicationUpdateInfo"},
|
||||||
|
{32, nullptr, "CancelApplicationDownload"},
|
||||||
|
{33, nullptr, "ResumeApplicationDownload"},
|
||||||
|
{35, nullptr, "UpdateVersionList"},
|
||||||
|
{36, nullptr, "PushLaunchVersion"},
|
||||||
|
{37, nullptr, "ListRequiredVersion"},
|
||||||
|
{38, nullptr, "CheckApplicationLaunchVersion"},
|
||||||
|
{39, nullptr, "CheckApplicationLaunchRights"},
|
||||||
|
{40, nullptr, "GetApplicationLogoData"},
|
||||||
|
{41, nullptr, "CalculateApplicationDownloadRequiredSize"},
|
||||||
|
{42, nullptr, "CleanupSdCard"},
|
||||||
|
{43, nullptr, "CheckSdCardMountStatus"},
|
||||||
|
{44, nullptr, "GetSdCardMountStatusChangedEvent"},
|
||||||
|
{45, nullptr, "GetGameCardAttachmentEvent"},
|
||||||
|
{46, nullptr, "GetGameCardAttachmentInfo"},
|
||||||
|
{47, nullptr, "GetTotalSpaceSize"},
|
||||||
|
{48, nullptr, "GetFreeSpaceSize"},
|
||||||
|
{49, nullptr, "GetSdCardRemovedEvent"},
|
||||||
|
{52, nullptr, "GetGameCardUpdateDetectionEvent"},
|
||||||
|
{53, nullptr, "DisableApplicationAutoDelete"},
|
||||||
|
{54, nullptr, "EnableApplicationAutoDelete"},
|
||||||
|
{55, &IApplicationManagerInterface::GetApplicationDesiredLanguage, "GetApplicationDesiredLanguage"},
|
||||||
|
{56, nullptr, "SetApplicationTerminateResult"},
|
||||||
|
{57, nullptr, "ClearApplicationTerminateResult"},
|
||||||
|
{58, nullptr, "GetLastSdCardMountUnexpectedResult"},
|
||||||
|
{59, &IApplicationManagerInterface::ConvertApplicationLanguageToLanguageCode, "ConvertApplicationLanguageToLanguageCode"},
|
||||||
|
{60, nullptr, "ConvertLanguageCodeToApplicationLanguage"},
|
||||||
|
{61, nullptr, "GetBackgroundDownloadStressTaskInfo"},
|
||||||
|
{62, nullptr, "GetGameCardStopper"},
|
||||||
|
{63, nullptr, "IsSystemProgramInstalled"},
|
||||||
|
{64, nullptr, "StartApplyDeltaTask"},
|
||||||
|
{65, nullptr, "GetRequestServerStopper"},
|
||||||
|
{66, nullptr, "GetBackgroundApplyDeltaStressTaskInfo"},
|
||||||
|
{67, nullptr, "CancelApplicationApplyDelta"},
|
||||||
|
{68, nullptr, "ResumeApplicationApplyDelta"},
|
||||||
|
{69, nullptr, "CalculateApplicationApplyDeltaRequiredSize"},
|
||||||
|
{70, nullptr, "ResumeAll"},
|
||||||
|
{71, nullptr, "GetStorageSize"},
|
||||||
|
{80, nullptr, "RequestDownloadApplication"},
|
||||||
|
{81, nullptr, "RequestDownloadAddOnContent"},
|
||||||
|
{82, nullptr, "DownloadApplication"},
|
||||||
|
{83, nullptr, "CheckApplicationResumeRights"},
|
||||||
|
{84, nullptr, "GetDynamicCommitEvent"},
|
||||||
|
{85, nullptr, "RequestUpdateApplication2"},
|
||||||
|
{86, nullptr, "EnableApplicationCrashReport"},
|
||||||
|
{87, nullptr, "IsApplicationCrashReportEnabled"},
|
||||||
|
{90, nullptr, "BoostSystemMemoryResourceLimit"},
|
||||||
|
{91, nullptr, "DeprecatedLaunchApplication"},
|
||||||
|
{92, nullptr, "GetRunningApplicationProgramId"},
|
||||||
|
{93, nullptr, "GetMainApplicationProgramIndex"},
|
||||||
|
{94, nullptr, "LaunchApplication"},
|
||||||
|
{95, nullptr, "GetApplicationLaunchInfo"},
|
||||||
|
{96, nullptr, "AcquireApplicationLaunchInfo"},
|
||||||
|
{97, nullptr, "GetMainApplicationProgramIndex2"},
|
||||||
|
{98, nullptr, "EnableApplicationAllThreadDumpOnCrash"},
|
||||||
|
{100, nullptr, "ResetToFactorySettings"},
|
||||||
|
{101, nullptr, "ResetToFactorySettingsWithoutUserSaveData"},
|
||||||
|
{102, nullptr, "ResetToFactorySettingsForRefurbishment"},
|
||||||
|
{200, nullptr, "CalculateUserSaveDataStatistics"},
|
||||||
|
{201, nullptr, "DeleteUserSaveDataAll"},
|
||||||
|
{210, nullptr, "DeleteUserSystemSaveData"},
|
||||||
|
{211, nullptr, "DeleteSaveData"},
|
||||||
|
{220, nullptr, "UnregisterNetworkServiceAccount"},
|
||||||
|
{221, nullptr, "UnregisterNetworkServiceAccountWithUserSaveDataDeletion"},
|
||||||
|
{300, nullptr, "GetApplicationShellEvent"},
|
||||||
|
{301, nullptr, "PopApplicationShellEventInfo"},
|
||||||
|
{302, nullptr, "LaunchLibraryApplet"},
|
||||||
|
{303, nullptr, "TerminateLibraryApplet"},
|
||||||
|
{304, nullptr, "LaunchSystemApplet"},
|
||||||
|
{305, nullptr, "TerminateSystemApplet"},
|
||||||
|
{306, nullptr, "LaunchOverlayApplet"},
|
||||||
|
{307, nullptr, "TerminateOverlayApplet"},
|
||||||
|
{400, &IApplicationManagerInterface::GetApplicationControlData, "GetApplicationControlData"},
|
||||||
|
{401, nullptr, "InvalidateAllApplicationControlCache"},
|
||||||
|
{402, nullptr, "RequestDownloadApplicationControlData"},
|
||||||
|
{403, nullptr, "GetMaxApplicationControlCacheCount"},
|
||||||
|
{404, nullptr, "InvalidateApplicationControlCache"},
|
||||||
|
{405, nullptr, "ListApplicationControlCacheEntryInfo"},
|
||||||
|
{406, nullptr, "GetApplicationControlProperty"},
|
||||||
|
{502, nullptr, "RequestCheckGameCardRegistration"},
|
||||||
|
{503, nullptr, "RequestGameCardRegistrationGoldPoint"},
|
||||||
|
{504, nullptr, "RequestRegisterGameCard"},
|
||||||
|
{505, nullptr, "GetGameCardMountFailureEvent"},
|
||||||
|
{506, nullptr, "IsGameCardInserted"},
|
||||||
|
{507, nullptr, "EnsureGameCardAccess"},
|
||||||
|
{508, nullptr, "GetLastGameCardMountFailureResult"},
|
||||||
|
{509, nullptr, "ListApplicationIdOnGameCard"},
|
||||||
|
{600, nullptr, "CountApplicationContentMeta"},
|
||||||
|
{601, nullptr, "ListApplicationContentMetaStatus"},
|
||||||
|
{602, nullptr, "ListAvailableAddOnContent"},
|
||||||
|
{603, nullptr, "GetOwnedApplicationContentMetaStatus"},
|
||||||
|
{604, nullptr, "RegisterContentsExternalKey"},
|
||||||
|
{605, nullptr, "ListApplicationContentMetaStatusWithRightsCheck"},
|
||||||
|
{606, nullptr, "GetContentMetaStorage"},
|
||||||
|
{607, nullptr, "ListAvailableAddOnContent"},
|
||||||
|
{700, nullptr, "PushDownloadTaskList"},
|
||||||
|
{701, nullptr, "ClearTaskStatusList"},
|
||||||
|
{702, nullptr, "RequestDownloadTaskList"},
|
||||||
|
{703, nullptr, "RequestEnsureDownloadTask"},
|
||||||
|
{704, nullptr, "ListDownloadTaskStatus"},
|
||||||
|
{705, nullptr, "RequestDownloadTaskListData"},
|
||||||
|
{800, nullptr, "RequestVersionList"},
|
||||||
|
{801, nullptr, "ListVersionList"},
|
||||||
|
{802, nullptr, "RequestVersionListData"},
|
||||||
|
{900, nullptr, "GetApplicationRecord"},
|
||||||
|
{901, nullptr, "GetApplicationRecordProperty"},
|
||||||
|
{902, nullptr, "EnableApplicationAutoUpdate"},
|
||||||
|
{903, nullptr, "DisableApplicationAutoUpdate"},
|
||||||
|
{904, nullptr, "TouchApplication"},
|
||||||
|
{905, nullptr, "RequestApplicationUpdate"},
|
||||||
|
{906, nullptr, "IsApplicationUpdateRequested"},
|
||||||
|
{907, nullptr, "WithdrawApplicationUpdateRequest"},
|
||||||
|
{908, nullptr, "ListApplicationRecordInstalledContentMeta"},
|
||||||
|
{909, nullptr, "WithdrawCleanupAddOnContentsWithNoRightsRecommendation"},
|
||||||
|
{910, nullptr, "HasApplicationRecord"},
|
||||||
|
{911, nullptr, "SetPreInstalledApplication"},
|
||||||
|
{912, nullptr, "ClearPreInstalledApplicationFlag"},
|
||||||
|
{1000, nullptr, "RequestVerifyApplicationDeprecated"},
|
||||||
|
{1001, nullptr, "CorruptApplicationForDebug"},
|
||||||
|
{1002, nullptr, "RequestVerifyAddOnContentsRights"},
|
||||||
|
{1003, nullptr, "RequestVerifyApplication"},
|
||||||
|
{1004, nullptr, "CorruptContentForDebug"},
|
||||||
|
{1200, nullptr, "NeedsUpdateVulnerability"},
|
||||||
|
{1300, nullptr, "IsAnyApplicationEntityInstalled"},
|
||||||
|
{1301, nullptr, "DeleteApplicationContentEntities"},
|
||||||
|
{1302, nullptr, "CleanupUnrecordedApplicationEntity"},
|
||||||
|
{1303, nullptr, "CleanupAddOnContentsWithNoRights"},
|
||||||
|
{1304, nullptr, "DeleteApplicationContentEntity"},
|
||||||
|
{1305, nullptr, "TryDeleteRunningApplicationEntity"},
|
||||||
|
{1306, nullptr, "TryDeleteRunningApplicationCompletely"},
|
||||||
|
{1307, nullptr, "TryDeleteRunningApplicationContentEntities"},
|
||||||
|
{1308, nullptr, "DeleteApplicationCompletelyForDebug"},
|
||||||
|
{1309, nullptr, "CleanupUnavailableAddOnContents"},
|
||||||
|
{1400, nullptr, "PrepareShutdown"},
|
||||||
|
{1500, nullptr, "FormatSdCard"},
|
||||||
|
{1501, nullptr, "NeedsSystemUpdateToFormatSdCard"},
|
||||||
|
{1502, nullptr, "GetLastSdCardFormatUnexpectedResult"},
|
||||||
|
{1504, nullptr, "InsertSdCard"},
|
||||||
|
{1505, nullptr, "RemoveSdCard"},
|
||||||
|
{1600, nullptr, "GetSystemSeedForPseudoDeviceId"},
|
||||||
|
{1601, nullptr, "ResetSystemSeedForPseudoDeviceId"},
|
||||||
|
{1700, nullptr, "ListApplicationDownloadingContentMeta"},
|
||||||
|
{1701, nullptr, "GetApplicationView"},
|
||||||
|
{1702, nullptr, "GetApplicationDownloadTaskStatus"},
|
||||||
|
{1703, nullptr, "GetApplicationViewDownloadErrorContext"},
|
||||||
|
{1800, nullptr, "IsNotificationSetupCompleted"},
|
||||||
|
{1801, nullptr, "GetLastNotificationInfoCount"},
|
||||||
|
{1802, nullptr, "ListLastNotificationInfo"},
|
||||||
|
{1803, nullptr, "ListNotificationTask"},
|
||||||
|
{1900, nullptr, "IsActiveAccount"},
|
||||||
|
{1901, nullptr, "RequestDownloadApplicationPrepurchasedRights"},
|
||||||
|
{1902, nullptr, "GetApplicationTicketInfo"},
|
||||||
|
{2000, nullptr, "GetSystemDeliveryInfo"},
|
||||||
|
{2001, nullptr, "SelectLatestSystemDeliveryInfo"},
|
||||||
|
{2002, nullptr, "VerifyDeliveryProtocolVersion"},
|
||||||
|
{2003, nullptr, "GetApplicationDeliveryInfo"},
|
||||||
|
{2004, nullptr, "HasAllContentsToDeliver"},
|
||||||
|
{2005, nullptr, "CompareApplicationDeliveryInfo"},
|
||||||
|
{2006, nullptr, "CanDeliverApplication"},
|
||||||
|
{2007, nullptr, "ListContentMetaKeyToDeliverApplication"},
|
||||||
|
{2008, nullptr, "NeedsSystemUpdateToDeliverApplication"},
|
||||||
|
{2009, nullptr, "EstimateRequiredSize"},
|
||||||
|
{2010, nullptr, "RequestReceiveApplication"},
|
||||||
|
{2011, nullptr, "CommitReceiveApplication"},
|
||||||
|
{2012, nullptr, "GetReceiveApplicationProgress"},
|
||||||
|
{2013, nullptr, "RequestSendApplication"},
|
||||||
|
{2014, nullptr, "GetSendApplicationProgress"},
|
||||||
|
{2015, nullptr, "CompareSystemDeliveryInfo"},
|
||||||
|
{2016, nullptr, "ListNotCommittedContentMeta"},
|
||||||
|
{2017, nullptr, "CreateDownloadTask"},
|
||||||
|
{2018, nullptr, "GetApplicationDeliveryInfoHash"},
|
||||||
|
{2050, nullptr, "GetApplicationRightsOnClient"},
|
||||||
|
{2100, nullptr, "GetApplicationTerminateResult"},
|
||||||
|
{2101, nullptr, "GetRawApplicationTerminateResult"},
|
||||||
|
{2150, nullptr, "CreateRightsEnvironment"},
|
||||||
|
{2151, nullptr, "DestroyRightsEnvironment"},
|
||||||
|
{2152, nullptr, "ActivateRightsEnvironment"},
|
||||||
|
{2153, nullptr, "DeactivateRightsEnvironment"},
|
||||||
|
{2154, nullptr, "ForceActivateRightsContextForExit"},
|
||||||
|
{2160, nullptr, "AddTargetApplicationToRightsEnvironment"},
|
||||||
|
{2161, nullptr, "SetUsersToRightsEnvironment"},
|
||||||
|
{2170, nullptr, "GetRightsEnvironmentStatus"},
|
||||||
|
{2171, nullptr, "GetRightsEnvironmentStatusChangedEvent"},
|
||||||
|
{2180, nullptr, "RequestExtendRightsInRightsEnvironment"},
|
||||||
|
{2181, nullptr, "GetLastResultOfExtendRightsInRightsEnvironment"},
|
||||||
|
{2182, nullptr, "SetActiveRightsContextUsingStateToRightsEnvironment"},
|
||||||
|
{2190, nullptr, "GetRightsEnvironmentHandleForApplication"},
|
||||||
|
{2199, nullptr, "GetRightsEnvironmentCountForDebug"},
|
||||||
|
{2200, nullptr, "GetGameCardApplicationCopyIdentifier"},
|
||||||
|
{2201, nullptr, "GetInstalledApplicationCopyIdentifier"},
|
||||||
|
{2250, nullptr, "RequestReportActiveELicence"},
|
||||||
|
{2300, nullptr, "ListEventLog"},
|
||||||
|
};
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
void GetApplicationControlData(Kernel::HLERequestContext& ctx) {
|
RegisterHandlers(functions);
|
||||||
IPC::RequestParser rp{ctx};
|
}
|
||||||
const auto flag = rp.PopRaw<u64>();
|
|
||||||
LOG_DEBUG(Service_NS, "called with flag={:016X}", flag);
|
|
||||||
|
|
||||||
const auto title_id = rp.PopRaw<u64>();
|
IApplicationManagerInterface::~IApplicationManagerInterface() = default;
|
||||||
|
|
||||||
const auto size = ctx.GetWriteBufferSize();
|
void IApplicationManagerInterface::GetApplicationControlData(Kernel::HLERequestContext& ctx) {
|
||||||
|
IPC::RequestParser rp{ctx};
|
||||||
|
const auto flag = rp.PopRaw<u64>();
|
||||||
|
LOG_DEBUG(Service_NS, "called with flag={:016X}", flag);
|
||||||
|
|
||||||
const FileSys::PatchManager pm{title_id};
|
const auto title_id = rp.PopRaw<u64>();
|
||||||
const auto control = pm.GetControlMetadata();
|
|
||||||
|
|
||||||
std::vector<u8> out;
|
const auto size = ctx.GetWriteBufferSize();
|
||||||
|
|
||||||
if (control.first != nullptr) {
|
const FileSys::PatchManager pm{title_id};
|
||||||
if (size < 0x4000) {
|
const auto control = pm.GetControlMetadata();
|
||||||
LOG_ERROR(Service_NS,
|
|
||||||
"output buffer is too small! (actual={:016X}, expected_min=0x4000)",
|
|
||||||
size);
|
|
||||||
IPC::ResponseBuilder rb{ctx, 2};
|
|
||||||
// TODO(DarkLordZach): Find a better error code for this.
|
|
||||||
rb.Push(ResultCode(-1));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
out.resize(0x4000);
|
std::vector<u8> out;
|
||||||
const auto bytes = control.first->GetRawBytes();
|
|
||||||
std::memcpy(out.data(), bytes.data(), bytes.size());
|
if (control.first != nullptr) {
|
||||||
} else {
|
if (size < 0x4000) {
|
||||||
LOG_WARNING(Service_NS, "missing NACP data for title_id={:016X}, defaulting to zeros.",
|
LOG_ERROR(Service_NS,
|
||||||
title_id);
|
"output buffer is too small! (actual={:016X}, expected_min=0x4000)", size);
|
||||||
out.resize(std::min<u64>(0x4000, size));
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
|
// TODO(DarkLordZach): Find a better error code for this.
|
||||||
|
rb.Push(ResultCode(-1));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
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 = 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 || (supported_languages & supported_flag) == supported_flag) {
|
||||||
static const FunctionInfo functions[] = {
|
return MakeResult(static_cast<u8>(lang));
|
||||||
{21, nullptr, "GetApplicationContentPath"},
|
}
|
||||||
{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 MakeResult(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);
|
||||||
|
}
|
||||||
|
|
||||||
|
IApplicationVersionInterface::~IApplicationVersionInterface() = default;
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
IContentManagerInterface::~IContentManagerInterface() = default;
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
IDocumentInterface::~IDocumentInterface() = default;
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
IDownloadTaskInterface::~IDownloadTaskInterface() = default;
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
IECommerceInterface::~IECommerceInterface() = default;
|
||||||
|
|
||||||
|
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> {
|
IFactoryResetInterface::~IFactoryResetInterface() = default;
|
||||||
public:
|
|
||||||
explicit NS(const char* name) : ServiceFramework{name} {
|
|
||||||
// clang-format off
|
|
||||||
static const FunctionInfo functions[] = {
|
|
||||||
{7992, &NS::PushInterface<IECommerceInterface>, "GetECommerceInterface"},
|
|
||||||
{7993, &NS::PushInterface<IApplicationVersionInterface>, "GetApplicationVersionInterface"},
|
|
||||||
{7994, &NS::PushInterface<IFactoryResetInterface>, "GetFactoryResetInterface"},
|
|
||||||
{7995, &NS::PushInterface<IAccountProxyInterface>, "GetAccountProxyInterface"},
|
|
||||||
{7996, &NS::PushInterface<IApplicationManagerInterface>, "GetApplicationManagerInterface"},
|
|
||||||
{7997, &NS::PushInterface<IDownloadTaskInterface>, "GetDownloadTaskInterface"},
|
|
||||||
{7998, &NS::PushInterface<IContentManagerInterface>, "GetContentManagementInterface"},
|
|
||||||
{7999, &NS::PushInterface<IDocumentInterface>, "GetDocumentInterface"},
|
|
||||||
};
|
|
||||||
// clang-format on
|
|
||||||
|
|
||||||
RegisterHandlers(functions);
|
NS::NS(const char* name) : ServiceFramework{name} {
|
||||||
}
|
// clang-format off
|
||||||
|
static const FunctionInfo functions[] = {
|
||||||
|
{7992, &NS::PushInterface<IECommerceInterface>, "GetECommerceInterface"},
|
||||||
|
{7993, &NS::PushInterface<IApplicationVersionInterface>, "GetApplicationVersionInterface"},
|
||||||
|
{7994, &NS::PushInterface<IFactoryResetInterface>, "GetFactoryResetInterface"},
|
||||||
|
{7995, &NS::PushInterface<IAccountProxyInterface>, "GetAccountProxyInterface"},
|
||||||
|
{7996, &NS::PushInterface<IApplicationManagerInterface>, "GetApplicationManagerInterface"},
|
||||||
|
{7997, &NS::PushInterface<IDownloadTaskInterface>, "GetDownloadTaskInterface"},
|
||||||
|
{7998, &NS::PushInterface<IContentManagerInterface>, "GetContentManagementInterface"},
|
||||||
|
{7999, &NS::PushInterface<IDocumentInterface>, "GetDocumentInterface"},
|
||||||
|
};
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
private:
|
RegisterHandlers(functions);
|
||||||
template <typename T>
|
}
|
||||||
void PushInterface(Kernel::HLERequestContext& ctx) {
|
|
||||||
LOG_DEBUG(Service_NS, "called");
|
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
NS::~NS() = default;
|
||||||
rb.Push(RESULT_SUCCESS);
|
|
||||||
rb.PushIpcInterface<T>();
|
std::shared_ptr<IApplicationManagerInterface> NS::GetApplicationManagerInterface() const {
|
||||||
}
|
return GetInterface<IApplicationManagerInterface>();
|
||||||
};
|
}
|
||||||
|
|
||||||
class NS_DEV final : public ServiceFramework<NS_DEV> {
|
class NS_DEV final : public ServiceFramework<NS_DEV> {
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -8,6 +8,88 @@
|
||||||
|
|
||||||
namespace Service::NS {
|
namespace Service::NS {
|
||||||
|
|
||||||
|
class IAccountProxyInterface final : public ServiceFramework<IAccountProxyInterface> {
|
||||||
|
public:
|
||||||
|
explicit IAccountProxyInterface();
|
||||||
|
~IAccountProxyInterface();
|
||||||
|
};
|
||||||
|
|
||||||
|
class IApplicationManagerInterface final : public ServiceFramework<IApplicationManagerInterface> {
|
||||||
|
public:
|
||||||
|
explicit IApplicationManagerInterface();
|
||||||
|
~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();
|
||||||
|
~IApplicationVersionInterface();
|
||||||
|
};
|
||||||
|
|
||||||
|
class IContentManagerInterface final : public ServiceFramework<IContentManagerInterface> {
|
||||||
|
public:
|
||||||
|
explicit IContentManagerInterface();
|
||||||
|
~IContentManagerInterface();
|
||||||
|
};
|
||||||
|
|
||||||
|
class IDocumentInterface final : public ServiceFramework<IDocumentInterface> {
|
||||||
|
public:
|
||||||
|
explicit IDocumentInterface();
|
||||||
|
~IDocumentInterface();
|
||||||
|
};
|
||||||
|
|
||||||
|
class IDownloadTaskInterface final : public ServiceFramework<IDownloadTaskInterface> {
|
||||||
|
public:
|
||||||
|
explicit IDownloadTaskInterface();
|
||||||
|
~IDownloadTaskInterface();
|
||||||
|
};
|
||||||
|
|
||||||
|
class IECommerceInterface final : public ServiceFramework<IECommerceInterface> {
|
||||||
|
public:
|
||||||
|
explicit IECommerceInterface();
|
||||||
|
~IECommerceInterface();
|
||||||
|
};
|
||||||
|
|
||||||
|
class IFactoryResetInterface final : public ServiceFramework<IFactoryResetInterface> {
|
||||||
|
public:
|
||||||
|
explicit IFactoryResetInterface();
|
||||||
|
~IFactoryResetInterface();
|
||||||
|
};
|
||||||
|
|
||||||
|
class NS final : public ServiceFramework<NS> {
|
||||||
|
public:
|
||||||
|
explicit NS(const char* name);
|
||||||
|
~NS();
|
||||||
|
|
||||||
|
std::shared_ptr<IApplicationManagerInterface> GetApplicationManagerInterface() const;
|
||||||
|
|
||||||
|
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() const {
|
||||||
|
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);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
// Copyright 2019 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);
|
||||||
|
} // namespace Service::NS
|
Loading…
Reference in New Issue