Skip to content

Commit

Permalink
cfg: Update preferred region data on-demand. (#7206)
Browse files Browse the repository at this point in the history
  • Loading branch information
Steveice10 authored Nov 25, 2023
1 parent 68e6a21 commit c0ecdb6
Show file tree
Hide file tree
Showing 11 changed files with 66 additions and 59 deletions.
6 changes: 1 addition & 5 deletions src/android/app/src/main/jni/system_save_game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,7 @@ void Java_org_citra_citra_1emu_utils_SystemSaveGame_save([[maybe_unused]] JNIEnv

void Java_org_citra_citra_1emu_utils_SystemSaveGame_load([[maybe_unused]] JNIEnv* env,
[[maybe_unused]] jobject obj) {
if (Core::System::GetInstance().IsPoweredOn()) {
cfg = Service::CFG::GetModule(Core::System::GetInstance());
} else {
cfg = std::make_shared<Service::CFG::Module>();
}
cfg = Service::CFG::GetModule(Core::System::GetInstance());
}

jboolean Java_org_citra_citra_1emu_utils_SystemSaveGame_getIsSystemSetupNeeded(
Expand Down
13 changes: 4 additions & 9 deletions src/citra_qt/configuration/configure_system.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -293,16 +293,11 @@ void ConfigureSystem::SetConfiguration() {
QTime time = QTime::fromMSecsSinceStartOfDay(static_cast<int>(time_offset * 1000));
ui->edit_init_time_offset_time->setTime(time);

if (!enabled) {
cfg = Service::CFG::GetModule(system);
ASSERT_MSG(cfg, "CFG Module missing!");
ReadSystemSettings();
ui->group_system_settings->setEnabled(false);
} else {
// This tab is enabled only when game is not running (i.e. all service are not initialized).
cfg = std::make_shared<Service::CFG::Module>();
ReadSystemSettings();
cfg = Service::CFG::GetModule(system);
ReadSystemSettings();

ui->group_system_settings->setEnabled(enabled);
if (enabled) {
ui->label_disable_info->hide();
}

Expand Down
1 change: 0 additions & 1 deletion src/core/frontend/applets/swkbd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,6 @@ void DefaultKeyboard::Execute(const Frontend::KeyboardConfig& config_) {
SoftwareKeyboard::Execute(config_);

auto cfg = Service::CFG::GetModule(Core::System::GetInstance());
ASSERT_MSG(cfg, "CFG Module missing!");
std::string username = Common::UTF16ToUTF8(cfg->GetUsername());
switch (this->config.button_config) {
case ButtonConfig::None:
Expand Down
2 changes: 0 additions & 2 deletions src/core/hle/service/apt/applet_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1358,8 +1358,6 @@ void AppletManager::EnsureHomeMenuLoaded() {
}

auto cfg = Service::CFG::GetModule(system);
ASSERT_MSG(cfg, "CFG Module missing!");

auto menu_title_id = GetTitleIdForApplet(AppletId::HomeMenu, cfg->GetRegionValue());
auto process = NS::LaunchTitle(FS::MediaType::NAND, menu_title_id);
if (!process) {
Expand Down
2 changes: 0 additions & 2 deletions src/core/hle/service/apt/apt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -195,8 +195,6 @@ static u32 DecompressLZ11(const u8* in, u8* out) {

bool Module::LoadSharedFont() {
auto cfg = Service::CFG::GetModule(system);
ASSERT_MSG(cfg, "CFG Module missing!");

u8 font_region_code;
switch (cfg->GetRegionValue()) {
case 4: // CHN
Expand Down
61 changes: 37 additions & 24 deletions src/core/hle/service/cfg/cfg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@
#include "core/hle/service/cfg/cfg_nor.h"
#include "core/hle/service/cfg/cfg_s.h"
#include "core/hle/service/cfg/cfg_u.h"
#include "core/loader/loader.h"

SERVICE_CONSTRUCT_IMPL(Service::CFG::Module)
SERIALIZE_EXPORT_IMPL(Service::CFG::Module)

namespace Service::CFG {
Expand Down Expand Up @@ -195,8 +197,10 @@ void Module::Interface::GetCountryCodeID(Kernel::HLERequestContext& ctx) {
}

u32 Module::GetRegionValue() {
if (Settings::values.region_value.GetValue() == Settings::REGION_VALUE_AUTO_SELECT)
if (Settings::values.region_value.GetValue() == Settings::REGION_VALUE_AUTO_SELECT) {
UpdatePreferredRegionCode();
return preferred_region_code;
}

return Settings::values.region_value.GetValue();
}
Expand Down Expand Up @@ -599,7 +603,7 @@ void Module::SaveMCUConfig() {
}
}

Module::Module() {
Module::Module(Core::System& system_) : system(system_) {
LoadConfigNANDSaveFile();
LoadMCUConfig();
// Check the config savegame EULA Version and update it to 0x7F7F if necessary
Expand Down Expand Up @@ -651,20 +655,23 @@ static std::tuple<u32 /*region*/, SystemLanguage> AdjustLanguageInfoBlock(
return {default_region, region_languages[default_region][0]};
}

void Module::SetPreferredRegionCodes(std::span<const u32> region_codes) {
const SystemLanguage current_language = GetSystemLanguage();
void Module::UpdatePreferredRegionCode() {
if (!system.IsPoweredOn()) {
return;
}

const auto preferred_regions = system.GetAppLoader().GetPreferredRegions();
const auto current_language = GetRawSystemLanguage();
const auto [region, adjusted_language] =
AdjustLanguageInfoBlock(region_codes, current_language);
AdjustLanguageInfoBlock(preferred_regions, current_language);

preferred_region_code = region;
LOG_INFO(Service_CFG, "Preferred region code set to {}", preferred_region_code);

if (Settings::values.region_value.GetValue() == Settings::REGION_VALUE_AUTO_SELECT) {
if (current_language != adjusted_language) {
LOG_WARNING(Service_CFG, "System language {} does not fit the region. Adjusted to {}",
current_language, adjusted_language);
SetSystemLanguage(adjusted_language);
}
if (current_language != adjusted_language) {
LOG_WARNING(Service_CFG, "System language {} does not fit the region. Adjusted to {}",
current_language, adjusted_language);
SetSystemLanguage(adjusted_language);
}
}

Expand Down Expand Up @@ -705,6 +712,13 @@ void Module::SetSystemLanguage(SystemLanguage language) {
}

SystemLanguage Module::GetSystemLanguage() {
if (Settings::values.region_value.GetValue() == Settings::REGION_VALUE_AUTO_SELECT) {
UpdatePreferredRegionCode();
}
return GetRawSystemLanguage();
}

SystemLanguage Module::GetRawSystemLanguage() {
u8 block{};
GetConfigBlock(LanguageBlockID, sizeof(block), AccessFlag::SystemRead, &block);
return static_cast<SystemLanguage>(block);
Expand Down Expand Up @@ -810,31 +824,30 @@ bool Module::IsSystemSetupNeeded() {
}

std::shared_ptr<Module> GetModule(Core::System& system) {
auto cfg = system.ServiceManager().GetService<Service::CFG::Module::Interface>("cfg:u");
if (!cfg)
return nullptr;
return cfg->GetModule();
if (system.IsPoweredOn()) {
auto cfg = system.ServiceManager().GetService<Module::Interface>("cfg:u");
if (cfg) {
return cfg->GetModule();
}
}

// If the system is not running or the module is missing,
// create an ad-hoc module instance to read data from.
return std::make_shared<Module>(system);
}

void InstallInterfaces(Core::System& system) {
auto& service_manager = system.ServiceManager();
auto cfg = std::make_shared<Module>();
auto cfg = std::make_shared<Module>(system);
std::make_shared<CFG_I>(cfg)->InstallAsService(service_manager);
std::make_shared<CFG_S>(cfg)->InstallAsService(service_manager);
std::make_shared<CFG_U>(cfg)->InstallAsService(service_manager);
std::make_shared<CFG_NOR>()->InstallAsService(service_manager);
}

std::string GetConsoleIdHash(Core::System& system) {
u64_le console_id{};
u64_le console_id = GetModule(system)->GetConsoleUniqueId();
std::array<u8, sizeof(console_id)> buffer;
if (system.IsPoweredOn()) {
auto cfg = GetModule(system);
ASSERT_MSG(cfg, "CFG Module missing!");
console_id = cfg->GetConsoleUniqueId();
} else {
console_id = std::make_unique<Service::CFG::Module>()->GetConsoleUniqueId();
}
std::memcpy(buffer.data(), &console_id, sizeof(console_id));

std::array<u8, CryptoPP::SHA256::DIGESTSIZE> hash;
Expand Down
15 changes: 7 additions & 8 deletions src/core/hle/service/cfg/cfg.h
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ DECLARE_ENUM_FLAG_OPERATORS(AccessFlag);

class Module final {
public:
Module();
Module(Core::System& system_);
~Module();

class Interface : public ServiceFramework<Interface> {
Expand Down Expand Up @@ -445,13 +445,6 @@ class Module final {
public:
u32 GetRegionValue();

/**
* 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 SetPreferredRegionCodes(std::span<const u32> region_codes);

// Utilities for frontend to set config data.
// Note: UpdateConfigNANDSavegame should be called after making changes to config data.

Expand Down Expand Up @@ -589,6 +582,11 @@ class Module final {
void SaveMCUConfig();

private:
void UpdatePreferredRegionCode();
SystemLanguage GetRawSystemLanguage();

Core::System& system;

static constexpr u32 CONFIG_SAVEFILE_SIZE = 0x8000;
std::array<u8, CONFIG_SAVEFILE_SIZE> cfg_config_file_buffer;
std::unique_ptr<FileSys::ArchiveBackend> cfg_system_save_data_archive;
Expand All @@ -609,4 +607,5 @@ std::string GetConsoleIdHash(Core::System& system);

} // namespace Service::CFG

SERVICE_CONSTRUCT(Service::CFG::Module)
BOOST_CLASS_EXPORT_KEY(Service::CFG::Module)
1 change: 0 additions & 1 deletion src/core/hle/service/frd/frd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,6 @@ void Module::Interface::GetMyScreenName(Kernel::HLERequestContext& ctx) {
IPC::RequestBuilder rb = rp.MakeBuilder(7, 0);

auto cfg = Service::CFG::GetModule(frd->system);
ASSERT_MSG(cfg, "CFG Module missing!");
auto username = cfg->GetUsername();
ASSERT_MSG(username.length() <= 10, "Username longer than expected!");
ScreenName screen_name{};
Expand Down
8 changes: 8 additions & 0 deletions src/core/loader/loader.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,14 @@ class AppLoader : NonCopyable {
*/
virtual FileType GetFileType() = 0;

/**
* Returns the preferred region codes of this file
* @return A vector of the preferred region codes
*/
[[nodiscard]] virtual std::span<const u32> GetPreferredRegions() const {
return {};
}

/**
* Load the application and return the created Process instance
* @param process The newly created process.
Expand Down
10 changes: 3 additions & 7 deletions src/core/loader/ncch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -196,28 +196,24 @@ void AppLoader_NCCH::ParseRegionLockoutInfo(u64 program_id) {
return;
}

auto cfg = Service::CFG::GetModule(Core::System::GetInstance());
ASSERT_MSG(cfg, "CFG Module missing!");
preferred_regions.clear();

std::vector<u8> smdh_buffer;
if (ReadIcon(smdh_buffer) == ResultStatus::Success && smdh_buffer.size() >= sizeof(SMDH)) {
SMDH smdh;
std::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) {
regions.push_back(region);
preferred_regions.push_back(region);
}
region_lockout >>= 1;
}
cfg->SetPreferredRegionCodes(regions);
} else {
const auto region = Core::GetSystemTitleRegion(program_id);
if (region.has_value()) {
const std::array regions{region.value()};
cfg->SetPreferredRegionCodes(regions);
preferred_regions.push_back(region.value());
}
}
}
Expand Down
6 changes: 6 additions & 0 deletions src/core/loader/ncch.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ class AppLoader_NCCH final : public AppLoader {
return IdentifyType(file);
}

[[nodiscard]] std::span<const u32> GetPreferredRegions() const override {
return preferred_regions;
}

ResultStatus Load(std::shared_ptr<Kernel::Process>& process) override;

std::pair<std::optional<u32>, ResultStatus> LoadCoreVersion() override;
Expand Down Expand Up @@ -87,6 +91,8 @@ class AppLoader_NCCH final : public AppLoader {
FileSys::NCCHContainer update_ncch;
FileSys::NCCHContainer* overlay_ncch;

std::vector<u32> preferred_regions;

std::string filepath;
};

Expand Down

0 comments on commit c0ecdb6

Please sign in to comment.