Merge pull request #4232 from wwylele/multi-region
loader, cfg: choose region based on language if multiple regions available
This commit is contained in:
commit
edc6e419b0
@ -3,6 +3,7 @@
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <algorithm>
|
||||
#include <tuple>
|
||||
#include <cryptopp/osrng.h>
|
||||
#include <cryptopp/sha.h>
|
||||
#include "common/file_util.h"
|
||||
@ -570,7 +571,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<u32 /*region*/, SystemLanguage> AdjustLanguageInfoBlock(
|
||||
const std::vector<u32>& region_code, SystemLanguage language) {
|
||||
static const std::array<std::vector<SystemLanguage>, 7> region_languages{{
|
||||
// JPN
|
||||
{LANGUAGE_JP},
|
||||
@ -589,21 +591,28 @@ static SystemLanguage AdjustLanguageInfoBlock(u32 region, SystemLanguage languag
|
||||
// TWN
|
||||
{LANGUAGE_TW},
|
||||
}};
|
||||
// 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()) {
|
||||
return available[0];
|
||||
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<u32>& 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<int>(current_language), static_cast<int>(adjusted_language));
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include <array>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "common/common_types.h"
|
||||
#include "core/hle/service/fs/archive.h"
|
||||
|
||||
@ -297,12 +298,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<u32>& region_codes);
|
||||
|
||||
// Utilities for frontend to set config data.
|
||||
// Note: UpdateConfigNANDSavegame should be called after making changes to config data.
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <cstring>
|
||||
#include <locale>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <fmt/format.h>
|
||||
#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<u32> 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user