diff --git a/src/core/hle/service/cfg/cfg.cpp b/src/core/hle/service/cfg/cfg.cpp index 49d17c190..321628664 100644 --- a/src/core/hle/service/cfg/cfg.cpp +++ b/src/core/hle/service/cfg/cfg.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include +#include #include #include #include "common/file_util.h" @@ -571,7 +572,8 @@ Module::Module() { Module::~Module() = default; /// Checks if the language is available in the chosen region, and returns a proper one -static SystemLanguage AdjustLanguageInfoBlock(u32 region, SystemLanguage language) { +static std::tuple AdjustLanguageInfoBlock( + const std::vector& region_code, SystemLanguage language) { static const std::array, 7> region_languages{{ // JPN {LANGUAGE_JP}, @@ -590,21 +592,28 @@ static SystemLanguage AdjustLanguageInfoBlock(u32 region, SystemLanguage languag // TWN {LANGUAGE_TW}, }}; - const auto& available = region_languages[region]; - if (std::find(available.begin(), available.end(), language) == available.end()) { - return available[0]; + // Check if any available region supports the languages + for (u32 region : region_code) { + const auto& available = region_languages[region]; + if (std::find(available.begin(), available.end(), language) != available.end()) { + // found a proper region, so return this region - language pair + return {region, language}; + } } - return language; + // The language is not available in any available region, so default to the first region and + // language + u32 default_region = region_code[0]; + return {default_region, region_languages[default_region][0]}; } -void Module::SetPreferredRegionCode(u32 region_code) { - preferred_region_code = region_code; +void Module::SetPreferredRegionCodes(const std::vector& region_codes) { + const SystemLanguage current_language = GetSystemLanguage(); + auto [region, adjusted_language] = AdjustLanguageInfoBlock(region_codes, current_language); + + preferred_region_code = region; LOG_INFO(Service_CFG, "Preferred region code set to {}", preferred_region_code); if (Settings::values.region_value == Settings::REGION_VALUE_AUTO_SELECT) { - const SystemLanguage current_language = GetSystemLanguage(); - const SystemLanguage adjusted_language = - AdjustLanguageInfoBlock(region_code, current_language); if (current_language != adjusted_language) { LOG_WARNING(Service_CFG, "System language {} does not fit the region. Adjusted to {}", static_cast(current_language), static_cast(adjusted_language)); diff --git a/src/core/hle/service/cfg/cfg.h b/src/core/hle/service/cfg/cfg.h index 5f5c8e1f1..190430a7e 100644 --- a/src/core/hle/service/cfg/cfg.h +++ b/src/core/hle/service/cfg/cfg.h @@ -7,6 +7,7 @@ #include #include #include +#include #include "common/common_types.h" #include "core/hle/service/fs/archive.h" @@ -298,12 +299,11 @@ public: u32 GetRegionValue(); /** - * Set the region code preferred by the game so that CFG will adjust to it when the region - * setting - * is auto. - * @param region_code the preferred region code to set + * Set the region codes preferred by the game so that CFG will adjust to it when the region + * setting is auto. + * @param region_codes the preferred region codes to set */ - void SetPreferredRegionCode(u32 region_code); + void SetPreferredRegionCodes(const std::vector& region_codes); // Utilities for frontend to set config data. // Note: UpdateConfigNANDSavegame should be called after making changes to config data. diff --git a/src/core/loader/ncch.cpp b/src/core/loader/ncch.cpp index 2e4d956cf..2b29a0f98 100644 --- a/src/core/loader/ncch.cpp +++ b/src/core/loader/ncch.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include "common/logging/log.h" #include "common/string_util.h" @@ -136,13 +137,14 @@ void AppLoader_NCCH::ParseRegionLockoutInfo() { memcpy(&smdh, smdh_buffer.data(), sizeof(SMDH)); u32 region_lockout = smdh.region_lockout; constexpr u32 REGION_COUNT = 7; + std::vector regions; for (u32 region = 0; region < REGION_COUNT; ++region) { if (region_lockout & 1) { - Service::CFG::GetCurrentModule()->SetPreferredRegionCode(region); - break; + regions.push_back(region); } region_lockout >>= 1; } + Service::CFG::GetCurrentModule()->SetPreferredRegionCodes(regions); } }