Merge pull request #4232 from wwylele/multi-region

loader, cfg: choose region based on language if multiple regions available
This commit is contained in:
Weiyi Wang 2018-09-29 23:01:36 -04:00 committed by GitHub
commit edc6e419b0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 28 additions and 17 deletions

View file

@ -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},
}}; }};
// Check if any available region supports the languages
for (u32 region : region_code) {
const auto& available = region_languages[region]; const auto& available = region_languages[region];
if (std::find(available.begin(), available.end(), language) == available.end()) { if (std::find(available.begin(), available.end(), language) != available.end()) {
return available[0]; // 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));

View file

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

View file

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