|
|
|
@ -115,6 +115,8 @@ static const std::vector<u8> cfg_system_savedata_id = { |
|
|
|
0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x01, 0x00, |
|
|
|
}; |
|
|
|
|
|
|
|
static u32 preferred_region_code = 0; |
|
|
|
|
|
|
|
void GetCountryCodeString(Service::Interface* self) { |
|
|
|
u32* cmd_buff = Kernel::GetCommandBuffer(); |
|
|
|
u32 country_code_id = cmd_buff[1]; |
|
|
|
@ -160,11 +162,18 @@ void GetCountryCodeID(Service::Interface* self) { |
|
|
|
cmd_buff[2] = country_code_id; |
|
|
|
} |
|
|
|
|
|
|
|
static u32 GetRegionValue() { |
|
|
|
if (Settings::values.region_value == Settings::REGION_VALUE_AUTO_SELECT) |
|
|
|
return preferred_region_code; |
|
|
|
|
|
|
|
return Settings::values.region_value; |
|
|
|
} |
|
|
|
|
|
|
|
void SecureInfoGetRegion(Service::Interface* self) { |
|
|
|
u32* cmd_buff = Kernel::GetCommandBuffer(); |
|
|
|
|
|
|
|
cmd_buff[1] = RESULT_SUCCESS.raw; |
|
|
|
cmd_buff[2] = Settings::values.region_value; |
|
|
|
cmd_buff[2] = GetRegionValue(); |
|
|
|
} |
|
|
|
|
|
|
|
void GenHashConsoleUnique(Service::Interface* self) { |
|
|
|
@ -184,7 +193,7 @@ void GetRegionCanadaUSA(Service::Interface* self) { |
|
|
|
cmd_buff[1] = RESULT_SUCCESS.raw; |
|
|
|
|
|
|
|
u8 canada_or_usa = 1; |
|
|
|
if (canada_or_usa == Settings::values.region_value) { |
|
|
|
if (canada_or_usa == GetRegionValue()) { |
|
|
|
cmd_buff[2] = 1; |
|
|
|
} else { |
|
|
|
cmd_buff[2] = 0; |
|
|
|
@ -314,10 +323,47 @@ static ResultVal<void*> GetConfigInfoBlockPointer(u32 block_id, u32 size, u32 fl |
|
|
|
return MakeResult<void*>(pointer); |
|
|
|
} |
|
|
|
|
|
|
|
/// Checks if the language is available in the chosen region, and returns a proper one
|
|
|
|
static u8 AdjustLanguageInfoBlock(u32 region, u8 language) { |
|
|
|
static const std::array<std::vector<u8>, 7> region_languages{{ |
|
|
|
// JPN
|
|
|
|
{LANGUAGE_JP}, |
|
|
|
// USA
|
|
|
|
{LANGUAGE_EN, LANGUAGE_FR, LANGUAGE_ES, LANGUAGE_PT}, |
|
|
|
// EUR
|
|
|
|
{LANGUAGE_EN, LANGUAGE_FR, LANGUAGE_DE, LANGUAGE_IT, LANGUAGE_ES, LANGUAGE_NL, LANGUAGE_PT, |
|
|
|
LANGUAGE_RU}, |
|
|
|
// AUS
|
|
|
|
{LANGUAGE_EN, LANGUAGE_FR, LANGUAGE_DE, LANGUAGE_IT, LANGUAGE_ES, LANGUAGE_NL, LANGUAGE_PT, |
|
|
|
LANGUAGE_RU}, |
|
|
|
// CHN
|
|
|
|
{LANGUAGE_ZH}, |
|
|
|
// KOR
|
|
|
|
{LANGUAGE_KO}, |
|
|
|
// TWN
|
|
|
|
{LANGUAGE_TW}, |
|
|
|
}}; |
|
|
|
const auto& available = region_languages[region]; |
|
|
|
if (std::find(available.begin(), available.end(), language) == available.end()) { |
|
|
|
return available[0]; |
|
|
|
} |
|
|
|
return language; |
|
|
|
} |
|
|
|
|
|
|
|
ResultCode GetConfigInfoBlock(u32 block_id, u32 size, u32 flag, void* output) { |
|
|
|
void* pointer; |
|
|
|
CASCADE_RESULT(pointer, GetConfigInfoBlockPointer(block_id, size, flag)); |
|
|
|
memcpy(output, pointer, size); |
|
|
|
|
|
|
|
// override the language setting if the region setting is auto
|
|
|
|
if (block_id == LanguageBlockID && |
|
|
|
Settings::values.region_value == Settings::REGION_VALUE_AUTO_SELECT) { |
|
|
|
u8 language; |
|
|
|
memcpy(&language, output, sizeof(u8)); |
|
|
|
language = AdjustLanguageInfoBlock(preferred_region_code, language); |
|
|
|
memcpy(output, &language, sizeof(u8)); |
|
|
|
} |
|
|
|
|
|
|
|
return RESULT_SUCCESS; |
|
|
|
} |
|
|
|
|
|
|
|
@ -535,10 +581,17 @@ void Init() { |
|
|
|
AddService(new CFG_U); |
|
|
|
|
|
|
|
LoadConfigNANDSaveFile(); |
|
|
|
|
|
|
|
preferred_region_code = 0; |
|
|
|
} |
|
|
|
|
|
|
|
void Shutdown() {} |
|
|
|
|
|
|
|
void SetPreferredRegionCode(u32 region_code) { |
|
|
|
preferred_region_code = region_code; |
|
|
|
LOG_INFO(Service_CFG, "Preferred region code set to %u", preferred_region_code); |
|
|
|
} |
|
|
|
|
|
|
|
void SetUsername(const std::u16string& name) { |
|
|
|
ASSERT(name.size() <= 10); |
|
|
|
UsernameBlock block{}; |
|
|
|
|