Browse Source

add polish & thai, remove serbian as system language

feat/new_lang
maufeat 2 weeks ago
parent
commit
57d81596f5
  1. 5
      src/android/app/src/main/res/values/arrays.xml
  2. 4
      src/android/app/src/main/res/values/strings.xml
  3. 2
      src/common/settings_enums.h
  4. 117
      src/core/file_sys/control_metadata.cpp
  5. 55
      src/core/file_sys/control_metadata.h
  6. 50
      src/core/hle/service/ns/language.cpp
  7. 2
      src/core/hle/service/ns/language.h
  8. 13
      src/core/hle/service/set/settings_types.h
  9. 3
      src/qt_common/config/shared_translation.cpp

5
src/android/app/src/main/res/values/arrays.xml

@ -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>

4
src/android/app/src/main/res/values/strings.xml

@ -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>

2
src/common/settings_enums.h

@ -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,

117
src/core/file_sys/control_metadata.cpp

@ -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 PACKED_LANGUAGE_REGION_MAX_SIZE = sizeof(LanguageEntry) * 32;
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;
}
bool InflateRawDeflate(std::span<const u8> compressed, std::vector<u8>& out)
{
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{};
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);
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); 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;
if (ret != Z_STREAM_END && ret != Z_OK) {
return false;
} }
std::memcpy(raw.language_entries.data(), decompressed.data(), LEGACY_LANGUAGE_REGION_SIZE);
// Shrink to actual decompressed size
out.resize(stream.total_out);
return true;
} }
} // 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 =
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; return names;
} }

55
src/core/file_sys/control_metadata.h

@ -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;
INSERT_PADDING_BYTES(5);
u8 runtime_add_on_content_install;
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

50
src/core/hle/service/ns/language.cpp

@ -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;
} }

2
src/core/hle/service/ns/language.h

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

13
src/core/hle/service/set/settings_types.h

@ -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

3
src/qt_common/config/shared_translation.cpp

@ -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(),
{ {

Loading…
Cancel
Save