mirror of
				https://git.suyu.dev/suyu/suyu
				synced 2025-11-04 08:59:03 -06:00 
			
		
		
		
	Merge pull request #2240 from wwylele/auto-region
Config: auto-select region and language
This commit is contained in:
		@@ -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{};
 | 
			
		||||
 
 | 
			
		||||
@@ -282,6 +282,13 @@ void Init();
 | 
			
		||||
/// Shutdown the config service
 | 
			
		||||
void Shutdown();
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 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
 | 
			
		||||
 */
 | 
			
		||||
void SetPreferredRegionCode(u32 region_code);
 | 
			
		||||
 | 
			
		||||
// Utilities for frontend to set config data.
 | 
			
		||||
// Note: before calling these functions, LoadConfigNANDSaveFile should be called,
 | 
			
		||||
// and UpdateConfigNANDSavegame should be called after making changes to config data.
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user