Compare commits
51 Commits
__refs_pul
...
__refs_pul
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ff9538f8d7 | ||
|
|
97e7d239a1 | ||
|
|
9dcf22cfe6 | ||
|
|
70cff73d03 | ||
|
|
a24f700176 | ||
|
|
0be18984ec | ||
|
|
6795d66c92 | ||
|
|
47b1ccc812 | ||
|
|
3756dc2276 | ||
|
|
eb458865d7 | ||
|
|
2c0587df0e | ||
|
|
83c50acf7c | ||
|
|
a48125b5c9 | ||
|
|
c21d62afc5 | ||
|
|
588209e514 | ||
|
|
525e14f452 | ||
|
|
b0c15ac20e | ||
|
|
8a7db4b6c7 | ||
|
|
513356d21b | ||
|
|
fabb0b8c3d | ||
|
|
dd28c11624 | ||
|
|
56321a8cbb | ||
|
|
f1640df97c | ||
|
|
59aef94c94 | ||
|
|
20eef91cd4 | ||
|
|
3b62d75257 | ||
|
|
c39112299a | ||
|
|
3893d8b39a | ||
|
|
081f91fcf8 | ||
|
|
4ac4554e9a | ||
|
|
256c50376f | ||
|
|
a542583075 | ||
|
|
c2d1750575 | ||
|
|
e2886132d9 | ||
|
|
08018d985c | ||
|
|
5afe9a375a | ||
|
|
36a5b83f1b | ||
|
|
3ad63dd4a0 | ||
|
|
ebcb9090ac | ||
|
|
efab7a126a | ||
|
|
de9350925b | ||
|
|
2d01d76ae5 | ||
|
|
94fb90596a | ||
|
|
bb1461ce6c | ||
|
|
e66c9a79b5 | ||
|
|
4342f759a3 | ||
|
|
1dedbbdaaa | ||
|
|
d96eb90144 | ||
|
|
9ca688a29e | ||
|
|
090f2ba446 | ||
|
|
5a06bb1808 |
@@ -193,7 +193,7 @@ long CubebSinkStream::DataCallback(cubeb_stream* stream, void* user_data, const
|
||||
const std::size_t samples_to_write = num_channels * num_frames;
|
||||
std::size_t samples_written;
|
||||
|
||||
if (Settings::values.enable_audio_stretching) {
|
||||
if (Settings::values.enable_audio_stretching.GetValue()) {
|
||||
const std::vector<s16> in{impl->queue.Pop()};
|
||||
const std::size_t num_in{in.size() / num_channels};
|
||||
s16* const out{reinterpret_cast<s16*>(buffer)};
|
||||
|
||||
@@ -105,9 +105,10 @@ void Stream::PlayNextBuffer(s64 cycles_late) {
|
||||
|
||||
sink_stream.EnqueueSamples(GetNumChannels(), active_buffer->GetSamples());
|
||||
|
||||
core_timing.ScheduleEvent(GetBufferReleaseNS(*active_buffer) -
|
||||
(Settings::values.enable_audio_stretching ? 0 : cycles_late),
|
||||
release_event, {});
|
||||
core_timing.ScheduleEvent(
|
||||
GetBufferReleaseNS(*active_buffer) -
|
||||
(Settings::values.enable_audio_stretching.GetValue() ? 0 : cycles_late),
|
||||
release_event, {});
|
||||
}
|
||||
|
||||
void Stream::ReleaseActiveBuffer(s64 cycles_late) {
|
||||
|
||||
@@ -147,8 +147,8 @@ struct System::Impl {
|
||||
|
||||
device_memory = std::make_unique<Core::DeviceMemory>(system);
|
||||
|
||||
is_multicore = Settings::values.use_multi_core;
|
||||
is_async_gpu = is_multicore || Settings::values.use_asynchronous_gpu_emulation;
|
||||
is_multicore = Settings::values.use_multi_core.GetValue();
|
||||
is_async_gpu = is_multicore || Settings::values.use_asynchronous_gpu_emulation.GetValue();
|
||||
|
||||
kernel.SetMulticore(is_multicore);
|
||||
cpu_manager.SetMulticore(is_multicore);
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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); });
|
||||
|
||||
@@ -731,14 +731,14 @@ void ICommonStateGetter::GetDefaultDisplayResolution(Kernel::HLERequestContext&
|
||||
|
||||
if (Settings::values.use_docked_mode) {
|
||||
rb.Push(static_cast<u32>(Service::VI::DisplayResolution::DockedWidth) *
|
||||
static_cast<u32>(Settings::values.resolution_factor));
|
||||
static_cast<u32>(Settings::values.resolution_factor.GetValue()));
|
||||
rb.Push(static_cast<u32>(Service::VI::DisplayResolution::DockedHeight) *
|
||||
static_cast<u32>(Settings::values.resolution_factor));
|
||||
static_cast<u32>(Settings::values.resolution_factor.GetValue()));
|
||||
} else {
|
||||
rb.Push(static_cast<u32>(Service::VI::DisplayResolution::UndockedWidth) *
|
||||
static_cast<u32>(Settings::values.resolution_factor));
|
||||
static_cast<u32>(Settings::values.resolution_factor.GetValue()));
|
||||
rb.Push(static_cast<u32>(Service::VI::DisplayResolution::UndockedHeight) *
|
||||
static_cast<u32>(Settings::values.resolution_factor));
|
||||
static_cast<u32>(Settings::values.resolution_factor.GetValue()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -366,7 +366,8 @@ ResultVal<u8> IApplicationManagerInterface::GetApplicationDesiredLanguage(
|
||||
LOG_DEBUG(Service_NS, "called with supported_languages={:08X}", supported_languages);
|
||||
|
||||
// Get language code from settings
|
||||
const auto language_code = Set::GetLanguageCodeFromIndex(Settings::values.language_index);
|
||||
const auto language_code =
|
||||
Set::GetLanguageCodeFromIndex(Settings::values.language_index.GetValue());
|
||||
|
||||
// Convert to application language, get priority list
|
||||
const auto application_language = ConvertToApplicationLanguage(language_code);
|
||||
|
||||
@@ -91,7 +91,7 @@ void GetAvailableLanguageCodesImpl(Kernel::HLERequestContext& ctx, std::size_t m
|
||||
}
|
||||
|
||||
void GetKeyCodeMapImpl(Kernel::HLERequestContext& ctx) {
|
||||
const auto language_code = available_language_codes[Settings::values.language_index];
|
||||
const auto language_code = available_language_codes[Settings::values.language_index.GetValue()];
|
||||
const auto key_code =
|
||||
std::find_if(language_to_layout.cbegin(), language_to_layout.cend(),
|
||||
[=](const auto& element) { return element.first == language_code; });
|
||||
@@ -99,7 +99,7 @@ void GetKeyCodeMapImpl(Kernel::HLERequestContext& ctx) {
|
||||
if (key_code == language_to_layout.cend()) {
|
||||
LOG_ERROR(Service_SET,
|
||||
"Could not find keyboard layout for language index {}, defaulting to English us",
|
||||
Settings::values.language_index);
|
||||
Settings::values.language_index.GetValue());
|
||||
} else {
|
||||
layout = key_code->second;
|
||||
}
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -519,9 +519,9 @@ private:
|
||||
IGBPConnectRequestParcel request{ctx.ReadBuffer()};
|
||||
IGBPConnectResponseParcel response{
|
||||
static_cast<u32>(static_cast<u32>(DisplayResolution::UndockedWidth) *
|
||||
Settings::values.resolution_factor),
|
||||
Settings::values.resolution_factor.GetValue()),
|
||||
static_cast<u32>(static_cast<u32>(DisplayResolution::UndockedHeight) *
|
||||
Settings::values.resolution_factor)};
|
||||
Settings::values.resolution_factor.GetValue())};
|
||||
ctx.WriteBuffer(response.Serialize());
|
||||
break;
|
||||
}
|
||||
@@ -748,14 +748,14 @@ private:
|
||||
|
||||
if (Settings::values.use_docked_mode) {
|
||||
rb.Push(static_cast<u32>(Service::VI::DisplayResolution::DockedWidth) *
|
||||
static_cast<u32>(Settings::values.resolution_factor));
|
||||
static_cast<u32>(Settings::values.resolution_factor.GetValue()));
|
||||
rb.Push(static_cast<u32>(Service::VI::DisplayResolution::DockedHeight) *
|
||||
static_cast<u32>(Settings::values.resolution_factor));
|
||||
static_cast<u32>(Settings::values.resolution_factor.GetValue()));
|
||||
} else {
|
||||
rb.Push(static_cast<u32>(Service::VI::DisplayResolution::UndockedWidth) *
|
||||
static_cast<u32>(Settings::values.resolution_factor));
|
||||
static_cast<u32>(Settings::values.resolution_factor.GetValue()));
|
||||
rb.Push(static_cast<u32>(Service::VI::DisplayResolution::UndockedHeight) *
|
||||
static_cast<u32>(Settings::values.resolution_factor));
|
||||
static_cast<u32>(Settings::values.resolution_factor.GetValue()));
|
||||
}
|
||||
|
||||
rb.PushRaw<float>(60.0f); // This wouldn't seem to be correct for 30 fps games.
|
||||
@@ -1029,9 +1029,9 @@ private:
|
||||
// between docked and undocked dimensions. We take the liberty of applying
|
||||
// the resolution scaling factor here.
|
||||
rb.Push(static_cast<u64>(DisplayResolution::UndockedWidth) *
|
||||
static_cast<u32>(Settings::values.resolution_factor));
|
||||
static_cast<u32>(Settings::values.resolution_factor.GetValue()));
|
||||
rb.Push(static_cast<u64>(DisplayResolution::UndockedHeight) *
|
||||
static_cast<u32>(Settings::values.resolution_factor));
|
||||
static_cast<u32>(Settings::values.resolution_factor.GetValue()));
|
||||
}
|
||||
|
||||
void SetLayerScalingMode(Kernel::HLERequestContext& ctx) {
|
||||
@@ -1064,8 +1064,8 @@ private:
|
||||
LOG_WARNING(Service_VI, "(STUBBED) called");
|
||||
|
||||
DisplayInfo display_info;
|
||||
display_info.width *= static_cast<u64>(Settings::values.resolution_factor);
|
||||
display_info.height *= static_cast<u64>(Settings::values.resolution_factor);
|
||||
display_info.width *= static_cast<u64>(Settings::values.resolution_factor.GetValue());
|
||||
display_info.height *= static_cast<u64>(Settings::values.resolution_factor.GetValue());
|
||||
ctx.WriteBuffer(&display_info, sizeof(DisplayInfo));
|
||||
IPC::ResponseBuilder rb{ctx, 4};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
|
||||
@@ -119,13 +119,14 @@ double PerfStats::GetLastFrameTimeScale() {
|
||||
}
|
||||
|
||||
void FrameLimiter::DoFrameLimiting(microseconds current_system_time_us) {
|
||||
if (!Settings::values.use_frame_limit || Settings::values.use_multi_core) {
|
||||
if (!Settings::values.use_frame_limit.GetValue() ||
|
||||
Settings::values.use_multi_core.GetValue()) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto now = Clock::now();
|
||||
|
||||
const double sleep_scale = Settings::values.frame_limit / 100.0;
|
||||
const double sleep_scale = Settings::values.frame_limit.GetValue() / 100.0;
|
||||
|
||||
// Max lag caused by slow frames. Shouldn't be more than the length of a frame at the current
|
||||
// speed percent or it will clamp too much and prevent this from properly limiting to that
|
||||
|
||||
@@ -62,6 +62,7 @@ const std::array<const char*, NumMouseButtons> mapping = {{
|
||||
}
|
||||
|
||||
Values values = {};
|
||||
bool configuring_global = true;
|
||||
|
||||
std::string GetTimeZoneString() {
|
||||
static constexpr std::array<const char*, 46> timezones{{
|
||||
@@ -73,9 +74,9 @@ std::string GetTimeZoneString() {
|
||||
"UCT", "Universal", "UTC", "W-SU", "WET", "Zulu",
|
||||
}};
|
||||
|
||||
ASSERT(Settings::values.time_zone_index < timezones.size());
|
||||
ASSERT(Settings::values.time_zone_index.GetValue() < timezones.size());
|
||||
|
||||
return timezones[Settings::values.time_zone_index];
|
||||
return timezones[Settings::values.time_zone_index.GetValue()];
|
||||
}
|
||||
|
||||
void Apply() {
|
||||
@@ -97,25 +98,25 @@ void LogSetting(const std::string& name, const T& value) {
|
||||
|
||||
void LogSettings() {
|
||||
LOG_INFO(Config, "yuzu Configuration:");
|
||||
LogSetting("System_UseDockedMode", Settings::values.use_docked_mode);
|
||||
LogSetting("System_RngSeed", Settings::values.rng_seed.value_or(0));
|
||||
LogSetting("Controls_UseDockedMode", Settings::values.use_docked_mode);
|
||||
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);
|
||||
LogSetting("System_TimeZoneIndex", Settings::values.time_zone_index);
|
||||
LogSetting("Core_UseMultiCore", Settings::values.use_multi_core);
|
||||
LogSetting("Renderer_UseResolutionFactor", Settings::values.resolution_factor);
|
||||
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("System_LanguageIndex", Settings::values.language_index.GetValue());
|
||||
LogSetting("System_RegionIndex", Settings::values.region_index.GetValue());
|
||||
LogSetting("System_TimeZoneIndex", Settings::values.time_zone_index.GetValue());
|
||||
LogSetting("Core_UseMultiCore", Settings::values.use_multi_core.GetValue());
|
||||
LogSetting("Renderer_UseResolutionFactor", Settings::values.resolution_factor.GetValue());
|
||||
LogSetting("Renderer_UseFrameLimit", Settings::values.use_frame_limit.GetValue());
|
||||
LogSetting("Renderer_FrameLimit", Settings::values.frame_limit.GetValue());
|
||||
LogSetting("Renderer_UseDiskShaderCache", Settings::values.use_disk_shader_cache.GetValue());
|
||||
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);
|
||||
Settings::values.use_asynchronous_gpu_emulation.GetValue());
|
||||
LogSetting("Renderer_UseVsync", Settings::values.use_vsync.GetValue());
|
||||
LogSetting("Renderer_UseAssemblyShaders", Settings::values.use_assembly_shaders.GetValue());
|
||||
LogSetting("Renderer_AnisotropicFilteringLevel", Settings::values.max_anisotropy.GetValue());
|
||||
LogSetting("Audio_OutputEngine", Settings::values.sink_id);
|
||||
LogSetting("Audio_EnableAudioStretching", Settings::values.enable_audio_stretching);
|
||||
LogSetting("Audio_EnableAudioStretching", Settings::values.enable_audio_stretching.GetValue());
|
||||
LogSetting("Audio_OutputDevice", Settings::values.audio_device_id);
|
||||
LogSetting("DataStorage_UseVirtualSd", Settings::values.use_virtual_sd);
|
||||
LogSetting("DataStorage_NandDir", FileUtil::GetUserPath(FileUtil::UserPath::NANDDir));
|
||||
@@ -131,15 +132,56 @@ float Volume() {
|
||||
if (values.audio_muted) {
|
||||
return 0.0f;
|
||||
}
|
||||
return values.volume;
|
||||
return values.volume.GetValue();
|
||||
}
|
||||
|
||||
bool IsGPULevelExtreme() {
|
||||
return values.gpu_accuracy == GPUAccuracy::Extreme;
|
||||
return values.gpu_accuracy.GetValue() == GPUAccuracy::Extreme;
|
||||
}
|
||||
|
||||
bool IsGPULevelHigh() {
|
||||
return values.gpu_accuracy == GPUAccuracy::Extreme || values.gpu_accuracy == GPUAccuracy::High;
|
||||
return values.gpu_accuracy.GetValue() == GPUAccuracy::Extreme ||
|
||||
values.gpu_accuracy.GetValue() == GPUAccuracy::High;
|
||||
}
|
||||
|
||||
void RestoreGlobalState() {
|
||||
// If a game is running, DO NOT restore the global settings state
|
||||
if (Core::System::GetInstance().IsPoweredOn()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Audio
|
||||
values.enable_audio_stretching.SetGlobal(true);
|
||||
values.volume.SetGlobal(true);
|
||||
|
||||
// Core
|
||||
values.use_multi_core.SetGlobal(true);
|
||||
|
||||
// Renderer
|
||||
values.renderer_backend.SetGlobal(true);
|
||||
values.vulkan_device.SetGlobal(true);
|
||||
values.aspect_ratio.SetGlobal(true);
|
||||
values.max_anisotropy.SetGlobal(true);
|
||||
values.use_frame_limit.SetGlobal(true);
|
||||
values.frame_limit.SetGlobal(true);
|
||||
values.use_disk_shader_cache.SetGlobal(true);
|
||||
values.gpu_accuracy.SetGlobal(true);
|
||||
values.use_asynchronous_gpu_emulation.SetGlobal(true);
|
||||
values.use_vsync.SetGlobal(true);
|
||||
values.use_assembly_shaders.SetGlobal(true);
|
||||
values.use_fast_gpu_time.SetGlobal(true);
|
||||
values.force_30fps_mode.SetGlobal(true);
|
||||
values.bg_red.SetGlobal(true);
|
||||
values.bg_green.SetGlobal(true);
|
||||
values.bg_blue.SetGlobal(true);
|
||||
|
||||
// System
|
||||
values.language_index.SetGlobal(true);
|
||||
values.region_index.SetGlobal(true);
|
||||
values.time_zone_index.SetGlobal(true);
|
||||
values.rng_seed.SetGlobal(true);
|
||||
values.custom_rtc.SetGlobal(true);
|
||||
values.sound_index.SetGlobal(true);
|
||||
}
|
||||
|
||||
} // namespace Settings
|
||||
|
||||
@@ -382,20 +382,85 @@ enum class GPUAccuracy : u32 {
|
||||
Extreme = 2,
|
||||
};
|
||||
|
||||
extern bool configuring_global;
|
||||
|
||||
template <typename Type>
|
||||
class Setting final {
|
||||
public:
|
||||
Setting() = default;
|
||||
explicit Setting(Type val) : global{val} {}
|
||||
~Setting() = default;
|
||||
void SetGlobal(bool to_global) {
|
||||
use_global = to_global;
|
||||
}
|
||||
bool UsingGlobal() const {
|
||||
return use_global;
|
||||
}
|
||||
Type GetValue(bool need_global = false) const {
|
||||
if (use_global || need_global) {
|
||||
return global;
|
||||
}
|
||||
return local;
|
||||
}
|
||||
void SetValue(const Type& value) {
|
||||
if (use_global) {
|
||||
global = value;
|
||||
} else {
|
||||
local = value;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
bool use_global = true;
|
||||
Type global{};
|
||||
Type local{};
|
||||
};
|
||||
|
||||
struct Values {
|
||||
// Audio
|
||||
std::string audio_device_id;
|
||||
std::string sink_id;
|
||||
bool audio_muted;
|
||||
Setting<bool> enable_audio_stretching;
|
||||
Setting<float> volume;
|
||||
|
||||
// Core
|
||||
Setting<bool> use_multi_core;
|
||||
|
||||
// Renderer
|
||||
Setting<RendererBackend> renderer_backend;
|
||||
bool renderer_debug;
|
||||
Setting<int> vulkan_device;
|
||||
|
||||
Setting<u16> resolution_factor = Setting(static_cast<u16>(1));
|
||||
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;
|
||||
|
||||
Setting<float> bg_red;
|
||||
Setting<float> bg_green;
|
||||
Setting<float> bg_blue;
|
||||
|
||||
// System
|
||||
bool use_docked_mode;
|
||||
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;
|
||||
|
||||
s32 current_user;
|
||||
s32 language_index;
|
||||
s32 region_index;
|
||||
s32 time_zone_index;
|
||||
s32 sound_index;
|
||||
Setting<s32> language_index;
|
||||
Setting<s32> region_index;
|
||||
Setting<s32> time_zone_index;
|
||||
Setting<s32> sound_index;
|
||||
|
||||
// Controls
|
||||
std::array<PlayerInput, 10> players;
|
||||
@@ -419,8 +484,7 @@ struct Values {
|
||||
u16 udp_input_port;
|
||||
u8 udp_pad_index;
|
||||
|
||||
// Core
|
||||
bool use_multi_core;
|
||||
bool use_docked_mode;
|
||||
|
||||
// Data Storage
|
||||
bool use_virtual_sd;
|
||||
@@ -432,39 +496,6 @@ struct Values {
|
||||
NANDUserSize nand_user_size;
|
||||
SDMCSize sdmc_size;
|
||||
|
||||
// Renderer
|
||||
RendererBackend renderer_backend;
|
||||
bool renderer_debug;
|
||||
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;
|
||||
|
||||
float bg_red;
|
||||
float bg_green;
|
||||
float bg_blue;
|
||||
|
||||
std::string log_filter;
|
||||
|
||||
bool use_dev_keys;
|
||||
|
||||
// Audio
|
||||
bool audio_muted;
|
||||
std::string sink_id;
|
||||
bool enable_audio_stretching;
|
||||
std::string audio_device_id;
|
||||
float volume;
|
||||
|
||||
// Debugging
|
||||
bool record_frame_times;
|
||||
bool use_gdbstub;
|
||||
@@ -477,7 +508,11 @@ struct Values {
|
||||
bool disable_cpu_opt;
|
||||
bool disable_macro_jit;
|
||||
|
||||
// BCAT
|
||||
// Misceallaneous
|
||||
std::string log_filter;
|
||||
bool use_dev_keys;
|
||||
|
||||
// Services
|
||||
std::string bcat_backend;
|
||||
bool bcat_boxcat_local;
|
||||
|
||||
@@ -501,4 +536,7 @@ std::string GetTimeZoneString();
|
||||
void Apply();
|
||||
void LogSettings();
|
||||
|
||||
// Restore the global state of all applicable settings in the Values struct
|
||||
void RestoreGlobalState();
|
||||
|
||||
} // namespace Settings
|
||||
|
||||
@@ -189,19 +189,24 @@ 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_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::values.use_docked_mode);
|
||||
}
|
||||
|
||||
|
||||
@@ -96,7 +96,8 @@ public:
|
||||
}
|
||||
if (is_written) {
|
||||
map->MarkAsModified(true, GetModifiedTicks());
|
||||
if (Settings::IsGPULevelHigh() && Settings::values.use_asynchronous_gpu_emulation) {
|
||||
if (Settings::IsGPULevelHigh() &&
|
||||
Settings::values.use_asynchronous_gpu_emulation.GetValue()) {
|
||||
MarkForAsyncFlush(map);
|
||||
}
|
||||
if (!map->is_written) {
|
||||
@@ -369,7 +370,8 @@ private:
|
||||
}
|
||||
if (modified_inheritance) {
|
||||
map->MarkAsModified(true, GetModifiedTicks());
|
||||
if (Settings::IsGPULevelHigh() && Settings::values.use_asynchronous_gpu_emulation) {
|
||||
if (Settings::IsGPULevelHigh() &&
|
||||
Settings::values.use_asynchronous_gpu_emulation.GetValue()) {
|
||||
MarkForAsyncFlush(map);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -157,7 +157,7 @@ u64 GPU::GetTicks() const {
|
||||
constexpr u64 gpu_ticks_den = 625;
|
||||
|
||||
u64 nanoseconds = system.CoreTiming().GetGlobalTimeNs().count();
|
||||
if (Settings::values.use_fast_gpu_time) {
|
||||
if (Settings::values.use_fast_gpu_time.GetValue()) {
|
||||
nanoseconds /= 256;
|
||||
}
|
||||
const u64 nanoseconds_num = nanoseconds / gpu_ticks_den;
|
||||
|
||||
@@ -132,7 +132,7 @@ public:
|
||||
}
|
||||
|
||||
query->BindCounter(Stream(type).Current(), timestamp);
|
||||
if (Settings::values.use_asynchronous_gpu_emulation) {
|
||||
if (Settings::values.use_asynchronous_gpu_emulation.GetValue()) {
|
||||
AsyncFlushQuery(cpu_addr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ RendererBase::~RendererBase() = default;
|
||||
void RendererBase::RefreshBaseSettings() {
|
||||
UpdateCurrentFramebufferLayout();
|
||||
|
||||
renderer_settings.use_framelimiter = Settings::values.use_frame_limit;
|
||||
renderer_settings.use_framelimiter = Settings::values.use_frame_limit.GetValue();
|
||||
renderer_settings.set_background_color = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -229,15 +229,15 @@ Device::Device()
|
||||
// uniform buffers as "push constants"
|
||||
has_fast_buffer_sub_data = is_nvidia && !disable_fast_buffer_sub_data;
|
||||
|
||||
use_assembly_shaders = Settings::values.use_assembly_shaders && GLAD_GL_NV_gpu_program5 &&
|
||||
GLAD_GL_NV_compute_program5 && GLAD_GL_NV_transform_feedback &&
|
||||
GLAD_GL_NV_transform_feedback2;
|
||||
use_assembly_shaders = Settings::values.use_assembly_shaders.GetValue() &&
|
||||
GLAD_GL_NV_gpu_program5 && GLAD_GL_NV_compute_program5 &&
|
||||
GLAD_GL_NV_transform_feedback && GLAD_GL_NV_transform_feedback2;
|
||||
|
||||
LOG_INFO(Render_OpenGL, "Renderer_VariableAOFFI: {}", has_variable_aoffi);
|
||||
LOG_INFO(Render_OpenGL, "Renderer_ComponentIndexingBug: {}", has_component_indexing_bug);
|
||||
LOG_INFO(Render_OpenGL, "Renderer_PreciseBug: {}", has_precise_bug);
|
||||
|
||||
if (Settings::values.use_assembly_shaders && !use_assembly_shaders) {
|
||||
if (Settings::values.use_assembly_shaders.GetValue() && !use_assembly_shaders) {
|
||||
LOG_ERROR(Render_OpenGL, "Assembly shaders enabled but not supported");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -213,7 +213,7 @@ ShaderDiskCacheOpenGL::~ShaderDiskCacheOpenGL() = default;
|
||||
std::optional<std::vector<ShaderDiskCacheEntry>> ShaderDiskCacheOpenGL::LoadTransferable() {
|
||||
// Skip games without title id
|
||||
const bool has_title_id = system.CurrentProcess()->GetTitleID() != 0;
|
||||
if (!Settings::values.use_disk_shader_cache || !has_title_id) {
|
||||
if (!Settings::values.use_disk_shader_cache.GetValue() || !has_title_id) {
|
||||
return {};
|
||||
}
|
||||
|
||||
|
||||
@@ -455,8 +455,8 @@ void RendererOpenGL::LoadColorToActiveGLTexture(u8 color_r, u8 color_g, u8 color
|
||||
void RendererOpenGL::InitOpenGLObjects() {
|
||||
frame_mailbox = std::make_unique<FrameMailbox>();
|
||||
|
||||
glClearColor(Settings::values.bg_red, Settings::values.bg_green, Settings::values.bg_blue,
|
||||
0.0f);
|
||||
glClearColor(Settings::values.bg_red.GetValue(), Settings::values.bg_green.GetValue(),
|
||||
Settings::values.bg_blue.GetValue(), 0.0f);
|
||||
|
||||
// Create shader programs
|
||||
OGLShader vertex_shader;
|
||||
@@ -561,8 +561,8 @@ void RendererOpenGL::ConfigureFramebufferTexture(TextureInfo& texture,
|
||||
void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) {
|
||||
if (renderer_settings.set_background_color) {
|
||||
// Update background color before drawing
|
||||
glClearColor(Settings::values.bg_red, Settings::values.bg_green, Settings::values.bg_blue,
|
||||
0.0f);
|
||||
glClearColor(Settings::values.bg_red.GetValue(), Settings::values.bg_green.GetValue(),
|
||||
Settings::values.bg_blue.GetValue(), 0.0f);
|
||||
}
|
||||
|
||||
// Set projection matrix
|
||||
|
||||
@@ -409,7 +409,7 @@ bool RendererVulkan::PickDevices() {
|
||||
return false;
|
||||
}
|
||||
|
||||
const s32 device_index = Settings::values.vulkan_device;
|
||||
const s32 device_index = Settings::values.vulkan_device.GetValue();
|
||||
if (device_index < 0 || device_index >= static_cast<s32>(devices->size())) {
|
||||
LOG_ERROR(Render_Vulkan, "Invalid device index {}!", device_index);
|
||||
return false;
|
||||
|
||||
@@ -249,7 +249,7 @@ public:
|
||||
auto& surface = render_targets[index].target;
|
||||
surface->MarkAsRenderTarget(false, NO_RT);
|
||||
const auto& cr_params = surface->GetSurfaceParams();
|
||||
if (!cr_params.is_tiled && Settings::values.use_asynchronous_gpu_emulation) {
|
||||
if (!cr_params.is_tiled && Settings::values.use_asynchronous_gpu_emulation.GetValue()) {
|
||||
AsyncFlushSurface(surface);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ constexpr std::array<float, 256> SRGB_CONVERSION_LUT = {
|
||||
};
|
||||
|
||||
unsigned SettingsMinimumAnisotropy() noexcept {
|
||||
switch (static_cast<Anisotropy>(Settings::values.max_anisotropy)) {
|
||||
switch (static_cast<Anisotropy>(Settings::values.max_anisotropy.GetValue())) {
|
||||
default:
|
||||
case Anisotropy::Default:
|
||||
return 1U;
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace {
|
||||
std::unique_ptr<VideoCore::RendererBase> CreateRenderer(Core::Frontend::EmuWindow& emu_window,
|
||||
Core::System& system,
|
||||
Core::Frontend::GraphicsContext& context) {
|
||||
switch (Settings::values.renderer_backend) {
|
||||
switch (Settings::values.renderer_backend.GetValue()) {
|
||||
case Settings::RendererBackend::OpenGL:
|
||||
return std::make_unique<OpenGL::RendererOpenGL>(emu_window, system, context);
|
||||
#ifdef HAS_VULKAN
|
||||
@@ -42,7 +42,7 @@ std::unique_ptr<Tegra::GPU> CreateGPU(Core::Frontend::EmuWindow& emu_window, Cor
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (Settings::values.use_asynchronous_gpu_emulation) {
|
||||
if (Settings::values.use_asynchronous_gpu_emulation.GetValue()) {
|
||||
return std::make_unique<VideoCommon::GPUAsynch>(system, std::move(renderer),
|
||||
std::move(context));
|
||||
}
|
||||
@@ -51,8 +51,8 @@ std::unique_ptr<Tegra::GPU> CreateGPU(Core::Frontend::EmuWindow& emu_window, Cor
|
||||
|
||||
u16 GetResolutionScaleFactor(const RendererBase& renderer) {
|
||||
return static_cast<u16>(
|
||||
Settings::values.resolution_factor != 0
|
||||
? Settings::values.resolution_factor
|
||||
Settings::values.resolution_factor.GetValue() != 0
|
||||
? Settings::values.resolution_factor.GetValue()
|
||||
: renderer.GetRenderWindow().GetFramebufferLayout().GetScalingRatio());
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,8 @@ add_executable(yuzu
|
||||
compatibility_list.h
|
||||
configuration/config.cpp
|
||||
configuration/config.h
|
||||
configuration/configuration_shared.cpp
|
||||
configuration/configuration_shared.h
|
||||
configuration/configure.ui
|
||||
configuration/configure_audio.cpp
|
||||
configuration/configure_audio.h
|
||||
@@ -60,9 +62,12 @@ add_executable(yuzu
|
||||
configuration/configure_mouse_advanced.cpp
|
||||
configuration/configure_mouse_advanced.h
|
||||
configuration/configure_mouse_advanced.ui
|
||||
configuration/configure_per_general.cpp
|
||||
configuration/configure_per_general.h
|
||||
configuration/configure_per_general.ui
|
||||
configuration/configure_per_game.cpp
|
||||
configuration/configure_per_game.h
|
||||
configuration/configure_per_game.ui
|
||||
configuration/configure_per_game_addons.cpp
|
||||
configuration/configure_per_game_addons.h
|
||||
configuration/configure_per_game_addons.ui
|
||||
configuration/configure_profile_manager.cpp
|
||||
configuration/configure_profile_manager.h
|
||||
configuration/configure_profile_manager.ui
|
||||
|
||||
@@ -145,7 +145,7 @@ public:
|
||||
|
||||
// disable vsync for any shared contexts
|
||||
auto format = share_context->format();
|
||||
format.setSwapInterval(main_surface ? Settings::values.use_vsync : 0);
|
||||
format.setSwapInterval(main_surface ? Settings::values.use_vsync.GetValue() : 0);
|
||||
|
||||
context = std::make_unique<QOpenGLContext>();
|
||||
context->setShareContext(share_context);
|
||||
@@ -495,7 +495,7 @@ void GRenderWindow::resizeEvent(QResizeEvent* event) {
|
||||
|
||||
std::unique_ptr<Core::Frontend::GraphicsContext> GRenderWindow::CreateSharedContext() const {
|
||||
#ifdef HAS_OPENGL
|
||||
if (Settings::values.renderer_backend == Settings::RendererBackend::OpenGL) {
|
||||
if (Settings::values.renderer_backend.GetValue() == Settings::RendererBackend::OpenGL) {
|
||||
auto c = static_cast<OpenGLSharedContext*>(main_context.get());
|
||||
// Bind the shared contexts to the main surface in case the backend wants to take over
|
||||
// presentation
|
||||
@@ -511,7 +511,7 @@ bool GRenderWindow::InitRenderTarget() {
|
||||
|
||||
first_frame = false;
|
||||
|
||||
switch (Settings::values.renderer_backend) {
|
||||
switch (Settings::values.renderer_backend.GetValue()) {
|
||||
case Settings::RendererBackend::OpenGL:
|
||||
if (!InitializeOpenGL()) {
|
||||
return false;
|
||||
@@ -538,7 +538,7 @@ bool GRenderWindow::InitRenderTarget() {
|
||||
OnFramebufferSizeChanged();
|
||||
BackupGeometry();
|
||||
|
||||
if (Settings::values.renderer_backend == Settings::RendererBackend::OpenGL) {
|
||||
if (Settings::values.renderer_backend.GetValue() == Settings::RendererBackend::OpenGL) {
|
||||
if (!LoadOpenGL()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -13,17 +13,20 @@
|
||||
#include "input_common/udp/client.h"
|
||||
#include "yuzu/configuration/config.h"
|
||||
|
||||
Config::Config() {
|
||||
Config::Config(const std::string& config_file, bool is_global) {
|
||||
// TODO: Don't hardcode the path; let the frontend decide where to put the config files.
|
||||
qt_config_loc = FileUtil::GetUserPath(FileUtil::UserPath::ConfigDir) + "qt-config.ini";
|
||||
qt_config_loc = FileUtil::GetUserPath(FileUtil::UserPath::ConfigDir) + config_file;
|
||||
FileUtil::CreateFullPath(qt_config_loc);
|
||||
qt_config =
|
||||
std::make_unique<QSettings>(QString::fromStdString(qt_config_loc), QSettings::IniFormat);
|
||||
global = is_global;
|
||||
Reload();
|
||||
}
|
||||
|
||||
Config::~Config() {
|
||||
Save();
|
||||
if (global) {
|
||||
Save();
|
||||
}
|
||||
}
|
||||
|
||||
const std::array<int, Settings::NativeButton::NumButtons> Config::default_buttons = {
|
||||
@@ -402,16 +405,19 @@ void Config::ApplyDefaultProfileIfInputInvalid() {
|
||||
void Config::ReadAudioValues() {
|
||||
qt_config->beginGroup(QStringLiteral("Audio"));
|
||||
|
||||
Settings::values.sink_id = ReadSetting(QStringLiteral("output_engine"), QStringLiteral("auto"))
|
||||
.toString()
|
||||
.toStdString();
|
||||
Settings::values.enable_audio_stretching =
|
||||
ReadSetting(QStringLiteral("enable_audio_stretching"), true).toBool();
|
||||
Settings::values.audio_device_id =
|
||||
ReadSetting(QStringLiteral("output_device"), QStringLiteral("auto"))
|
||||
.toString()
|
||||
.toStdString();
|
||||
Settings::values.volume = ReadSetting(QStringLiteral("volume"), 1).toFloat();
|
||||
if (global) {
|
||||
Settings::values.sink_id =
|
||||
ReadSetting(QStringLiteral("output_engine"), QStringLiteral("auto"))
|
||||
.toString()
|
||||
.toStdString();
|
||||
Settings::values.audio_device_id =
|
||||
ReadSetting(QStringLiteral("output_device"), QStringLiteral("auto"))
|
||||
.toString()
|
||||
.toStdString();
|
||||
}
|
||||
ReadSettingGlobal(Settings::values.enable_audio_stretching,
|
||||
QStringLiteral("enable_audio_stretching"), true);
|
||||
ReadSettingGlobal(Settings::values.volume, QStringLiteral("volume"), 1);
|
||||
|
||||
qt_config->endGroup();
|
||||
}
|
||||
@@ -440,6 +446,8 @@ void Config::ReadControlValues() {
|
||||
.toInt());
|
||||
Settings::values.udp_pad_index =
|
||||
static_cast<u8>(ReadSetting(QStringLiteral("udp_pad_index"), 0).toUInt());
|
||||
Settings::values.use_docked_mode =
|
||||
ReadSetting(QStringLiteral("use_docked_mode"), false).toBool();
|
||||
|
||||
qt_config->endGroup();
|
||||
}
|
||||
@@ -447,7 +455,7 @@ void Config::ReadControlValues() {
|
||||
void Config::ReadCoreValues() {
|
||||
qt_config->beginGroup(QStringLiteral("Core"));
|
||||
|
||||
Settings::values.use_multi_core = ReadSetting(QStringLiteral("use_multi_core"), false).toBool();
|
||||
ReadSettingGlobal(Settings::values.use_multi_core, QStringLiteral("use_multi_core"), false);
|
||||
|
||||
qt_config->endGroup();
|
||||
}
|
||||
@@ -628,32 +636,28 @@ void Config::ReadPathValues() {
|
||||
void Config::ReadRendererValues() {
|
||||
qt_config->beginGroup(QStringLiteral("Renderer"));
|
||||
|
||||
Settings::values.renderer_backend =
|
||||
static_cast<Settings::RendererBackend>(ReadSetting(QStringLiteral("backend"), 0).toInt());
|
||||
Settings::values.renderer_debug = ReadSetting(QStringLiteral("debug"), false).toBool();
|
||||
Settings::values.vulkan_device = ReadSetting(QStringLiteral("vulkan_device"), 0).toInt();
|
||||
Settings::values.aspect_ratio = ReadSetting(QStringLiteral("aspect_ratio"), 0).toInt();
|
||||
Settings::values.max_anisotropy = ReadSetting(QStringLiteral("max_anisotropy"), 0).toInt();
|
||||
Settings::values.use_frame_limit =
|
||||
ReadSetting(QStringLiteral("use_frame_limit"), true).toBool();
|
||||
Settings::values.frame_limit = ReadSetting(QStringLiteral("frame_limit"), 100).toUInt();
|
||||
Settings::values.use_disk_shader_cache =
|
||||
ReadSetting(QStringLiteral("use_disk_shader_cache"), true).toBool();
|
||||
const int gpu_accuracy_level = ReadSetting(QStringLiteral("gpu_accuracy"), 0).toInt();
|
||||
Settings::values.gpu_accuracy = static_cast<Settings::GPUAccuracy>(gpu_accuracy_level);
|
||||
Settings::values.use_asynchronous_gpu_emulation =
|
||||
ReadSetting(QStringLiteral("use_asynchronous_gpu_emulation"), false).toBool();
|
||||
Settings::values.use_vsync = ReadSetting(QStringLiteral("use_vsync"), true).toBool();
|
||||
Settings::values.use_assembly_shaders =
|
||||
ReadSetting(QStringLiteral("use_assembly_shaders"), false).toBool();
|
||||
Settings::values.use_fast_gpu_time =
|
||||
ReadSetting(QStringLiteral("use_fast_gpu_time"), true).toBool();
|
||||
Settings::values.force_30fps_mode =
|
||||
ReadSetting(QStringLiteral("force_30fps_mode"), false).toBool();
|
||||
ReadSettingGlobal(Settings::values.renderer_backend, QStringLiteral("backend"), 0);
|
||||
ReadSettingGlobal(Settings::values.renderer_debug, QStringLiteral("debug"), false);
|
||||
ReadSettingGlobal(Settings::values.vulkan_device, QStringLiteral("vulkan_device"), 0);
|
||||
ReadSettingGlobal(Settings::values.aspect_ratio, QStringLiteral("aspect_ratio"), 0);
|
||||
ReadSettingGlobal(Settings::values.max_anisotropy, QStringLiteral("max_anisotropy"), 0);
|
||||
ReadSettingGlobal(Settings::values.use_frame_limit, QStringLiteral("use_frame_limit"), true);
|
||||
ReadSettingGlobal(Settings::values.frame_limit, QStringLiteral("frame_limit"), 100);
|
||||
ReadSettingGlobal(Settings::values.use_disk_shader_cache,
|
||||
QStringLiteral("use_disk_shader_cache"), true);
|
||||
ReadSettingGlobal(Settings::values.gpu_accuracy, QStringLiteral("gpu_accuracy"), 0);
|
||||
ReadSettingGlobal(Settings::values.use_asynchronous_gpu_emulation,
|
||||
QStringLiteral("use_asynchronous_gpu_emulation"), false);
|
||||
ReadSettingGlobal(Settings::values.use_vsync, QStringLiteral("use_vsync"), true);
|
||||
ReadSettingGlobal(Settings::values.use_assembly_shaders, QStringLiteral("use_assembly_shaders"),
|
||||
false);
|
||||
ReadSettingGlobal(Settings::values.use_fast_gpu_time, QStringLiteral("use_fast_gpu_time"),
|
||||
true);
|
||||
ReadSettingGlobal(Settings::values.force_30fps_mode, QStringLiteral("force_30fps_mode"), false);
|
||||
|
||||
Settings::values.bg_red = ReadSetting(QStringLiteral("bg_red"), 0.0).toFloat();
|
||||
Settings::values.bg_green = ReadSetting(QStringLiteral("bg_green"), 0.0).toFloat();
|
||||
Settings::values.bg_blue = ReadSetting(QStringLiteral("bg_blue"), 0.0).toFloat();
|
||||
ReadSettingGlobal(Settings::values.bg_red, QStringLiteral("bg_red"), 0.0);
|
||||
ReadSettingGlobal(Settings::values.bg_green, QStringLiteral("bg_green"), 0.0);
|
||||
ReadSettingGlobal(Settings::values.bg_blue, QStringLiteral("bg_blue"), 0.0);
|
||||
|
||||
qt_config->endGroup();
|
||||
}
|
||||
@@ -682,35 +686,45 @@ void Config::ReadShortcutValues() {
|
||||
void Config::ReadSystemValues() {
|
||||
qt_config->beginGroup(QStringLiteral("System"));
|
||||
|
||||
Settings::values.use_docked_mode =
|
||||
ReadSetting(QStringLiteral("use_docked_mode"), false).toBool();
|
||||
ReadSettingGlobal(Settings::values.current_user, QStringLiteral("current_user"), 0);
|
||||
Settings::values.current_user =
|
||||
std::clamp<int>(Settings::values.current_user, 0, Service::Account::MAX_USERS - 1);
|
||||
|
||||
Settings::values.current_user = std::clamp<int>(
|
||||
ReadSetting(QStringLiteral("current_user"), 0).toInt(), 0, Service::Account::MAX_USERS - 1);
|
||||
ReadSettingGlobal(Settings::values.language_index, QStringLiteral("language_index"), 1);
|
||||
|
||||
Settings::values.language_index = ReadSetting(QStringLiteral("language_index"), 1).toInt();
|
||||
ReadSettingGlobal(Settings::values.region_index, QStringLiteral("region_index"), 1);
|
||||
|
||||
Settings::values.region_index = ReadSetting(QStringLiteral("region_index"), 1).toInt();
|
||||
ReadSettingGlobal(Settings::values.time_zone_index, QStringLiteral("time_zone_index"), 0);
|
||||
|
||||
Settings::values.time_zone_index = ReadSetting(QStringLiteral("time_zone_index"), 0).toInt();
|
||||
|
||||
const auto rng_seed_enabled = ReadSetting(QStringLiteral("rng_seed_enabled"), false).toBool();
|
||||
if (rng_seed_enabled) {
|
||||
Settings::values.rng_seed = ReadSetting(QStringLiteral("rng_seed"), 0).toULongLong();
|
||||
} else {
|
||||
Settings::values.rng_seed = std::nullopt;
|
||||
bool rng_seed_enabled;
|
||||
ReadSettingGlobal(rng_seed_enabled, QStringLiteral("rng_seed_enabled"), false);
|
||||
bool rng_seed_global =
|
||||
global || qt_config->value(QStringLiteral("rng_seed/use_global"), true).toBool();
|
||||
Settings::values.rng_seed.SetGlobal(rng_seed_global);
|
||||
if (global || !rng_seed_global) {
|
||||
if (rng_seed_enabled) {
|
||||
Settings::values.rng_seed.SetValue(
|
||||
ReadSetting(QStringLiteral("rng_seed"), 0).toULongLong());
|
||||
} else {
|
||||
Settings::values.rng_seed.SetValue(std::nullopt);
|
||||
}
|
||||
}
|
||||
|
||||
const auto custom_rtc_enabled =
|
||||
ReadSetting(QStringLiteral("custom_rtc_enabled"), false).toBool();
|
||||
if (custom_rtc_enabled) {
|
||||
Settings::values.custom_rtc =
|
||||
std::chrono::seconds(ReadSetting(QStringLiteral("custom_rtc"), 0).toULongLong());
|
||||
} else {
|
||||
Settings::values.custom_rtc = std::nullopt;
|
||||
bool custom_rtc_enabled;
|
||||
ReadSettingGlobal(custom_rtc_enabled, QStringLiteral("custom_rtc_enabled"), false);
|
||||
bool custom_rtc_global =
|
||||
global || qt_config->value(QStringLiteral("custom_rtc/use_global"), true).toBool();
|
||||
Settings::values.custom_rtc.SetGlobal(custom_rtc_global);
|
||||
if (global || !custom_rtc_global) {
|
||||
if (custom_rtc_enabled) {
|
||||
Settings::values.custom_rtc.SetValue(
|
||||
std::chrono::seconds(ReadSetting(QStringLiteral("custom_rtc"), 0).toULongLong()));
|
||||
} else {
|
||||
Settings::values.custom_rtc.SetValue(std::nullopt);
|
||||
}
|
||||
}
|
||||
|
||||
Settings::values.sound_index = ReadSetting(QStringLiteral("sound_index"), 1).toInt();
|
||||
ReadSettingGlobal(Settings::values.sound_index, QStringLiteral("sound_index"), 1);
|
||||
|
||||
qt_config->endGroup();
|
||||
}
|
||||
@@ -804,18 +818,20 @@ void Config::ReadWebServiceValues() {
|
||||
}
|
||||
|
||||
void Config::ReadValues() {
|
||||
ReadControlValues();
|
||||
if (global) {
|
||||
ReadControlValues();
|
||||
ReadDataStorageValues();
|
||||
ReadDebuggingValues();
|
||||
ReadDisabledAddOnValues();
|
||||
ReadServiceValues();
|
||||
ReadUIValues();
|
||||
ReadWebServiceValues();
|
||||
ReadMiscellaneousValues();
|
||||
}
|
||||
ReadCoreValues();
|
||||
ReadRendererValues();
|
||||
ReadAudioValues();
|
||||
ReadDataStorageValues();
|
||||
ReadSystemValues();
|
||||
ReadMiscellaneousValues();
|
||||
ReadDebuggingValues();
|
||||
ReadWebServiceValues();
|
||||
ReadServiceValues();
|
||||
ReadDisabledAddOnValues();
|
||||
ReadUIValues();
|
||||
}
|
||||
|
||||
void Config::SavePlayerValues() {
|
||||
@@ -902,30 +918,35 @@ void Config::SaveTouchscreenValues() {
|
||||
}
|
||||
|
||||
void Config::SaveValues() {
|
||||
SaveControlValues();
|
||||
if (global) {
|
||||
SaveControlValues();
|
||||
SaveDataStorageValues();
|
||||
SaveDebuggingValues();
|
||||
SaveDisabledAddOnValues();
|
||||
SaveServiceValues();
|
||||
SaveUIValues();
|
||||
SaveWebServiceValues();
|
||||
SaveMiscellaneousValues();
|
||||
}
|
||||
SaveCoreValues();
|
||||
SaveRendererValues();
|
||||
SaveAudioValues();
|
||||
SaveDataStorageValues();
|
||||
SaveSystemValues();
|
||||
SaveMiscellaneousValues();
|
||||
SaveDebuggingValues();
|
||||
SaveWebServiceValues();
|
||||
SaveServiceValues();
|
||||
SaveDisabledAddOnValues();
|
||||
SaveUIValues();
|
||||
}
|
||||
|
||||
void Config::SaveAudioValues() {
|
||||
qt_config->beginGroup(QStringLiteral("Audio"));
|
||||
|
||||
WriteSetting(QStringLiteral("output_engine"), QString::fromStdString(Settings::values.sink_id),
|
||||
QStringLiteral("auto"));
|
||||
WriteSetting(QStringLiteral("enable_audio_stretching"),
|
||||
Settings::values.enable_audio_stretching, true);
|
||||
WriteSetting(QStringLiteral("output_device"),
|
||||
QString::fromStdString(Settings::values.audio_device_id), QStringLiteral("auto"));
|
||||
WriteSetting(QStringLiteral("volume"), Settings::values.volume, 1.0f);
|
||||
if (global) {
|
||||
WriteSetting(QStringLiteral("output_engine"),
|
||||
QString::fromStdString(Settings::values.sink_id), QStringLiteral("auto"));
|
||||
WriteSetting(QStringLiteral("output_device"),
|
||||
QString::fromStdString(Settings::values.audio_device_id),
|
||||
QStringLiteral("auto"));
|
||||
}
|
||||
WriteSettingGlobal(QStringLiteral("enable_audio_stretching"),
|
||||
Settings::values.enable_audio_stretching, true);
|
||||
WriteSettingGlobal(QStringLiteral("volume"), Settings::values.volume, 1.0f);
|
||||
|
||||
qt_config->endGroup();
|
||||
}
|
||||
@@ -948,6 +969,7 @@ void Config::SaveControlValues() {
|
||||
WriteSetting(QStringLiteral("udp_input_port"), Settings::values.udp_input_port,
|
||||
InputCommon::CemuhookUDP::DEFAULT_PORT);
|
||||
WriteSetting(QStringLiteral("udp_pad_index"), Settings::values.udp_pad_index, 0);
|
||||
WriteSetting(QStringLiteral("use_docked_mode"), Settings::values.use_docked_mode, false);
|
||||
|
||||
qt_config->endGroup();
|
||||
}
|
||||
@@ -955,7 +977,7 @@ void Config::SaveControlValues() {
|
||||
void Config::SaveCoreValues() {
|
||||
qt_config->beginGroup(QStringLiteral("Core"));
|
||||
|
||||
WriteSetting(QStringLiteral("use_multi_core"), Settings::values.use_multi_core, false);
|
||||
WriteSettingGlobal(QStringLiteral("use_multi_core"), Settings::values.use_multi_core, false);
|
||||
|
||||
qt_config->endGroup();
|
||||
}
|
||||
@@ -1078,29 +1100,34 @@ void Config::SavePathValues() {
|
||||
void Config::SaveRendererValues() {
|
||||
qt_config->beginGroup(QStringLiteral("Renderer"));
|
||||
|
||||
WriteSetting(QStringLiteral("backend"), static_cast<int>(Settings::values.renderer_backend), 0);
|
||||
WriteSettingGlobal(QStringLiteral("backend"),
|
||||
static_cast<int>(Settings::values.renderer_backend.GetValue(global)),
|
||||
Settings::values.renderer_backend.UsingGlobal(), 0);
|
||||
WriteSetting(QStringLiteral("debug"), Settings::values.renderer_debug, false);
|
||||
WriteSetting(QStringLiteral("vulkan_device"), Settings::values.vulkan_device, 0);
|
||||
WriteSetting(QStringLiteral("aspect_ratio"), Settings::values.aspect_ratio, 0);
|
||||
WriteSetting(QStringLiteral("max_anisotropy"), Settings::values.max_anisotropy, 0);
|
||||
WriteSetting(QStringLiteral("use_frame_limit"), Settings::values.use_frame_limit, true);
|
||||
WriteSetting(QStringLiteral("frame_limit"), Settings::values.frame_limit, 100);
|
||||
WriteSetting(QStringLiteral("use_disk_shader_cache"), Settings::values.use_disk_shader_cache,
|
||||
true);
|
||||
WriteSetting(QStringLiteral("gpu_accuracy"), static_cast<int>(Settings::values.gpu_accuracy),
|
||||
0);
|
||||
WriteSetting(QStringLiteral("use_asynchronous_gpu_emulation"),
|
||||
Settings::values.use_asynchronous_gpu_emulation, false);
|
||||
WriteSetting(QStringLiteral("use_vsync"), Settings::values.use_vsync, true);
|
||||
WriteSetting(QStringLiteral("use_assembly_shaders"), Settings::values.use_assembly_shaders,
|
||||
false);
|
||||
WriteSetting(QStringLiteral("use_fast_gpu_time"), Settings::values.use_fast_gpu_time, true);
|
||||
WriteSetting(QStringLiteral("force_30fps_mode"), Settings::values.force_30fps_mode, false);
|
||||
WriteSettingGlobal(QStringLiteral("vulkan_device"), Settings::values.vulkan_device, 0);
|
||||
WriteSettingGlobal(QStringLiteral("aspect_ratio"), Settings::values.aspect_ratio, 0);
|
||||
WriteSettingGlobal(QStringLiteral("max_anisotropy"), Settings::values.max_anisotropy, 0);
|
||||
WriteSettingGlobal(QStringLiteral("use_frame_limit"), Settings::values.use_frame_limit, true);
|
||||
WriteSettingGlobal(QStringLiteral("frame_limit"), Settings::values.frame_limit, 100);
|
||||
WriteSettingGlobal(QStringLiteral("use_disk_shader_cache"),
|
||||
Settings::values.use_disk_shader_cache, true);
|
||||
WriteSettingGlobal(QStringLiteral("gpu_accuracy"),
|
||||
static_cast<int>(Settings::values.gpu_accuracy.GetValue(global)),
|
||||
Settings::values.gpu_accuracy.UsingGlobal(), 0);
|
||||
WriteSettingGlobal(QStringLiteral("use_asynchronous_gpu_emulation"),
|
||||
Settings::values.use_asynchronous_gpu_emulation, false);
|
||||
WriteSettingGlobal(QStringLiteral("use_vsync"), Settings::values.use_vsync, true);
|
||||
WriteSettingGlobal(QStringLiteral("use_assembly_shaders"),
|
||||
Settings::values.use_assembly_shaders, false);
|
||||
WriteSettingGlobal(QStringLiteral("use_fast_gpu_time"), Settings::values.use_fast_gpu_time,
|
||||
true);
|
||||
WriteSettingGlobal(QStringLiteral("force_30fps_mode"), Settings::values.force_30fps_mode,
|
||||
false);
|
||||
|
||||
// Cast to double because Qt's written float values are not human-readable
|
||||
WriteSetting(QStringLiteral("bg_red"), static_cast<double>(Settings::values.bg_red), 0.0);
|
||||
WriteSetting(QStringLiteral("bg_green"), static_cast<double>(Settings::values.bg_green), 0.0);
|
||||
WriteSetting(QStringLiteral("bg_blue"), static_cast<double>(Settings::values.bg_blue), 0.0);
|
||||
WriteSettingGlobal(QStringLiteral("bg_red"), Settings::values.bg_red, 0.0);
|
||||
WriteSettingGlobal(QStringLiteral("bg_green"), Settings::values.bg_green, 0.0);
|
||||
WriteSettingGlobal(QStringLiteral("bg_blue"), Settings::values.bg_blue, 0.0);
|
||||
|
||||
qt_config->endGroup();
|
||||
}
|
||||
@@ -1128,23 +1155,28 @@ void Config::SaveShortcutValues() {
|
||||
void Config::SaveSystemValues() {
|
||||
qt_config->beginGroup(QStringLiteral("System"));
|
||||
|
||||
WriteSetting(QStringLiteral("use_docked_mode"), Settings::values.use_docked_mode, false);
|
||||
WriteSetting(QStringLiteral("current_user"), Settings::values.current_user, 0);
|
||||
WriteSetting(QStringLiteral("language_index"), Settings::values.language_index, 1);
|
||||
WriteSetting(QStringLiteral("region_index"), Settings::values.region_index, 1);
|
||||
WriteSetting(QStringLiteral("time_zone_index"), Settings::values.time_zone_index, 0);
|
||||
WriteSettingGlobal(QStringLiteral("language_index"), Settings::values.language_index, 1);
|
||||
WriteSettingGlobal(QStringLiteral("region_index"), Settings::values.region_index, 1);
|
||||
WriteSettingGlobal(QStringLiteral("time_zone_index"), Settings::values.time_zone_index, 0);
|
||||
|
||||
WriteSetting(QStringLiteral("rng_seed_enabled"), Settings::values.rng_seed.has_value(), false);
|
||||
WriteSetting(QStringLiteral("rng_seed"), Settings::values.rng_seed.value_or(0), 0);
|
||||
WriteSettingGlobal(QStringLiteral("rng_seed_enabled"),
|
||||
Settings::values.rng_seed.GetValue(global).has_value(),
|
||||
Settings::values.rng_seed.UsingGlobal(), false);
|
||||
WriteSettingGlobal(QStringLiteral("rng_seed"),
|
||||
Settings::values.rng_seed.GetValue(global).value_or(0),
|
||||
Settings::values.rng_seed.UsingGlobal(), 0);
|
||||
|
||||
WriteSetting(QStringLiteral("custom_rtc_enabled"), Settings::values.custom_rtc.has_value(),
|
||||
false);
|
||||
WriteSetting(QStringLiteral("custom_rtc"),
|
||||
QVariant::fromValue<long long>(
|
||||
Settings::values.custom_rtc.value_or(std::chrono::seconds{}).count()),
|
||||
0);
|
||||
WriteSettingGlobal(QStringLiteral("custom_rtc_enabled"),
|
||||
Settings::values.custom_rtc.GetValue(global).has_value(),
|
||||
Settings::values.custom_rtc.UsingGlobal(), false);
|
||||
WriteSettingGlobal(
|
||||
QStringLiteral("custom_rtc"),
|
||||
QVariant::fromValue<long long>(
|
||||
Settings::values.custom_rtc.GetValue(global).value_or(std::chrono::seconds{}).count()),
|
||||
Settings::values.custom_rtc.UsingGlobal(), 0);
|
||||
|
||||
WriteSetting(QStringLiteral("sound_index"), Settings::values.sound_index, 1);
|
||||
WriteSettingGlobal(QStringLiteral("sound_index"), Settings::values.sound_index, 1);
|
||||
|
||||
qt_config->endGroup();
|
||||
}
|
||||
@@ -1236,6 +1268,34 @@ QVariant Config::ReadSetting(const QString& name, const QVariant& default_value)
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
void Config::ReadSettingGlobal(Settings::Setting<Type>& setting, const QString& name) {
|
||||
const bool use_global = qt_config->value(name + QStringLiteral("/use_global"), true).toBool();
|
||||
setting.SetGlobal(use_global);
|
||||
if (global || !use_global) {
|
||||
setting.SetValue(ReadSetting(name).value<Type>());
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
void Config::ReadSettingGlobal(Settings::Setting<Type>& setting, const QString& name,
|
||||
const QVariant& default_value) {
|
||||
const bool use_global = qt_config->value(name + QStringLiteral("/use_global"), true).toBool();
|
||||
setting.SetGlobal(use_global);
|
||||
if (global || !use_global) {
|
||||
setting.SetValue(ReadSetting(name, default_value).value<Type>());
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
void Config::ReadSettingGlobal(Type& setting, const QString& name,
|
||||
const QVariant& default_value) const {
|
||||
const bool use_global = qt_config->value(name + QStringLiteral("/use_global"), true).toBool();
|
||||
if (global || !use_global) {
|
||||
setting = ReadSetting(name, default_value).value<Type>();
|
||||
}
|
||||
}
|
||||
|
||||
void Config::WriteSetting(const QString& name, const QVariant& value) {
|
||||
qt_config->setValue(name, value);
|
||||
}
|
||||
@@ -1246,6 +1306,40 @@ void Config::WriteSetting(const QString& name, const QVariant& value,
|
||||
qt_config->setValue(name, value);
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
void Config::WriteSettingGlobal(const QString& name, const Settings::Setting<Type>& setting) {
|
||||
if (!global) {
|
||||
qt_config->setValue(name + QStringLiteral("/use_global"), setting.UsingGlobal());
|
||||
}
|
||||
if (global || !setting.UsingGlobal()) {
|
||||
qt_config->setValue(name, setting.GetValue(global));
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
void Config::WriteSettingGlobal(const QString& name, const Settings::Setting<Type>& setting,
|
||||
const QVariant& default_value) {
|
||||
if (!global) {
|
||||
qt_config->setValue(name + QStringLiteral("/use_global"), setting.UsingGlobal());
|
||||
}
|
||||
if (global || !setting.UsingGlobal()) {
|
||||
qt_config->setValue(name + QStringLiteral("/default"),
|
||||
setting.GetValue(global) == default_value.value<Type>());
|
||||
qt_config->setValue(name, setting.GetValue(global));
|
||||
}
|
||||
}
|
||||
|
||||
void Config::WriteSettingGlobal(const QString& name, const QVariant& value, bool use_global,
|
||||
const QVariant& default_value) {
|
||||
if (!global) {
|
||||
qt_config->setValue(name + QStringLiteral("/use_global"), use_global);
|
||||
}
|
||||
if (global || !use_global) {
|
||||
qt_config->setValue(name + QStringLiteral("/default"), value == default_value);
|
||||
qt_config->setValue(name, value);
|
||||
}
|
||||
}
|
||||
|
||||
void Config::Reload() {
|
||||
ReadValues();
|
||||
// To apply default value changes
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <array>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <QMetaType>
|
||||
#include <QVariant>
|
||||
#include "core/settings.h"
|
||||
#include "yuzu/uisettings.h"
|
||||
@@ -15,7 +16,7 @@ class QSettings;
|
||||
|
||||
class Config {
|
||||
public:
|
||||
Config();
|
||||
explicit Config(const std::string& config_loc = "qt-config.ini", bool is_global = true);
|
||||
~Config();
|
||||
|
||||
void Reload();
|
||||
@@ -82,9 +83,33 @@ private:
|
||||
|
||||
QVariant ReadSetting(const QString& name) const;
|
||||
QVariant ReadSetting(const QString& name, const QVariant& default_value) const;
|
||||
// Templated ReadSettingGlobal functions will also look for the use_global setting and set
|
||||
// both the value and the global state properly
|
||||
template <typename Type>
|
||||
void ReadSettingGlobal(Settings::Setting<Type>& setting, const QString& name);
|
||||
template <typename Type>
|
||||
void ReadSettingGlobal(Settings::Setting<Type>& setting, const QString& name,
|
||||
const QVariant& default_value);
|
||||
template <typename Type>
|
||||
void ReadSettingGlobal(Type& setting, const QString& name, const QVariant& default_value) const;
|
||||
// Templated WriteSettingGlobal functions will also write the global state if needed and will
|
||||
// skip writing the actual setting if it defers to the global value
|
||||
void WriteSetting(const QString& name, const QVariant& value);
|
||||
void WriteSetting(const QString& name, const QVariant& value, const QVariant& default_value);
|
||||
template <typename Type>
|
||||
void WriteSettingGlobal(const QString& name, const Settings::Setting<Type>& setting);
|
||||
template <typename Type>
|
||||
void WriteSettingGlobal(const QString& name, const Settings::Setting<Type>& setting,
|
||||
const QVariant& default_value);
|
||||
void WriteSettingGlobal(const QString& name, const QVariant& value, bool use_global,
|
||||
const QVariant& default_value);
|
||||
|
||||
std::unique_ptr<QSettings> qt_config;
|
||||
std::string qt_config_loc;
|
||||
|
||||
bool global;
|
||||
};
|
||||
|
||||
// These metatype declarations cannot be in core/settings.h because core is devoid of QT
|
||||
Q_DECLARE_METATYPE(Settings::RendererBackend);
|
||||
Q_DECLARE_METATYPE(Settings::GPUAccuracy);
|
||||
|
||||
76
src/yuzu/configuration/configuration_shared.cpp
Normal file
76
src/yuzu/configuration/configuration_shared.cpp
Normal file
@@ -0,0 +1,76 @@
|
||||
// Copyright 2016 Citra Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QComboBox>
|
||||
#include "core/settings.h"
|
||||
#include "yuzu/configuration/configuration_shared.h"
|
||||
#include "yuzu/configuration/configure_per_game.h"
|
||||
|
||||
void ConfigurationShared::ApplyPerGameSetting(Settings::Setting<bool>* setting,
|
||||
const QCheckBox* checkbox) {
|
||||
if (checkbox->checkState() == Qt::PartiallyChecked) {
|
||||
setting->SetGlobal(true);
|
||||
} else {
|
||||
setting->SetGlobal(false);
|
||||
setting->SetValue(checkbox->checkState() == Qt::Checked);
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigurationShared::ApplyPerGameSetting(Settings::Setting<int>* setting,
|
||||
const QComboBox* combobox) {
|
||||
if (combobox->currentIndex() == ConfigurationShared::USE_GLOBAL_INDEX) {
|
||||
setting->SetGlobal(true);
|
||||
} else {
|
||||
setting->SetGlobal(false);
|
||||
setting->SetValue(combobox->currentIndex() - ConfigurationShared::USE_GLOBAL_OFFSET);
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigurationShared::ApplyPerGameSetting(Settings::Setting<Settings::RendererBackend>* setting,
|
||||
const QComboBox* combobox) {
|
||||
if (combobox->currentIndex() == ConfigurationShared::USE_GLOBAL_INDEX) {
|
||||
setting->SetGlobal(true);
|
||||
} else {
|
||||
setting->SetGlobal(false);
|
||||
setting->SetValue(static_cast<Settings::RendererBackend>(
|
||||
combobox->currentIndex() - ConfigurationShared::USE_GLOBAL_OFFSET));
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigurationShared::SetPerGameSetting(QCheckBox* checkbox,
|
||||
const Settings::Setting<bool>* setting) {
|
||||
if (setting->UsingGlobal()) {
|
||||
checkbox->setCheckState(Qt::PartiallyChecked);
|
||||
} else {
|
||||
checkbox->setCheckState(setting->GetValue() ? Qt::Checked : Qt::Unchecked);
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigurationShared::SetPerGameSetting(QComboBox* combobox,
|
||||
const Settings::Setting<int>* setting) {
|
||||
combobox->setCurrentIndex(setting->UsingGlobal()
|
||||
? ConfigurationShared::USE_GLOBAL_INDEX
|
||||
: setting->GetValue() + ConfigurationShared::USE_GLOBAL_OFFSET);
|
||||
}
|
||||
|
||||
void ConfigurationShared::SetPerGameSetting(
|
||||
QComboBox* combobox, const Settings::Setting<Settings::RendererBackend>* setting) {
|
||||
combobox->setCurrentIndex(setting->UsingGlobal() ? ConfigurationShared::USE_GLOBAL_INDEX
|
||||
: static_cast<int>(setting->GetValue()) +
|
||||
ConfigurationShared::USE_GLOBAL_OFFSET);
|
||||
}
|
||||
|
||||
void ConfigurationShared::SetPerGameSetting(
|
||||
QComboBox* combobox, const Settings::Setting<Settings::GPUAccuracy>* setting) {
|
||||
combobox->setCurrentIndex(setting->UsingGlobal() ? ConfigurationShared::USE_GLOBAL_INDEX
|
||||
: static_cast<int>(setting->GetValue()) +
|
||||
ConfigurationShared::USE_GLOBAL_OFFSET);
|
||||
}
|
||||
|
||||
void ConfigurationShared::InsertGlobalItem(QComboBox* combobox) {
|
||||
const QString use_global_text = ConfigurePerGame::tr("Use global configuration");
|
||||
combobox->insertItem(ConfigurationShared::USE_GLOBAL_INDEX, use_global_text);
|
||||
combobox->insertSeparator(ConfigurationShared::USE_GLOBAL_SEPARATOR_INDEX);
|
||||
}
|
||||
36
src/yuzu/configuration/configuration_shared.h
Normal file
36
src/yuzu/configuration/configuration_shared.h
Normal file
@@ -0,0 +1,36 @@
|
||||
// Copyright 2016 Citra Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QComboBox>
|
||||
#include <QString>
|
||||
#include "core/settings.h"
|
||||
|
||||
namespace ConfigurationShared {
|
||||
|
||||
constexpr int USE_GLOBAL_INDEX = 0;
|
||||
constexpr int USE_GLOBAL_SEPARATOR_INDEX = 1;
|
||||
constexpr int USE_GLOBAL_OFFSET = 2;
|
||||
|
||||
// Global-aware apply and set functions
|
||||
|
||||
void ApplyPerGameSetting(Settings::Setting<bool>* setting, const QCheckBox* checkbox);
|
||||
void ApplyPerGameSetting(Settings::Setting<int>* setting, const QComboBox* combobox);
|
||||
void ApplyPerGameSetting(Settings::Setting<Settings::RendererBackend>* setting,
|
||||
const QComboBox* combobox);
|
||||
void ApplyPerGameSetting(Settings::Setting<Settings::GPUAccuracy>* setting,
|
||||
const QComboBox* combobox);
|
||||
|
||||
void SetPerGameSetting(QCheckBox* checkbox, const Settings::Setting<bool>* setting);
|
||||
void SetPerGameSetting(QComboBox* combobox, const Settings::Setting<int>* setting);
|
||||
void SetPerGameSetting(QComboBox* combobox,
|
||||
const Settings::Setting<Settings::RendererBackend>* setting);
|
||||
void SetPerGameSetting(QComboBox* combobox,
|
||||
const Settings::Setting<Settings::GPUAccuracy>* setting);
|
||||
|
||||
void InsertGlobalItem(QComboBox* combobox);
|
||||
|
||||
} // namespace ConfigurationShared
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "core/core.h"
|
||||
#include "core/settings.h"
|
||||
#include "ui_configure_audio.h"
|
||||
#include "yuzu/configuration/configuration_shared.h"
|
||||
#include "yuzu/configuration/configure_audio.h"
|
||||
|
||||
ConfigureAudio::ConfigureAudio(QWidget* parent)
|
||||
@@ -24,6 +25,11 @@ ConfigureAudio::ConfigureAudio(QWidget* parent)
|
||||
connect(ui->output_sink_combo_box, qOverload<int>(&QComboBox::currentIndexChanged), this,
|
||||
&ConfigureAudio::UpdateAudioDevices);
|
||||
|
||||
ui->volume_label->setVisible(Settings::configuring_global);
|
||||
ui->volume_combo_box->setVisible(!Settings::configuring_global);
|
||||
|
||||
SetupPerGameUI();
|
||||
|
||||
SetConfiguration();
|
||||
|
||||
const bool is_powered_on = Core::System::GetInstance().IsPoweredOn();
|
||||
@@ -41,8 +47,22 @@ void ConfigureAudio::SetConfiguration() {
|
||||
|
||||
SetAudioDeviceFromDeviceID();
|
||||
|
||||
ui->toggle_audio_stretching->setChecked(Settings::values.enable_audio_stretching);
|
||||
ui->volume_slider->setValue(Settings::values.volume * ui->volume_slider->maximum());
|
||||
ui->volume_slider->setValue(Settings::values.volume.GetValue() * ui->volume_slider->maximum());
|
||||
|
||||
if (Settings::configuring_global) {
|
||||
ui->toggle_audio_stretching->setChecked(
|
||||
Settings::values.enable_audio_stretching.GetValue());
|
||||
} else {
|
||||
ConfigurationShared::SetPerGameSetting(ui->toggle_audio_stretching,
|
||||
&Settings::values.enable_audio_stretching);
|
||||
if (Settings::values.volume.UsingGlobal()) {
|
||||
ui->volume_combo_box->setCurrentIndex(0);
|
||||
ui->volume_slider->setEnabled(false);
|
||||
} else {
|
||||
ui->volume_combo_box->setCurrentIndex(1);
|
||||
ui->volume_slider->setEnabled(true);
|
||||
}
|
||||
}
|
||||
SetVolumeIndicatorText(ui->volume_slider->sliderPosition());
|
||||
}
|
||||
|
||||
@@ -80,15 +100,36 @@ void ConfigureAudio::SetVolumeIndicatorText(int percentage) {
|
||||
}
|
||||
|
||||
void ConfigureAudio::ApplyConfiguration() {
|
||||
Settings::values.sink_id =
|
||||
ui->output_sink_combo_box->itemText(ui->output_sink_combo_box->currentIndex())
|
||||
.toStdString();
|
||||
Settings::values.enable_audio_stretching = ui->toggle_audio_stretching->isChecked();
|
||||
Settings::values.audio_device_id =
|
||||
ui->audio_device_combo_box->itemText(ui->audio_device_combo_box->currentIndex())
|
||||
.toStdString();
|
||||
Settings::values.volume =
|
||||
static_cast<float>(ui->volume_slider->sliderPosition()) / ui->volume_slider->maximum();
|
||||
if (Settings::configuring_global) {
|
||||
Settings::values.sink_id =
|
||||
ui->output_sink_combo_box->itemText(ui->output_sink_combo_box->currentIndex())
|
||||
.toStdString();
|
||||
Settings::values.audio_device_id =
|
||||
ui->audio_device_combo_box->itemText(ui->audio_device_combo_box->currentIndex())
|
||||
.toStdString();
|
||||
|
||||
// Guard if during game and set to game-specific value
|
||||
if (Settings::values.enable_audio_stretching.UsingGlobal()) {
|
||||
Settings::values.enable_audio_stretching.SetValue(
|
||||
ui->toggle_audio_stretching->isChecked());
|
||||
}
|
||||
if (Settings::values.volume.UsingGlobal()) {
|
||||
Settings::values.volume.SetValue(
|
||||
static_cast<float>(ui->volume_slider->sliderPosition()) /
|
||||
ui->volume_slider->maximum());
|
||||
}
|
||||
} else {
|
||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.enable_audio_stretching,
|
||||
ui->toggle_audio_stretching);
|
||||
if (ui->volume_combo_box->currentIndex() == 0) {
|
||||
Settings::values.volume.SetGlobal(true);
|
||||
} else {
|
||||
Settings::values.volume.SetGlobal(false);
|
||||
Settings::values.volume.SetValue(
|
||||
static_cast<float>(ui->volume_slider->sliderPosition()) /
|
||||
ui->volume_slider->maximum());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigureAudio::changeEvent(QEvent* event) {
|
||||
@@ -122,3 +163,22 @@ void ConfigureAudio::RetranslateUI() {
|
||||
ui->retranslateUi(this);
|
||||
SetVolumeIndicatorText(ui->volume_slider->sliderPosition());
|
||||
}
|
||||
|
||||
void ConfigureAudio::SetupPerGameUI() {
|
||||
if (Settings::configuring_global) {
|
||||
ui->volume_slider->setEnabled(Settings::values.volume.UsingGlobal());
|
||||
ui->toggle_audio_stretching->setEnabled(
|
||||
Settings::values.enable_audio_stretching.UsingGlobal());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
ui->toggle_audio_stretching->setTristate(true);
|
||||
connect(ui->volume_combo_box, static_cast<void (QComboBox::*)(int)>(&QComboBox::activated),
|
||||
this, [this](int index) { ui->volume_slider->setEnabled(index == 1); });
|
||||
|
||||
ui->output_sink_combo_box->setVisible(false);
|
||||
ui->output_sink_label->setVisible(false);
|
||||
ui->audio_device_combo_box->setVisible(false);
|
||||
ui->audio_device_label->setVisible(false);
|
||||
}
|
||||
|
||||
@@ -34,5 +34,7 @@ private:
|
||||
void SetAudioDeviceFromDeviceID();
|
||||
void SetVolumeIndicatorText(int percentage);
|
||||
|
||||
void SetupPerGameUI();
|
||||
|
||||
std::unique_ptr<Ui::ConfigureAudio> ui;
|
||||
};
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>188</width>
|
||||
<height>246</height>
|
||||
<width>367</width>
|
||||
<height>368</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout">
|
||||
@@ -18,9 +18,9 @@
|
||||
</property>
|
||||
<layout class="QVBoxLayout">
|
||||
<item>
|
||||
<layout class="QHBoxLayout">
|
||||
<layout class="QHBoxLayout" name="_3">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_1">
|
||||
<widget class="QLabel" name="output_sink_label">
|
||||
<property name="text">
|
||||
<string>Output Engine:</string>
|
||||
</property>
|
||||
@@ -31,20 +31,20 @@
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="toggle_audio_stretching">
|
||||
<property name="toolTip">
|
||||
<string>This post-processing effect adjusts audio speed to match emulation speed and helps prevent audio stutter. This however increases audio latency.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Enable audio stretching</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout">
|
||||
<widget class="QCheckBox" name="toggle_audio_stretching">
|
||||
<property name="toolTip">
|
||||
<string>This post-processing effect adjusts audio speed to match emulation speed and helps prevent audio stutter. This however increases audio latency.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Enable audio stretching</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="_2">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<widget class="QLabel" name="audio_device_label">
|
||||
<property name="text">
|
||||
<string>Audio Device:</string>
|
||||
</property>
|
||||
@@ -61,7 +61,21 @@
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<widget class="QComboBox" name="volume_combo_box">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Use global volume</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Set volume:</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="volume_label">
|
||||
<property name="text">
|
||||
<string>Volume:</string>
|
||||
</property>
|
||||
@@ -74,7 +88,7 @@
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<width>30</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
|
||||
ConfigureDialog::ConfigureDialog(QWidget* parent, HotkeyRegistry& registry)
|
||||
: QDialog(parent), ui(new Ui::ConfigureDialog), registry(registry) {
|
||||
Settings::configuring_global = true;
|
||||
|
||||
ui->setupUi(this);
|
||||
ui->hotkeysTab->Populate(registry);
|
||||
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
|
||||
|
||||
@@ -7,17 +7,21 @@
|
||||
#include "core/core.h"
|
||||
#include "core/settings.h"
|
||||
#include "ui_configure_general.h"
|
||||
#include "yuzu/configuration/configuration_shared.h"
|
||||
#include "yuzu/configuration/configure_general.h"
|
||||
#include "yuzu/uisettings.h"
|
||||
|
||||
ConfigureGeneral::ConfigureGeneral(QWidget* parent)
|
||||
: QWidget(parent), ui(new Ui::ConfigureGeneral) {
|
||||
|
||||
ui->setupUi(this);
|
||||
|
||||
SetupPerGameUI();
|
||||
|
||||
SetConfiguration();
|
||||
|
||||
connect(ui->toggle_frame_limit, &QCheckBox::toggled, ui->frame_limit, &QSpinBox::setEnabled);
|
||||
connect(ui->toggle_frame_limit, &QCheckBox::stateChanged, ui->frame_limit, [this]() {
|
||||
ui->frame_limit->setEnabled(ui->toggle_frame_limit->checkState() == Qt::Checked);
|
||||
});
|
||||
}
|
||||
|
||||
ConfigureGeneral::~ConfigureGeneral() = default;
|
||||
@@ -26,27 +30,56 @@ void ConfigureGeneral::SetConfiguration() {
|
||||
const bool runtime_lock = !Core::System::GetInstance().IsPoweredOn();
|
||||
|
||||
ui->use_multi_core->setEnabled(runtime_lock);
|
||||
ui->use_multi_core->setChecked(Settings::values.use_multi_core);
|
||||
ui->use_multi_core->setChecked(Settings::values.use_multi_core.GetValue());
|
||||
|
||||
ui->toggle_check_exit->setChecked(UISettings::values.confirm_before_closing);
|
||||
ui->toggle_user_on_boot->setChecked(UISettings::values.select_user_on_boot);
|
||||
ui->toggle_background_pause->setChecked(UISettings::values.pause_when_in_background);
|
||||
ui->toggle_hide_mouse->setChecked(UISettings::values.hide_mouse);
|
||||
|
||||
ui->toggle_frame_limit->setChecked(Settings::values.use_frame_limit);
|
||||
ui->frame_limit->setEnabled(ui->toggle_frame_limit->isChecked());
|
||||
ui->frame_limit->setValue(Settings::values.frame_limit);
|
||||
ui->toggle_frame_limit->setChecked(Settings::values.use_frame_limit.GetValue());
|
||||
ui->frame_limit->setValue(Settings::values.frame_limit.GetValue());
|
||||
|
||||
if (!Settings::configuring_global) {
|
||||
if (Settings::values.use_multi_core.UsingGlobal()) {
|
||||
ui->use_multi_core->setCheckState(Qt::PartiallyChecked);
|
||||
}
|
||||
if (Settings::values.use_frame_limit.UsingGlobal()) {
|
||||
ui->toggle_frame_limit->setCheckState(Qt::PartiallyChecked);
|
||||
}
|
||||
}
|
||||
|
||||
ui->frame_limit->setEnabled(ui->toggle_frame_limit->checkState() == Qt::Checked &&
|
||||
ui->toggle_frame_limit->isEnabled());
|
||||
}
|
||||
|
||||
void ConfigureGeneral::ApplyConfiguration() {
|
||||
UISettings::values.confirm_before_closing = ui->toggle_check_exit->isChecked();
|
||||
UISettings::values.select_user_on_boot = ui->toggle_user_on_boot->isChecked();
|
||||
UISettings::values.pause_when_in_background = ui->toggle_background_pause->isChecked();
|
||||
UISettings::values.hide_mouse = ui->toggle_hide_mouse->isChecked();
|
||||
if (Settings::configuring_global) {
|
||||
UISettings::values.confirm_before_closing = ui->toggle_check_exit->isChecked();
|
||||
UISettings::values.select_user_on_boot = ui->toggle_user_on_boot->isChecked();
|
||||
UISettings::values.pause_when_in_background = ui->toggle_background_pause->isChecked();
|
||||
UISettings::values.hide_mouse = ui->toggle_hide_mouse->isChecked();
|
||||
|
||||
Settings::values.use_frame_limit = ui->toggle_frame_limit->isChecked();
|
||||
Settings::values.frame_limit = ui->frame_limit->value();
|
||||
Settings::values.use_multi_core = ui->use_multi_core->isChecked();
|
||||
// Guard if during game and set to game-specific value
|
||||
if (Settings::values.use_frame_limit.UsingGlobal()) {
|
||||
Settings::values.use_frame_limit.SetValue(ui->toggle_frame_limit->checkState() ==
|
||||
Qt::Checked);
|
||||
Settings::values.frame_limit.SetValue(ui->frame_limit->value());
|
||||
Settings::values.use_multi_core.SetValue(ui->use_multi_core->isChecked());
|
||||
}
|
||||
} else {
|
||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_multi_core,
|
||||
ui->use_multi_core);
|
||||
|
||||
bool global_frame_limit = ui->toggle_frame_limit->checkState() == Qt::PartiallyChecked;
|
||||
Settings::values.use_frame_limit.SetGlobal(global_frame_limit);
|
||||
Settings::values.frame_limit.SetGlobal(global_frame_limit);
|
||||
if (!global_frame_limit) {
|
||||
Settings::values.use_frame_limit.SetValue(ui->toggle_frame_limit->checkState() ==
|
||||
Qt::Checked);
|
||||
Settings::values.frame_limit.SetValue(ui->frame_limit->value());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigureGeneral::changeEvent(QEvent* event) {
|
||||
@@ -60,3 +93,20 @@ void ConfigureGeneral::changeEvent(QEvent* event) {
|
||||
void ConfigureGeneral::RetranslateUI() {
|
||||
ui->retranslateUi(this);
|
||||
}
|
||||
|
||||
void ConfigureGeneral::SetupPerGameUI() {
|
||||
if (Settings::configuring_global) {
|
||||
ui->toggle_frame_limit->setEnabled(Settings::values.use_frame_limit.UsingGlobal());
|
||||
ui->frame_limit->setEnabled(Settings::values.frame_limit.UsingGlobal());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
ui->toggle_check_exit->setVisible(false);
|
||||
ui->toggle_user_on_boot->setVisible(false);
|
||||
ui->toggle_background_pause->setVisible(false);
|
||||
ui->toggle_hide_mouse->setVisible(false);
|
||||
|
||||
ui->toggle_frame_limit->setTristate(true);
|
||||
ui->use_multi_core->setTristate(true);
|
||||
}
|
||||
|
||||
@@ -28,5 +28,7 @@ private:
|
||||
|
||||
void SetConfiguration();
|
||||
|
||||
void SetupPerGameUI();
|
||||
|
||||
std::unique_ptr<Ui::ConfigureGeneral> ui;
|
||||
};
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "core/core.h"
|
||||
#include "core/settings.h"
|
||||
#include "ui_configure_graphics.h"
|
||||
#include "yuzu/configuration/configuration_shared.h"
|
||||
#include "yuzu/configuration/configure_graphics.h"
|
||||
|
||||
#ifdef HAS_VULKAN
|
||||
@@ -21,11 +22,13 @@
|
||||
|
||||
ConfigureGraphics::ConfigureGraphics(QWidget* parent)
|
||||
: QWidget(parent), ui(new Ui::ConfigureGraphics) {
|
||||
vulkan_device = Settings::values.vulkan_device;
|
||||
vulkan_device = Settings::values.vulkan_device.GetValue();
|
||||
RetrieveVulkanDevices();
|
||||
|
||||
ui->setupUi(this);
|
||||
|
||||
SetupPerGameUI();
|
||||
|
||||
SetConfiguration();
|
||||
|
||||
connect(ui->api, qOverload<int>(&QComboBox::currentIndexChanged), this,
|
||||
@@ -40,6 +43,9 @@ ConfigureGraphics::ConfigureGraphics(QWidget* parent)
|
||||
}
|
||||
UpdateBackgroundColorButton(new_bg_color);
|
||||
});
|
||||
|
||||
ui->bg_label->setVisible(Settings::configuring_global);
|
||||
ui->bg_combobox->setVisible(!Settings::configuring_global);
|
||||
}
|
||||
|
||||
void ConfigureGraphics::UpdateDeviceSelection(int device) {
|
||||
@@ -57,27 +63,95 @@ void ConfigureGraphics::SetConfiguration() {
|
||||
const bool runtime_lock = !Core::System::GetInstance().IsPoweredOn();
|
||||
|
||||
ui->api->setEnabled(runtime_lock);
|
||||
ui->api->setCurrentIndex(static_cast<int>(Settings::values.renderer_backend));
|
||||
ui->aspect_ratio_combobox->setCurrentIndex(Settings::values.aspect_ratio);
|
||||
ui->use_disk_shader_cache->setEnabled(runtime_lock);
|
||||
ui->use_disk_shader_cache->setChecked(Settings::values.use_disk_shader_cache);
|
||||
ui->use_asynchronous_gpu_emulation->setEnabled(runtime_lock);
|
||||
ui->use_asynchronous_gpu_emulation->setChecked(Settings::values.use_asynchronous_gpu_emulation);
|
||||
UpdateBackgroundColorButton(QColor::fromRgbF(Settings::values.bg_red, Settings::values.bg_green,
|
||||
Settings::values.bg_blue));
|
||||
ui->use_disk_shader_cache->setEnabled(runtime_lock);
|
||||
|
||||
if (Settings::configuring_global) {
|
||||
ui->api->setCurrentIndex(static_cast<int>(Settings::values.renderer_backend.GetValue()));
|
||||
ui->aspect_ratio_combobox->setCurrentIndex(Settings::values.aspect_ratio.GetValue());
|
||||
ui->use_disk_shader_cache->setChecked(Settings::values.use_disk_shader_cache.GetValue());
|
||||
ui->use_asynchronous_gpu_emulation->setChecked(
|
||||
Settings::values.use_asynchronous_gpu_emulation.GetValue());
|
||||
} else {
|
||||
ConfigurationShared::SetPerGameSetting(ui->use_disk_shader_cache,
|
||||
&Settings::values.use_disk_shader_cache);
|
||||
ConfigurationShared::SetPerGameSetting(ui->use_asynchronous_gpu_emulation,
|
||||
&Settings::values.use_asynchronous_gpu_emulation);
|
||||
|
||||
ConfigurationShared::SetPerGameSetting(ui->api, &Settings::values.renderer_backend);
|
||||
ConfigurationShared::SetPerGameSetting(ui->aspect_ratio_combobox,
|
||||
&Settings::values.aspect_ratio);
|
||||
|
||||
ui->bg_combobox->setCurrentIndex(Settings::values.bg_red.UsingGlobal() ? 0 : 1);
|
||||
ui->bg_button->setEnabled(!Settings::values.bg_red.UsingGlobal());
|
||||
}
|
||||
|
||||
UpdateBackgroundColorButton(QColor::fromRgbF(Settings::values.bg_red.GetValue(),
|
||||
Settings::values.bg_green.GetValue(),
|
||||
Settings::values.bg_blue.GetValue()));
|
||||
UpdateDeviceComboBox();
|
||||
}
|
||||
|
||||
void ConfigureGraphics::ApplyConfiguration() {
|
||||
Settings::values.renderer_backend = GetCurrentGraphicsBackend();
|
||||
Settings::values.vulkan_device = vulkan_device;
|
||||
Settings::values.aspect_ratio = ui->aspect_ratio_combobox->currentIndex();
|
||||
Settings::values.use_disk_shader_cache = ui->use_disk_shader_cache->isChecked();
|
||||
Settings::values.use_asynchronous_gpu_emulation =
|
||||
ui->use_asynchronous_gpu_emulation->isChecked();
|
||||
Settings::values.bg_red = static_cast<float>(bg_color.redF());
|
||||
Settings::values.bg_green = static_cast<float>(bg_color.greenF());
|
||||
Settings::values.bg_blue = static_cast<float>(bg_color.blueF());
|
||||
if (Settings::configuring_global) {
|
||||
// Guard if during game and set to game-specific value
|
||||
if (Settings::values.renderer_backend.UsingGlobal()) {
|
||||
Settings::values.renderer_backend.SetValue(GetCurrentGraphicsBackend());
|
||||
}
|
||||
if (Settings::values.vulkan_device.UsingGlobal()) {
|
||||
Settings::values.vulkan_device.SetValue(vulkan_device);
|
||||
}
|
||||
if (Settings::values.aspect_ratio.UsingGlobal()) {
|
||||
Settings::values.aspect_ratio.SetValue(ui->aspect_ratio_combobox->currentIndex());
|
||||
}
|
||||
if (Settings::values.use_disk_shader_cache.UsingGlobal()) {
|
||||
Settings::values.use_disk_shader_cache.SetValue(ui->use_disk_shader_cache->isChecked());
|
||||
}
|
||||
if (Settings::values.use_asynchronous_gpu_emulation.UsingGlobal()) {
|
||||
Settings::values.use_asynchronous_gpu_emulation.SetValue(
|
||||
ui->use_asynchronous_gpu_emulation->isChecked());
|
||||
}
|
||||
if (Settings::values.bg_red.UsingGlobal()) {
|
||||
Settings::values.bg_red.SetValue(static_cast<float>(bg_color.redF()));
|
||||
Settings::values.bg_green.SetValue(static_cast<float>(bg_color.greenF()));
|
||||
Settings::values.bg_blue.SetValue(static_cast<float>(bg_color.blueF()));
|
||||
}
|
||||
} else {
|
||||
if (ui->api->currentIndex() == ConfigurationShared::USE_GLOBAL_INDEX) {
|
||||
Settings::values.renderer_backend.SetGlobal(true);
|
||||
Settings::values.vulkan_device.SetGlobal(true);
|
||||
} else {
|
||||
Settings::values.renderer_backend.SetGlobal(false);
|
||||
Settings::values.renderer_backend.SetValue(GetCurrentGraphicsBackend());
|
||||
if (GetCurrentGraphicsBackend() == Settings::RendererBackend::Vulkan) {
|
||||
Settings::values.vulkan_device.SetGlobal(false);
|
||||
Settings::values.vulkan_device.SetValue(vulkan_device);
|
||||
} else {
|
||||
Settings::values.vulkan_device.SetGlobal(true);
|
||||
}
|
||||
}
|
||||
|
||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.aspect_ratio,
|
||||
ui->aspect_ratio_combobox);
|
||||
|
||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_disk_shader_cache,
|
||||
ui->use_disk_shader_cache);
|
||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_asynchronous_gpu_emulation,
|
||||
ui->use_asynchronous_gpu_emulation);
|
||||
|
||||
if (ui->bg_combobox->currentIndex() == ConfigurationShared::USE_GLOBAL_INDEX) {
|
||||
Settings::values.bg_red.SetGlobal(true);
|
||||
Settings::values.bg_green.SetGlobal(true);
|
||||
Settings::values.bg_blue.SetGlobal(true);
|
||||
} else {
|
||||
Settings::values.bg_red.SetGlobal(false);
|
||||
Settings::values.bg_green.SetGlobal(false);
|
||||
Settings::values.bg_blue.SetGlobal(false);
|
||||
Settings::values.bg_red.SetValue(static_cast<float>(bg_color.redF()));
|
||||
Settings::values.bg_green.SetValue(static_cast<float>(bg_color.greenF()));
|
||||
Settings::values.bg_blue.SetValue(static_cast<float>(bg_color.blueF()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigureGraphics::changeEvent(QEvent* event) {
|
||||
@@ -106,6 +180,11 @@ void ConfigureGraphics::UpdateDeviceComboBox() {
|
||||
ui->device->clear();
|
||||
|
||||
bool enabled = false;
|
||||
|
||||
if (!Settings::configuring_global &&
|
||||
ui->api->currentIndex() == ConfigurationShared::USE_GLOBAL_INDEX) {
|
||||
vulkan_device = Settings::values.vulkan_device.GetValue();
|
||||
}
|
||||
switch (GetCurrentGraphicsBackend()) {
|
||||
case Settings::RendererBackend::OpenGL:
|
||||
ui->device->addItem(tr("OpenGL Graphics Device"));
|
||||
@@ -119,6 +198,9 @@ void ConfigureGraphics::UpdateDeviceComboBox() {
|
||||
enabled = !vulkan_devices.empty();
|
||||
break;
|
||||
}
|
||||
// If in per-game config and use global is selected, don't enable.
|
||||
enabled &= !(!Settings::configuring_global &&
|
||||
ui->api->currentIndex() == ConfigurationShared::USE_GLOBAL_INDEX);
|
||||
ui->device->setEnabled(enabled && !Core::System::GetInstance().IsPoweredOn());
|
||||
}
|
||||
|
||||
@@ -132,5 +214,37 @@ void ConfigureGraphics::RetrieveVulkanDevices() {
|
||||
}
|
||||
|
||||
Settings::RendererBackend ConfigureGraphics::GetCurrentGraphicsBackend() const {
|
||||
return static_cast<Settings::RendererBackend>(ui->api->currentIndex());
|
||||
if (Settings::configuring_global) {
|
||||
return static_cast<Settings::RendererBackend>(ui->api->currentIndex());
|
||||
}
|
||||
|
||||
if (ui->api->currentIndex() == ConfigurationShared::USE_GLOBAL_INDEX) {
|
||||
Settings::values.renderer_backend.SetGlobal(true);
|
||||
return Settings::values.renderer_backend.GetValue();
|
||||
}
|
||||
Settings::values.renderer_backend.SetGlobal(false);
|
||||
return static_cast<Settings::RendererBackend>(ui->api->currentIndex() -
|
||||
ConfigurationShared::USE_GLOBAL_OFFSET);
|
||||
}
|
||||
|
||||
void ConfigureGraphics::SetupPerGameUI() {
|
||||
if (Settings::configuring_global) {
|
||||
ui->api->setEnabled(Settings::values.renderer_backend.UsingGlobal());
|
||||
ui->device->setEnabled(Settings::values.renderer_backend.UsingGlobal());
|
||||
ui->aspect_ratio_combobox->setEnabled(Settings::values.aspect_ratio.UsingGlobal());
|
||||
ui->use_asynchronous_gpu_emulation->setEnabled(
|
||||
Settings::values.use_asynchronous_gpu_emulation.UsingGlobal());
|
||||
ui->use_disk_shader_cache->setEnabled(Settings::values.use_disk_shader_cache.UsingGlobal());
|
||||
ui->bg_button->setEnabled(Settings::values.bg_red.UsingGlobal());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
connect(ui->bg_combobox, static_cast<void (QComboBox::*)(int)>(&QComboBox::activated), this,
|
||||
[this](int index) { ui->bg_button->setEnabled(index == 1); });
|
||||
|
||||
ui->use_disk_shader_cache->setTristate(true);
|
||||
ui->use_asynchronous_gpu_emulation->setTristate(true);
|
||||
ConfigurationShared::InsertGlobalItem(ui->aspect_ratio_combobox);
|
||||
ConfigurationShared::InsertGlobalItem(ui->api);
|
||||
}
|
||||
|
||||
@@ -35,6 +35,8 @@ private:
|
||||
|
||||
void RetrieveVulkanDevices();
|
||||
|
||||
void SetupPerGameUI();
|
||||
|
||||
Settings::RendererBackend GetCurrentGraphicsBackend() const;
|
||||
|
||||
std::unique_ptr<Ui::ConfigureGraphics> ui;
|
||||
|
||||
@@ -121,6 +121,29 @@
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<widget class="QComboBox" name="bg_combobox">
|
||||
<property name="currentText">
|
||||
<string>Use global background color</string>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="maxVisibleItems">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Use global background color</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Set background color:</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="bg_label">
|
||||
<property name="text">
|
||||
@@ -128,6 +151,19 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="bg_button">
|
||||
<property name="maximumSize">
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "core/core.h"
|
||||
#include "core/settings.h"
|
||||
#include "ui_configure_graphics_advanced.h"
|
||||
#include "yuzu/configuration/configuration_shared.h"
|
||||
#include "yuzu/configuration/configure_graphics_advanced.h"
|
||||
|
||||
ConfigureGraphicsAdvanced::ConfigureGraphicsAdvanced(QWidget* parent)
|
||||
@@ -12,6 +13,8 @@ ConfigureGraphicsAdvanced::ConfigureGraphicsAdvanced(QWidget* parent)
|
||||
|
||||
ui->setupUi(this);
|
||||
|
||||
SetupPerGameUI();
|
||||
|
||||
SetConfiguration();
|
||||
}
|
||||
|
||||
@@ -19,26 +22,81 @@ ConfigureGraphicsAdvanced::~ConfigureGraphicsAdvanced() = default;
|
||||
|
||||
void ConfigureGraphicsAdvanced::SetConfiguration() {
|
||||
const bool runtime_lock = !Core::System::GetInstance().IsPoweredOn();
|
||||
ui->gpu_accuracy->setCurrentIndex(static_cast<int>(Settings::values.gpu_accuracy));
|
||||
ui->use_vsync->setEnabled(runtime_lock);
|
||||
ui->use_vsync->setChecked(Settings::values.use_vsync);
|
||||
ui->use_assembly_shaders->setEnabled(runtime_lock);
|
||||
ui->use_assembly_shaders->setChecked(Settings::values.use_assembly_shaders);
|
||||
ui->use_fast_gpu_time->setChecked(Settings::values.use_fast_gpu_time);
|
||||
ui->force_30fps_mode->setEnabled(runtime_lock);
|
||||
ui->force_30fps_mode->setChecked(Settings::values.force_30fps_mode);
|
||||
ui->anisotropic_filtering_combobox->setEnabled(runtime_lock);
|
||||
ui->anisotropic_filtering_combobox->setCurrentIndex(Settings::values.max_anisotropy);
|
||||
|
||||
if (Settings::configuring_global) {
|
||||
ui->gpu_accuracy->setCurrentIndex(
|
||||
static_cast<int>(Settings::values.gpu_accuracy.GetValue()));
|
||||
ui->use_vsync->setChecked(Settings::values.use_vsync.GetValue());
|
||||
ui->use_assembly_shaders->setChecked(Settings::values.use_assembly_shaders.GetValue());
|
||||
ui->use_fast_gpu_time->setChecked(Settings::values.use_fast_gpu_time.GetValue());
|
||||
ui->force_30fps_mode->setChecked(Settings::values.force_30fps_mode.GetValue());
|
||||
ui->anisotropic_filtering_combobox->setCurrentIndex(
|
||||
Settings::values.max_anisotropy.GetValue());
|
||||
} else {
|
||||
ConfigurationShared::SetPerGameSetting(ui->gpu_accuracy, &Settings::values.gpu_accuracy);
|
||||
ConfigurationShared::SetPerGameSetting(ui->use_vsync, &Settings::values.use_vsync);
|
||||
ConfigurationShared::SetPerGameSetting(ui->use_assembly_shaders,
|
||||
&Settings::values.use_assembly_shaders);
|
||||
ConfigurationShared::SetPerGameSetting(ui->use_fast_gpu_time,
|
||||
&Settings::values.use_fast_gpu_time);
|
||||
ConfigurationShared::SetPerGameSetting(ui->force_30fps_mode,
|
||||
&Settings::values.force_30fps_mode);
|
||||
ConfigurationShared::SetPerGameSetting(ui->anisotropic_filtering_combobox,
|
||||
&Settings::values.max_anisotropy);
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigureGraphicsAdvanced::ApplyConfiguration() {
|
||||
auto gpu_accuracy = static_cast<Settings::GPUAccuracy>(ui->gpu_accuracy->currentIndex());
|
||||
Settings::values.gpu_accuracy = gpu_accuracy;
|
||||
Settings::values.use_vsync = ui->use_vsync->isChecked();
|
||||
Settings::values.use_assembly_shaders = ui->use_assembly_shaders->isChecked();
|
||||
Settings::values.use_fast_gpu_time = ui->use_fast_gpu_time->isChecked();
|
||||
Settings::values.force_30fps_mode = ui->force_30fps_mode->isChecked();
|
||||
Settings::values.max_anisotropy = ui->anisotropic_filtering_combobox->currentIndex();
|
||||
// Subtract 2 if configuring per-game (separator and "use global configuration" take 2 slots)
|
||||
const auto gpu_accuracy = static_cast<Settings::GPUAccuracy>(
|
||||
ui->gpu_accuracy->currentIndex() -
|
||||
((Settings::configuring_global) ? 0 : ConfigurationShared::USE_GLOBAL_OFFSET));
|
||||
|
||||
if (Settings::configuring_global) {
|
||||
// Must guard in case of a during-game configuration when set to be game-specific.
|
||||
if (Settings::values.gpu_accuracy.UsingGlobal()) {
|
||||
Settings::values.gpu_accuracy.SetValue(gpu_accuracy);
|
||||
}
|
||||
if (Settings::values.use_vsync.UsingGlobal()) {
|
||||
Settings::values.use_vsync.SetValue(ui->use_vsync->isChecked());
|
||||
}
|
||||
if (Settings::values.use_assembly_shaders.UsingGlobal()) {
|
||||
Settings::values.use_assembly_shaders.SetValue(ui->use_assembly_shaders->isChecked());
|
||||
}
|
||||
if (Settings::values.use_fast_gpu_time.UsingGlobal()) {
|
||||
Settings::values.use_fast_gpu_time.SetValue(ui->use_fast_gpu_time->isChecked());
|
||||
}
|
||||
if (Settings::values.force_30fps_mode.UsingGlobal()) {
|
||||
Settings::values.force_30fps_mode.SetValue(ui->force_30fps_mode->isChecked());
|
||||
}
|
||||
if (Settings::values.max_anisotropy.UsingGlobal()) {
|
||||
Settings::values.max_anisotropy.SetValue(
|
||||
ui->anisotropic_filtering_combobox->currentIndex());
|
||||
}
|
||||
} else {
|
||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.max_anisotropy,
|
||||
ui->anisotropic_filtering_combobox);
|
||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_vsync, ui->use_vsync);
|
||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_assembly_shaders,
|
||||
ui->use_assembly_shaders);
|
||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_fast_gpu_time,
|
||||
ui->use_fast_gpu_time);
|
||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.force_30fps_mode,
|
||||
ui->force_30fps_mode);
|
||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.max_anisotropy,
|
||||
ui->anisotropic_filtering_combobox);
|
||||
|
||||
if (ui->gpu_accuracy->currentIndex() == ConfigurationShared::USE_GLOBAL_INDEX) {
|
||||
Settings::values.gpu_accuracy.SetGlobal(true);
|
||||
} else {
|
||||
Settings::values.gpu_accuracy.SetGlobal(false);
|
||||
Settings::values.gpu_accuracy.SetValue(gpu_accuracy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigureGraphicsAdvanced::changeEvent(QEvent* event) {
|
||||
@@ -52,3 +110,25 @@ void ConfigureGraphicsAdvanced::changeEvent(QEvent* event) {
|
||||
void ConfigureGraphicsAdvanced::RetranslateUI() {
|
||||
ui->retranslateUi(this);
|
||||
}
|
||||
|
||||
void ConfigureGraphicsAdvanced::SetupPerGameUI() {
|
||||
// Disable if not global (only happens during game)
|
||||
if (Settings::configuring_global) {
|
||||
ui->gpu_accuracy->setEnabled(Settings::values.gpu_accuracy.UsingGlobal());
|
||||
ui->use_vsync->setEnabled(Settings::values.use_vsync.UsingGlobal());
|
||||
ui->use_assembly_shaders->setEnabled(Settings::values.use_assembly_shaders.UsingGlobal());
|
||||
ui->use_fast_gpu_time->setEnabled(Settings::values.use_fast_gpu_time.UsingGlobal());
|
||||
ui->force_30fps_mode->setEnabled(Settings::values.force_30fps_mode.UsingGlobal());
|
||||
ui->anisotropic_filtering_combobox->setEnabled(
|
||||
Settings::values.max_anisotropy.UsingGlobal());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
ConfigurationShared::InsertGlobalItem(ui->gpu_accuracy);
|
||||
ui->use_vsync->setTristate(true);
|
||||
ui->use_assembly_shaders->setTristate(true);
|
||||
ui->use_fast_gpu_time->setTristate(true);
|
||||
ui->force_30fps_mode->setTristate(true);
|
||||
ConfigurationShared::InsertGlobalItem(ui->anisotropic_filtering_combobox);
|
||||
}
|
||||
|
||||
@@ -26,5 +26,7 @@ private:
|
||||
|
||||
void SetConfiguration();
|
||||
|
||||
void SetupPerGameUI();
|
||||
|
||||
std::unique_ptr<Ui::ConfigureGraphicsAdvanced> ui;
|
||||
};
|
||||
|
||||
140
src/yuzu/configuration/configure_per_game.cpp
Normal file
140
src/yuzu/configuration/configure_per_game.cpp
Normal file
@@ -0,0 +1,140 @@
|
||||
// Copyright 2020 yuzu Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QHeaderView>
|
||||
#include <QMenu>
|
||||
#include <QStandardItemModel>
|
||||
#include <QString>
|
||||
#include <QTimer>
|
||||
#include <QTreeView>
|
||||
|
||||
#include "common/common_paths.h"
|
||||
#include "common/file_util.h"
|
||||
#include "core/file_sys/control_metadata.h"
|
||||
#include "core/file_sys/patch_manager.h"
|
||||
#include "core/file_sys/xts_archive.h"
|
||||
#include "core/loader/loader.h"
|
||||
#include "ui_configure_per_game.h"
|
||||
#include "yuzu/configuration/config.h"
|
||||
#include "yuzu/configuration/configure_input.h"
|
||||
#include "yuzu/configuration/configure_per_game.h"
|
||||
#include "yuzu/uisettings.h"
|
||||
#include "yuzu/util/util.h"
|
||||
|
||||
ConfigurePerGame::ConfigurePerGame(QWidget* parent, u64 title_id)
|
||||
: QDialog(parent), ui(std::make_unique<Ui::ConfigurePerGame>()), title_id(title_id) {
|
||||
game_config = std::make_unique<Config>(fmt::format("{:016X}.ini", title_id), false);
|
||||
|
||||
Settings::configuring_global = false;
|
||||
|
||||
ui->setupUi(this);
|
||||
setFocusPolicy(Qt::ClickFocus);
|
||||
setWindowTitle(tr("Properties"));
|
||||
|
||||
ui->addonsTab->SetTitleId(title_id);
|
||||
|
||||
scene = new QGraphicsScene;
|
||||
ui->icon_view->setScene(scene);
|
||||
|
||||
LoadConfiguration();
|
||||
}
|
||||
|
||||
ConfigurePerGame::~ConfigurePerGame() = default;
|
||||
|
||||
void ConfigurePerGame::ApplyConfiguration() {
|
||||
ui->addonsTab->ApplyConfiguration();
|
||||
ui->generalTab->ApplyConfiguration();
|
||||
ui->systemTab->ApplyConfiguration();
|
||||
ui->graphicsTab->ApplyConfiguration();
|
||||
ui->graphicsAdvancedTab->ApplyConfiguration();
|
||||
ui->audioTab->ApplyConfiguration();
|
||||
|
||||
Settings::Apply();
|
||||
Settings::LogSettings();
|
||||
|
||||
game_config->Save();
|
||||
}
|
||||
|
||||
void ConfigurePerGame::changeEvent(QEvent* event) {
|
||||
if (event->type() == QEvent::LanguageChange) {
|
||||
RetranslateUI();
|
||||
}
|
||||
|
||||
QDialog::changeEvent(event);
|
||||
}
|
||||
|
||||
void ConfigurePerGame::RetranslateUI() {
|
||||
ui->retranslateUi(this);
|
||||
}
|
||||
|
||||
void ConfigurePerGame::LoadFromFile(FileSys::VirtualFile file) {
|
||||
this->file = std::move(file);
|
||||
LoadConfiguration();
|
||||
}
|
||||
|
||||
void ConfigurePerGame::LoadConfiguration() {
|
||||
if (file == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
ui->addonsTab->LoadFromFile(file);
|
||||
|
||||
ui->display_title_id->setText(
|
||||
QStringLiteral("%1").arg(title_id, 16, 16, QLatin1Char{'0'}).toUpper());
|
||||
|
||||
FileSys::PatchManager pm{title_id};
|
||||
const auto control = pm.GetControlMetadata();
|
||||
const auto loader = Loader::GetLoader(file);
|
||||
|
||||
if (control.first != nullptr) {
|
||||
ui->display_version->setText(QString::fromStdString(control.first->GetVersionString()));
|
||||
ui->display_name->setText(QString::fromStdString(control.first->GetApplicationName()));
|
||||
ui->display_developer->setText(QString::fromStdString(control.first->GetDeveloperName()));
|
||||
} else {
|
||||
std::string title;
|
||||
if (loader->ReadTitle(title) == Loader::ResultStatus::Success)
|
||||
ui->display_name->setText(QString::fromStdString(title));
|
||||
|
||||
FileSys::NACP nacp;
|
||||
if (loader->ReadControlData(nacp) == Loader::ResultStatus::Success)
|
||||
ui->display_developer->setText(QString::fromStdString(nacp.GetDeveloperName()));
|
||||
|
||||
ui->display_version->setText(QStringLiteral("1.0.0"));
|
||||
}
|
||||
|
||||
if (control.second != nullptr) {
|
||||
scene->clear();
|
||||
|
||||
QPixmap map;
|
||||
const auto bytes = control.second->ReadAllBytes();
|
||||
map.loadFromData(bytes.data(), static_cast<u32>(bytes.size()));
|
||||
|
||||
scene->addPixmap(map.scaled(ui->icon_view->width(), ui->icon_view->height(),
|
||||
Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
|
||||
} else {
|
||||
std::vector<u8> bytes;
|
||||
if (loader->ReadIcon(bytes) == Loader::ResultStatus::Success) {
|
||||
scene->clear();
|
||||
|
||||
QPixmap map;
|
||||
map.loadFromData(bytes.data(), static_cast<u32>(bytes.size()));
|
||||
|
||||
scene->addPixmap(map.scaled(ui->icon_view->width(), ui->icon_view->height(),
|
||||
Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
|
||||
}
|
||||
}
|
||||
|
||||
ui->display_filename->setText(QString::fromStdString(file->GetName()));
|
||||
|
||||
ui->display_format->setText(
|
||||
QString::fromStdString(Loader::GetFileTypeString(loader->GetFileType())));
|
||||
|
||||
const auto valueText = ReadableByteSize(file->GetSize());
|
||||
ui->display_size->setText(valueText);
|
||||
}
|
||||
51
src/yuzu/configuration/configure_per_game.h
Normal file
51
src/yuzu/configuration/configure_per_game.h
Normal file
@@ -0,0 +1,51 @@
|
||||
// Copyright 2020 yuzu Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include <QDialog>
|
||||
#include <QList>
|
||||
|
||||
#include "core/file_sys/vfs_types.h"
|
||||
#include "yuzu/configuration/config.h"
|
||||
|
||||
class QGraphicsScene;
|
||||
class QStandardItem;
|
||||
class QStandardItemModel;
|
||||
class QTreeView;
|
||||
class QVBoxLayout;
|
||||
|
||||
namespace Ui {
|
||||
class ConfigurePerGame;
|
||||
}
|
||||
|
||||
class ConfigurePerGame : public QDialog {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ConfigurePerGame(QWidget* parent, u64 title_id);
|
||||
~ConfigurePerGame() override;
|
||||
|
||||
/// Save all button configurations to settings file
|
||||
void ApplyConfiguration();
|
||||
|
||||
void LoadFromFile(FileSys::VirtualFile file);
|
||||
|
||||
private:
|
||||
void changeEvent(QEvent* event) override;
|
||||
void RetranslateUI();
|
||||
|
||||
void LoadConfiguration();
|
||||
|
||||
std::unique_ptr<Ui::ConfigurePerGame> ui;
|
||||
FileSys::VirtualFile file;
|
||||
u64 title_id;
|
||||
|
||||
QGraphicsScene* scene;
|
||||
|
||||
std::unique_ptr<Config> game_config;
|
||||
};
|
||||
350
src/yuzu/configuration/configure_per_game.ui
Normal file
350
src/yuzu/configuration/configure_per_game.ui
Normal file
@@ -0,0 +1,350 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>ConfigurePerGame</class>
|
||||
<widget class="QDialog" name="ConfigurePerGame">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>800</width>
|
||||
<height>600</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Dialog</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Info</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item alignment="Qt::AlignHCenter">
|
||||
<widget class="QGraphicsView" name="icon_view">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Maximum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>256</width>
|
||||
<height>256</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>256</width>
|
||||
<height>256</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="verticalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAlwaysOff</enum>
|
||||
</property>
|
||||
<property name="horizontalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAlwaysOff</enum>
|
||||
</property>
|
||||
<property name="interactive">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="6" column="1">
|
||||
<widget class="QLineEdit" name="display_size">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QLineEdit" name="display_version">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Name</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Title ID</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QLineEdit" name="display_title_id">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="1">
|
||||
<widget class="QLineEdit" name="display_filename">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QLineEdit" name="display_format">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>Filename</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="display_name">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLineEdit" name="display_developer">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>Format</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Version</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>Size</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Developer</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="VerticalLayout">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTabWidget" name="tabWidget">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="usesScrollButtons">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="documentMode">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="tabsClosable">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<widget class="ConfigurePerGameAddons" name="addonsTab">
|
||||
<attribute name="title">
|
||||
<string>Add-Ons</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
<widget class="ConfigureGeneral" name="generalTab">
|
||||
<attribute name="title">
|
||||
<string>General</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
<widget class="ConfigureSystem" name="systemTab">
|
||||
<attribute name="title">
|
||||
<string>System</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
<widget class="ConfigureGraphics" name="graphicsTab">
|
||||
<attribute name="title">
|
||||
<string>Graphics</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
<widget class="ConfigureGraphicsAdvanced" name="graphicsAdvancedTab">
|
||||
<attribute name="title">
|
||||
<string>Adv. Graphics</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
<widget class="ConfigureAudio" name="audioTab">
|
||||
<attribute name="title">
|
||||
<string>Audio</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>ConfigureGeneral</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>configuration/configure_general.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>ConfigureSystem</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>configuration/configure_system.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>ConfigureAudio</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>configuration/configure_audio.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>ConfigureGraphics</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>configuration/configure_graphics.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>ConfigureGraphicsAdvanced</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>configuration/configure_graphics_advanced.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>ConfigurePerGameAddons</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>configuration/configure_per_game_addons.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>ConfigurePerGame</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>248</x>
|
||||
<y>254</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>ConfigurePerGame</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>316</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
||||
@@ -15,23 +15,20 @@
|
||||
|
||||
#include "common/common_paths.h"
|
||||
#include "common/file_util.h"
|
||||
#include "core/file_sys/control_metadata.h"
|
||||
#include "core/core.h"
|
||||
#include "core/file_sys/patch_manager.h"
|
||||
#include "core/file_sys/xts_archive.h"
|
||||
#include "core/loader/loader.h"
|
||||
#include "ui_configure_per_general.h"
|
||||
#include "ui_configure_per_game_addons.h"
|
||||
#include "yuzu/configuration/config.h"
|
||||
#include "yuzu/configuration/configure_input.h"
|
||||
#include "yuzu/configuration/configure_per_general.h"
|
||||
#include "yuzu/configuration/configure_per_game_addons.h"
|
||||
#include "yuzu/uisettings.h"
|
||||
#include "yuzu/util/util.h"
|
||||
|
||||
ConfigurePerGameGeneral::ConfigurePerGameGeneral(QWidget* parent, u64 title_id)
|
||||
: QDialog(parent), ui(std::make_unique<Ui::ConfigurePerGameGeneral>()), title_id(title_id) {
|
||||
|
||||
ConfigurePerGameAddons::ConfigurePerGameAddons(QWidget* parent)
|
||||
: QWidget(parent), ui(new Ui::ConfigurePerGameAddons) {
|
||||
ui->setupUi(this);
|
||||
setFocusPolicy(Qt::ClickFocus);
|
||||
setWindowTitle(tr("Properties"));
|
||||
|
||||
layout = new QVBoxLayout;
|
||||
tree_view = new QTreeView;
|
||||
@@ -52,7 +49,7 @@ ConfigurePerGameGeneral::ConfigurePerGameGeneral(QWidget* parent, u64 title_id)
|
||||
item_model->setHeaderData(1, Qt::Horizontal, tr("Version"));
|
||||
|
||||
// We must register all custom types with the Qt Automoc system so that we are able to use it
|
||||
// with signals/slots. In this case, QList falls under the umbrells of custom types.
|
||||
// with signals/slots. In this case, QList falls under the umbrella of custom types.
|
||||
qRegisterMetaType<QList<QStandardItem*>>("QList<QStandardItem*>");
|
||||
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
@@ -61,18 +58,15 @@ ConfigurePerGameGeneral::ConfigurePerGameGeneral(QWidget* parent, u64 title_id)
|
||||
|
||||
ui->scrollArea->setLayout(layout);
|
||||
|
||||
scene = new QGraphicsScene;
|
||||
ui->icon_view->setScene(scene);
|
||||
ui->scrollArea->setEnabled(!Core::System::GetInstance().IsPoweredOn());
|
||||
|
||||
connect(item_model, &QStandardItemModel::itemChanged,
|
||||
[] { UISettings::values.is_game_list_reload_pending.exchange(true); });
|
||||
|
||||
LoadConfiguration();
|
||||
}
|
||||
|
||||
ConfigurePerGameGeneral::~ConfigurePerGameGeneral() = default;
|
||||
ConfigurePerGameAddons::~ConfigurePerGameAddons() = default;
|
||||
|
||||
void ConfigurePerGameGeneral::ApplyConfiguration() {
|
||||
void ConfigurePerGameAddons::ApplyConfiguration() {
|
||||
std::vector<std::string> disabled_addons;
|
||||
|
||||
for (const auto& item : list_items) {
|
||||
@@ -92,72 +86,35 @@ void ConfigurePerGameGeneral::ApplyConfiguration() {
|
||||
Settings::values.disabled_addons[title_id] = disabled_addons;
|
||||
}
|
||||
|
||||
void ConfigurePerGameGeneral::changeEvent(QEvent* event) {
|
||||
if (event->type() == QEvent::LanguageChange) {
|
||||
RetranslateUI();
|
||||
}
|
||||
|
||||
QDialog::changeEvent(event);
|
||||
}
|
||||
|
||||
void ConfigurePerGameGeneral::RetranslateUI() {
|
||||
ui->retranslateUi(this);
|
||||
}
|
||||
|
||||
void ConfigurePerGameGeneral::LoadFromFile(FileSys::VirtualFile file) {
|
||||
void ConfigurePerGameAddons::LoadFromFile(FileSys::VirtualFile file) {
|
||||
this->file = std::move(file);
|
||||
LoadConfiguration();
|
||||
}
|
||||
|
||||
void ConfigurePerGameGeneral::LoadConfiguration() {
|
||||
void ConfigurePerGameAddons::SetTitleId(u64 id) {
|
||||
this->title_id = id;
|
||||
}
|
||||
|
||||
void ConfigurePerGameAddons::changeEvent(QEvent* event) {
|
||||
if (event->type() == QEvent::LanguageChange) {
|
||||
RetranslateUI();
|
||||
}
|
||||
|
||||
QWidget::changeEvent(event);
|
||||
}
|
||||
|
||||
void ConfigurePerGameAddons::RetranslateUI() {
|
||||
ui->retranslateUi(this);
|
||||
}
|
||||
|
||||
void ConfigurePerGameAddons::LoadConfiguration() {
|
||||
if (file == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
ui->display_title_id->setText(QString::fromStdString(fmt::format("{:016X}", title_id)));
|
||||
|
||||
FileSys::PatchManager pm{title_id};
|
||||
const auto control = pm.GetControlMetadata();
|
||||
const auto loader = Loader::GetLoader(file);
|
||||
|
||||
if (control.first != nullptr) {
|
||||
ui->display_version->setText(QString::fromStdString(control.first->GetVersionString()));
|
||||
ui->display_name->setText(QString::fromStdString(control.first->GetApplicationName()));
|
||||
ui->display_developer->setText(QString::fromStdString(control.first->GetDeveloperName()));
|
||||
} else {
|
||||
std::string title;
|
||||
if (loader->ReadTitle(title) == Loader::ResultStatus::Success)
|
||||
ui->display_name->setText(QString::fromStdString(title));
|
||||
|
||||
FileSys::NACP nacp;
|
||||
if (loader->ReadControlData(nacp) == Loader::ResultStatus::Success)
|
||||
ui->display_developer->setText(QString::fromStdString(nacp.GetDeveloperName()));
|
||||
|
||||
ui->display_version->setText(QStringLiteral("1.0.0"));
|
||||
}
|
||||
|
||||
if (control.second != nullptr) {
|
||||
scene->clear();
|
||||
|
||||
QPixmap map;
|
||||
const auto bytes = control.second->ReadAllBytes();
|
||||
map.loadFromData(bytes.data(), static_cast<u32>(bytes.size()));
|
||||
|
||||
scene->addPixmap(map.scaled(ui->icon_view->width(), ui->icon_view->height(),
|
||||
Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
|
||||
} else {
|
||||
std::vector<u8> bytes;
|
||||
if (loader->ReadIcon(bytes) == Loader::ResultStatus::Success) {
|
||||
scene->clear();
|
||||
|
||||
QPixmap map;
|
||||
map.loadFromData(bytes.data(), static_cast<u32>(bytes.size()));
|
||||
|
||||
scene->addPixmap(map.scaled(ui->icon_view->width(), ui->icon_view->height(),
|
||||
Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
|
||||
}
|
||||
}
|
||||
|
||||
FileSys::VirtualFile update_raw;
|
||||
loader->ReadUpdateRaw(update_raw);
|
||||
|
||||
@@ -182,12 +139,4 @@ void ConfigurePerGameGeneral::LoadConfiguration() {
|
||||
}
|
||||
|
||||
tree_view->setColumnWidth(0, 5 * tree_view->width() / 16);
|
||||
|
||||
ui->display_filename->setText(QString::fromStdString(file->GetName()));
|
||||
|
||||
ui->display_format->setText(
|
||||
QString::fromStdString(Loader::GetFileTypeString(loader->GetFileType())));
|
||||
|
||||
const auto valueText = ReadableByteSize(file->GetSize());
|
||||
ui->display_size->setText(valueText);
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2016 Citra Emulator Project
|
||||
// Copyright 2016 Citra Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include <QDialog>
|
||||
#include <QList>
|
||||
|
||||
#include "core/file_sys/vfs_types.h"
|
||||
@@ -19,35 +18,36 @@ class QTreeView;
|
||||
class QVBoxLayout;
|
||||
|
||||
namespace Ui {
|
||||
class ConfigurePerGameGeneral;
|
||||
class ConfigurePerGameAddons;
|
||||
}
|
||||
|
||||
class ConfigurePerGameGeneral : public QDialog {
|
||||
class ConfigurePerGameAddons : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ConfigurePerGameGeneral(QWidget* parent, u64 title_id);
|
||||
~ConfigurePerGameGeneral() override;
|
||||
explicit ConfigurePerGameAddons(QWidget* parent = nullptr);
|
||||
~ConfigurePerGameAddons() override;
|
||||
|
||||
/// Save all button configurations to settings file
|
||||
void ApplyConfiguration();
|
||||
|
||||
void LoadFromFile(FileSys::VirtualFile file);
|
||||
|
||||
void SetTitleId(u64 id);
|
||||
|
||||
private:
|
||||
void changeEvent(QEvent* event) override;
|
||||
void RetranslateUI();
|
||||
|
||||
void LoadConfiguration();
|
||||
|
||||
std::unique_ptr<Ui::ConfigurePerGameGeneral> ui;
|
||||
std::unique_ptr<Ui::ConfigurePerGameAddons> ui;
|
||||
FileSys::VirtualFile file;
|
||||
u64 title_id;
|
||||
|
||||
QVBoxLayout* layout;
|
||||
QTreeView* tree_view;
|
||||
QStandardItemModel* item_model;
|
||||
QGraphicsScene* scene;
|
||||
|
||||
std::vector<QList<QStandardItem*>> list_items;
|
||||
};
|
||||
38
src/yuzu/configuration/configure_per_game_addons.ui
Normal file
38
src/yuzu/configuration/configure_per_game_addons.ui
Normal file
@@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>ConfigurePerGameAddons</class>
|
||||
<widget class="QWidget" name="ConfigurePerGameAddons">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>300</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QScrollArea" name="scrollArea">
|
||||
<property name="widgetResizable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<widget class="QWidget" name="scrollAreaWidgetContents">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>380</width>
|
||||
<height>280</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
@@ -1,276 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>ConfigurePerGameGeneral</class>
|
||||
<widget class="QDialog" name="ConfigurePerGameGeneral">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>520</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>ConfigurePerGameGeneral</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="HorizontalLayout">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="VerticalLayout">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="GeneralGroupBox">
|
||||
<property name="title">
|
||||
<string>Info</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="GeneralHorizontalLayout">
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="6" column="1" colspan="2">
|
||||
<widget class="QLineEdit" name="display_filename">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="display_name">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Developer</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1" colspan="2">
|
||||
<widget class="QLineEdit" name="display_size">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Name</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>Filename</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Version</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>Format</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLineEdit" name="display_version">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QLineEdit" name="display_format">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>Size</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="display_developer">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Title ID</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QLineEdit" name="display_title_id">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2" rowspan="5">
|
||||
<widget class="QGraphicsView" name="icon_view">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Maximum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>128</width>
|
||||
<height>128</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>128</width>
|
||||
<height>128</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="verticalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAlwaysOff</enum>
|
||||
</property>
|
||||
<property name="horizontalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAlwaysOff</enum>
|
||||
</property>
|
||||
<property name="sizeAdjustPolicy">
|
||||
<enum>QAbstractScrollArea::AdjustToContents</enum>
|
||||
</property>
|
||||
<property name="interactive">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="PerformanceGroupBox">
|
||||
<property name="title">
|
||||
<string>Add-Ons</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="PerformanceHorizontalLayout">
|
||||
<item>
|
||||
<widget class="QScrollArea" name="scrollArea">
|
||||
<property name="widgetResizable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<widget class="QWidget" name="scrollAreaWidgetContents">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>350</width>
|
||||
<height>169</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="PerformanceVerticalLayout"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>ConfigurePerGameGeneral</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>269</x>
|
||||
<y>567</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>269</x>
|
||||
<y>294</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>ConfigurePerGameGeneral</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>269</x>
|
||||
<y>567</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>269</x>
|
||||
<y>294</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "core/core.h"
|
||||
#include "core/settings.h"
|
||||
#include "ui_configure_system.h"
|
||||
#include "yuzu/configuration/configuration_shared.h"
|
||||
#include "yuzu/configuration/configure_system.h"
|
||||
|
||||
ConfigureSystem::ConfigureSystem(QWidget* parent) : QWidget(parent), ui(new Ui::ConfigureSystem) {
|
||||
@@ -21,20 +22,25 @@ ConfigureSystem::ConfigureSystem(QWidget* parent) : QWidget(parent), ui(new Ui::
|
||||
connect(ui->button_regenerate_console_id, &QPushButton::clicked, this,
|
||||
&ConfigureSystem::RefreshConsoleID);
|
||||
|
||||
connect(ui->rng_seed_checkbox, &QCheckBox::stateChanged, this, [this](bool checked) {
|
||||
ui->rng_seed_edit->setEnabled(checked);
|
||||
if (!checked) {
|
||||
connect(ui->rng_seed_checkbox, &QCheckBox::stateChanged, this, [this](int state) {
|
||||
ui->rng_seed_edit->setEnabled(state == Qt::Checked);
|
||||
if (state != Qt::Checked) {
|
||||
ui->rng_seed_edit->setText(QStringLiteral("00000000"));
|
||||
}
|
||||
});
|
||||
|
||||
connect(ui->custom_rtc_checkbox, &QCheckBox::stateChanged, this, [this](bool checked) {
|
||||
ui->custom_rtc_edit->setEnabled(checked);
|
||||
if (!checked) {
|
||||
connect(ui->custom_rtc_checkbox, &QCheckBox::stateChanged, this, [this](int state) {
|
||||
ui->custom_rtc_edit->setEnabled(state == Qt::Checked);
|
||||
if (state != Qt::Checked) {
|
||||
ui->custom_rtc_edit->setDateTime(QDateTime::currentDateTime());
|
||||
}
|
||||
});
|
||||
|
||||
ui->label_console_id->setVisible(Settings::configuring_global);
|
||||
ui->button_regenerate_console_id->setVisible(Settings::configuring_global);
|
||||
|
||||
SetupPerGameUI();
|
||||
|
||||
SetConfiguration();
|
||||
}
|
||||
|
||||
@@ -54,26 +60,58 @@ void ConfigureSystem::RetranslateUI() {
|
||||
|
||||
void ConfigureSystem::SetConfiguration() {
|
||||
enabled = !Core::System::GetInstance().IsPoweredOn();
|
||||
|
||||
ui->combo_language->setCurrentIndex(Settings::values.language_index);
|
||||
ui->combo_region->setCurrentIndex(Settings::values.region_index);
|
||||
ui->combo_time_zone->setCurrentIndex(Settings::values.time_zone_index);
|
||||
ui->combo_sound->setCurrentIndex(Settings::values.sound_index);
|
||||
|
||||
ui->rng_seed_checkbox->setChecked(Settings::values.rng_seed.has_value());
|
||||
ui->rng_seed_edit->setEnabled(Settings::values.rng_seed.has_value());
|
||||
|
||||
const auto rng_seed = QStringLiteral("%1")
|
||||
.arg(Settings::values.rng_seed.value_or(0), 8, 16, QLatin1Char{'0'})
|
||||
.toUpper();
|
||||
ui->rng_seed_edit->setText(rng_seed);
|
||||
|
||||
ui->custom_rtc_checkbox->setChecked(Settings::values.custom_rtc.has_value());
|
||||
ui->custom_rtc_edit->setEnabled(Settings::values.custom_rtc.has_value());
|
||||
|
||||
const auto rtc_time = Settings::values.custom_rtc.value_or(
|
||||
const auto rng_seed =
|
||||
QStringLiteral("%1")
|
||||
.arg(Settings::values.rng_seed.GetValue().value_or(0), 8, 16, QLatin1Char{'0'})
|
||||
.toUpper();
|
||||
const auto rtc_time = Settings::values.custom_rtc.GetValue().value_or(
|
||||
std::chrono::seconds(QDateTime::currentSecsSinceEpoch()));
|
||||
ui->custom_rtc_edit->setDateTime(QDateTime::fromSecsSinceEpoch(rtc_time.count()));
|
||||
|
||||
if (Settings::configuring_global) {
|
||||
ui->combo_language->setCurrentIndex(Settings::values.language_index.GetValue());
|
||||
ui->combo_region->setCurrentIndex(Settings::values.region_index.GetValue());
|
||||
ui->combo_time_zone->setCurrentIndex(Settings::values.time_zone_index.GetValue());
|
||||
ui->combo_sound->setCurrentIndex(Settings::values.sound_index.GetValue());
|
||||
|
||||
ui->rng_seed_checkbox->setChecked(Settings::values.rng_seed.GetValue().has_value());
|
||||
ui->rng_seed_edit->setEnabled(Settings::values.rng_seed.GetValue().has_value() &&
|
||||
Settings::values.rng_seed.UsingGlobal());
|
||||
ui->rng_seed_edit->setText(rng_seed);
|
||||
|
||||
ui->custom_rtc_checkbox->setChecked(Settings::values.custom_rtc.GetValue().has_value());
|
||||
ui->custom_rtc_edit->setEnabled(Settings::values.custom_rtc.GetValue().has_value() &&
|
||||
Settings::values.rng_seed.UsingGlobal());
|
||||
ui->custom_rtc_edit->setDateTime(QDateTime::fromSecsSinceEpoch(rtc_time.count()));
|
||||
} else {
|
||||
ConfigurationShared::SetPerGameSetting(ui->combo_language,
|
||||
&Settings::values.language_index);
|
||||
ConfigurationShared::SetPerGameSetting(ui->combo_region, &Settings::values.region_index);
|
||||
ConfigurationShared::SetPerGameSetting(ui->combo_time_zone,
|
||||
&Settings::values.time_zone_index);
|
||||
ConfigurationShared::SetPerGameSetting(ui->combo_sound, &Settings::values.sound_index);
|
||||
|
||||
if (Settings::values.rng_seed.UsingGlobal()) {
|
||||
ui->rng_seed_checkbox->setCheckState(Qt::PartiallyChecked);
|
||||
} else {
|
||||
ui->rng_seed_checkbox->setCheckState(
|
||||
Settings::values.rng_seed.GetValue().has_value() ? Qt::Checked : Qt::Unchecked);
|
||||
ui->rng_seed_edit->setEnabled(Settings::values.rng_seed.GetValue().has_value());
|
||||
if (Settings::values.rng_seed.GetValue().has_value()) {
|
||||
ui->rng_seed_edit->setText(rng_seed);
|
||||
}
|
||||
}
|
||||
|
||||
if (Settings::values.custom_rtc.UsingGlobal()) {
|
||||
ui->custom_rtc_checkbox->setCheckState(Qt::PartiallyChecked);
|
||||
} else {
|
||||
ui->custom_rtc_checkbox->setCheckState(
|
||||
Settings::values.custom_rtc.GetValue().has_value() ? Qt::Checked : Qt::Unchecked);
|
||||
ui->custom_rtc_edit->setEnabled(Settings::values.custom_rtc.GetValue().has_value());
|
||||
if (Settings::values.custom_rtc.GetValue().has_value()) {
|
||||
ui->custom_rtc_edit->setDateTime(QDateTime::fromSecsSinceEpoch(rtc_time.count()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigureSystem::ReadSystemSettings() {}
|
||||
@@ -83,22 +121,78 @@ void ConfigureSystem::ApplyConfiguration() {
|
||||
return;
|
||||
}
|
||||
|
||||
Settings::values.language_index = ui->combo_language->currentIndex();
|
||||
Settings::values.region_index = ui->combo_region->currentIndex();
|
||||
Settings::values.time_zone_index = ui->combo_time_zone->currentIndex();
|
||||
Settings::values.sound_index = ui->combo_sound->currentIndex();
|
||||
if (Settings::configuring_global) {
|
||||
// Guard if during game and set to game-specific value
|
||||
if (Settings::values.language_index.UsingGlobal()) {
|
||||
Settings::values.language_index.SetValue(ui->combo_language->currentIndex());
|
||||
}
|
||||
if (Settings::values.region_index.UsingGlobal()) {
|
||||
Settings::values.region_index.SetValue(ui->combo_region->currentIndex());
|
||||
}
|
||||
if (Settings::values.time_zone_index.UsingGlobal()) {
|
||||
Settings::values.time_zone_index.SetValue(ui->combo_time_zone->currentIndex());
|
||||
}
|
||||
if (Settings::values.sound_index.UsingGlobal()) {
|
||||
Settings::values.sound_index.SetValue(ui->combo_sound->currentIndex());
|
||||
}
|
||||
|
||||
if (ui->rng_seed_checkbox->isChecked()) {
|
||||
Settings::values.rng_seed = ui->rng_seed_edit->text().toULongLong(nullptr, 16);
|
||||
} else {
|
||||
Settings::values.rng_seed = std::nullopt;
|
||||
}
|
||||
if (Settings::values.rng_seed.UsingGlobal()) {
|
||||
if (ui->rng_seed_checkbox->isChecked()) {
|
||||
Settings::values.rng_seed.SetValue(
|
||||
ui->rng_seed_edit->text().toULongLong(nullptr, 16));
|
||||
} else {
|
||||
Settings::values.rng_seed.SetValue(std::nullopt);
|
||||
}
|
||||
}
|
||||
|
||||
if (ui->custom_rtc_checkbox->isChecked()) {
|
||||
Settings::values.custom_rtc =
|
||||
std::chrono::seconds(ui->custom_rtc_edit->dateTime().toSecsSinceEpoch());
|
||||
if (Settings::values.custom_rtc.UsingGlobal()) {
|
||||
if (ui->custom_rtc_checkbox->isChecked()) {
|
||||
Settings::values.custom_rtc.SetValue(
|
||||
std::chrono::seconds(ui->custom_rtc_edit->dateTime().toSecsSinceEpoch()));
|
||||
} else {
|
||||
Settings::values.custom_rtc.SetValue(std::nullopt);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Settings::values.custom_rtc = std::nullopt;
|
||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.language_index,
|
||||
ui->combo_language);
|
||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.region_index, ui->combo_region);
|
||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.time_zone_index,
|
||||
ui->combo_time_zone);
|
||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.sound_index, ui->combo_sound);
|
||||
|
||||
switch (ui->rng_seed_checkbox->checkState()) {
|
||||
case Qt::Checked:
|
||||
Settings::values.rng_seed.SetGlobal(false);
|
||||
Settings::values.rng_seed.SetValue(ui->rng_seed_edit->text().toULongLong(nullptr, 16));
|
||||
break;
|
||||
case Qt::Unchecked:
|
||||
Settings::values.rng_seed.SetGlobal(false);
|
||||
Settings::values.rng_seed.SetValue(std::nullopt);
|
||||
break;
|
||||
case Qt::PartiallyChecked:
|
||||
Settings::values.rng_seed.SetGlobal(false);
|
||||
Settings::values.rng_seed.SetValue(std::nullopt);
|
||||
Settings::values.rng_seed.SetGlobal(true);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (ui->custom_rtc_checkbox->checkState()) {
|
||||
case Qt::Checked:
|
||||
Settings::values.custom_rtc.SetGlobal(false);
|
||||
Settings::values.custom_rtc.SetValue(
|
||||
std::chrono::seconds(ui->custom_rtc_edit->dateTime().toSecsSinceEpoch()));
|
||||
break;
|
||||
case Qt::Unchecked:
|
||||
Settings::values.custom_rtc.SetGlobal(false);
|
||||
Settings::values.custom_rtc.SetValue(std::nullopt);
|
||||
break;
|
||||
case Qt::PartiallyChecked:
|
||||
Settings::values.custom_rtc.SetGlobal(false);
|
||||
Settings::values.custom_rtc.SetValue(std::nullopt);
|
||||
Settings::values.custom_rtc.SetGlobal(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Settings::Apply();
|
||||
@@ -120,3 +214,25 @@ void ConfigureSystem::RefreshConsoleID() {
|
||||
ui->label_console_id->setText(
|
||||
tr("Console ID: 0x%1").arg(QString::number(console_id, 16).toUpper()));
|
||||
}
|
||||
|
||||
void ConfigureSystem::SetupPerGameUI() {
|
||||
if (Settings::configuring_global) {
|
||||
ui->combo_language->setEnabled(Settings::values.language_index.UsingGlobal());
|
||||
ui->combo_region->setEnabled(Settings::values.region_index.UsingGlobal());
|
||||
ui->combo_time_zone->setEnabled(Settings::values.time_zone_index.UsingGlobal());
|
||||
ui->combo_sound->setEnabled(Settings::values.sound_index.UsingGlobal());
|
||||
ui->rng_seed_checkbox->setEnabled(Settings::values.rng_seed.UsingGlobal());
|
||||
ui->rng_seed_edit->setEnabled(Settings::values.rng_seed.UsingGlobal());
|
||||
ui->custom_rtc_checkbox->setEnabled(Settings::values.custom_rtc.UsingGlobal());
|
||||
ui->custom_rtc_edit->setEnabled(Settings::values.custom_rtc.UsingGlobal());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
ConfigurationShared::InsertGlobalItem(ui->combo_language);
|
||||
ConfigurationShared::InsertGlobalItem(ui->combo_region);
|
||||
ConfigurationShared::InsertGlobalItem(ui->combo_time_zone);
|
||||
ConfigurationShared::InsertGlobalItem(ui->combo_sound);
|
||||
ui->rng_seed_checkbox->setTristate(true);
|
||||
ui->custom_rtc_checkbox->setTristate(true);
|
||||
}
|
||||
|
||||
@@ -32,6 +32,8 @@ private:
|
||||
|
||||
void RefreshConsoleID();
|
||||
|
||||
void SetupPerGameUI();
|
||||
|
||||
std::unique_ptr<Ui::ConfigureSystem> ui;
|
||||
bool enabled = false;
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
#include "applets/software_keyboard.h"
|
||||
#include "applets/web_browser.h"
|
||||
#include "configuration/configure_input.h"
|
||||
#include "configuration/configure_per_general.h"
|
||||
#include "configuration/configure_per_game.h"
|
||||
#include "core/file_sys/vfs.h"
|
||||
#include "core/file_sys/vfs_real.h"
|
||||
#include "core/frontend/applets/general_frontend.h"
|
||||
@@ -534,15 +534,15 @@ void GMainWindow::InitializeWidgets() {
|
||||
if (emulation_running) {
|
||||
return;
|
||||
}
|
||||
bool is_async =
|
||||
!Settings::values.use_asynchronous_gpu_emulation || Settings::values.use_multi_core;
|
||||
Settings::values.use_asynchronous_gpu_emulation = is_async;
|
||||
async_status_button->setChecked(Settings::values.use_asynchronous_gpu_emulation);
|
||||
bool is_async = !Settings::values.use_asynchronous_gpu_emulation.GetValue() ||
|
||||
Settings::values.use_multi_core.GetValue();
|
||||
Settings::values.use_asynchronous_gpu_emulation.SetValue(is_async);
|
||||
async_status_button->setChecked(Settings::values.use_asynchronous_gpu_emulation.GetValue());
|
||||
Settings::Apply();
|
||||
});
|
||||
async_status_button->setText(tr("ASYNC"));
|
||||
async_status_button->setCheckable(true);
|
||||
async_status_button->setChecked(Settings::values.use_asynchronous_gpu_emulation);
|
||||
async_status_button->setChecked(Settings::values.use_asynchronous_gpu_emulation.GetValue());
|
||||
|
||||
// Setup Multicore button
|
||||
multicore_status_button = new QPushButton();
|
||||
@@ -552,17 +552,17 @@ void GMainWindow::InitializeWidgets() {
|
||||
if (emulation_running) {
|
||||
return;
|
||||
}
|
||||
Settings::values.use_multi_core = !Settings::values.use_multi_core;
|
||||
bool is_async =
|
||||
Settings::values.use_asynchronous_gpu_emulation || Settings::values.use_multi_core;
|
||||
Settings::values.use_asynchronous_gpu_emulation = is_async;
|
||||
async_status_button->setChecked(Settings::values.use_asynchronous_gpu_emulation);
|
||||
multicore_status_button->setChecked(Settings::values.use_multi_core);
|
||||
Settings::values.use_multi_core.SetValue(!Settings::values.use_multi_core.GetValue());
|
||||
bool is_async = Settings::values.use_asynchronous_gpu_emulation.GetValue() ||
|
||||
Settings::values.use_multi_core.GetValue();
|
||||
Settings::values.use_asynchronous_gpu_emulation.SetValue(is_async);
|
||||
async_status_button->setChecked(Settings::values.use_asynchronous_gpu_emulation.GetValue());
|
||||
multicore_status_button->setChecked(Settings::values.use_multi_core.GetValue());
|
||||
Settings::Apply();
|
||||
});
|
||||
multicore_status_button->setText(tr("MULTICORE"));
|
||||
multicore_status_button->setCheckable(true);
|
||||
multicore_status_button->setChecked(Settings::values.use_multi_core);
|
||||
multicore_status_button->setChecked(Settings::values.use_multi_core.GetValue());
|
||||
statusBar()->insertPermanentWidget(0, multicore_status_button);
|
||||
statusBar()->insertPermanentWidget(0, async_status_button);
|
||||
|
||||
@@ -581,16 +581,16 @@ void GMainWindow::InitializeWidgets() {
|
||||
renderer_status_button->setCheckable(false);
|
||||
renderer_status_button->setDisabled(true);
|
||||
#else
|
||||
renderer_status_button->setChecked(Settings::values.renderer_backend ==
|
||||
renderer_status_button->setChecked(Settings::values.renderer_backend.GetValue() ==
|
||||
Settings::RendererBackend::Vulkan);
|
||||
connect(renderer_status_button, &QPushButton::clicked, [=] {
|
||||
if (emulation_running) {
|
||||
return;
|
||||
}
|
||||
if (renderer_status_button->isChecked()) {
|
||||
Settings::values.renderer_backend = Settings::RendererBackend::Vulkan;
|
||||
Settings::values.renderer_backend.SetValue(Settings::RendererBackend::Vulkan);
|
||||
} else {
|
||||
Settings::values.renderer_backend = Settings::RendererBackend::OpenGL;
|
||||
Settings::values.renderer_backend.SetValue(Settings::RendererBackend::OpenGL);
|
||||
}
|
||||
|
||||
Settings::Apply();
|
||||
@@ -727,21 +727,24 @@ void GMainWindow::InitializeHotkeys() {
|
||||
});
|
||||
connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Toggle Speed Limit"), this),
|
||||
&QShortcut::activated, this, [&] {
|
||||
Settings::values.use_frame_limit = !Settings::values.use_frame_limit;
|
||||
Settings::values.use_frame_limit.SetValue(
|
||||
!Settings::values.use_frame_limit.GetValue());
|
||||
UpdateStatusBar();
|
||||
});
|
||||
constexpr u16 SPEED_LIMIT_STEP = 5;
|
||||
connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Increase Speed Limit"), this),
|
||||
&QShortcut::activated, this, [&] {
|
||||
if (Settings::values.frame_limit < 9999 - SPEED_LIMIT_STEP) {
|
||||
Settings::values.frame_limit += SPEED_LIMIT_STEP;
|
||||
if (Settings::values.frame_limit.GetValue() < 9999 - SPEED_LIMIT_STEP) {
|
||||
Settings::values.frame_limit.SetValue(SPEED_LIMIT_STEP +
|
||||
Settings::values.frame_limit.GetValue());
|
||||
UpdateStatusBar();
|
||||
}
|
||||
});
|
||||
connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Decrease Speed Limit"), this),
|
||||
&QShortcut::activated, this, [&] {
|
||||
if (Settings::values.frame_limit > SPEED_LIMIT_STEP) {
|
||||
Settings::values.frame_limit -= SPEED_LIMIT_STEP;
|
||||
if (Settings::values.frame_limit.GetValue() > SPEED_LIMIT_STEP) {
|
||||
Settings::values.frame_limit.SetValue(Settings::values.frame_limit.GetValue() -
|
||||
SPEED_LIMIT_STEP);
|
||||
UpdateStatusBar();
|
||||
}
|
||||
});
|
||||
@@ -1039,6 +1042,17 @@ void GMainWindow::BootGame(const QString& filename) {
|
||||
LOG_INFO(Frontend, "yuzu starting...");
|
||||
StoreRecentFile(filename); // Put the filename on top of the list
|
||||
|
||||
u64 title_id{0};
|
||||
|
||||
const auto v_file = Core::GetGameFileFromPath(vfs, filename.toUtf8().constData());
|
||||
const auto loader = Loader::GetLoader(v_file);
|
||||
if (!(loader == nullptr || loader->ReadProgramId(title_id) != Loader::ResultStatus::Success)) {
|
||||
// Load per game settings
|
||||
Config per_game_config(fmt::format("{:016X}.ini", title_id), false);
|
||||
}
|
||||
|
||||
Settings::LogSettings();
|
||||
|
||||
if (UISettings::values.select_user_on_boot) {
|
||||
SelectAndSetCurrentUser();
|
||||
}
|
||||
@@ -1063,6 +1077,7 @@ void GMainWindow::BootGame(const QString& filename) {
|
||||
&LoadingScreen::OnLoadProgress, Qt::QueuedConnection);
|
||||
|
||||
// Update the GUI
|
||||
UpdateStatusButtons();
|
||||
if (ui.action_Single_Window_Mode->isChecked()) {
|
||||
game_list->hide();
|
||||
game_list_placeholder->hide();
|
||||
@@ -1078,8 +1093,6 @@ void GMainWindow::BootGame(const QString& filename) {
|
||||
ui.centralwidget->setMouseTracking(true);
|
||||
}
|
||||
|
||||
const u64 title_id = Core::System::GetInstance().CurrentProcess()->GetTitleID();
|
||||
|
||||
std::string title_name;
|
||||
std::string title_version;
|
||||
const auto res = Core::System::GetInstance().GetGameName(title_name);
|
||||
@@ -1521,7 +1534,7 @@ void GMainWindow::OnGameListOpenPerGameProperties(const std::string& file) {
|
||||
return;
|
||||
}
|
||||
|
||||
ConfigurePerGameGeneral dialog(this, title_id);
|
||||
ConfigurePerGame dialog(this, title_id);
|
||||
dialog.LoadFromFile(v_file);
|
||||
auto result = dialog.exec();
|
||||
if (result == QDialog::Accepted) {
|
||||
@@ -1532,7 +1545,14 @@ void GMainWindow::OnGameListOpenPerGameProperties(const std::string& file) {
|
||||
game_list->PopulateAsync(UISettings::values.game_dirs);
|
||||
}
|
||||
|
||||
config->Save();
|
||||
// Do not cause the global config to write local settings into the config file
|
||||
Settings::RestoreGlobalState();
|
||||
|
||||
if (!Core::System::GetInstance().IsPoweredOn()) {
|
||||
config->Save();
|
||||
}
|
||||
} else {
|
||||
Settings::RestoreGlobalState();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1819,6 +1839,9 @@ void GMainWindow::OnStopGame() {
|
||||
}
|
||||
|
||||
ShutdownGame();
|
||||
|
||||
Settings::RestoreGlobalState();
|
||||
UpdateStatusButtons();
|
||||
}
|
||||
|
||||
void GMainWindow::OnLoadComplete() {
|
||||
@@ -1926,7 +1949,7 @@ void GMainWindow::ToggleWindowMode() {
|
||||
|
||||
void GMainWindow::ResetWindowSize() {
|
||||
const auto aspect_ratio = Layout::EmulationAspectRatio(
|
||||
static_cast<Layout::AspectRatio>(Settings::values.aspect_ratio),
|
||||
static_cast<Layout::AspectRatio>(Settings::values.aspect_ratio.GetValue()),
|
||||
static_cast<float>(Layout::ScreenUndocked::Height) / Layout::ScreenUndocked::Width);
|
||||
if (!ui.action_Single_Window_Mode->isChecked()) {
|
||||
render_window->resize(Layout::ScreenUndocked::Height / aspect_ratio,
|
||||
@@ -1974,16 +1997,7 @@ void GMainWindow::OnConfigure() {
|
||||
ui.centralwidget->setMouseTracking(false);
|
||||
}
|
||||
|
||||
dock_status_button->setChecked(Settings::values.use_docked_mode);
|
||||
multicore_status_button->setChecked(Settings::values.use_multi_core);
|
||||
Settings::values.use_asynchronous_gpu_emulation =
|
||||
Settings::values.use_asynchronous_gpu_emulation || Settings::values.use_multi_core;
|
||||
async_status_button->setChecked(Settings::values.use_asynchronous_gpu_emulation);
|
||||
|
||||
#ifdef HAS_VULKAN
|
||||
renderer_status_button->setChecked(Settings::values.renderer_backend ==
|
||||
Settings::RendererBackend::Vulkan);
|
||||
#endif
|
||||
UpdateStatusButtons();
|
||||
}
|
||||
|
||||
void GMainWindow::OnLoadAmiibo() {
|
||||
@@ -2097,21 +2111,34 @@ void GMainWindow::UpdateStatusBar() {
|
||||
|
||||
auto results = Core::System::GetInstance().GetAndResetPerfStats();
|
||||
|
||||
if (Settings::values.use_frame_limit) {
|
||||
if (Settings::values.use_frame_limit.GetValue()) {
|
||||
emu_speed_label->setText(tr("Speed: %1% / %2%")
|
||||
.arg(results.emulation_speed * 100.0, 0, 'f', 0)
|
||||
.arg(Settings::values.frame_limit));
|
||||
.arg(Settings::values.frame_limit.GetValue()));
|
||||
} else {
|
||||
emu_speed_label->setText(tr("Speed: %1%").arg(results.emulation_speed * 100.0, 0, 'f', 0));
|
||||
}
|
||||
game_fps_label->setText(tr("Game: %1 FPS").arg(results.game_fps, 0, 'f', 0));
|
||||
emu_frametime_label->setText(tr("Frame: %1 ms").arg(results.frametime * 1000.0, 0, 'f', 2));
|
||||
|
||||
emu_speed_label->setVisible(!Settings::values.use_multi_core);
|
||||
emu_speed_label->setVisible(!Settings::values.use_multi_core.GetValue());
|
||||
game_fps_label->setVisible(true);
|
||||
emu_frametime_label->setVisible(true);
|
||||
}
|
||||
|
||||
void GMainWindow::UpdateStatusButtons() {
|
||||
dock_status_button->setChecked(Settings::values.use_docked_mode);
|
||||
multicore_status_button->setChecked(Settings::values.use_multi_core.GetValue());
|
||||
Settings::values.use_asynchronous_gpu_emulation.SetValue(
|
||||
Settings::values.use_asynchronous_gpu_emulation.GetValue() ||
|
||||
Settings::values.use_multi_core.GetValue());
|
||||
async_status_button->setChecked(Settings::values.use_asynchronous_gpu_emulation.GetValue());
|
||||
#ifdef HAS_VULKAN
|
||||
renderer_status_button->setChecked(Settings::values.renderer_backend.GetValue() ==
|
||||
Settings::RendererBackend::Vulkan);
|
||||
#endif
|
||||
}
|
||||
|
||||
void GMainWindow::HideMouseCursor() {
|
||||
if (emu_thread == nullptr || UISettings::values.hide_mouse == false) {
|
||||
mouse_hide_timer.stop();
|
||||
@@ -2195,6 +2222,9 @@ void GMainWindow::OnCoreError(Core::System::ResultStatus result, std::string det
|
||||
if (answer == QMessageBox::Yes) {
|
||||
if (emu_thread) {
|
||||
ShutdownGame();
|
||||
|
||||
Settings::RestoreGlobalState();
|
||||
UpdateStatusButtons();
|
||||
}
|
||||
} else {
|
||||
// Only show the message if the game is still running.
|
||||
@@ -2357,9 +2387,13 @@ void GMainWindow::closeEvent(QCloseEvent* event) {
|
||||
hotkey_registry.SaveHotkeys();
|
||||
|
||||
// Shutdown session if the emu thread is active...
|
||||
if (emu_thread != nullptr)
|
||||
if (emu_thread != nullptr) {
|
||||
ShutdownGame();
|
||||
|
||||
Settings::RestoreGlobalState();
|
||||
UpdateStatusButtons();
|
||||
}
|
||||
|
||||
render_window->close();
|
||||
|
||||
QWidget::closeEvent(event);
|
||||
@@ -2539,8 +2573,6 @@ int main(int argc, char* argv[]) {
|
||||
QObject::connect(&app, &QGuiApplication::applicationStateChanged, &main_window,
|
||||
&GMainWindow::OnAppFocusStateChanged);
|
||||
|
||||
Settings::LogSettings();
|
||||
|
||||
int result = app.exec();
|
||||
detached_tasks.WaitForAllTasks();
|
||||
return result;
|
||||
|
||||
@@ -221,6 +221,7 @@ private:
|
||||
void UpdateWindowTitle(const std::string& title_name = {},
|
||||
const std::string& title_version = {});
|
||||
void UpdateStatusBar();
|
||||
void UpdateStatusButtons();
|
||||
void HideMouseCursor();
|
||||
void ShowMouseCursor();
|
||||
void OpenURL(const QUrl& url);
|
||||
|
||||
@@ -354,63 +354,72 @@ void Config::ReadValues() {
|
||||
|
||||
const auto rng_seed_enabled = sdl2_config->GetBoolean("System", "rng_seed_enabled", false);
|
||||
if (rng_seed_enabled) {
|
||||
Settings::values.rng_seed = sdl2_config->GetInteger("System", "rng_seed", 0);
|
||||
Settings::values.rng_seed.SetValue(sdl2_config->GetInteger("System", "rng_seed", 0));
|
||||
} else {
|
||||
Settings::values.rng_seed = std::nullopt;
|
||||
Settings::values.rng_seed.SetValue(std::nullopt);
|
||||
}
|
||||
|
||||
const auto custom_rtc_enabled = sdl2_config->GetBoolean("System", "custom_rtc_enabled", false);
|
||||
if (custom_rtc_enabled) {
|
||||
Settings::values.custom_rtc =
|
||||
std::chrono::seconds(sdl2_config->GetInteger("System", "custom_rtc", 0));
|
||||
Settings::values.custom_rtc.SetValue(
|
||||
std::chrono::seconds(sdl2_config->GetInteger("System", "custom_rtc", 0)));
|
||||
} else {
|
||||
Settings::values.custom_rtc = std::nullopt;
|
||||
Settings::values.custom_rtc.SetValue(std::nullopt);
|
||||
}
|
||||
|
||||
Settings::values.language_index = sdl2_config->GetInteger("System", "language_index", 1);
|
||||
Settings::values.time_zone_index = sdl2_config->GetInteger("System", "time_zone_index", 0);
|
||||
Settings::values.language_index.SetValue(
|
||||
sdl2_config->GetInteger("System", "language_index", 1));
|
||||
Settings::values.time_zone_index.SetValue(
|
||||
sdl2_config->GetInteger("System", "time_zone_index", 0));
|
||||
|
||||
// Core
|
||||
Settings::values.use_multi_core = sdl2_config->GetBoolean("Core", "use_multi_core", false);
|
||||
Settings::values.use_multi_core.SetValue(
|
||||
sdl2_config->GetBoolean("Core", "use_multi_core", false));
|
||||
|
||||
// Renderer
|
||||
const int renderer_backend = sdl2_config->GetInteger(
|
||||
"Renderer", "backend", static_cast<int>(Settings::RendererBackend::OpenGL));
|
||||
Settings::values.renderer_backend = static_cast<Settings::RendererBackend>(renderer_backend);
|
||||
Settings::values.renderer_backend.SetValue(
|
||||
static_cast<Settings::RendererBackend>(renderer_backend));
|
||||
Settings::values.renderer_debug = sdl2_config->GetBoolean("Renderer", "debug", false);
|
||||
Settings::values.vulkan_device = sdl2_config->GetInteger("Renderer", "vulkan_device", 0);
|
||||
Settings::values.vulkan_device.SetValue(
|
||||
sdl2_config->GetInteger("Renderer", "vulkan_device", 0));
|
||||
|
||||
Settings::values.aspect_ratio =
|
||||
static_cast<int>(sdl2_config->GetInteger("Renderer", "aspect_ratio", 0));
|
||||
Settings::values.max_anisotropy =
|
||||
static_cast<int>(sdl2_config->GetInteger("Renderer", "max_anisotropy", 0));
|
||||
Settings::values.use_frame_limit = sdl2_config->GetBoolean("Renderer", "use_frame_limit", true);
|
||||
Settings::values.frame_limit =
|
||||
static_cast<u16>(sdl2_config->GetInteger("Renderer", "frame_limit", 100));
|
||||
Settings::values.use_disk_shader_cache =
|
||||
sdl2_config->GetBoolean("Renderer", "use_disk_shader_cache", false);
|
||||
Settings::values.aspect_ratio.SetValue(
|
||||
static_cast<int>(sdl2_config->GetInteger("Renderer", "aspect_ratio", 0)));
|
||||
Settings::values.max_anisotropy.SetValue(
|
||||
static_cast<int>(sdl2_config->GetInteger("Renderer", "max_anisotropy", 0)));
|
||||
Settings::values.use_frame_limit.SetValue(
|
||||
sdl2_config->GetBoolean("Renderer", "use_frame_limit", true));
|
||||
Settings::values.frame_limit.SetValue(
|
||||
static_cast<u16>(sdl2_config->GetInteger("Renderer", "frame_limit", 100)));
|
||||
Settings::values.use_disk_shader_cache.SetValue(
|
||||
sdl2_config->GetBoolean("Renderer", "use_disk_shader_cache", false));
|
||||
const int gpu_accuracy_level = sdl2_config->GetInteger("Renderer", "gpu_accuracy", 0);
|
||||
Settings::values.gpu_accuracy = static_cast<Settings::GPUAccuracy>(gpu_accuracy_level);
|
||||
Settings::values.use_asynchronous_gpu_emulation =
|
||||
sdl2_config->GetBoolean("Renderer", "use_asynchronous_gpu_emulation", false);
|
||||
Settings::values.use_vsync =
|
||||
static_cast<u16>(sdl2_config->GetInteger("Renderer", "use_vsync", 1));
|
||||
Settings::values.use_assembly_shaders =
|
||||
sdl2_config->GetBoolean("Renderer", "use_assembly_shaders", false);
|
||||
Settings::values.use_fast_gpu_time =
|
||||
sdl2_config->GetBoolean("Renderer", "use_fast_gpu_time", true);
|
||||
Settings::values.gpu_accuracy.SetValue(static_cast<Settings::GPUAccuracy>(gpu_accuracy_level));
|
||||
Settings::values.use_asynchronous_gpu_emulation.SetValue(
|
||||
sdl2_config->GetBoolean("Renderer", "use_asynchronous_gpu_emulation", false));
|
||||
Settings::values.use_vsync.SetValue(
|
||||
static_cast<u16>(sdl2_config->GetInteger("Renderer", "use_vsync", 1)));
|
||||
Settings::values.use_assembly_shaders.SetValue(
|
||||
sdl2_config->GetBoolean("Renderer", "use_assembly_shaders", false));
|
||||
Settings::values.use_fast_gpu_time.SetValue(
|
||||
sdl2_config->GetBoolean("Renderer", "use_fast_gpu_time", true));
|
||||
|
||||
Settings::values.bg_red = static_cast<float>(sdl2_config->GetReal("Renderer", "bg_red", 0.0));
|
||||
Settings::values.bg_green =
|
||||
static_cast<float>(sdl2_config->GetReal("Renderer", "bg_green", 0.0));
|
||||
Settings::values.bg_blue = static_cast<float>(sdl2_config->GetReal("Renderer", "bg_blue", 0.0));
|
||||
Settings::values.bg_red.SetValue(
|
||||
static_cast<float>(sdl2_config->GetReal("Renderer", "bg_red", 0.0)));
|
||||
Settings::values.bg_green.SetValue(
|
||||
static_cast<float>(sdl2_config->GetReal("Renderer", "bg_green", 0.0)));
|
||||
Settings::values.bg_blue.SetValue(
|
||||
static_cast<float>(sdl2_config->GetReal("Renderer", "bg_blue", 0.0)));
|
||||
|
||||
// Audio
|
||||
Settings::values.sink_id = sdl2_config->Get("Audio", "output_engine", "auto");
|
||||
Settings::values.enable_audio_stretching =
|
||||
sdl2_config->GetBoolean("Audio", "enable_audio_stretching", true);
|
||||
Settings::values.enable_audio_stretching.SetValue(
|
||||
sdl2_config->GetBoolean("Audio", "enable_audio_stretching", true));
|
||||
Settings::values.audio_device_id = sdl2_config->Get("Audio", "output_device", "auto");
|
||||
Settings::values.volume = static_cast<float>(sdl2_config->GetReal("Audio", "volume", 1));
|
||||
Settings::values.volume.SetValue(
|
||||
static_cast<float>(sdl2_config->GetReal("Audio", "volume", 1)));
|
||||
|
||||
// Miscellaneous
|
||||
Settings::values.log_filter = sdl2_config->Get("Miscellaneous", "log_filter", "*:Trace");
|
||||
|
||||
@@ -165,7 +165,7 @@ std::unique_ptr<Core::Frontend::GraphicsContext> EmuWindow_SDL2_GL::CreateShared
|
||||
|
||||
void EmuWindow_SDL2_GL::Present() {
|
||||
SDL_GL_MakeCurrent(render_window, window_context);
|
||||
SDL_GL_SetSwapInterval(Settings::values.use_vsync ? 1 : 0);
|
||||
SDL_GL_SetSwapInterval(Settings::values.use_vsync.GetValue() ? 1 : 0);
|
||||
while (IsOpen()) {
|
||||
system.Renderer().TryPresent(100);
|
||||
SDL_GL_SwapWindow(render_window);
|
||||
|
||||
@@ -181,7 +181,7 @@ int main(int argc, char** argv) {
|
||||
Core::System& system{Core::System::GetInstance()};
|
||||
|
||||
std::unique_ptr<EmuWindow_SDL2> emu_window;
|
||||
switch (Settings::values.renderer_backend) {
|
||||
switch (Settings::values.renderer_backend.GetValue()) {
|
||||
case Settings::RendererBackend::OpenGL:
|
||||
emu_window = std::make_unique<EmuWindow_SDL2_GL>(system, fullscreen);
|
||||
break;
|
||||
|
||||
@@ -81,6 +81,9 @@ void Config::ReadValues() {
|
||||
Settings::values.touchscreen.diameter_x = 15;
|
||||
Settings::values.touchscreen.diameter_y = 15;
|
||||
|
||||
Settings::values.use_docked_mode =
|
||||
sdl2_config->GetBoolean("Controls", "use_docked_mode", false);
|
||||
|
||||
// Data Storage
|
||||
Settings::values.use_virtual_sd =
|
||||
sdl2_config->GetBoolean("Data Storage", "use_virtual_sd", true);
|
||||
@@ -92,57 +95,59 @@ void Config::ReadValues() {
|
||||
FileUtil::GetUserPath(FileUtil::UserPath::SDMCDir)));
|
||||
|
||||
// System
|
||||
Settings::values.use_docked_mode = sdl2_config->GetBoolean("System", "use_docked_mode", false);
|
||||
|
||||
Settings::values.current_user = std::clamp<int>(
|
||||
sdl2_config->GetInteger("System", "current_user", 0), 0, Service::Account::MAX_USERS - 1);
|
||||
|
||||
const auto rng_seed_enabled = sdl2_config->GetBoolean("System", "rng_seed_enabled", false);
|
||||
if (rng_seed_enabled) {
|
||||
Settings::values.rng_seed = sdl2_config->GetInteger("System", "rng_seed", 0);
|
||||
Settings::values.rng_seed.SetValue(sdl2_config->GetInteger("System", "rng_seed", 0));
|
||||
} else {
|
||||
Settings::values.rng_seed = std::nullopt;
|
||||
Settings::values.rng_seed.SetValue(std::nullopt);
|
||||
}
|
||||
|
||||
const auto custom_rtc_enabled = sdl2_config->GetBoolean("System", "custom_rtc_enabled", false);
|
||||
if (custom_rtc_enabled) {
|
||||
Settings::values.custom_rtc =
|
||||
std::chrono::seconds(sdl2_config->GetInteger("System", "custom_rtc", 0));
|
||||
Settings::values.custom_rtc.SetValue(
|
||||
std::chrono::seconds(sdl2_config->GetInteger("System", "custom_rtc", 0)));
|
||||
} else {
|
||||
Settings::values.custom_rtc = std::nullopt;
|
||||
Settings::values.custom_rtc.SetValue(std::nullopt);
|
||||
}
|
||||
|
||||
// Core
|
||||
Settings::values.use_multi_core = sdl2_config->GetBoolean("Core", "use_multi_core", false);
|
||||
Settings::values.use_multi_core.SetValue(
|
||||
sdl2_config->GetBoolean("Core", "use_multi_core", false));
|
||||
|
||||
// Renderer
|
||||
Settings::values.aspect_ratio =
|
||||
static_cast<int>(sdl2_config->GetInteger("Renderer", "aspect_ratio", 0));
|
||||
Settings::values.max_anisotropy =
|
||||
static_cast<int>(sdl2_config->GetInteger("Renderer", "max_anisotropy", 0));
|
||||
Settings::values.use_frame_limit = false;
|
||||
Settings::values.frame_limit = 100;
|
||||
Settings::values.use_disk_shader_cache =
|
||||
sdl2_config->GetBoolean("Renderer", "use_disk_shader_cache", false);
|
||||
Settings::values.aspect_ratio.SetValue(
|
||||
static_cast<int>(sdl2_config->GetInteger("Renderer", "aspect_ratio", 0)));
|
||||
Settings::values.max_anisotropy.SetValue(
|
||||
static_cast<int>(sdl2_config->GetInteger("Renderer", "max_anisotropy", 0)));
|
||||
Settings::values.use_frame_limit.SetValue(false);
|
||||
Settings::values.frame_limit.SetValue(100);
|
||||
Settings::values.use_disk_shader_cache.SetValue(
|
||||
sdl2_config->GetBoolean("Renderer", "use_disk_shader_cache", false));
|
||||
const int gpu_accuracy_level = sdl2_config->GetInteger("Renderer", "gpu_accuracy", 0);
|
||||
Settings::values.gpu_accuracy = static_cast<Settings::GPUAccuracy>(gpu_accuracy_level);
|
||||
Settings::values.use_asynchronous_gpu_emulation =
|
||||
sdl2_config->GetBoolean("Renderer", "use_asynchronous_gpu_emulation", false);
|
||||
Settings::values.use_fast_gpu_time =
|
||||
sdl2_config->GetBoolean("Renderer", "use_fast_gpu_time", true);
|
||||
Settings::values.gpu_accuracy.SetValue(static_cast<Settings::GPUAccuracy>(gpu_accuracy_level));
|
||||
Settings::values.use_asynchronous_gpu_emulation.SetValue(
|
||||
sdl2_config->GetBoolean("Renderer", "use_asynchronous_gpu_emulation", false));
|
||||
Settings::values.use_fast_gpu_time.SetValue(
|
||||
sdl2_config->GetBoolean("Renderer", "use_fast_gpu_time", true));
|
||||
|
||||
Settings::values.bg_red = static_cast<float>(sdl2_config->GetReal("Renderer", "bg_red", 0.0));
|
||||
Settings::values.bg_green =
|
||||
static_cast<float>(sdl2_config->GetReal("Renderer", "bg_green", 0.0));
|
||||
Settings::values.bg_blue = static_cast<float>(sdl2_config->GetReal("Renderer", "bg_blue", 0.0));
|
||||
Settings::values.bg_red.SetValue(
|
||||
static_cast<float>(sdl2_config->GetReal("Renderer", "bg_red", 0.0)));
|
||||
Settings::values.bg_green.SetValue(
|
||||
static_cast<float>(sdl2_config->GetReal("Renderer", "bg_green", 0.0)));
|
||||
Settings::values.bg_blue.SetValue(
|
||||
static_cast<float>(sdl2_config->GetReal("Renderer", "bg_blue", 0.0)));
|
||||
|
||||
// Audio
|
||||
Settings::values.sink_id = "null";
|
||||
Settings::values.enable_audio_stretching = false;
|
||||
Settings::values.enable_audio_stretching.SetValue(false);
|
||||
Settings::values.audio_device_id = "auto";
|
||||
Settings::values.volume = 0;
|
||||
Settings::values.volume.SetValue(0);
|
||||
|
||||
Settings::values.language_index = sdl2_config->GetInteger("System", "language_index", 1);
|
||||
Settings::values.language_index.SetValue(
|
||||
sdl2_config->GetInteger("System", "language_index", 1));
|
||||
|
||||
// Miscellaneous
|
||||
Settings::values.log_filter = sdl2_config->Get("Miscellaneous", "log_filter", "*:Trace");
|
||||
|
||||
Reference in New Issue
Block a user