[common, hle] add new updates Polish+Thai languages (#3587)
Signed-off-by: lizzie <lizzie@eden-emu.dev> Co-authored-by: maufeat <sahyno1996@gmail.com> Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3587 Reviewed-by: Maufeat <sahyno1996@gmail.com> Reviewed-by: DraVee <dravee@eden-emu.dev> Co-authored-by: lizzie <lizzie@eden-emu.dev> Co-committed-by: lizzie <lizzie@eden-emu.dev>
This commit is contained in:
parent
963f9981ce
commit
c610b61126
|
|
@ -64,7 +64,8 @@
|
|||
<item>@string/language_spanish</item>
|
||||
<item>@string/language_taiwanese</item>
|
||||
<item>@string/language_traditional_chinese</item>
|
||||
<item>@string/language_serbian</item>
|
||||
<item>@string/language_polish</item>
|
||||
<item>@string/language_thai</item>
|
||||
</string-array>
|
||||
|
||||
<integer-array name="languageValues">
|
||||
|
|
@ -87,6 +88,7 @@
|
|||
<item>11</item>
|
||||
<item>16</item>
|
||||
<item>18</item>
|
||||
<item>19</item>
|
||||
</integer-array>
|
||||
|
||||
<string-array name="rendererApiNames">
|
||||
|
|
@ -407,6 +409,7 @@
|
|||
<item>@string/app_language_persian</item>
|
||||
<item>@string/app_language_hebrew</item>
|
||||
<item>@string/app_language_serbian</item>
|
||||
<item>@string/app_language_thai</item>
|
||||
</string-array>
|
||||
<integer-array name="appLanguageValues">
|
||||
<item>0</item>
|
||||
|
|
|
|||
|
|
@ -1011,7 +1011,8 @@
|
|||
<string name="language_simplified_chinese" translatable="false">简体中文</string>
|
||||
<string name="language_traditional_chinese" translatable="false">正體中文</string>
|
||||
<string name="language_brazilian_portuguese" translatable="false">Português do Brasil</string>
|
||||
<string name="language_serbian" translatable="false">српски</string>
|
||||
<string name="language_polish" translatable="false">Polska</string>
|
||||
<string name="language_thai" translatable="false">แบบไทย</string>
|
||||
|
||||
<!-- Memory Sizes -->
|
||||
<string name="memory_byte_shorthand">B</string>
|
||||
|
|
@ -1216,6 +1217,7 @@
|
|||
<string name="app_language_persian" translatable="false">فارسی</string>
|
||||
<string name="app_language_hebrew" translatable="false">עברית</string>
|
||||
<string name="app_language_serbian" translatable="false">Српски</string>
|
||||
<string name="app_language_thai" translatable="false">แบบไทย</string>
|
||||
|
||||
<!-- Static Themes -->
|
||||
<string name="static_theme_color">Theme Color</string>
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ ENUM(AudioMode, Mono, Stereo, Surround);
|
|||
|
||||
ENUM(Language, Japanese, EnglishAmerican, French, German, Italian, Spanish, Chinese, Korean, Dutch,
|
||||
Portuguese, Russian, Taiwanese, EnglishBritish, FrenchCanadian, SpanishLatin,
|
||||
ChineseSimplified, ChineseTraditional, PortugueseBrazilian, Serbian);
|
||||
ChineseSimplified, ChineseTraditional, PortugueseBrazilian, Polish, Thai);
|
||||
ENUM(Region, Japan, Usa, Europe, Australia, China, Korea, Taiwan);
|
||||
ENUM(TimeZone, Auto, Default, Cet, Cst6Cdt, Cuba, Eet, Egypt, Eire, Est, Est5Edt, Gb, GbEire, Gmt,
|
||||
GmtPlusZero, GmtMinusZero, GmtZero, Greenwich, Hongkong, Hst, Iceland, Iran, Israel, Jamaica,
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
#include <zlib.h>
|
||||
|
||||
#include "common/settings.h"
|
||||
#include "common/settings_enums.h"
|
||||
#include "common/string_util.h"
|
||||
#include "common/swap.h"
|
||||
#include "core/file_sys/control_metadata.h"
|
||||
|
|
@ -19,7 +20,7 @@
|
|||
|
||||
namespace FileSys {
|
||||
|
||||
const std::array<const char*, 16> LANGUAGE_NAMES{{
|
||||
const std::array<const char*, size_t(Language::Count)> LANGUAGE_NAMES{{
|
||||
"AmericanEnglish",
|
||||
"BritishEnglish",
|
||||
"Japanese",
|
||||
|
|
@ -36,137 +37,95 @@ const std::array<const char*, 16> LANGUAGE_NAMES{{
|
|||
"TraditionalChinese",
|
||||
"SimplifiedChinese",
|
||||
"BrazilianPortuguese",
|
||||
"Polish",
|
||||
"Thai",
|
||||
}};
|
||||
|
||||
namespace {
|
||||
constexpr std::size_t LEGACY_LANGUAGE_REGION_SIZE = sizeof(std::array<LanguageEntry, 16>);
|
||||
constexpr std::size_t PACKED_LANGUAGE_REGION_MAX_SIZE = sizeof(LanguageEntry) * 32;
|
||||
namespace
|
||||
{
|
||||
constexpr std::size_t MAX_EXPANDED_LANG_SIZE = sizeof(LanguageEntry) * 32;
|
||||
|
||||
bool InflateRawDeflate(std::span<const u8> compressed, std::vector<u8>& out) {
|
||||
if (compressed.empty() || compressed.size() > std::numeric_limits<uInt>::max()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
z_stream stream{};
|
||||
stream.next_in = const_cast<Bytef*>(reinterpret_cast<const Bytef*>(compressed.data()));
|
||||
stream.avail_in = static_cast<uInt>(compressed.size());
|
||||
if (inflateInit2(&stream, -MAX_WBITS) != Z_OK) {
|
||||
return false;
|
||||
}
|
||||
bool InflateRawDeflate(std::span<const u8> compressed, std::vector<u8>& out)
|
||||
{
|
||||
if (compressed.empty()) return false;
|
||||
|
||||
std::array<u8, 0x1000> chunk{};
|
||||
int ret = Z_OK;
|
||||
while (ret == Z_OK) {
|
||||
stream.next_out = reinterpret_cast<Bytef*>(chunk.data());
|
||||
stream.avail_out = static_cast<uInt>(chunk.size());
|
||||
ret = inflate(&stream, Z_NO_FLUSH);
|
||||
if (ret != Z_OK && ret != Z_STREAM_END) {
|
||||
inflateEnd(&stream);
|
||||
z_stream stream{};
|
||||
stream.next_in = const_cast<Bytef*>(reinterpret_cast<const Bytef*>(compressed.data()));
|
||||
stream.avail_in = static_cast<uInt>(compressed.size());
|
||||
if (inflateInit2(&stream, -MAX_WBITS) != Z_OK) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto produced = chunk.size() - static_cast<std::size_t>(stream.avail_out);
|
||||
if (produced != 0) {
|
||||
if (out.size() + produced > PACKED_LANGUAGE_REGION_MAX_SIZE) {
|
||||
inflateEnd(&stream);
|
||||
return false;
|
||||
}
|
||||
out.insert(out.end(), chunk.begin(),
|
||||
chunk.begin() + static_cast<std::ptrdiff_t>(produced));
|
||||
out.resize(MAX_EXPANDED_LANG_SIZE);
|
||||
stream.next_out = reinterpret_cast<Bytef*>(out.data());
|
||||
stream.avail_out = static_cast<uInt>(out.size());
|
||||
|
||||
int ret = inflate(&stream, Z_FINISH);
|
||||
inflateEnd(&stream);
|
||||
|
||||
if (ret != Z_STREAM_END && ret != Z_OK) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Shrink to actual decompressed size
|
||||
out.resize(stream.total_out);
|
||||
return true;
|
||||
}
|
||||
|
||||
inflateEnd(&stream);
|
||||
return ret == Z_STREAM_END;
|
||||
}
|
||||
|
||||
void DecodePackedLanguageEntries(RawNACP& raw) {
|
||||
auto* packed_region = reinterpret_cast<u8*>(raw.language_entries.data());
|
||||
u16_le compressed_size_le{};
|
||||
std::memcpy(&compressed_size_le, packed_region, sizeof(compressed_size_le));
|
||||
const auto compressed_size = static_cast<std::size_t>(compressed_size_le);
|
||||
|
||||
if (compressed_size == 0 || compressed_size > LEGACY_LANGUAGE_REGION_SIZE - sizeof(u16_le)) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<u8> decompressed;
|
||||
if (!InflateRawDeflate(
|
||||
std::span<const u8>(packed_region + sizeof(u16_le), compressed_size), decompressed)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (decompressed.size() < LEGACY_LANGUAGE_REGION_SIZE ||
|
||||
decompressed.size() % sizeof(LanguageEntry) != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::memcpy(raw.language_entries.data(), decompressed.data(), LEGACY_LANGUAGE_REGION_SIZE);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
std::string LanguageEntry::GetApplicationName() const {
|
||||
return Common::StringFromFixedZeroTerminatedBuffer(application_name.data(),
|
||||
application_name.size());
|
||||
return Common::StringFromFixedZeroTerminatedBuffer(application_name.data(), application_name.size());
|
||||
}
|
||||
|
||||
std::string LanguageEntry::GetDeveloperName() const {
|
||||
return Common::StringFromFixedZeroTerminatedBuffer(developer_name.data(),
|
||||
developer_name.size());
|
||||
return Common::StringFromFixedZeroTerminatedBuffer(developer_name.data(), developer_name.size());
|
||||
}
|
||||
|
||||
constexpr std::array<Language, 18> language_to_codes = {{
|
||||
Language::Japanese,
|
||||
Language::AmericanEnglish,
|
||||
Language::French,
|
||||
Language::German,
|
||||
Language::Italian,
|
||||
Language::Spanish,
|
||||
Language::SimplifiedChinese,
|
||||
Language::Korean,
|
||||
Language::Dutch,
|
||||
Language::Portuguese,
|
||||
Language::Russian,
|
||||
Language::TraditionalChinese,
|
||||
Language::BritishEnglish,
|
||||
Language::CanadianFrench,
|
||||
Language::LatinAmericanSpanish,
|
||||
Language::SimplifiedChinese,
|
||||
Language::TraditionalChinese,
|
||||
Language::BrazilianPortuguese,
|
||||
}};
|
||||
|
||||
NACP::NACP() = default;
|
||||
|
||||
NACP::NACP(VirtualFile file) {
|
||||
NACP::NACP(VirtualFile file)
|
||||
{
|
||||
file->ReadObject(&raw);
|
||||
DecodePackedLanguageEntries(raw);
|
||||
if (raw.titles_data_format == TitleDataFormat::Compressed) {
|
||||
const u16 compressed_size = raw.language_entries.compressed_data.buffer_size;
|
||||
std::span<const u8> compressed_payload{raw.language_entries.compressed_data.buffer,
|
||||
compressed_size};
|
||||
|
||||
std::vector<u8> decompressed;
|
||||
if (InflateRawDeflate(compressed_payload, decompressed)) {
|
||||
const size_t entry_count = decompressed.size() / sizeof(LanguageEntry);
|
||||
language_entries.resize(entry_count);
|
||||
std::memcpy(language_entries.data(), decompressed.data(), decompressed.size());
|
||||
}
|
||||
} else {
|
||||
language_entries.resize(16);
|
||||
std::memcpy(language_entries.data(), raw.language_entries.language_entries.data(),
|
||||
sizeof(raw.language_entries.language_entries));
|
||||
}
|
||||
}
|
||||
|
||||
NACP::~NACP() = default;
|
||||
|
||||
const LanguageEntry& NACP::GetLanguageEntry() const {
|
||||
Language language =
|
||||
language_to_codes[static_cast<s32>(Settings::values.language_index.GetValue())];
|
||||
u32 index = static_cast<u32>(Settings::values.language_index.GetValue());
|
||||
|
||||
{
|
||||
const auto& language_entry = raw.language_entries.at(static_cast<u8>(language));
|
||||
if (!language_entry.GetApplicationName().empty())
|
||||
return language_entry;
|
||||
if (index < language_entries.size()) {
|
||||
return language_entries[index];
|
||||
}
|
||||
|
||||
for (const auto& language_entry : raw.language_entries) {
|
||||
if (!language_entry.GetApplicationName().empty())
|
||||
return language_entry;
|
||||
for (const auto& entry : language_entries) {
|
||||
return entry;
|
||||
}
|
||||
|
||||
return raw.language_entries.at(static_cast<u8>(Language::AmericanEnglish));
|
||||
return language_entries.at(static_cast<u8>(Language::AmericanEnglish));
|
||||
}
|
||||
|
||||
std::array<std::string, 16> NACP::GetApplicationNames() const {
|
||||
std::array<std::string, 16> names{};
|
||||
for (size_t i = 0; i < raw.language_entries.size(); ++i) {
|
||||
names[i] = raw.language_entries[i].GetApplicationName();
|
||||
std::vector<std::string> NACP::GetApplicationNames() const {
|
||||
std::vector<std::string> names;
|
||||
names.reserve(language_entries.size());
|
||||
for (const auto& entry : language_entries) {
|
||||
names.push_back(entry.GetApplicationName());
|
||||
}
|
||||
return names;
|
||||
}
|
||||
|
|
@ -205,7 +164,7 @@ bool NACP::GetUserAccountSwitchLock() const {
|
|||
}
|
||||
|
||||
u32 NACP::GetSupportedLanguages() const {
|
||||
return raw.supported_languages;
|
||||
return u32(raw.supported_languages);
|
||||
}
|
||||
|
||||
u64 NACP::GetDeviceSaveDataSize() const {
|
||||
|
|
|
|||
|
|
@ -25,22 +25,176 @@ struct LanguageEntry {
|
|||
std::string GetApplicationName() const;
|
||||
std::string GetDeveloperName() const;
|
||||
};
|
||||
static_assert(sizeof(LanguageEntry) == 0x300, "LanguageEntry has incorrect size.");
|
||||
static_assert(sizeof(LanguageEntry) == 0x300);
|
||||
|
||||
struct LanguageEntryData {
|
||||
union {
|
||||
// TitleDataFormat::Uncompressed (16 entries)
|
||||
std::array<LanguageEntry, 16> language_entries;
|
||||
|
||||
// TitleDataFormat::Compressed (18+ entries)
|
||||
struct {
|
||||
u16 buffer_size;
|
||||
u8 buffer[0x2FFE];
|
||||
} compressed_data;
|
||||
};
|
||||
};
|
||||
|
||||
enum class TitleDataFormat : u8 {
|
||||
Uncompressed = 0,
|
||||
Compressed = 1,
|
||||
};
|
||||
|
||||
struct ApplicationNeighborDetectionGroupConfiguration {
|
||||
u64 group_id; ///< GroupId
|
||||
std::array<u8, 0x10> key;
|
||||
};
|
||||
static_assert(sizeof(ApplicationNeighborDetectionGroupConfiguration) == 0x18);
|
||||
|
||||
// NeighborDetectionClientConfiguration
|
||||
struct NeighborDetectionClientConfiguration {
|
||||
ApplicationNeighborDetectionGroupConfiguration send_group_configuration; ///< SendGroupConfiguration
|
||||
std::array<ApplicationNeighborDetectionGroupConfiguration, 0x10> receivable_group_configurations; ///< ReceivableGroupConfigurations
|
||||
};
|
||||
static_assert(sizeof(NeighborDetectionClientConfiguration) == 0x198);
|
||||
|
||||
enum class ApparentPlatform : u8 {
|
||||
NX = 0,
|
||||
Ounce = 1,
|
||||
Count = 2
|
||||
};
|
||||
|
||||
enum class JitConfigurationFlag : u64 {
|
||||
None = 0,
|
||||
IsEnabled = 1,
|
||||
};
|
||||
|
||||
struct JitConfiguration {
|
||||
JitConfigurationFlag jit_configuration_flag;
|
||||
u64 memory_size;
|
||||
};
|
||||
static_assert(sizeof(JitConfiguration) == 0x10);
|
||||
|
||||
enum RequiredAddOnContentsSetDescriptorFlag : u16 {
|
||||
None = 0,
|
||||
Continue = 1
|
||||
};
|
||||
struct RequiredAddOnContentsSetDescriptor {
|
||||
u16 index : 15;
|
||||
RequiredAddOnContentsSetDescriptorFlag flag : 1;
|
||||
};
|
||||
static_assert(sizeof(RequiredAddOnContentsSetDescriptor) == 0x2);
|
||||
|
||||
struct RequiredAddOnContentsSetBinaryDescriptor {
|
||||
RequiredAddOnContentsSetDescriptor descriptors[0x20];
|
||||
};
|
||||
static_assert(sizeof(RequiredAddOnContentsSetBinaryDescriptor) == 0x40);
|
||||
|
||||
enum class PlayReportPermission : u8 {
|
||||
None = 0,
|
||||
TargetMarketing = 1,
|
||||
};
|
||||
|
||||
enum class CrashScreenshotForProd : u8 {
|
||||
Deny = 0,
|
||||
Allow = 1,
|
||||
};
|
||||
|
||||
enum class CrashScreenshotForDev : u8 {
|
||||
Deny = 0,
|
||||
Allow = 1,
|
||||
};
|
||||
|
||||
enum class ContentsAvailabilityTransitionPolicy : u8 {
|
||||
NoPolicy = 0,
|
||||
Stable = 1,
|
||||
Changeable = 2,
|
||||
};
|
||||
|
||||
struct AccessibleLaunchRequiredVersion {
|
||||
std::array<u64, 8> application_id;
|
||||
};
|
||||
static_assert(sizeof(AccessibleLaunchRequiredVersion) == 0x40);
|
||||
|
||||
enum class CrashReport : u8 {
|
||||
Deny = 0,
|
||||
Allow = 1,
|
||||
};
|
||||
|
||||
enum class PlayLogQueryCapability : u8 {
|
||||
None = 0,
|
||||
WhiteList = 1,
|
||||
All = 2,
|
||||
};
|
||||
|
||||
struct ApplicationControlDataConditionData {
|
||||
u8 priority;
|
||||
INSERT_PADDING_BYTES(7);
|
||||
u16 aoc_index;
|
||||
INSERT_PADDING_BYTES(6);
|
||||
};
|
||||
static_assert(sizeof(ApplicationControlDataConditionData) == 0x10);
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct ApplicationControlDataCondition {
|
||||
u64 type;
|
||||
std::array<ApplicationControlDataConditionData, 0x8> data;
|
||||
u8 count;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
static_assert(sizeof(ApplicationControlDataCondition) == 0x89);
|
||||
|
||||
// A language on the NX. These are for names and icons.
|
||||
#define NACP_LANGUAGE_LIST \
|
||||
NACP_LANGUAGE_ELEM(AmericanEnglish, 0) \
|
||||
NACP_LANGUAGE_ELEM(BritishEnglish, 1) \
|
||||
NACP_LANGUAGE_ELEM(Japanese, 2) \
|
||||
NACP_LANGUAGE_ELEM(French, 3) \
|
||||
NACP_LANGUAGE_ELEM(German, 4) \
|
||||
NACP_LANGUAGE_ELEM(LatinAmericanSpanish, 5) \
|
||||
NACP_LANGUAGE_ELEM(Spanish, 6) \
|
||||
NACP_LANGUAGE_ELEM(Italian, 7) \
|
||||
NACP_LANGUAGE_ELEM(Dutch, 8) \
|
||||
NACP_LANGUAGE_ELEM(CanadianFrench, 9) \
|
||||
NACP_LANGUAGE_ELEM(Portuguese, 10) \
|
||||
NACP_LANGUAGE_ELEM(Russian, 11) \
|
||||
NACP_LANGUAGE_ELEM(Korean, 12) \
|
||||
NACP_LANGUAGE_ELEM(TraditionalChinese, 13) \
|
||||
NACP_LANGUAGE_ELEM(SimplifiedChinese, 14) \
|
||||
NACP_LANGUAGE_ELEM(BrazilianPortuguese, 15) \
|
||||
NACP_LANGUAGE_ELEM(Polish, 16) \
|
||||
NACP_LANGUAGE_ELEM(Thai, 17) \
|
||||
|
||||
enum class Language : u8 {
|
||||
#define NACP_LANGUAGE_ELEM(X, N) X = N,
|
||||
NACP_LANGUAGE_LIST
|
||||
#undef NACP_LANGUAGE_ELEM
|
||||
Count = 18,
|
||||
Default = 255,
|
||||
};
|
||||
|
||||
// Yes it's duplicated, why? Bits i guess
|
||||
enum class SupportedLanguage : u32 {
|
||||
#define NACP_LANGUAGE_ELEM(X, N) X = 1ULL << N,
|
||||
NACP_LANGUAGE_LIST
|
||||
#undef NACP_LANGUAGE_ELEM
|
||||
};
|
||||
#undef NACP_LANGUAGE_LIST
|
||||
|
||||
// The raw file format of a NACP file.
|
||||
struct RawNACP {
|
||||
std::array<LanguageEntry, 16> language_entries;
|
||||
LanguageEntryData language_entries;
|
||||
std::array<u8, 0x25> isbn;
|
||||
u8 startup_user_account;
|
||||
u8 user_account_switch_lock;
|
||||
u8 addon_content_registration_type;
|
||||
u32_le application_attribute;
|
||||
u32_le supported_languages;
|
||||
SupportedLanguage supported_languages;
|
||||
u32_le parental_control;
|
||||
bool screenshot_enabled;
|
||||
u8 video_capture_mode;
|
||||
bool data_loss_confirmation;
|
||||
INSERT_PADDING_BYTES(1);
|
||||
u8 play_log_policy;
|
||||
u64_le presence_group_id;
|
||||
std::array<u8, 0x20> rating_age;
|
||||
std::array<char, 0x10> version_string;
|
||||
|
|
@ -56,10 +210,14 @@ struct RawNACP {
|
|||
u8 logo_type;
|
||||
u8 logo_handling;
|
||||
bool runtime_add_on_content_install;
|
||||
INSERT_PADDING_BYTES(5);
|
||||
u8 runtime_parameter_delivery;
|
||||
u8 appropriate_age_for_china;
|
||||
INSERT_PADDING_BYTES(1);
|
||||
CrashReport crash_report;
|
||||
u64_le seed_for_pseudo_device_id;
|
||||
std::array<u8, 0x41> bcat_passphrase;
|
||||
INSERT_PADDING_BYTES(7);
|
||||
u8 startup_user_account_option;
|
||||
INSERT_PADDING_BYTES(6); // ReservedForUserAccountSaveDataOperation
|
||||
u64_le user_account_save_data_max_size;
|
||||
u64_le user_account_save_data_max_journal_size;
|
||||
u64_le device_save_data_max_size;
|
||||
|
|
@ -69,13 +227,28 @@ struct RawNACP {
|
|||
u64_le cache_storage_journal_size;
|
||||
u64_le cache_storage_data_and_journal_max_size;
|
||||
u16_le cache_storage_max_index;
|
||||
INSERT_PADDING_BYTES(0x8B);
|
||||
u8 runtime_upgrade;
|
||||
u32_le supporting_limited_application_licenses;
|
||||
std::array<u8, 0x8*16> play_log_queryable_application_id;
|
||||
PlayLogQueryCapability play_log_query_capability;
|
||||
u8 repair_flag;
|
||||
u8 program_index;
|
||||
u8 required_network_service_license_on_launch_flag;
|
||||
u8 app_error_code_prefix;
|
||||
INSERT_PADDING_BYTES(1);
|
||||
TitleDataFormat titles_data_format;
|
||||
u8 acd_index;
|
||||
u8 apparent_platform;
|
||||
INSERT_PADDING_BYTES(0x22F);
|
||||
std::array<u8, 0x89> app_control_data_condition;
|
||||
ApparentPlatform apparent_platform;
|
||||
// NeighborDetectionClientConfiguration neighbor_detection_client_configuration;
|
||||
// JitConfiguration jit_configuration;
|
||||
// RequiredAddOnContentsSetBinaryDescriptor required_add_on_contents_set_binary_descriptor;
|
||||
// PlayReportPermission play_report_permission;
|
||||
// CrashScreenshotForProd crash_screenshot_for_prod;
|
||||
// CrashScreenshotForDev crash_screenshot_for_dev;
|
||||
// ContentsAvailabilityTransitionPolicy contents_availability_transition_policy;
|
||||
// SupportedLanguage supported_language_copy; ///< TODO: add to XML generation.
|
||||
INSERT_PADDING_BYTES(0x1EF);
|
||||
AccessibleLaunchRequiredVersion accessible_launch_required_version;
|
||||
ApplicationControlDataCondition application_control_data_condition; ///< Used for Switch 2 upgrade packs, which are distributed as AddOnContent titles
|
||||
u8 initial_program_index;
|
||||
INSERT_PADDING_BYTES(2);
|
||||
u32_le accessible_program_index_flags;
|
||||
|
|
@ -85,34 +258,13 @@ struct RawNACP {
|
|||
u8 has_ingame_voice_chat;
|
||||
INSERT_PADDING_BYTES(3);
|
||||
u32_le supported_extra_addon_content_flag;
|
||||
INSERT_PADDING_BYTES(0x698);
|
||||
u8 has_karaoke_feature;
|
||||
INSERT_PADDING_BYTES(0x697);
|
||||
std::array<u8, 0x400> platform_specific_region;
|
||||
};
|
||||
static_assert(sizeof(RawNACP) == 0x4000, "RawNACP has incorrect size.");
|
||||
|
||||
// A language on the NX. These are for names and icons.
|
||||
enum class Language : u8 {
|
||||
AmericanEnglish = 0,
|
||||
BritishEnglish = 1,
|
||||
Japanese = 2,
|
||||
French = 3,
|
||||
German = 4,
|
||||
LatinAmericanSpanish = 5,
|
||||
Spanish = 6,
|
||||
Italian = 7,
|
||||
Dutch = 8,
|
||||
CanadianFrench = 9,
|
||||
Portuguese = 10,
|
||||
Russian = 11,
|
||||
Korean = 12,
|
||||
TraditionalChinese = 13,
|
||||
SimplifiedChinese = 14,
|
||||
BrazilianPortuguese = 15,
|
||||
|
||||
Default = 255,
|
||||
};
|
||||
|
||||
extern const std::array<const char*, 16> LANGUAGE_NAMES;
|
||||
extern const std::array<const char*, size_t(Language::Count)> LANGUAGE_NAMES;
|
||||
|
||||
// A class representing the format used by NX metadata files, typically named Control.nacp.
|
||||
// These store application name, dev name, title id, and other miscellaneous data.
|
||||
|
|
@ -131,7 +283,7 @@ public:
|
|||
u64 GetDefaultNormalSaveSize() const;
|
||||
u64 GetDefaultJournalSaveSize() const;
|
||||
u32 GetSupportedLanguages() const;
|
||||
std::array<std::string, 16> GetApplicationNames() const;
|
||||
std::vector<std::string> GetApplicationNames() const;
|
||||
std::vector<u8> GetRawBytes() const;
|
||||
bool GetUserAccountSwitchLock() const;
|
||||
u64 GetDeviceSaveDataSize() const;
|
||||
|
|
@ -140,6 +292,7 @@ public:
|
|||
|
||||
private:
|
||||
RawNACP raw{};
|
||||
std::vector<LanguageEntry> language_entries;
|
||||
};
|
||||
|
||||
} // namespace FileSys
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
|
|
@ -22,6 +25,8 @@ constexpr ApplicationLanguagePriorityList priority_list_american_english = {{
|
|||
ApplicationLanguage::SimplifiedChinese,
|
||||
ApplicationLanguage::TraditionalChinese,
|
||||
ApplicationLanguage::Korean,
|
||||
ApplicationLanguage::Polish,
|
||||
ApplicationLanguage::Thai,
|
||||
}};
|
||||
|
||||
constexpr ApplicationLanguagePriorityList priority_list_british_english = {{
|
||||
|
|
@ -40,6 +45,8 @@ constexpr ApplicationLanguagePriorityList priority_list_british_english = {{
|
|||
ApplicationLanguage::SimplifiedChinese,
|
||||
ApplicationLanguage::TraditionalChinese,
|
||||
ApplicationLanguage::Korean,
|
||||
ApplicationLanguage::Polish,
|
||||
ApplicationLanguage::Thai,
|
||||
}};
|
||||
|
||||
constexpr ApplicationLanguagePriorityList priority_list_japanese = {{
|
||||
|
|
@ -58,6 +65,8 @@ constexpr ApplicationLanguagePriorityList priority_list_japanese = {{
|
|||
ApplicationLanguage::SimplifiedChinese,
|
||||
ApplicationLanguage::TraditionalChinese,
|
||||
ApplicationLanguage::Korean,
|
||||
ApplicationLanguage::Polish,
|
||||
ApplicationLanguage::Thai,
|
||||
}};
|
||||
|
||||
constexpr ApplicationLanguagePriorityList priority_list_french = {{
|
||||
|
|
@ -76,6 +85,8 @@ constexpr ApplicationLanguagePriorityList priority_list_french = {{
|
|||
ApplicationLanguage::SimplifiedChinese,
|
||||
ApplicationLanguage::TraditionalChinese,
|
||||
ApplicationLanguage::Korean,
|
||||
ApplicationLanguage::Polish,
|
||||
ApplicationLanguage::Thai,
|
||||
}};
|
||||
|
||||
constexpr ApplicationLanguagePriorityList priority_list_german = {{
|
||||
|
|
@ -94,6 +105,8 @@ constexpr ApplicationLanguagePriorityList priority_list_german = {{
|
|||
ApplicationLanguage::SimplifiedChinese,
|
||||
ApplicationLanguage::TraditionalChinese,
|
||||
ApplicationLanguage::Korean,
|
||||
ApplicationLanguage::Polish,
|
||||
ApplicationLanguage::Thai,
|
||||
}};
|
||||
|
||||
constexpr ApplicationLanguagePriorityList priority_list_latin_american_spanish = {{
|
||||
|
|
@ -112,6 +125,8 @@ constexpr ApplicationLanguagePriorityList priority_list_latin_american_spanish =
|
|||
ApplicationLanguage::SimplifiedChinese,
|
||||
ApplicationLanguage::TraditionalChinese,
|
||||
ApplicationLanguage::Korean,
|
||||
ApplicationLanguage::Polish,
|
||||
ApplicationLanguage::Thai,
|
||||
}};
|
||||
|
||||
constexpr ApplicationLanguagePriorityList priority_list_spanish = {{
|
||||
|
|
@ -130,6 +145,8 @@ constexpr ApplicationLanguagePriorityList priority_list_spanish = {{
|
|||
ApplicationLanguage::SimplifiedChinese,
|
||||
ApplicationLanguage::TraditionalChinese,
|
||||
ApplicationLanguage::Korean,
|
||||
ApplicationLanguage::Polish,
|
||||
ApplicationLanguage::Thai,
|
||||
}};
|
||||
|
||||
constexpr ApplicationLanguagePriorityList priority_list_italian = {{
|
||||
|
|
@ -148,6 +165,8 @@ constexpr ApplicationLanguagePriorityList priority_list_italian = {{
|
|||
ApplicationLanguage::SimplifiedChinese,
|
||||
ApplicationLanguage::TraditionalChinese,
|
||||
ApplicationLanguage::Korean,
|
||||
ApplicationLanguage::Polish,
|
||||
ApplicationLanguage::Thai,
|
||||
}};
|
||||
|
||||
constexpr ApplicationLanguagePriorityList priority_list_dutch = {{
|
||||
|
|
@ -166,6 +185,8 @@ constexpr ApplicationLanguagePriorityList priority_list_dutch = {{
|
|||
ApplicationLanguage::SimplifiedChinese,
|
||||
ApplicationLanguage::TraditionalChinese,
|
||||
ApplicationLanguage::Korean,
|
||||
ApplicationLanguage::Polish,
|
||||
ApplicationLanguage::Thai,
|
||||
}};
|
||||
|
||||
constexpr ApplicationLanguagePriorityList priority_list_canadian_french = {{
|
||||
|
|
@ -184,6 +205,8 @@ constexpr ApplicationLanguagePriorityList priority_list_canadian_french = {{
|
|||
ApplicationLanguage::SimplifiedChinese,
|
||||
ApplicationLanguage::TraditionalChinese,
|
||||
ApplicationLanguage::Korean,
|
||||
ApplicationLanguage::Polish,
|
||||
ApplicationLanguage::Thai,
|
||||
}};
|
||||
|
||||
constexpr ApplicationLanguagePriorityList priority_list_portuguese = {{
|
||||
|
|
@ -202,6 +225,8 @@ constexpr ApplicationLanguagePriorityList priority_list_portuguese = {{
|
|||
ApplicationLanguage::SimplifiedChinese,
|
||||
ApplicationLanguage::TraditionalChinese,
|
||||
ApplicationLanguage::Korean,
|
||||
ApplicationLanguage::Polish,
|
||||
ApplicationLanguage::Thai,
|
||||
}};
|
||||
|
||||
constexpr ApplicationLanguagePriorityList priority_list_russian = {{
|
||||
|
|
@ -220,6 +245,8 @@ constexpr ApplicationLanguagePriorityList priority_list_russian = {{
|
|||
ApplicationLanguage::SimplifiedChinese,
|
||||
ApplicationLanguage::TraditionalChinese,
|
||||
ApplicationLanguage::Korean,
|
||||
ApplicationLanguage::Polish,
|
||||
ApplicationLanguage::Thai,
|
||||
}};
|
||||
|
||||
constexpr ApplicationLanguagePriorityList priority_list_korean = {{
|
||||
|
|
@ -238,6 +265,8 @@ constexpr ApplicationLanguagePriorityList priority_list_korean = {{
|
|||
ApplicationLanguage::Japanese,
|
||||
ApplicationLanguage::SimplifiedChinese,
|
||||
ApplicationLanguage::TraditionalChinese,
|
||||
ApplicationLanguage::Polish,
|
||||
ApplicationLanguage::Thai,
|
||||
}};
|
||||
|
||||
constexpr ApplicationLanguagePriorityList priority_list_traditional_chinese = {{
|
||||
|
|
@ -256,6 +285,8 @@ constexpr ApplicationLanguagePriorityList priority_list_traditional_chinese = {{
|
|||
ApplicationLanguage::Portuguese,
|
||||
ApplicationLanguage::Russian,
|
||||
ApplicationLanguage::Korean,
|
||||
ApplicationLanguage::Polish,
|
||||
ApplicationLanguage::Thai,
|
||||
}};
|
||||
|
||||
constexpr ApplicationLanguagePriorityList priority_list_simplified_chinese = {{
|
||||
|
|
@ -274,6 +305,8 @@ constexpr ApplicationLanguagePriorityList priority_list_simplified_chinese = {{
|
|||
ApplicationLanguage::Portuguese,
|
||||
ApplicationLanguage::Russian,
|
||||
ApplicationLanguage::Korean,
|
||||
ApplicationLanguage::Polish,
|
||||
ApplicationLanguage::Thai,
|
||||
}};
|
||||
|
||||
constexpr ApplicationLanguagePriorityList priority_list_brazilian_portuguese = {{
|
||||
|
|
@ -293,6 +326,43 @@ constexpr ApplicationLanguagePriorityList priority_list_brazilian_portuguese = {
|
|||
ApplicationLanguage::Korean,
|
||||
ApplicationLanguage::SimplifiedChinese,
|
||||
ApplicationLanguage::TraditionalChinese,
|
||||
ApplicationLanguage::Polish,
|
||||
ApplicationLanguage::Thai,
|
||||
}};
|
||||
|
||||
constexpr ApplicationLanguagePriorityList priority_list_thai = {{
|
||||
ApplicationLanguage::Thai,
|
||||
ApplicationLanguage::AmericanEnglish,
|
||||
ApplicationLanguage::BritishEnglish,
|
||||
ApplicationLanguage::Japanese,
|
||||
ApplicationLanguage::French,
|
||||
ApplicationLanguage::German,
|
||||
ApplicationLanguage::Spanish,
|
||||
ApplicationLanguage::Italian,
|
||||
ApplicationLanguage::Dutch,
|
||||
ApplicationLanguage::CanadianFrench,
|
||||
ApplicationLanguage::Russian,
|
||||
ApplicationLanguage::Korean,
|
||||
ApplicationLanguage::SimplifiedChinese,
|
||||
ApplicationLanguage::TraditionalChinese,
|
||||
ApplicationLanguage::Polish,
|
||||
}};
|
||||
|
||||
constexpr ApplicationLanguagePriorityList priority_list_polish = {{
|
||||
ApplicationLanguage::Polish,
|
||||
ApplicationLanguage::AmericanEnglish,
|
||||
ApplicationLanguage::BritishEnglish,
|
||||
ApplicationLanguage::Japanese,
|
||||
ApplicationLanguage::French,
|
||||
ApplicationLanguage::German,
|
||||
ApplicationLanguage::Spanish,
|
||||
ApplicationLanguage::Italian,
|
||||
ApplicationLanguage::Dutch,
|
||||
ApplicationLanguage::CanadianFrench,
|
||||
ApplicationLanguage::Russian,
|
||||
ApplicationLanguage::Korean,
|
||||
ApplicationLanguage::SimplifiedChinese,
|
||||
ApplicationLanguage::TraditionalChinese,
|
||||
}};
|
||||
|
||||
const ApplicationLanguagePriorityList* GetApplicationLanguagePriorityList(
|
||||
|
|
@ -330,6 +400,10 @@ const ApplicationLanguagePriorityList* GetApplicationLanguagePriorityList(
|
|||
return &priority_list_simplified_chinese;
|
||||
case ApplicationLanguage::BrazilianPortuguese:
|
||||
return &priority_list_brazilian_portuguese;
|
||||
case ApplicationLanguage::Polish:
|
||||
return &priority_list_polish;
|
||||
case ApplicationLanguage::Thai:
|
||||
return &priority_list_thai;
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
|
|
@ -372,6 +446,10 @@ std::optional<ApplicationLanguage> ConvertToApplicationLanguage(
|
|||
return ApplicationLanguage::SimplifiedChinese;
|
||||
case Set::LanguageCode::PT_BR:
|
||||
return ApplicationLanguage::BrazilianPortuguese;
|
||||
case Set::LanguageCode::TH:
|
||||
return ApplicationLanguage::Thai;
|
||||
case Set::LanguageCode::PL:
|
||||
return ApplicationLanguage::Polish;
|
||||
default:
|
||||
return std::nullopt;
|
||||
}
|
||||
|
|
@ -411,6 +489,10 @@ std::optional<Set::LanguageCode> ConvertToLanguageCode(const ApplicationLanguage
|
|||
return Set::LanguageCode::ZH_HANS;
|
||||
case ApplicationLanguage::BrazilianPortuguese:
|
||||
return Set::LanguageCode::PT_BR;
|
||||
case ApplicationLanguage::Thai:
|
||||
return Set::LanguageCode::TH;
|
||||
case ApplicationLanguage::Polish:
|
||||
return Set::LanguageCode::PL;
|
||||
default:
|
||||
return std::nullopt;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
|
|
@ -26,6 +29,8 @@ enum class ApplicationLanguage : u8 {
|
|||
TraditionalChinese,
|
||||
SimplifiedChinese,
|
||||
BrazilianPortuguese,
|
||||
Polish,
|
||||
Thai,
|
||||
Count
|
||||
};
|
||||
using ApplicationLanguagePriorityList =
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
|
|
@ -169,6 +172,8 @@ enum class Language : u32 {
|
|||
SimplifiedCHhinese,
|
||||
TraditionalChinese,
|
||||
BrazilianPortuguese,
|
||||
Polish,
|
||||
Thai
|
||||
};
|
||||
|
||||
/// This is "nn::settings::LanguageCode", which is a NUL-terminated string stored in a u64.
|
||||
|
|
@ -191,6 +196,8 @@ enum class LanguageCode : u64 {
|
|||
ZH_HANS = 0x00736E61482D687A,
|
||||
ZH_HANT = 0x00746E61482D687A,
|
||||
PT_BR = 0x00000052422D7470,
|
||||
PL = 0x000000000000706C,
|
||||
TH = 0x0000000000006874,
|
||||
};
|
||||
|
||||
/// This is nn::settings::system::NotificationVolume
|
||||
|
|
@ -248,7 +255,7 @@ enum class PlatformRegion : s32 {
|
|||
Terra = 2,
|
||||
};
|
||||
|
||||
constexpr std::array<LanguageCode, 18> available_language_codes = {{
|
||||
constexpr std::array<LanguageCode, 20> available_language_codes = {{
|
||||
LanguageCode::JA,
|
||||
LanguageCode::EN_US,
|
||||
LanguageCode::FR,
|
||||
|
|
@ -267,9 +274,11 @@ constexpr std::array<LanguageCode, 18> available_language_codes = {{
|
|||
LanguageCode::ZH_HANS,
|
||||
LanguageCode::ZH_HANT,
|
||||
LanguageCode::PT_BR,
|
||||
LanguageCode::PL,
|
||||
LanguageCode::TH
|
||||
}};
|
||||
|
||||
static constexpr std::array<std::pair<LanguageCode, KeyboardLayout>, 18> language_to_layout{{
|
||||
static constexpr std::array<std::pair<LanguageCode, KeyboardLayout>, 20> language_to_layout{{
|
||||
{LanguageCode::JA, KeyboardLayout::Japanese},
|
||||
{LanguageCode::EN_US, KeyboardLayout::EnglishUs},
|
||||
{LanguageCode::FR, KeyboardLayout::French},
|
||||
|
|
@ -288,6 +297,8 @@ static constexpr std::array<std::pair<LanguageCode, KeyboardLayout>, 18> languag
|
|||
{LanguageCode::ZH_HANS, KeyboardLayout::ChineseSimplified},
|
||||
{LanguageCode::ZH_HANT, KeyboardLayout::ChineseTraditional},
|
||||
{LanguageCode::PT_BR, KeyboardLayout::Portuguese},
|
||||
{LanguageCode::PL, KeyboardLayout::EnglishUsInternational},
|
||||
{LanguageCode::TH, KeyboardLayout::EnglishUsInternational}
|
||||
}};
|
||||
|
||||
/// This is nn::settings::system::AccountNotificationFlag
|
||||
|
|
|
|||
|
|
@ -651,7 +651,8 @@ std::unique_ptr<ComboboxTranslationMap> ComboboxEnumeration(QObject* parent)
|
|||
PAIR(Language, ChineseSimplified, tr("Simplified Chinese")),
|
||||
PAIR(Language, ChineseTraditional, tr("Traditional Chinese (正體中文)")),
|
||||
PAIR(Language, PortugueseBrazilian, tr("Brazilian Portuguese (português do Brasil)")),
|
||||
PAIR(Language, Serbian, tr("Serbian (српски)")),
|
||||
PAIR(Language, Polish, tr("Polish (polska)")),
|
||||
PAIR(Language, Thai, tr("Thai (แบบไทย)")),
|
||||
}});
|
||||
translations->insert({Settings::EnumMetadata<Settings::Region>::Index(),
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue