settings: use a template to duplicate memory for each setting

Replaces the type of each variable in the Settings::Values struct with a new
class that allows basic data reading and writing. The new struct
Settings::Setting duplicates the data in memory and can manage global overrides
per each setting.
This commit is contained in:
lat9nq
2020-06-20 19:44:24 -04:00
parent efab7a126a
commit ebcb9090ac
19 changed files with 177 additions and 107 deletions

View File

@@ -162,7 +162,7 @@ struct System::Impl {
const auto current_time = std::chrono::duration_cast<std::chrono::seconds>(
std::chrono::system_clock::now().time_since_epoch());
Settings::values->custom_rtc_differential =
Settings::values->custom_rtc.value_or(current_time) - current_time;
Settings::values->custom_rtc.GetValue().value_or(current_time) - current_time;
// Create a default fs if one doesn't already exist.
if (virtual_filesystem == nullptr)

View File

@@ -29,7 +29,7 @@ FramebufferLayout DefaultFrameLayout(u32 width, u32 height) {
const float window_aspect_ratio = static_cast<float>(height) / width;
const float emulation_aspect_ratio = EmulationAspectRatio(
static_cast<AspectRatio>(Settings::values->aspect_ratio), window_aspect_ratio);
static_cast<AspectRatio>(Settings::values->aspect_ratio.GetValue()), window_aspect_ratio);
const Common::Rectangle<u32> screen_window_area{0, 0, width, height};
Common::Rectangle<u32> screen = MaxRectangle(screen_window_area, emulation_aspect_ratio);

View File

@@ -123,7 +123,7 @@ std::shared_ptr<Process> Process::Create(Core::System& system, std::string name,
: kernel.CreateNewUserProcessID();
process->capabilities.InitializeForMetadatalessProcess();
std::mt19937 rng(Settings::values->rng_seed.value_or(0));
std::mt19937 rng(Settings::values->rng_seed.GetValue().value_or(0));
std::uniform_int_distribution<u64> distribution;
std::generate(process->random_entropy.begin(), process->random_entropy.end(),
[&] { return distribution(rng); });

View File

@@ -163,11 +163,11 @@ void SET::GetQuestFlag(Kernel::HLERequestContext& ctx) {
}
void SET::GetLanguageCode(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_SET, "called {}", Settings::values->language_index);
LOG_DEBUG(Service_SET, "called {}", Settings::values->language_index.GetValue());
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(RESULT_SUCCESS);
rb.PushEnum(available_language_codes[Settings::values->language_index]);
rb.PushEnum(available_language_codes[Settings::values->language_index.GetValue()]);
}
void SET::GetRegionCode(Kernel::HLERequestContext& ctx) {
@@ -175,7 +175,7 @@ void SET::GetRegionCode(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(RESULT_SUCCESS);
rb.Push(Settings::values->region_index);
rb.Push(Settings::values->region_index.GetValue());
}
void SET::GetKeyCodeMap(Kernel::HLERequestContext& ctx) {

View File

@@ -19,7 +19,7 @@ namespace Service::SPL {
Module::Interface::Interface(std::shared_ptr<Module> module, const char* name)
: ServiceFramework(name), module(std::move(module)),
rng(Settings::values->rng_seed.value_or(std::time(nullptr))) {}
rng(Settings::values->rng_seed.GetValue().value_or(std::time(nullptr))) {}
Module::Interface::~Interface() = default;

View File

@@ -19,7 +19,7 @@ constexpr Clock::TimeSpanType standard_network_clock_accuracy{0x0009356907420000
static std::chrono::seconds GetSecondsSinceEpoch() {
return std::chrono::duration_cast<std::chrono::seconds>(
std::chrono::system_clock::now().time_since_epoch()) +
Settings::values->custom_rtc_differential;
Settings::values->custom_rtc_differential.GetValue();
}
static s64 GetExternalTimeZoneOffset() {

View File

@@ -177,7 +177,7 @@ void LogSetting(const std::string& name, const T& value) {
void LogSettings() {
LOG_INFO(Config, "yuzu Configuration:");
LogSetting("System_UseDockedMode", Settings::base_values.use_docked_mode);
LogSetting("System_RngSeed", Settings::values->rng_seed.value_or(0));
LogSetting("System_RngSeed", Settings::values->rng_seed.GetValue().value_or(0));
LogSetting("System_CurrentUser", Settings::values->current_user);
LogSetting("System_LanguageIndex", Settings::values->language_index);
LogSetting("System_RegionIndex", Settings::values->region_index);
@@ -187,15 +187,15 @@ void LogSettings() {
LogSetting("Renderer_UseFrameLimit", Settings::values->use_frame_limit);
LogSetting("Renderer_FrameLimit", Settings::values->frame_limit);
LogSetting("Renderer_UseDiskShaderCache", Settings::values->use_disk_shader_cache);
LogSetting("Renderer_GPUAccuracyLevel", Settings::values->gpu_accuracy);
LogSetting("Renderer_GPUAccuracyLevel", Settings::values->gpu_accuracy.GetValue());
LogSetting("Renderer_UseAsynchronousGpuEmulation",
Settings::values->use_asynchronous_gpu_emulation);
LogSetting("Renderer_UseVsync", Settings::values->use_vsync);
LogSetting("Renderer_UseAssemblyShaders", Settings::values->use_assembly_shaders);
LogSetting("Renderer_AnisotropicFilteringLevel", Settings::values->max_anisotropy);
LogSetting("Audio_OutputEngine", Settings::values->sink_id);
LogSetting("Audio_OutputEngine", Settings::values->sink_id.GetValue());
LogSetting("Audio_EnableAudioStretching", Settings::values->enable_audio_stretching);
LogSetting("Audio_OutputDevice", Settings::values->audio_device_id);
LogSetting("Audio_OutputDevice", Settings::values->audio_device_id.GetValue());
LogSetting("DataStorage_UseVirtualSd", Settings::base_values.use_virtual_sd);
LogSetting("DataStorage_NandDir", FileUtil::GetUserPath(FileUtil::UserPath::NANDDir));
LogSetting("DataStorage_SdmcDir", FileUtil::GetUserPath(FileUtil::UserPath::SDMCDir));

View File

@@ -382,55 +382,99 @@ enum class GPUAccuracy : u32 {
Extreme = 2,
};
template <typename Type>
class Setting {
public:
Setting() {
use_global = true;
}
~Setting() = default;
void SetGlobal(bool to_global) {
use_global = to_global;
};
Type GetValue() {
if (use_global) {
return global;
}
return local;
};
void SetValue(Type value) {
if (use_global) {
global = value;
}
else {
local = value;
}
};
operator Type() const {
if (use_global)
return global;
return local;
};
Type operator=(const Type& b) {
if (use_global) {
global = b;
}
else {
local = b;
}
return b;
};
private:
bool use_global;
Type global;
Type local;
};
struct Values {
// Audio
std::string sink_id;
bool enable_audio_stretching;
std::string audio_device_id;
float volume;
Setting<std::string> sink_id;
Setting<bool> enable_audio_stretching;
Setting<std::string> audio_device_id;
Setting<float> volume;
// Core
bool use_multi_core;
Setting<bool> use_multi_core;
// Misceallaneous
std::string log_filter;
bool use_dev_keys;
bool use_global_values;
Setting<std::string> log_filter;
Setting<bool> use_dev_keys;
Setting<bool> use_global_values;
// Renderer
RendererBackend renderer_backend;
bool renderer_debug;
int vulkan_device;
Setting<RendererBackend> renderer_backend;
Setting<bool> renderer_debug;
Setting<int> vulkan_device;
u16 resolution_factor{1};
int aspect_ratio;
int max_anisotropy;
bool use_frame_limit;
u16 frame_limit;
bool use_disk_shader_cache;
GPUAccuracy gpu_accuracy;
bool use_asynchronous_gpu_emulation;
bool use_vsync;
bool use_assembly_shaders;
bool force_30fps_mode;
bool use_fast_gpu_time;
Setting<u16> resolution_factor;
Setting<int> aspect_ratio;
Setting<int> max_anisotropy;
Setting<bool> use_frame_limit;
Setting<u16> frame_limit;
Setting<bool> use_disk_shader_cache;
Setting<GPUAccuracy> gpu_accuracy;
Setting<bool> use_asynchronous_gpu_emulation;
Setting<bool> use_vsync;
Setting<bool> use_assembly_shaders;
Setting<bool> force_30fps_mode;
Setting<bool> use_fast_gpu_time;
float bg_red;
float bg_green;
float bg_blue;
Setting<float> bg_red;
Setting<float> bg_green;
Setting<float> bg_blue;
// System
std::optional<u32> rng_seed;
Setting<std::optional<u32>> rng_seed;
// Measured in seconds since epoch
std::optional<std::chrono::seconds> custom_rtc;
Setting<std::optional<std::chrono::seconds>> custom_rtc;
// Set on game boot, reset on stop. Seconds difference between current time and `custom_rtc`
std::chrono::seconds custom_rtc_differential;
Setting<std::chrono::seconds> custom_rtc_differential;
s32 current_user;
s32 language_index;
s32 region_index;
s32 time_zone_index;
s32 sound_index;
Setting<s32> current_user;
Setting<s32> language_index;
Setting<s32> region_index;
Setting<s32> time_zone_index;
Setting<s32> sound_index;
};
struct NonSwitchingValues {

View File

@@ -189,20 +189,25 @@ void TelemetrySession::AddInitialInfo(Loader::AppLoader& app_loader) {
// Log user configuration information
constexpr auto field_type = Telemetry::FieldType::UserConfig;
AddField(field_type, "Audio_SinkId", Settings::values->sink_id);
AddField(field_type, "Audio_EnableAudioStretching", Settings::values->enable_audio_stretching);
AddField(field_type, "Core_UseMultiCore", Settings::values->use_multi_core);
AddField(field_type, "Renderer_Backend", TranslateRenderer(Settings::values->renderer_backend));
AddField(field_type, "Renderer_ResolutionFactor", Settings::values->resolution_factor);
AddField(field_type, "Renderer_UseFrameLimit", Settings::values->use_frame_limit);
AddField(field_type, "Renderer_FrameLimit", Settings::values->frame_limit);
AddField(field_type, "Renderer_UseDiskShaderCache", Settings::values->use_disk_shader_cache);
AddField(field_type, "Audio_SinkId", Settings::values->sink_id.GetValue());
AddField(field_type, "Audio_EnableAudioStretching",
Settings::values->enable_audio_stretching.GetValue());
AddField(field_type, "Core_UseMultiCore", Settings::values->use_multi_core.GetValue());
AddField(field_type, "Renderer_Backend",
TranslateRenderer(Settings::values->renderer_backend.GetValue()));
AddField(field_type, "Renderer_ResolutionFactor",
Settings::values->resolution_factor.GetValue());
AddField(field_type, "Renderer_UseFrameLimit", Settings::values->use_frame_limit.GetValue());
AddField(field_type, "Renderer_FrameLimit", Settings::values->frame_limit.GetValue());
AddField(field_type, "Renderer_UseDiskShaderCache",
Settings::values->use_disk_shader_cache.GetValue());
AddField(field_type, "Renderer_GPUAccuracyLevel",
TranslateGPUAccuracyLevel(Settings::values->gpu_accuracy));
TranslateGPUAccuracyLevel(Settings::values->gpu_accuracy.GetValue()));
AddField(field_type, "Renderer_UseAsynchronousGpuEmulation",
Settings::values->use_asynchronous_gpu_emulation);
AddField(field_type, "Renderer_UseVsync", Settings::values->use_vsync);
AddField(field_type, "Renderer_UseAssemblyShaders", Settings::values->use_assembly_shaders);
Settings::values->use_asynchronous_gpu_emulation.GetValue());
AddField(field_type, "Renderer_UseVsync", Settings::values->use_vsync.GetValue());
AddField(field_type, "Renderer_UseAssemblyShaders",
Settings::values->use_assembly_shaders.GetValue());
AddField(field_type, "System_UseDockedMode", Settings::base_values.use_docked_mode);
}