diff --git a/Source/options.cpp b/Source/options.cpp index fa0445c2f..e4cffee48 100644 --- a/Source/options.cpp +++ b/Source/options.cpp @@ -997,6 +997,25 @@ void OptionEntryLanguageCode::LoadFromIni(string_view category) } } + std::vector fallbackLocales; + fallbackLocales.reserve(locales.size()); + + for (const auto &locale : locales) { + std::string neutralLocale = locale.substr(0, locale.find('_')); + if (std::find(fallbackLocales.cbegin(), fallbackLocales.cend(), neutralLocale) == fallbackLocales.cend()) { + fallbackLocales.push_back(neutralLocale); + } + } + + for (const auto &fallbackLocale : fallbackLocales) { + LogVerbose("Trying to load fallback translation: {}", fallbackLocale); + if (HasTranslation(fallbackLocale)) { + LogVerbose("Found matching fallback locale: {}", fallbackLocale); + CopyUtf8(szCode, fallbackLocale, sizeof(szCode)); + return; + } + } + LogVerbose("No suitable translation found"); strcpy(szCode, "en"); } diff --git a/Source/utils/language.cpp b/Source/utils/language.cpp index f5e640a8c..0c28d8dab 100644 --- a/Source/utils/language.cpp +++ b/Source/utils/language.cpp @@ -270,15 +270,19 @@ const std::string &LanguageTranslate(const char *key) bool HasTranslation(const std::string &locale) { - for (const char *ext : { ".mo", ".gmo" }) { - SDL_RWops *rw = OpenAsset((locale + ext).c_str()); + if (locale == "en") { + return true; + } + + constexpr std::array Extensions { ".mo", ".gmo" }; + return std::any_of(Extensions.cbegin(), Extensions.cend(), [locale](const std::string &extension) { + SDL_RWops *rw = OpenAsset((locale + extension).c_str()); if (rw != nullptr) { SDL_RWclose(rw); return true; } - } - - return false; + return false; + }); } bool IsSmallFontTall()