add polish & thai, remove serbian as system language

This commit is contained in:
maufeat 2026-02-22 12:20:47 +01:00
parent 4014b45cb6
commit 57d81596f5
9 changed files with 168 additions and 83 deletions

View file

@ -64,7 +64,8 @@
<item>@string/language_spanish</item> <item>@string/language_spanish</item>
<item>@string/language_taiwanese</item> <item>@string/language_taiwanese</item>
<item>@string/language_traditional_chinese</item> <item>@string/language_traditional_chinese</item>
<item>@string/language_serbian</item> <item>@string/language_polish</item>
<item>@string/language_thai</item>
</string-array> </string-array>
<integer-array name="languageValues"> <integer-array name="languageValues">
@ -87,6 +88,7 @@
<item>11</item> <item>11</item>
<item>16</item> <item>16</item>
<item>18</item> <item>18</item>
<item>19</item>
</integer-array> </integer-array>
<string-array name="rendererApiNames"> <string-array name="rendererApiNames">
@ -407,6 +409,7 @@
<item>@string/app_language_persian</item> <item>@string/app_language_persian</item>
<item>@string/app_language_hebrew</item> <item>@string/app_language_hebrew</item>
<item>@string/app_language_serbian</item> <item>@string/app_language_serbian</item>
<item>@string/app_language_thai</item>
</string-array> </string-array>
<integer-array name="appLanguageValues"> <integer-array name="appLanguageValues">
<item>0</item> <item>0</item>

View file

@ -1009,7 +1009,8 @@
<string name="language_simplified_chinese" translatable="false">简体中文</string> <string name="language_simplified_chinese" translatable="false">简体中文</string>
<string name="language_traditional_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_brazilian_portuguese" translatable="false">Português do Brasil</string>
<string name="language_serbian" translatable="false">српски</string> <string name="language_polish" translatable="false">Polski</string>
<string name="language_thai" translatable="false">ไทย</string>
<!-- Memory Sizes --> <!-- Memory Sizes -->
<string name="memory_byte_shorthand">B</string> <string name="memory_byte_shorthand">B</string>
@ -1214,6 +1215,7 @@
<string name="app_language_persian" translatable="false">فارسی</string> <string name="app_language_persian" translatable="false">فارسی</string>
<string name="app_language_hebrew" translatable="false">עברית</string> <string name="app_language_hebrew" translatable="false">עברית</string>
<string name="app_language_serbian" translatable="false">Српски</string> <string name="app_language_serbian" translatable="false">Српски</string>
<string name="app_language_thai" translatable="false">ไทย</string>
<!-- Static Themes --> <!-- Static Themes -->
<string name="static_theme_color">Theme Color</string> <string name="static_theme_color">Theme Color</string>

View file

@ -120,7 +120,7 @@ ENUM(AudioMode, Mono, Stereo, Surround);
ENUM(Language, Japanese, EnglishAmerican, French, German, Italian, Spanish, Chinese, Korean, Dutch, ENUM(Language, Japanese, EnglishAmerican, French, German, Italian, Spanish, Chinese, Korean, Dutch,
Portuguese, Russian, Taiwanese, EnglishBritish, FrenchCanadian, SpanishLatin, 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(Region, Japan, Usa, Europe, Australia, China, Korea, Taiwan);
ENUM(TimeZone, Auto, Default, Cet, Cst6Cdt, Cuba, Eet, Egypt, Eire, Est, Est5Edt, Gb, GbEire, Gmt, 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, GmtPlusZero, GmtMinusZero, GmtZero, Greenwich, Hongkong, Hst, Iceland, Iran, Israel, Jamaica,

View file

@ -15,11 +15,13 @@
#include "common/string_util.h" #include "common/string_util.h"
#include "common/swap.h" #include "common/swap.h"
#include "core/file_sys/control_metadata.h" #include "core/file_sys/control_metadata.h"
#include "common/logging/log.h"
#include "core/file_sys/vfs/vfs.h" #include "core/file_sys/vfs/vfs.h"
namespace FileSys { namespace FileSys {
const std::array<const char*, 16> LANGUAGE_NAMES{{ const std::array<const char*, 18> LANGUAGE_NAMES{{
"AmericanEnglish", "AmericanEnglish",
"BritishEnglish", "BritishEnglish",
"Japanese", "Japanese",
@ -36,16 +38,16 @@ const std::array<const char*, 16> LANGUAGE_NAMES{{
"TraditionalChinese", "TraditionalChinese",
"SimplifiedChinese", "SimplifiedChinese",
"BrazilianPortuguese", "BrazilianPortuguese",
"Polish",
"Thai"
}}; }};
namespace { namespace {
constexpr std::size_t LEGACY_LANGUAGE_REGION_SIZE = sizeof(std::array<LanguageEntry, 16>); constexpr std::size_t MAX_EXPANDED_LANG_SIZE = sizeof(LanguageEntry) * 32;
constexpr std::size_t PACKED_LANGUAGE_REGION_MAX_SIZE = sizeof(LanguageEntry) * 32;
bool InflateRawDeflate(std::span<const u8> compressed, std::vector<u8>& out) { bool InflateRawDeflate(std::span<const u8> compressed, std::vector<u8>& out)
if (compressed.empty() || compressed.size() > std::numeric_limits<uInt>::max()) { {
return false; if (compressed.empty()) return false;
}
z_stream stream{}; z_stream stream{};
stream.next_in = const_cast<Bytef*>(reinterpret_cast<const Bytef*>(compressed.data())); stream.next_in = const_cast<Bytef*>(reinterpret_cast<const Bytef*>(compressed.data()));
@ -54,54 +56,20 @@ bool InflateRawDeflate(std::span<const u8> compressed, std::vector<u8>& out) {
return false; return false;
} }
std::array<u8, 0x1000> chunk{}; out.resize(MAX_EXPANDED_LANG_SIZE);
int ret = Z_OK; stream.next_out = reinterpret_cast<Bytef*>(out.data());
while (ret == Z_OK) { stream.avail_out = static_cast<uInt>(out.size());
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);
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));
}
}
int ret = inflate(&stream, Z_FINISH);
inflateEnd(&stream); inflateEnd(&stream);
return ret == Z_STREAM_END;
}
void DecodePackedLanguageEntries(RawNACP& raw) { if (ret != Z_STREAM_END && ret != Z_OK) {
auto* packed_region = reinterpret_cast<u8*>(raw.language_entries.data()); return false;
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; // Shrink to actual decompressed size
if (!InflateRawDeflate( out.resize(stream.total_out);
std::span<const u8>(packed_region + sizeof(u16_le), compressed_size), decompressed)) { return true;
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 } // namespace
@ -115,7 +83,7 @@ std::string LanguageEntry::GetDeveloperName() const {
developer_name.size()); developer_name.size());
} }
constexpr std::array<Language, 18> language_to_codes = {{ constexpr std::array<Language, 20> language_to_codes = {{
Language::Japanese, Language::Japanese,
Language::AmericanEnglish, Language::AmericanEnglish,
Language::French, Language::French,
@ -134,39 +102,54 @@ constexpr std::array<Language, 18> language_to_codes = {{
Language::SimplifiedChinese, Language::SimplifiedChinese,
Language::TraditionalChinese, Language::TraditionalChinese,
Language::BrazilianPortuguese, Language::BrazilianPortuguese,
Language::Polish,
Language::Thai
}}; }};
NACP::NACP() = default; NACP::NACP() = default;
NACP::NACP(VirtualFile file) { NACP::NACP(VirtualFile file)
{
file->ReadObject(&raw); 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; NACP::~NACP() = default;
const LanguageEntry& NACP::GetLanguageEntry() const { const LanguageEntry& NACP::GetLanguageEntry() const {
Language language = u32 index = static_cast<u32>(Settings::values.language_index.GetValue());
language_to_codes[static_cast<s32>(Settings::values.language_index.GetValue())];
{ if (index < language_entries.size()) {
const auto& language_entry = raw.language_entries.at(static_cast<u8>(language)); return language_entries[index];
if (!language_entry.GetApplicationName().empty())
return language_entry;
} }
for (const auto& language_entry : raw.language_entries) { for (const auto& entry : language_entries) {
if (!language_entry.GetApplicationName().empty()) return entry;
return language_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::vector<std::string> NACP::GetApplicationNames() const {
std::array<std::string, 16> names{}; std::vector<std::string> names;
for (size_t i = 0; i < raw.language_entries.size(); ++i) { names.reserve(language_entries.size());
names[i] = raw.language_entries[i].GetApplicationName(); for (const auto& entry : language_entries) {
names.push_back(entry.GetApplicationName());
} }
return names; return names;
} }

View file

@ -27,9 +27,29 @@ struct LanguageEntry {
}; };
static_assert(sizeof(LanguageEntry) == 0x300, "LanguageEntry has incorrect size."); static_assert(sizeof(LanguageEntry) == 0x300, "LanguageEntry has incorrect size.");
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 TitleDataFormat : u8 {
Uncompressed = 0,
Compressed = 1,
};
// The raw file format of a NACP file. // The raw file format of a NACP file.
struct RawNACP { struct RawNACP {
std::array<LanguageEntry, 16> language_entries; LanguageEntryData language_entries;
std::array<u8, 0x25> isbn; std::array<u8, 0x25> isbn;
u8 startup_user_account; u8 startup_user_account;
u8 user_account_switch_lock; u8 user_account_switch_lock;
@ -40,7 +60,7 @@ struct RawNACP {
bool screenshot_enabled; bool screenshot_enabled;
u8 video_capture_mode; u8 video_capture_mode;
bool data_loss_confirmation; bool data_loss_confirmation;
INSERT_PADDING_BYTES(1); u8 play_log_policy;
u64_le presence_group_id; u64_le presence_group_id;
std::array<u8, 0x20> rating_age; std::array<u8, 0x20> rating_age;
std::array<char, 0x10> version_string; std::array<char, 0x10> version_string;
@ -55,11 +75,15 @@ struct RawNACP {
std::array<u64_le, 0x8> local_communication; std::array<u64_le, 0x8> local_communication;
u8 logo_type; u8 logo_type;
u8 logo_handling; u8 logo_handling;
bool runtime_add_on_content_install; u8 runtime_add_on_content_install;
INSERT_PADDING_BYTES(5); u8 runtime_parameter_delivery;
u8 appropriate_age_for_china;
INSERT_PADDING_BYTES(1);
u8 crash_report;
u64_le seed_for_pseudo_device_id; u64_le seed_for_pseudo_device_id;
std::array<u8, 0x41> bcat_passphrase; 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_size;
u64_le user_account_save_data_max_journal_size; u64_le user_account_save_data_max_journal_size;
u64_le device_save_data_max_size; u64_le device_save_data_max_size;
@ -69,9 +93,16 @@ struct RawNACP {
u64_le cache_storage_journal_size; u64_le cache_storage_journal_size;
u64_le cache_storage_data_and_journal_max_size; u64_le cache_storage_data_and_journal_max_size;
u16_le cache_storage_max_index; u16_le cache_storage_max_index;
INSERT_PADDING_BYTES(0x8B);
u8 app_error_code_prefix;
INSERT_PADDING_BYTES(1); INSERT_PADDING_BYTES(1);
u8 runtime_upgrade;
u32_le supporting_limited_application_licenses;
std::array<u8, 0x8*16> play_log_queryable_application_id;
u8 play_log_query_capability;
u8 repair_flag;
u8 program_index;
u8 required_network_service_license_on_launch_flag;
u8 app_error_code_prefix;
TitleDataFormat titles_data_format;
u8 acd_index; u8 acd_index;
u8 apparent_platform; u8 apparent_platform;
INSERT_PADDING_BYTES(0x22F); INSERT_PADDING_BYTES(0x22F);
@ -85,7 +116,8 @@ struct RawNACP {
u8 has_ingame_voice_chat; u8 has_ingame_voice_chat;
INSERT_PADDING_BYTES(3); INSERT_PADDING_BYTES(3);
u32_le supported_extra_addon_content_flag; 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; std::array<u8, 0x400> platform_specific_region;
}; };
static_assert(sizeof(RawNACP) == 0x4000, "RawNACP has incorrect size."); static_assert(sizeof(RawNACP) == 0x4000, "RawNACP has incorrect size.");
@ -108,11 +140,13 @@ enum class Language : u8 {
TraditionalChinese = 13, TraditionalChinese = 13,
SimplifiedChinese = 14, SimplifiedChinese = 14,
BrazilianPortuguese = 15, BrazilianPortuguese = 15,
Polish = 16,
Thai = 17,
Default = 255, Default = 255,
}; };
extern const std::array<const char*, 16> LANGUAGE_NAMES; extern const std::array<const char*, 18> LANGUAGE_NAMES;
// A class representing the format used by NX metadata files, typically named Control.nacp. // 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. // These store application name, dev name, title id, and other miscellaneous data.
@ -131,7 +165,7 @@ public:
u64 GetDefaultNormalSaveSize() const; u64 GetDefaultNormalSaveSize() const;
u64 GetDefaultJournalSaveSize() const; u64 GetDefaultJournalSaveSize() const;
u32 GetSupportedLanguages() const; u32 GetSupportedLanguages() const;
std::array<std::string, 16> GetApplicationNames() const; std::vector<std::string> GetApplicationNames() const;
std::vector<u8> GetRawBytes() const; std::vector<u8> GetRawBytes() const;
bool GetUserAccountSwitchLock() const; bool GetUserAccountSwitchLock() const;
u64 GetDeviceSaveDataSize() const; u64 GetDeviceSaveDataSize() const;
@ -140,6 +174,7 @@ public:
private: private:
RawNACP raw{}; RawNACP raw{};
std::vector<LanguageEntry> language_entries;
}; };
} // namespace FileSys } // namespace FileSys

View file

@ -295,6 +295,44 @@ constexpr ApplicationLanguagePriorityList priority_list_brazilian_portuguese = {
ApplicationLanguage::TraditionalChinese, ApplicationLanguage::TraditionalChinese,
}}; }};
constexpr ApplicationLanguagePriorityList priority_list_polish = {{
ApplicationLanguage::Polish,
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_thai = {{
ApplicationLanguage::Thai,
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,
}};
const ApplicationLanguagePriorityList* GetApplicationLanguagePriorityList( const ApplicationLanguagePriorityList* GetApplicationLanguagePriorityList(
const ApplicationLanguage lang) { const ApplicationLanguage lang) {
switch (lang) { switch (lang) {
@ -330,6 +368,10 @@ const ApplicationLanguagePriorityList* GetApplicationLanguagePriorityList(
return &priority_list_simplified_chinese; return &priority_list_simplified_chinese;
case ApplicationLanguage::BrazilianPortuguese: case ApplicationLanguage::BrazilianPortuguese:
return &priority_list_brazilian_portuguese; return &priority_list_brazilian_portuguese;
case ApplicationLanguage::Polish:
return &priority_list_polish;
case ApplicationLanguage::Thai:
return &priority_list_thai;
default: default:
return nullptr; return nullptr;
} }
@ -372,6 +414,10 @@ std::optional<ApplicationLanguage> ConvertToApplicationLanguage(
return ApplicationLanguage::SimplifiedChinese; return ApplicationLanguage::SimplifiedChinese;
case Set::LanguageCode::PT_BR: case Set::LanguageCode::PT_BR:
return ApplicationLanguage::BrazilianPortuguese; return ApplicationLanguage::BrazilianPortuguese;
case Set::LanguageCode::PL:
return ApplicationLanguage::Polish;
case Set::LanguageCode::TH:
return ApplicationLanguage::Thai;
default: default:
return std::nullopt; return std::nullopt;
} }
@ -411,6 +457,10 @@ std::optional<Set::LanguageCode> ConvertToLanguageCode(const ApplicationLanguage
return Set::LanguageCode::ZH_HANS; return Set::LanguageCode::ZH_HANS;
case ApplicationLanguage::BrazilianPortuguese: case ApplicationLanguage::BrazilianPortuguese:
return Set::LanguageCode::PT_BR; return Set::LanguageCode::PT_BR;
case ApplicationLanguage::Polish:
return Set::LanguageCode::PL;
case ApplicationLanguage::Thai:
return Set::LanguageCode::TH;
default: default:
return std::nullopt; return std::nullopt;
} }

View file

@ -26,6 +26,8 @@ enum class ApplicationLanguage : u8 {
TraditionalChinese, TraditionalChinese,
SimplifiedChinese, SimplifiedChinese,
BrazilianPortuguese, BrazilianPortuguese,
Polish,
Thai,
Count Count
}; };
using ApplicationLanguagePriorityList = using ApplicationLanguagePriorityList =

View file

@ -169,6 +169,8 @@ enum class Language : u32 {
SimplifiedCHhinese, SimplifiedCHhinese,
TraditionalChinese, TraditionalChinese,
BrazilianPortuguese, BrazilianPortuguese,
Polish,
Thai
}; };
/// This is "nn::settings::LanguageCode", which is a NUL-terminated string stored in a u64. /// This is "nn::settings::LanguageCode", which is a NUL-terminated string stored in a u64.
@ -191,6 +193,8 @@ enum class LanguageCode : u64 {
ZH_HANS = 0x00736E61482D687A, ZH_HANS = 0x00736E61482D687A,
ZH_HANT = 0x00746E61482D687A, ZH_HANT = 0x00746E61482D687A,
PT_BR = 0x00000052422D7470, PT_BR = 0x00000052422D7470,
PL = 0x0000000000006C70,
TH = 0x0000000000006874,
}; };
/// This is nn::settings::system::NotificationVolume /// This is nn::settings::system::NotificationVolume
@ -248,7 +252,7 @@ enum class PlatformRegion : s32 {
Terra = 2, Terra = 2,
}; };
constexpr std::array<LanguageCode, 18> available_language_codes = {{ constexpr std::array<LanguageCode, 20> available_language_codes = {{
LanguageCode::JA, LanguageCode::JA,
LanguageCode::EN_US, LanguageCode::EN_US,
LanguageCode::FR, LanguageCode::FR,
@ -267,9 +271,11 @@ constexpr std::array<LanguageCode, 18> available_language_codes = {{
LanguageCode::ZH_HANS, LanguageCode::ZH_HANS,
LanguageCode::ZH_HANT, LanguageCode::ZH_HANT,
LanguageCode::PT_BR, 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::JA, KeyboardLayout::Japanese},
{LanguageCode::EN_US, KeyboardLayout::EnglishUs}, {LanguageCode::EN_US, KeyboardLayout::EnglishUs},
{LanguageCode::FR, KeyboardLayout::French}, {LanguageCode::FR, KeyboardLayout::French},
@ -288,6 +294,9 @@ static constexpr std::array<std::pair<LanguageCode, KeyboardLayout>, 18> languag
{LanguageCode::ZH_HANS, KeyboardLayout::ChineseSimplified}, {LanguageCode::ZH_HANS, KeyboardLayout::ChineseSimplified},
{LanguageCode::ZH_HANT, KeyboardLayout::ChineseTraditional}, {LanguageCode::ZH_HANT, KeyboardLayout::ChineseTraditional},
{LanguageCode::PT_BR, KeyboardLayout::Portuguese}, {LanguageCode::PT_BR, KeyboardLayout::Portuguese},
{LanguageCode::PL, KeyboardLayout::EnglishUsInternational},
{LanguageCode::TH, KeyboardLayout::EnglishUsInternational}
}}; }};
/// This is nn::settings::system::AccountNotificationFlag /// This is nn::settings::system::AccountNotificationFlag

View file

@ -651,7 +651,8 @@ std::unique_ptr<ComboboxTranslationMap> ComboboxEnumeration(QObject* parent)
PAIR(Language, ChineseSimplified, tr("Simplified Chinese")), PAIR(Language, ChineseSimplified, tr("Simplified Chinese")),
PAIR(Language, ChineseTraditional, tr("Traditional Chinese (正體中文)")), PAIR(Language, ChineseTraditional, tr("Traditional Chinese (正體中文)")),
PAIR(Language, PortugueseBrazilian, tr("Brazilian Portuguese (português do Brasil)")), PAIR(Language, PortugueseBrazilian, tr("Brazilian Portuguese (português do Brasil)")),
PAIR(Language, Serbian, tr("Serbian (српски)")), PAIR(Language, Polish, tr("Polish (Polski)")),
PAIR(Language, Thai, tr("Thai (ไทย)")),
}}); }});
translations->insert({Settings::EnumMetadata<Settings::Region>::Index(), translations->insert({Settings::EnumMetadata<Settings::Region>::Index(),
{ {