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,14 +7,16 @@
|
||||||
#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:
|
|
||||||
explicit IAccountProxyInterface() : ServiceFramework{"IAccountProxyInterface"} {
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
static const FunctionInfo functions[] = {
|
static const FunctionInfo functions[] = {
|
||||||
{0, nullptr, "CreateUserAccount"},
|
{0, nullptr, "CreateUserAccount"},
|
||||||
|
@ -22,12 +24,12 @@ public:
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
RegisterHandlers(functions);
|
RegisterHandlers(functions);
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
class IApplicationManagerInterface final : public ServiceFramework<IApplicationManagerInterface> {
|
IAccountProxyInterface::~IAccountProxyInterface() = default;
|
||||||
public:
|
|
||||||
explicit IApplicationManagerInterface() : ServiceFramework{"IApplicationManagerInterface"} {
|
IApplicationManagerInterface::IApplicationManagerInterface()
|
||||||
|
: ServiceFramework{"IApplicationManagerInterface"} {
|
||||||
// clang-format off
|
// clang-format off
|
||||||
static const FunctionInfo functions[] = {
|
static const FunctionInfo functions[] = {
|
||||||
{0, nullptr, "ListApplicationRecord"},
|
{0, nullptr, "ListApplicationRecord"},
|
||||||
|
@ -70,11 +72,11 @@ public:
|
||||||
{52, nullptr, "GetGameCardUpdateDetectionEvent"},
|
{52, nullptr, "GetGameCardUpdateDetectionEvent"},
|
||||||
{53, nullptr, "DisableApplicationAutoDelete"},
|
{53, nullptr, "DisableApplicationAutoDelete"},
|
||||||
{54, nullptr, "EnableApplicationAutoDelete"},
|
{54, nullptr, "EnableApplicationAutoDelete"},
|
||||||
{55, nullptr, "GetApplicationDesiredLanguage"},
|
{55, &IApplicationManagerInterface::GetApplicationDesiredLanguage, "GetApplicationDesiredLanguage"},
|
||||||
{56, nullptr, "SetApplicationTerminateResult"},
|
{56, nullptr, "SetApplicationTerminateResult"},
|
||||||
{57, nullptr, "ClearApplicationTerminateResult"},
|
{57, nullptr, "ClearApplicationTerminateResult"},
|
||||||
{58, nullptr, "GetLastSdCardMountUnexpectedResult"},
|
{58, nullptr, "GetLastSdCardMountUnexpectedResult"},
|
||||||
{59, nullptr, "ConvertApplicationLanguageToLanguageCode"},
|
{59, &IApplicationManagerInterface::ConvertApplicationLanguageToLanguageCode, "ConvertApplicationLanguageToLanguageCode"},
|
||||||
{60, nullptr, "ConvertLanguageCodeToApplicationLanguage"},
|
{60, nullptr, "ConvertLanguageCodeToApplicationLanguage"},
|
||||||
{61, nullptr, "GetBackgroundDownloadStressTaskInfo"},
|
{61, nullptr, "GetBackgroundDownloadStressTaskInfo"},
|
||||||
{62, nullptr, "GetGameCardStopper"},
|
{62, nullptr, "GetGameCardStopper"},
|
||||||
|
@ -245,9 +247,11 @@ public:
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
RegisterHandlers(functions);
|
RegisterHandlers(functions);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GetApplicationControlData(Kernel::HLERequestContext& ctx) {
|
IApplicationManagerInterface::~IApplicationManagerInterface() = default;
|
||||||
|
|
||||||
|
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);
|
||||||
|
@ -264,8 +268,7 @@ public:
|
||||||
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));
|
||||||
|
@ -284,8 +287,8 @@ public:
|
||||||
if (control.second != nullptr) {
|
if (control.second != nullptr) {
|
||||||
if (size < 0x4000 + control.second->GetSize()) {
|
if (size < 0x4000 + control.second->GetSize()) {
|
||||||
LOG_ERROR(Service_NS,
|
LOG_ERROR(Service_NS,
|
||||||
"output buffer is too small! (actual={:016X}, expected_min={:016X})",
|
"output buffer is too small! (actual={:016X}, expected_min={:016X})", size,
|
||||||
size, 0x4000 + control.second->GetSize());
|
0x4000 + control.second->GetSize());
|
||||||
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));
|
||||||
|
@ -304,12 +307,80 @@ public:
|
||||||
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>(static_cast<u32>(out.size()));
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
class IApplicationVersionInterface final : public ServiceFramework<IApplicationVersionInterface> {
|
void IApplicationManagerInterface::GetApplicationDesiredLanguage(Kernel::HLERequestContext& ctx) {
|
||||||
public:
|
IPC::RequestParser rp{ctx};
|
||||||
explicit IApplicationVersionInterface() : ServiceFramework{"IApplicationVersionInterface"} {
|
const auto supported_languages = rp.Pop<u32>();
|
||||||
|
|
||||||
|
const auto res = GetApplicationDesiredLanguage(supported_languages);
|
||||||
|
if (res.Succeeded()) {
|
||||||
|
IPC::ResponseBuilder rb{ctx, 3};
|
||||||
|
rb.Push(RESULT_SUCCESS);
|
||||||
|
rb.Push<u32>(*res);
|
||||||
|
} else {
|
||||||
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
|
rb.Push(res.Code());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ResultVal<u8> IApplicationManagerInterface::GetApplicationDesiredLanguage(
|
||||||
|
const u32 supported_languages) {
|
||||||
|
LOG_DEBUG(Service_NS, "called with supported_languages={:08X}", supported_languages);
|
||||||
|
|
||||||
|
// 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) {
|
||||||
|
return ERR_APPLICATION_LANGUAGE_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to find a valid language.
|
||||||
|
for (const auto lang : *priority_list) {
|
||||||
|
const auto supported_flag = GetSupportedLanguageFlag(lang);
|
||||||
|
if (supported_languages == 0 || (supported_languages & supported_flag) == supported_flag) {
|
||||||
|
return MakeResult(static_cast<u8>(lang));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ERR_APPLICATION_LANGUAGE_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ResultVal<u64> IApplicationManagerInterface::ConvertApplicationLanguageToLanguageCode(
|
||||||
|
u8 application_language) {
|
||||||
|
const auto language_code =
|
||||||
|
ConvertToLanguageCode(static_cast<ApplicationLanguage>(application_language));
|
||||||
|
if (language_code == std::nullopt) {
|
||||||
|
return ERR_APPLICATION_LANGUAGE_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
return MakeResult(static_cast<u64>(*language_code));
|
||||||
|
}
|
||||||
|
|
||||||
|
IApplicationVersionInterface::IApplicationVersionInterface()
|
||||||
|
: ServiceFramework{"IApplicationVersionInterface"} {
|
||||||
// clang-format off
|
// clang-format off
|
||||||
static const FunctionInfo functions[] = {
|
static const FunctionInfo functions[] = {
|
||||||
{0, nullptr, "GetLaunchRequiredVersion"},
|
{0, nullptr, "GetLaunchRequiredVersion"},
|
||||||
|
@ -325,12 +396,12 @@ public:
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
RegisterHandlers(functions);
|
RegisterHandlers(functions);
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
class IContentManagerInterface final : public ServiceFramework<IContentManagerInterface> {
|
IApplicationVersionInterface::~IApplicationVersionInterface() = default;
|
||||||
public:
|
|
||||||
explicit IContentManagerInterface() : ServiceFramework{"IContentManagerInterface"} {
|
IContentManagerInterface::IContentManagerInterface()
|
||||||
|
: ServiceFramework{"IContentManagerInterface"} {
|
||||||
// clang-format off
|
// clang-format off
|
||||||
static const FunctionInfo functions[] = {
|
static const FunctionInfo functions[] = {
|
||||||
{11, nullptr, "CalculateApplicationOccupiedSize"},
|
{11, nullptr, "CalculateApplicationOccupiedSize"},
|
||||||
|
@ -345,12 +416,11 @@ public:
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
RegisterHandlers(functions);
|
RegisterHandlers(functions);
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
class IDocumentInterface final : public ServiceFramework<IDocumentInterface> {
|
IContentManagerInterface::~IContentManagerInterface() = default;
|
||||||
public:
|
|
||||||
explicit IDocumentInterface() : ServiceFramework{"IDocumentInterface"} {
|
IDocumentInterface::IDocumentInterface() : ServiceFramework{"IDocumentInterface"} {
|
||||||
// clang-format off
|
// clang-format off
|
||||||
static const FunctionInfo functions[] = {
|
static const FunctionInfo functions[] = {
|
||||||
{21, nullptr, "GetApplicationContentPath"},
|
{21, nullptr, "GetApplicationContentPath"},
|
||||||
|
@ -360,12 +430,11 @@ public:
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
RegisterHandlers(functions);
|
RegisterHandlers(functions);
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
class IDownloadTaskInterface final : public ServiceFramework<IDownloadTaskInterface> {
|
IDocumentInterface::~IDocumentInterface() = default;
|
||||||
public:
|
|
||||||
explicit IDownloadTaskInterface() : ServiceFramework{"IDownloadTaskInterface"} {
|
IDownloadTaskInterface::IDownloadTaskInterface() : ServiceFramework{"IDownloadTaskInterface"} {
|
||||||
// clang-format off
|
// clang-format off
|
||||||
static const FunctionInfo functions[] = {
|
static const FunctionInfo functions[] = {
|
||||||
{701, nullptr, "ClearTaskStatusList"},
|
{701, nullptr, "ClearTaskStatusList"},
|
||||||
|
@ -381,12 +450,11 @@ public:
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
RegisterHandlers(functions);
|
RegisterHandlers(functions);
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
class IECommerceInterface final : public ServiceFramework<IECommerceInterface> {
|
IDownloadTaskInterface::~IDownloadTaskInterface() = default;
|
||||||
public:
|
|
||||||
explicit IECommerceInterface() : ServiceFramework{"IECommerceInterface"} {
|
IECommerceInterface::IECommerceInterface() : ServiceFramework{"IECommerceInterface"} {
|
||||||
// clang-format off
|
// clang-format off
|
||||||
static const FunctionInfo functions[] = {
|
static const FunctionInfo functions[] = {
|
||||||
{0, nullptr, "RequestLinkDevice"},
|
{0, nullptr, "RequestLinkDevice"},
|
||||||
|
@ -399,12 +467,12 @@ public:
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
RegisterHandlers(functions);
|
RegisterHandlers(functions);
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
class IFactoryResetInterface final : public ServiceFramework<IFactoryResetInterface> {
|
IECommerceInterface::~IECommerceInterface() = default;
|
||||||
public:
|
|
||||||
explicit IFactoryResetInterface() : ServiceFramework{"IFactoryResetInterface"} {
|
IFactoryResetInterface::IFactoryResetInterface::IFactoryResetInterface()
|
||||||
|
: ServiceFramework{"IFactoryResetInterface"} {
|
||||||
// clang-format off
|
// clang-format off
|
||||||
static const FunctionInfo functions[] = {
|
static const FunctionInfo functions[] = {
|
||||||
{100, nullptr, "ResetToFactorySettings"},
|
{100, nullptr, "ResetToFactorySettings"},
|
||||||
|
@ -414,12 +482,11 @@ public:
|
||||||
// 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} {
|
NS::NS(const char* name) : ServiceFramework{name} {
|
||||||
// clang-format off
|
// clang-format off
|
||||||
static const FunctionInfo functions[] = {
|
static const FunctionInfo functions[] = {
|
||||||
{7992, &NS::PushInterface<IECommerceInterface>, "GetECommerceInterface"},
|
{7992, &NS::PushInterface<IECommerceInterface>, "GetECommerceInterface"},
|
||||||
|
@ -434,18 +501,13 @@ public:
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
RegisterHandlers(functions);
|
RegisterHandlers(functions);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
NS::~NS() = default;
|
||||||
template <typename T>
|
|
||||||
void PushInterface(Kernel::HLERequestContext& ctx) {
|
|
||||||
LOG_DEBUG(Service_NS, "called");
|
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
std::shared_ptr<IApplicationManagerInterface> NS::GetApplicationManagerInterface() const {
|
||||||
rb.Push(RESULT_SUCCESS);
|
return GetInterface<IApplicationManagerInterface>();
|
||||||
rb.PushIpcInterface<T>();
|
}
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
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
|
Reference in New Issue