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.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <tuple>
|
||||||
#include <cryptopp/osrng.h>
|
#include <cryptopp/osrng.h>
|
||||||
#include <cryptopp/sha.h>
|
#include <cryptopp/sha.h>
|
||||||
#include "common/file_util.h"
|
#include "common/file_util.h"
|
||||||
|
@ -570,7 +571,8 @@ Module::Module() {
|
||||||
Module::~Module() = default;
|
Module::~Module() = default;
|
||||||
|
|
||||||
/// Checks if the language is available in the chosen region, and returns a proper one
|
/// 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{{
|
static const std::array<std::vector<SystemLanguage>, 7> region_languages{{
|
||||||
// JPN
|
// JPN
|
||||||
{LANGUAGE_JP},
|
{LANGUAGE_JP},
|
||||||
|
@ -589,21 +591,28 @@ static SystemLanguage AdjustLanguageInfoBlock(u32 region, SystemLanguage languag
|
||||||
// TWN
|
// TWN
|
||||||
{LANGUAGE_TW},
|
{LANGUAGE_TW},
|
||||||
}};
|
}};
|
||||||
const auto& available = region_languages[region];
|
// Check if any available region supports the languages
|
||||||
if (std::find(available.begin(), available.end(), language) == available.end()) {
|
for (u32 region : region_code) {
|
||||||
return available[0];
|
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) {
|
void Module::SetPreferredRegionCodes(const std::vector<u32>& region_codes) {
|
||||||
preferred_region_code = region_code;
|
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);
|
LOG_INFO(Service_CFG, "Preferred region code set to {}", preferred_region_code);
|
||||||
|
|
||||||
if (Settings::values.region_value == Settings::REGION_VALUE_AUTO_SELECT) {
|
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) {
|
if (current_language != adjusted_language) {
|
||||||
LOG_WARNING(Service_CFG, "System language {} does not fit the region. Adjusted to {}",
|
LOG_WARNING(Service_CFG, "System language {} does not fit the region. Adjusted to {}",
|
||||||
static_cast<int>(current_language), static_cast<int>(adjusted_language));
|
static_cast<int>(current_language), static_cast<int>(adjusted_language));
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "core/hle/service/fs/archive.h"
|
#include "core/hle/service/fs/archive.h"
|
||||||
|
|
||||||
|
@ -297,12 +298,11 @@ public:
|
||||||
u32 GetRegionValue();
|
u32 GetRegionValue();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the region code preferred by the game so that CFG will adjust to it when the region
|
* Set the region codes preferred by the game so that CFG will adjust to it when the region
|
||||||
* setting
|
* setting is auto.
|
||||||
* is auto.
|
* @param region_codes the preferred region codes to set
|
||||||
* @param region_code the preferred region code to set
|
|
||||||
*/
|
*/
|
||||||
void SetPreferredRegionCode(u32 region_code);
|
void SetPreferredRegionCodes(const std::vector<u32>& region_codes);
|
||||||
|
|
||||||
// Utilities for frontend to set config data.
|
// Utilities for frontend to set config data.
|
||||||
// Note: UpdateConfigNANDSavegame should be called after making changes to config data.
|
// Note: UpdateConfigNANDSavegame should be called after making changes to config data.
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <locale>
|
#include <locale>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "common/string_util.h"
|
#include "common/string_util.h"
|
||||||
|
@ -136,13 +137,14 @@ void AppLoader_NCCH::ParseRegionLockoutInfo() {
|
||||||
memcpy(&smdh, smdh_buffer.data(), sizeof(SMDH));
|
memcpy(&smdh, smdh_buffer.data(), sizeof(SMDH));
|
||||||
u32 region_lockout = smdh.region_lockout;
|
u32 region_lockout = smdh.region_lockout;
|
||||||
constexpr u32 REGION_COUNT = 7;
|
constexpr u32 REGION_COUNT = 7;
|
||||||
|
std::vector<u32> regions;
|
||||||
for (u32 region = 0; region < REGION_COUNT; ++region) {
|
for (u32 region = 0; region < REGION_COUNT; ++region) {
|
||||||
if (region_lockout & 1) {
|
if (region_lockout & 1) {
|
||||||
Service::CFG::GetCurrentModule()->SetPreferredRegionCode(region);
|
regions.push_back(region);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
region_lockout >>= 1;
|
region_lockout >>= 1;
|
||||||
}
|
}
|
||||||
|
Service::CFG::GetCurrentModule()->SetPreferredRegionCodes(regions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Reference in New Issue