Merge pull request #10839 from lat9nq/pgc-plus
general: Reimplement per-game configurations
This commit is contained in:
commit
fca7d975fd
|
@ -3,4 +3,4 @@
|
||||||
|
|
||||||
[codespell]
|
[codespell]
|
||||||
skip = ./.git,./build,./dist,./Doxyfile,./externals,./LICENSES,./src/android/app/src/main/res
|
skip = ./.git,./build,./dist,./Doxyfile,./externals,./LICENSES,./src/android/app/src/main/res
|
||||||
ignore-words-list = aci,allright,ba,deques,froms,hda,inout,lod,masia,nam,nax,nd,optin,pullrequests,pullrequest,te,transfered,unstall,uscaled,zink
|
ignore-words-list = aci,allright,ba,canonicalizations,deques,froms,hda,inout,lod,masia,nam,nax,nd,optin,pullrequests,pullrequest,te,transfered,unstall,uscaled,zink
|
||||||
|
|
|
@ -35,6 +35,7 @@ if (MSVC)
|
||||||
# /volatile:iso - Use strict standards-compliant volatile semantics.
|
# /volatile:iso - Use strict standards-compliant volatile semantics.
|
||||||
# /Zc:externConstexpr - Allow extern constexpr variables to have external linkage, like the standard mandates
|
# /Zc:externConstexpr - Allow extern constexpr variables to have external linkage, like the standard mandates
|
||||||
# /Zc:inline - Let codegen omit inline functions in object files
|
# /Zc:inline - Let codegen omit inline functions in object files
|
||||||
|
# /Zc:preprocessor - Enable standards-conforming preprocessor
|
||||||
# /Zc:throwingNew - Let codegen assume `operator new` (without std::nothrow) will never return null
|
# /Zc:throwingNew - Let codegen assume `operator new` (without std::nothrow) will never return null
|
||||||
# /GT - Supports fiber safety for data allocated using static thread-local storage
|
# /GT - Supports fiber safety for data allocated using static thread-local storage
|
||||||
add_compile_options(
|
add_compile_options(
|
||||||
|
@ -48,6 +49,7 @@ if (MSVC)
|
||||||
/volatile:iso
|
/volatile:iso
|
||||||
/Zc:externConstexpr
|
/Zc:externConstexpr
|
||||||
/Zc:inline
|
/Zc:inline
|
||||||
|
/Zc:preprocessor
|
||||||
/Zc:throwingNew
|
/Zc:throwingNew
|
||||||
/GT
|
/GT
|
||||||
|
|
||||||
|
|
|
@ -150,15 +150,17 @@ void Config::ReadValues() {
|
||||||
if (rng_seed_enabled) {
|
if (rng_seed_enabled) {
|
||||||
Settings::values.rng_seed.SetValue(config->GetInteger("System", "rng_seed", 0));
|
Settings::values.rng_seed.SetValue(config->GetInteger("System", "rng_seed", 0));
|
||||||
} else {
|
} else {
|
||||||
Settings::values.rng_seed.SetValue(std::nullopt);
|
Settings::values.rng_seed.SetValue(0);
|
||||||
}
|
}
|
||||||
|
Settings::values.rng_seed_enabled.SetValue(rng_seed_enabled);
|
||||||
|
|
||||||
const auto custom_rtc_enabled = config->GetBoolean("System", "custom_rtc_enabled", false);
|
const auto custom_rtc_enabled = config->GetBoolean("System", "custom_rtc_enabled", false);
|
||||||
if (custom_rtc_enabled) {
|
if (custom_rtc_enabled) {
|
||||||
Settings::values.custom_rtc = config->GetInteger("System", "custom_rtc", 0);
|
Settings::values.custom_rtc = config->GetInteger("System", "custom_rtc", 0);
|
||||||
} else {
|
} else {
|
||||||
Settings::values.custom_rtc = std::nullopt;
|
Settings::values.custom_rtc = 0;
|
||||||
}
|
}
|
||||||
|
Settings::values.custom_rtc_enabled = custom_rtc_enabled;
|
||||||
|
|
||||||
ReadSetting("System", Settings::values.language_index);
|
ReadSetting("System", Settings::values.language_index);
|
||||||
ReadSetting("System", Settings::values.region_index);
|
ReadSetting("System", Settings::values.region_index);
|
||||||
|
@ -167,7 +169,7 @@ void Config::ReadValues() {
|
||||||
|
|
||||||
// Core
|
// Core
|
||||||
ReadSetting("Core", Settings::values.use_multi_core);
|
ReadSetting("Core", Settings::values.use_multi_core);
|
||||||
ReadSetting("Core", Settings::values.use_unsafe_extended_memory_layout);
|
ReadSetting("Core", Settings::values.memory_layout_mode);
|
||||||
|
|
||||||
// Cpu
|
// Cpu
|
||||||
ReadSetting("Cpu", Settings::values.cpu_accuracy);
|
ReadSetting("Cpu", Settings::values.cpu_accuracy);
|
||||||
|
@ -222,14 +224,17 @@ void Config::ReadValues() {
|
||||||
ReadSetting("Renderer", Settings::values.bg_blue);
|
ReadSetting("Renderer", Settings::values.bg_blue);
|
||||||
|
|
||||||
// Use GPU accuracy normal by default on Android
|
// Use GPU accuracy normal by default on Android
|
||||||
Settings::values.gpu_accuracy = static_cast<Settings::GPUAccuracy>(config->GetInteger(
|
Settings::values.gpu_accuracy = static_cast<Settings::GpuAccuracy>(config->GetInteger(
|
||||||
"Renderer", "gpu_accuracy", static_cast<u32>(Settings::GPUAccuracy::Normal)));
|
"Renderer", "gpu_accuracy", static_cast<u32>(Settings::GpuAccuracy::Normal)));
|
||||||
|
|
||||||
// Use GPU default anisotropic filtering on Android
|
// Use GPU default anisotropic filtering on Android
|
||||||
Settings::values.max_anisotropy = config->GetInteger("Renderer", "max_anisotropy", 1);
|
Settings::values.max_anisotropy =
|
||||||
|
static_cast<Settings::AnisotropyMode>(config->GetInteger("Renderer", "max_anisotropy", 1));
|
||||||
|
|
||||||
// Disable ASTC compute by default on Android
|
// Disable ASTC compute by default on Android
|
||||||
Settings::values.accelerate_astc = config->GetBoolean("Renderer", "accelerate_astc", false);
|
Settings::values.accelerate_astc.SetValue(
|
||||||
|
config->GetBoolean("Renderer", "accelerate_astc", false) ? Settings::AstcDecodeMode::Gpu
|
||||||
|
: Settings::AstcDecodeMode::Cpu);
|
||||||
|
|
||||||
// Enable asynchronous presentation by default on Android
|
// Enable asynchronous presentation by default on Android
|
||||||
Settings::values.async_presentation =
|
Settings::values.async_presentation =
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#endif
|
#endif
|
||||||
#include "audio_core/sink/null_sink.h"
|
#include "audio_core/sink/null_sink.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
|
#include "common/settings_enums.h"
|
||||||
|
|
||||||
namespace AudioCore::Sink {
|
namespace AudioCore::Sink {
|
||||||
namespace {
|
namespace {
|
||||||
|
@ -24,7 +25,7 @@ struct SinkDetails {
|
||||||
using LatencyFn = u32 (*)();
|
using LatencyFn = u32 (*)();
|
||||||
|
|
||||||
/// Name for this sink.
|
/// Name for this sink.
|
||||||
std::string_view id;
|
Settings::AudioEngine id;
|
||||||
/// A method to call to construct an instance of this type of sink.
|
/// A method to call to construct an instance of this type of sink.
|
||||||
FactoryFn factory;
|
FactoryFn factory;
|
||||||
/// A method to call to list available devices.
|
/// A method to call to list available devices.
|
||||||
|
@ -37,7 +38,7 @@ struct SinkDetails {
|
||||||
constexpr SinkDetails sink_details[] = {
|
constexpr SinkDetails sink_details[] = {
|
||||||
#ifdef HAVE_CUBEB
|
#ifdef HAVE_CUBEB
|
||||||
SinkDetails{
|
SinkDetails{
|
||||||
"cubeb",
|
Settings::AudioEngine::Cubeb,
|
||||||
[](std::string_view device_id) -> std::unique_ptr<Sink> {
|
[](std::string_view device_id) -> std::unique_ptr<Sink> {
|
||||||
return std::make_unique<CubebSink>(device_id);
|
return std::make_unique<CubebSink>(device_id);
|
||||||
},
|
},
|
||||||
|
@ -47,7 +48,7 @@ constexpr SinkDetails sink_details[] = {
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_SDL2
|
#ifdef HAVE_SDL2
|
||||||
SinkDetails{
|
SinkDetails{
|
||||||
"sdl2",
|
Settings::AudioEngine::Sdl2,
|
||||||
[](std::string_view device_id) -> std::unique_ptr<Sink> {
|
[](std::string_view device_id) -> std::unique_ptr<Sink> {
|
||||||
return std::make_unique<SDLSink>(device_id);
|
return std::make_unique<SDLSink>(device_id);
|
||||||
},
|
},
|
||||||
|
@ -55,46 +56,47 @@ constexpr SinkDetails sink_details[] = {
|
||||||
&GetSDLLatency,
|
&GetSDLLatency,
|
||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
SinkDetails{"null",
|
SinkDetails{Settings::AudioEngine::Null,
|
||||||
[](std::string_view device_id) -> std::unique_ptr<Sink> {
|
[](std::string_view device_id) -> std::unique_ptr<Sink> {
|
||||||
return std::make_unique<NullSink>(device_id);
|
return std::make_unique<NullSink>(device_id);
|
||||||
},
|
},
|
||||||
[](bool capture) { return std::vector<std::string>{"null"}; }, []() { return 0u; }},
|
[](bool capture) { return std::vector<std::string>{"null"}; }, []() { return 0u; }},
|
||||||
};
|
};
|
||||||
|
|
||||||
const SinkDetails& GetOutputSinkDetails(std::string_view sink_id) {
|
const SinkDetails& GetOutputSinkDetails(Settings::AudioEngine sink_id) {
|
||||||
const auto find_backend{[](std::string_view id) {
|
const auto find_backend{[](Settings::AudioEngine id) {
|
||||||
return std::find_if(std::begin(sink_details), std::end(sink_details),
|
return std::find_if(std::begin(sink_details), std::end(sink_details),
|
||||||
[&id](const auto& sink_detail) { return sink_detail.id == id; });
|
[&id](const auto& sink_detail) { return sink_detail.id == id; });
|
||||||
}};
|
}};
|
||||||
|
|
||||||
auto iter = find_backend(sink_id);
|
auto iter = find_backend(sink_id);
|
||||||
|
|
||||||
if (sink_id == "auto") {
|
if (sink_id == Settings::AudioEngine::Auto) {
|
||||||
// Auto-select a backend. Prefer CubeB, but it may report a large minimum latency which
|
// Auto-select a backend. Prefer CubeB, but it may report a large minimum latency which
|
||||||
// causes audio issues, in that case go with SDL.
|
// causes audio issues, in that case go with SDL.
|
||||||
#if defined(HAVE_CUBEB) && defined(HAVE_SDL2)
|
#if defined(HAVE_CUBEB) && defined(HAVE_SDL2)
|
||||||
iter = find_backend("cubeb");
|
iter = find_backend(Settings::AudioEngine::Cubeb);
|
||||||
if (iter->latency() > TargetSampleCount * 3) {
|
if (iter->latency() > TargetSampleCount * 3) {
|
||||||
iter = find_backend("sdl2");
|
iter = find_backend(Settings::AudioEngine::Sdl2);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
iter = std::begin(sink_details);
|
iter = std::begin(sink_details);
|
||||||
#endif
|
#endif
|
||||||
LOG_INFO(Service_Audio, "Auto-selecting the {} backend", iter->id);
|
LOG_INFO(Service_Audio, "Auto-selecting the {} backend",
|
||||||
|
Settings::CanonicalizeEnum(iter->id));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (iter == std::end(sink_details)) {
|
if (iter == std::end(sink_details)) {
|
||||||
LOG_ERROR(Audio, "Invalid sink_id {}", sink_id);
|
LOG_ERROR(Audio, "Invalid sink_id {}", Settings::CanonicalizeEnum(sink_id));
|
||||||
iter = find_backend("null");
|
iter = find_backend(Settings::AudioEngine::Null);
|
||||||
}
|
}
|
||||||
|
|
||||||
return *iter;
|
return *iter;
|
||||||
}
|
}
|
||||||
} // Anonymous namespace
|
} // Anonymous namespace
|
||||||
|
|
||||||
std::vector<std::string_view> GetSinkIDs() {
|
std::vector<Settings::AudioEngine> GetSinkIDs() {
|
||||||
std::vector<std::string_view> sink_ids(std::size(sink_details));
|
std::vector<Settings::AudioEngine> sink_ids(std::size(sink_details));
|
||||||
|
|
||||||
std::transform(std::begin(sink_details), std::end(sink_details), std::begin(sink_ids),
|
std::transform(std::begin(sink_details), std::end(sink_details), std::begin(sink_ids),
|
||||||
[](const auto& sink) { return sink.id; });
|
[](const auto& sink) { return sink.id; });
|
||||||
|
@ -102,11 +104,11 @@ std::vector<std::string_view> GetSinkIDs() {
|
||||||
return sink_ids;
|
return sink_ids;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> GetDeviceListForSink(std::string_view sink_id, bool capture) {
|
std::vector<std::string> GetDeviceListForSink(Settings::AudioEngine sink_id, bool capture) {
|
||||||
return GetOutputSinkDetails(sink_id).list_devices(capture);
|
return GetOutputSinkDetails(sink_id).list_devices(capture);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<Sink> CreateSinkFromID(std::string_view sink_id, std::string_view device_id) {
|
std::unique_ptr<Sink> CreateSinkFromID(Settings::AudioEngine sink_id, std::string_view device_id) {
|
||||||
return GetOutputSinkDetails(sink_id).factory(device_id);
|
return GetOutputSinkDetails(sink_id).factory(device_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,9 +3,11 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include "common/settings_enums.h"
|
||||||
|
|
||||||
namespace AudioCore {
|
namespace AudioCore {
|
||||||
class AudioManager;
|
class AudioManager;
|
||||||
|
@ -19,7 +21,7 @@ class Sink;
|
||||||
*
|
*
|
||||||
* @return Vector of available sink names.
|
* @return Vector of available sink names.
|
||||||
*/
|
*/
|
||||||
std::vector<std::string_view> GetSinkIDs();
|
std::vector<Settings::AudioEngine> GetSinkIDs();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the list of devices for a particular sink identified by the given ID.
|
* Gets the list of devices for a particular sink identified by the given ID.
|
||||||
|
@ -28,7 +30,7 @@ std::vector<std::string_view> GetSinkIDs();
|
||||||
* @param capture - Get capture (input) devices, or output devices?
|
* @param capture - Get capture (input) devices, or output devices?
|
||||||
* @return Vector of device names.
|
* @return Vector of device names.
|
||||||
*/
|
*/
|
||||||
std::vector<std::string> GetDeviceListForSink(std::string_view sink_id, bool capture);
|
std::vector<std::string> GetDeviceListForSink(Settings::AudioEngine sink_id, bool capture);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an audio sink identified by the given device ID.
|
* Creates an audio sink identified by the given device ID.
|
||||||
|
@ -37,7 +39,7 @@ std::vector<std::string> GetDeviceListForSink(std::string_view sink_id, bool cap
|
||||||
* @param device_id - Name of the device to create.
|
* @param device_id - Name of the device to create.
|
||||||
* @return Pointer to the created sink.
|
* @return Pointer to the created sink.
|
||||||
*/
|
*/
|
||||||
std::unique_ptr<Sink> CreateSinkFromID(std::string_view sink_id, std::string_view device_id);
|
std::unique_ptr<Sink> CreateSinkFromID(Settings::AudioEngine sink_id, std::string_view device_id);
|
||||||
|
|
||||||
} // namespace Sink
|
} // namespace Sink
|
||||||
} // namespace AudioCore
|
} // namespace AudioCore
|
||||||
|
|
|
@ -110,8 +110,12 @@ add_library(common STATIC
|
||||||
scratch_buffer.h
|
scratch_buffer.h
|
||||||
settings.cpp
|
settings.cpp
|
||||||
settings.h
|
settings.h
|
||||||
|
settings_common.cpp
|
||||||
|
settings_common.h
|
||||||
|
settings_enums.h
|
||||||
settings_input.cpp
|
settings_input.cpp
|
||||||
settings_input.h
|
settings_input.h
|
||||||
|
settings_setting.h
|
||||||
socket_types.h
|
socket_types.h
|
||||||
spin_lock.cpp
|
spin_lock.cpp
|
||||||
spin_lock.h
|
spin_lock.h
|
||||||
|
@ -193,9 +197,16 @@ if (MSVC)
|
||||||
/we4254 # 'operator': conversion from 'type1:field_bits' to 'type2:field_bits', possible loss of data
|
/we4254 # 'operator': conversion from 'type1:field_bits' to 'type2:field_bits', possible loss of data
|
||||||
/we4800 # Implicit conversion from 'type' to bool. Possible information loss
|
/we4800 # Implicit conversion from 'type' to bool. Possible information loss
|
||||||
)
|
)
|
||||||
else()
|
endif()
|
||||||
|
|
||||||
|
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||||
target_compile_options(common PRIVATE
|
target_compile_options(common PRIVATE
|
||||||
$<$<CXX_COMPILER_ID:Clang>:-fsized-deallocation>
|
-fsized-deallocation
|
||||||
|
-Werror=unreachable-code-aggressive
|
||||||
|
)
|
||||||
|
target_compile_definitions(common PRIVATE
|
||||||
|
# Clang 14 and earlier have errors when explicitly instantiating Settings::Setting
|
||||||
|
$<$<VERSION_LESS:$<CXX_COMPILER_VERSION>,15>:CANNOT_EXPLICITLY_INSTANTIATE>
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
|
@ -108,7 +108,7 @@ public:
|
||||||
|
|
||||||
using namespace Common::Literals;
|
using namespace Common::Literals;
|
||||||
// Prevent logs from exceeding a set maximum size in the event that log entries are spammed.
|
// Prevent logs from exceeding a set maximum size in the event that log entries are spammed.
|
||||||
const auto write_limit = Settings::values.extended_logging ? 1_GiB : 100_MiB;
|
const auto write_limit = Settings::values.extended_logging.GetValue() ? 1_GiB : 100_MiB;
|
||||||
const bool write_limit_exceeded = bytes_written > write_limit;
|
const bool write_limit_exceeded = bytes_written > write_limit;
|
||||||
if (entry.log_level >= Level::Error || write_limit_exceeded) {
|
if (entry.log_level >= Level::Error || write_limit_exceeded) {
|
||||||
if (write_limit_exceeded) {
|
if (write_limit_exceeded) {
|
||||||
|
|
|
@ -7,9 +7,16 @@
|
||||||
#include <exception>
|
#include <exception>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#endif
|
#endif
|
||||||
|
#include <compare>
|
||||||
|
#include <cstddef>
|
||||||
|
#include <filesystem>
|
||||||
|
#include <functional>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
|
#include <type_traits>
|
||||||
|
#include <fmt/core.h>
|
||||||
|
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
|
#include "common/fs/fs_util.h"
|
||||||
#include "common/fs/path_util.h"
|
#include "common/fs/path_util.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "common/settings.h"
|
#include "common/settings.h"
|
||||||
|
@ -17,11 +24,50 @@
|
||||||
|
|
||||||
namespace Settings {
|
namespace Settings {
|
||||||
|
|
||||||
Values values;
|
// Clang 14 and earlier have errors when explicitly instantiating these classes
|
||||||
static bool configuring_global = true;
|
#ifndef CANNOT_EXPLICITLY_INSTANTIATE
|
||||||
|
#define SETTING(TYPE, RANGED) template class Setting<TYPE, RANGED>
|
||||||
|
#define SWITCHABLE(TYPE, RANGED) template class SwitchableSetting<TYPE, RANGED>
|
||||||
|
|
||||||
std::string GetTimeZoneString() {
|
SETTING(AudioEngine, false);
|
||||||
const auto time_zone_index = static_cast<std::size_t>(values.time_zone_index.GetValue());
|
SETTING(bool, false);
|
||||||
|
SETTING(int, false);
|
||||||
|
SETTING(std::string, false);
|
||||||
|
SETTING(u16, false);
|
||||||
|
SWITCHABLE(AnisotropyMode, true);
|
||||||
|
SWITCHABLE(AntiAliasing, false);
|
||||||
|
SWITCHABLE(AspectRatio, true);
|
||||||
|
SWITCHABLE(AstcDecodeMode, true);
|
||||||
|
SWITCHABLE(AstcRecompression, true);
|
||||||
|
SWITCHABLE(AudioMode, true);
|
||||||
|
SWITCHABLE(CpuAccuracy, true);
|
||||||
|
SWITCHABLE(FullscreenMode, true);
|
||||||
|
SWITCHABLE(GpuAccuracy, true);
|
||||||
|
SWITCHABLE(Language, true);
|
||||||
|
SWITCHABLE(NvdecEmulation, false);
|
||||||
|
SWITCHABLE(Region, true);
|
||||||
|
SWITCHABLE(RendererBackend, true);
|
||||||
|
SWITCHABLE(ScalingFilter, false);
|
||||||
|
SWITCHABLE(ShaderBackend, true);
|
||||||
|
SWITCHABLE(TimeZone, true);
|
||||||
|
SETTING(VSyncMode, true);
|
||||||
|
SWITCHABLE(bool, false);
|
||||||
|
SWITCHABLE(int, false);
|
||||||
|
SWITCHABLE(int, true);
|
||||||
|
SWITCHABLE(s64, false);
|
||||||
|
SWITCHABLE(u16, true);
|
||||||
|
SWITCHABLE(u32, false);
|
||||||
|
SWITCHABLE(u8, false);
|
||||||
|
SWITCHABLE(u8, true);
|
||||||
|
|
||||||
|
#undef SETTING
|
||||||
|
#undef SWITCHABLE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Values values;
|
||||||
|
|
||||||
|
std::string GetTimeZoneString(TimeZone time_zone) {
|
||||||
|
const auto time_zone_index = static_cast<std::size_t>(time_zone);
|
||||||
ASSERT(time_zone_index < Common::TimeZone::GetTimeZoneStrings().size());
|
ASSERT(time_zone_index < Common::TimeZone::GetTimeZoneStrings().size());
|
||||||
|
|
||||||
std::string location_name;
|
std::string location_name;
|
||||||
|
@ -61,73 +107,35 @@ void LogSettings() {
|
||||||
};
|
};
|
||||||
|
|
||||||
LOG_INFO(Config, "yuzu Configuration:");
|
LOG_INFO(Config, "yuzu Configuration:");
|
||||||
log_setting("Controls_UseDockedMode", values.use_docked_mode.GetValue());
|
for (auto& [category, settings] : values.linkage.by_category) {
|
||||||
log_setting("System_RngSeed", values.rng_seed.GetValue().value_or(0));
|
for (const auto& setting : settings) {
|
||||||
log_setting("System_DeviceName", values.device_name.GetValue());
|
if (setting->Id() == values.yuzu_token.Id()) {
|
||||||
log_setting("System_CurrentUser", values.current_user.GetValue());
|
// Hide the token secret, for security reasons.
|
||||||
log_setting("System_LanguageIndex", values.language_index.GetValue());
|
continue;
|
||||||
log_setting("System_RegionIndex", values.region_index.GetValue());
|
}
|
||||||
log_setting("System_TimeZoneIndex", values.time_zone_index.GetValue());
|
|
||||||
log_setting("System_UnsafeMemoryLayout", values.use_unsafe_extended_memory_layout.GetValue());
|
const auto name = fmt::format(
|
||||||
log_setting("Core_UseMultiCore", values.use_multi_core.GetValue());
|
"{:c}{:c} {}.{}", setting->ToString() == setting->DefaultToString() ? '-' : 'M',
|
||||||
log_setting("CPU_Accuracy", values.cpu_accuracy.GetValue());
|
setting->UsingGlobal() ? '-' : 'C', TranslateCategory(category),
|
||||||
log_setting("Renderer_UseResolutionScaling", values.resolution_setup.GetValue());
|
setting->GetLabel());
|
||||||
log_setting("Renderer_ScalingFilter", values.scaling_filter.GetValue());
|
|
||||||
log_setting("Renderer_FSRSlider", values.fsr_sharpening_slider.GetValue());
|
log_setting(name, setting->Canonicalize());
|
||||||
log_setting("Renderer_AntiAliasing", values.anti_aliasing.GetValue());
|
}
|
||||||
log_setting("Renderer_UseSpeedLimit", values.use_speed_limit.GetValue());
|
}
|
||||||
log_setting("Renderer_SpeedLimit", values.speed_limit.GetValue());
|
|
||||||
log_setting("Renderer_UseDiskShaderCache", values.use_disk_shader_cache.GetValue());
|
|
||||||
log_setting("Renderer_GPUAccuracyLevel", values.gpu_accuracy.GetValue());
|
|
||||||
log_setting("Renderer_UseAsynchronousGpuEmulation",
|
|
||||||
values.use_asynchronous_gpu_emulation.GetValue());
|
|
||||||
log_setting("Renderer_NvdecEmulation", values.nvdec_emulation.GetValue());
|
|
||||||
log_setting("Renderer_AccelerateASTC", values.accelerate_astc.GetValue());
|
|
||||||
log_setting("Renderer_AsyncASTC", values.async_astc.GetValue());
|
|
||||||
log_setting("Renderer_AstcRecompression", values.astc_recompression.GetValue());
|
|
||||||
log_setting("Renderer_UseVsync", values.vsync_mode.GetValue());
|
|
||||||
log_setting("Renderer_UseReactiveFlushing", values.use_reactive_flushing.GetValue());
|
|
||||||
log_setting("Renderer_ShaderBackend", values.shader_backend.GetValue());
|
|
||||||
log_setting("Renderer_UseAsynchronousShaders", values.use_asynchronous_shaders.GetValue());
|
|
||||||
log_setting("Renderer_AnisotropicFilteringLevel", values.max_anisotropy.GetValue());
|
|
||||||
log_setting("Audio_OutputEngine", values.sink_id.GetValue());
|
|
||||||
log_setting("Audio_OutputDevice", values.audio_output_device_id.GetValue());
|
|
||||||
log_setting("Audio_InputDevice", values.audio_input_device_id.GetValue());
|
|
||||||
log_setting("DataStorage_UseVirtualSd", values.use_virtual_sd.GetValue());
|
|
||||||
log_path("DataStorage_CacheDir", Common::FS::GetYuzuPath(Common::FS::YuzuPath::CacheDir));
|
log_path("DataStorage_CacheDir", Common::FS::GetYuzuPath(Common::FS::YuzuPath::CacheDir));
|
||||||
log_path("DataStorage_ConfigDir", Common::FS::GetYuzuPath(Common::FS::YuzuPath::ConfigDir));
|
log_path("DataStorage_ConfigDir", Common::FS::GetYuzuPath(Common::FS::YuzuPath::ConfigDir));
|
||||||
log_path("DataStorage_LoadDir", Common::FS::GetYuzuPath(Common::FS::YuzuPath::LoadDir));
|
log_path("DataStorage_LoadDir", Common::FS::GetYuzuPath(Common::FS::YuzuPath::LoadDir));
|
||||||
log_path("DataStorage_NANDDir", Common::FS::GetYuzuPath(Common::FS::YuzuPath::NANDDir));
|
log_path("DataStorage_NANDDir", Common::FS::GetYuzuPath(Common::FS::YuzuPath::NANDDir));
|
||||||
log_path("DataStorage_SDMCDir", Common::FS::GetYuzuPath(Common::FS::YuzuPath::SDMCDir));
|
log_path("DataStorage_SDMCDir", Common::FS::GetYuzuPath(Common::FS::YuzuPath::SDMCDir));
|
||||||
log_setting("Debugging_ProgramArgs", values.program_args.GetValue());
|
|
||||||
log_setting("Debugging_GDBStub", values.use_gdbstub.GetValue());
|
|
||||||
log_setting("Input_EnableMotion", values.motion_enabled.GetValue());
|
|
||||||
log_setting("Input_EnableVibration", values.vibration_enabled.GetValue());
|
|
||||||
log_setting("Input_EnableTouch", values.touchscreen.enabled);
|
|
||||||
log_setting("Input_EnableMouse", values.mouse_enabled.GetValue());
|
|
||||||
log_setting("Input_EnableKeyboard", values.keyboard_enabled.GetValue());
|
|
||||||
log_setting("Input_EnableRingController", values.enable_ring_controller.GetValue());
|
|
||||||
log_setting("Input_EnableIrSensor", values.enable_ir_sensor.GetValue());
|
|
||||||
log_setting("Input_EnableCustomJoycon", values.enable_joycon_driver.GetValue());
|
|
||||||
log_setting("Input_EnableCustomProController", values.enable_procon_driver.GetValue());
|
|
||||||
log_setting("Input_EnableRawInput", values.enable_raw_input.GetValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsConfiguringGlobal() {
|
|
||||||
return configuring_global;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetConfiguringGlobal(bool is_global) {
|
|
||||||
configuring_global = is_global;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsGPULevelExtreme() {
|
bool IsGPULevelExtreme() {
|
||||||
return values.gpu_accuracy.GetValue() == GPUAccuracy::Extreme;
|
return values.gpu_accuracy.GetValue() == GpuAccuracy::Extreme;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsGPULevelHigh() {
|
bool IsGPULevelHigh() {
|
||||||
return values.gpu_accuracy.GetValue() == GPUAccuracy::Extreme ||
|
return values.gpu_accuracy.GetValue() == GpuAccuracy::Extreme ||
|
||||||
values.gpu_accuracy.GetValue() == GPUAccuracy::High;
|
values.gpu_accuracy.GetValue() == GpuAccuracy::High;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsFastmemEnabled() {
|
bool IsFastmemEnabled() {
|
||||||
|
@ -144,6 +152,61 @@ float Volume() {
|
||||||
return values.volume.GetValue() / static_cast<f32>(values.volume.GetDefault());
|
return values.volume.GetValue() / static_cast<f32>(values.volume.GetDefault());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char* TranslateCategory(Category category) {
|
||||||
|
switch (category) {
|
||||||
|
case Category::Audio:
|
||||||
|
return "Audio";
|
||||||
|
case Category::Core:
|
||||||
|
return "Core";
|
||||||
|
case Category::Cpu:
|
||||||
|
case Category::CpuDebug:
|
||||||
|
case Category::CpuUnsafe:
|
||||||
|
return "Cpu";
|
||||||
|
case Category::Renderer:
|
||||||
|
case Category::RendererAdvanced:
|
||||||
|
case Category::RendererDebug:
|
||||||
|
return "Renderer";
|
||||||
|
case Category::System:
|
||||||
|
case Category::SystemAudio:
|
||||||
|
return "System";
|
||||||
|
case Category::DataStorage:
|
||||||
|
return "Data Storage";
|
||||||
|
case Category::Debugging:
|
||||||
|
case Category::DebuggingGraphics:
|
||||||
|
return "Debugging";
|
||||||
|
case Category::Miscellaneous:
|
||||||
|
return "Miscellaneous";
|
||||||
|
case Category::Network:
|
||||||
|
return "Network";
|
||||||
|
case Category::WebService:
|
||||||
|
return "WebService";
|
||||||
|
case Category::AddOns:
|
||||||
|
return "DisabledAddOns";
|
||||||
|
case Category::Controls:
|
||||||
|
return "Controls";
|
||||||
|
case Category::Ui:
|
||||||
|
case Category::UiGeneral:
|
||||||
|
return "UI";
|
||||||
|
case Category::UiLayout:
|
||||||
|
return "UiLayout";
|
||||||
|
case Category::UiGameList:
|
||||||
|
return "UiGameList";
|
||||||
|
case Category::Screenshots:
|
||||||
|
return "Screenshots";
|
||||||
|
case Category::Shortcuts:
|
||||||
|
return "Shortcuts";
|
||||||
|
case Category::Multiplayer:
|
||||||
|
return "Multiplayer";
|
||||||
|
case Category::Services:
|
||||||
|
return "Services";
|
||||||
|
case Category::Paths:
|
||||||
|
return "Paths";
|
||||||
|
case Category::MaxEnum:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return "Miscellaneous";
|
||||||
|
}
|
||||||
|
|
||||||
void UpdateRescalingInfo() {
|
void UpdateRescalingInfo() {
|
||||||
const auto setup = values.resolution_setup.GetValue();
|
const auto setup = values.resolution_setup.GetValue();
|
||||||
auto& info = values.resolution_info;
|
auto& info = values.resolution_info;
|
||||||
|
@ -212,66 +275,19 @@ void RestoreGlobalState(bool is_powered_on) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Audio
|
for (const auto& reset : values.linkage.restore_functions) {
|
||||||
values.volume.SetGlobal(true);
|
reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Core
|
static bool configuring_global = true;
|
||||||
values.use_multi_core.SetGlobal(true);
|
|
||||||
values.use_unsafe_extended_memory_layout.SetGlobal(true);
|
|
||||||
|
|
||||||
// CPU
|
bool IsConfiguringGlobal() {
|
||||||
values.cpu_accuracy.SetGlobal(true);
|
return configuring_global;
|
||||||
values.cpuopt_unsafe_unfuse_fma.SetGlobal(true);
|
}
|
||||||
values.cpuopt_unsafe_reduce_fp_error.SetGlobal(true);
|
|
||||||
values.cpuopt_unsafe_ignore_standard_fpcr.SetGlobal(true);
|
|
||||||
values.cpuopt_unsafe_inaccurate_nan.SetGlobal(true);
|
|
||||||
values.cpuopt_unsafe_fastmem_check.SetGlobal(true);
|
|
||||||
values.cpuopt_unsafe_ignore_global_monitor.SetGlobal(true);
|
|
||||||
|
|
||||||
// Renderer
|
void SetConfiguringGlobal(bool is_global) {
|
||||||
values.fsr_sharpening_slider.SetGlobal(true);
|
configuring_global = is_global;
|
||||||
values.renderer_backend.SetGlobal(true);
|
|
||||||
values.async_presentation.SetGlobal(true);
|
|
||||||
values.renderer_force_max_clock.SetGlobal(true);
|
|
||||||
values.vulkan_device.SetGlobal(true);
|
|
||||||
values.fullscreen_mode.SetGlobal(true);
|
|
||||||
values.aspect_ratio.SetGlobal(true);
|
|
||||||
values.resolution_setup.SetGlobal(true);
|
|
||||||
values.scaling_filter.SetGlobal(true);
|
|
||||||
values.anti_aliasing.SetGlobal(true);
|
|
||||||
values.max_anisotropy.SetGlobal(true);
|
|
||||||
values.use_speed_limit.SetGlobal(true);
|
|
||||||
values.speed_limit.SetGlobal(true);
|
|
||||||
values.use_disk_shader_cache.SetGlobal(true);
|
|
||||||
values.gpu_accuracy.SetGlobal(true);
|
|
||||||
values.use_asynchronous_gpu_emulation.SetGlobal(true);
|
|
||||||
values.nvdec_emulation.SetGlobal(true);
|
|
||||||
values.accelerate_astc.SetGlobal(true);
|
|
||||||
values.async_astc.SetGlobal(true);
|
|
||||||
values.astc_recompression.SetGlobal(true);
|
|
||||||
values.use_reactive_flushing.SetGlobal(true);
|
|
||||||
values.shader_backend.SetGlobal(true);
|
|
||||||
values.use_asynchronous_shaders.SetGlobal(true);
|
|
||||||
values.use_fast_gpu_time.SetGlobal(true);
|
|
||||||
values.use_vulkan_driver_pipeline_cache.SetGlobal(true);
|
|
||||||
values.bg_red.SetGlobal(true);
|
|
||||||
values.bg_green.SetGlobal(true);
|
|
||||||
values.bg_blue.SetGlobal(true);
|
|
||||||
values.enable_compute_pipelines.SetGlobal(true);
|
|
||||||
values.use_video_framerate.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.sound_index.SetGlobal(true);
|
|
||||||
|
|
||||||
// Controls
|
|
||||||
values.players.SetGlobal(true);
|
|
||||||
values.use_docked_mode.SetGlobal(true);
|
|
||||||
values.vibration_enabled.SetGlobal(true);
|
|
||||||
values.motion_enabled.SetGlobal(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Settings
|
} // namespace Settings
|
||||||
|
|
|
@ -6,95 +6,21 @@
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <optional>
|
#include <memory>
|
||||||
|
#include <stdexcept>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
#include "common/settings_common.h"
|
||||||
|
#include "common/settings_enums.h"
|
||||||
#include "common/settings_input.h"
|
#include "common/settings_input.h"
|
||||||
|
#include "common/settings_setting.h"
|
||||||
|
|
||||||
namespace Settings {
|
namespace Settings {
|
||||||
|
|
||||||
enum class VSyncMode : u32 {
|
const char* TranslateCategory(Settings::Category category);
|
||||||
Immediate = 0,
|
|
||||||
Mailbox = 1,
|
|
||||||
FIFO = 2,
|
|
||||||
FIFORelaxed = 3,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class RendererBackend : u32 {
|
|
||||||
OpenGL = 0,
|
|
||||||
Vulkan = 1,
|
|
||||||
Null = 2,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class ShaderBackend : u32 {
|
|
||||||
GLSL = 0,
|
|
||||||
GLASM = 1,
|
|
||||||
SPIRV = 2,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class GPUAccuracy : u32 {
|
|
||||||
Normal = 0,
|
|
||||||
High = 1,
|
|
||||||
Extreme = 2,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class CPUAccuracy : u32 {
|
|
||||||
Auto = 0,
|
|
||||||
Accurate = 1,
|
|
||||||
Unsafe = 2,
|
|
||||||
Paranoid = 3,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class FullscreenMode : u32 {
|
|
||||||
Borderless = 0,
|
|
||||||
Exclusive = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class NvdecEmulation : u32 {
|
|
||||||
Off = 0,
|
|
||||||
CPU = 1,
|
|
||||||
GPU = 2,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class ResolutionSetup : u32 {
|
|
||||||
Res1_2X = 0,
|
|
||||||
Res3_4X = 1,
|
|
||||||
Res1X = 2,
|
|
||||||
Res3_2X = 3,
|
|
||||||
Res2X = 4,
|
|
||||||
Res3X = 5,
|
|
||||||
Res4X = 6,
|
|
||||||
Res5X = 7,
|
|
||||||
Res6X = 8,
|
|
||||||
Res7X = 9,
|
|
||||||
Res8X = 10,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class ScalingFilter : u32 {
|
|
||||||
NearestNeighbor = 0,
|
|
||||||
Bilinear = 1,
|
|
||||||
Bicubic = 2,
|
|
||||||
Gaussian = 3,
|
|
||||||
ScaleForce = 4,
|
|
||||||
Fsr = 5,
|
|
||||||
LastFilter = Fsr,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class AntiAliasing : u32 {
|
|
||||||
None = 0,
|
|
||||||
Fxaa = 1,
|
|
||||||
Smaa = 2,
|
|
||||||
LastAA = Smaa,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class AstcRecompression : u32 {
|
|
||||||
Uncompressed = 0,
|
|
||||||
Bc1 = 1,
|
|
||||||
Bc3 = 2,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ResolutionScalingInfo {
|
struct ResolutionScalingInfo {
|
||||||
u32 up_scale{1};
|
u32 up_scale{1};
|
||||||
|
@ -119,239 +45,47 @@ struct ResolutionScalingInfo {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/** The Setting class is a simple resource manager. It defines a label and default value alongside
|
#ifndef CANNOT_EXPLICITLY_INSTANTIATE
|
||||||
* the actual value of the setting for simpler and less-error prone use with frontend
|
// Instantiate the classes elsewhere (settings.cpp) to reduce compiler/linker work
|
||||||
* configurations. Specifying a default value and label is required. A minimum and maximum range can
|
#define SETTING(TYPE, RANGED) extern template class Setting<TYPE, RANGED>
|
||||||
* be specified for sanitization.
|
#define SWITCHABLE(TYPE, RANGED) extern template class SwitchableSetting<TYPE, RANGED>
|
||||||
*/
|
|
||||||
template <typename Type, bool ranged = false>
|
|
||||||
class Setting {
|
|
||||||
protected:
|
|
||||||
Setting() = default;
|
|
||||||
|
|
||||||
/**
|
SETTING(AudioEngine, false);
|
||||||
* Only sets the setting to the given initializer, leaving the other members to their default
|
SETTING(bool, false);
|
||||||
* initializers.
|
SETTING(int, false);
|
||||||
*
|
SETTING(s32, false);
|
||||||
* @param global_val Initial value of the setting
|
SETTING(std::string, false);
|
||||||
*/
|
SETTING(std::string, false);
|
||||||
explicit Setting(const Type& val) : value{val} {}
|
SETTING(u16, false);
|
||||||
|
SWITCHABLE(AnisotropyMode, true);
|
||||||
|
SWITCHABLE(AntiAliasing, false);
|
||||||
|
SWITCHABLE(AspectRatio, true);
|
||||||
|
SWITCHABLE(AstcDecodeMode, true);
|
||||||
|
SWITCHABLE(AstcRecompression, true);
|
||||||
|
SWITCHABLE(AudioMode, true);
|
||||||
|
SWITCHABLE(CpuAccuracy, true);
|
||||||
|
SWITCHABLE(FullscreenMode, true);
|
||||||
|
SWITCHABLE(GpuAccuracy, true);
|
||||||
|
SWITCHABLE(Language, true);
|
||||||
|
SWITCHABLE(NvdecEmulation, false);
|
||||||
|
SWITCHABLE(Region, true);
|
||||||
|
SWITCHABLE(RendererBackend, true);
|
||||||
|
SWITCHABLE(ScalingFilter, false);
|
||||||
|
SWITCHABLE(ShaderBackend, true);
|
||||||
|
SWITCHABLE(TimeZone, true);
|
||||||
|
SETTING(VSyncMode, true);
|
||||||
|
SWITCHABLE(bool, false);
|
||||||
|
SWITCHABLE(int, false);
|
||||||
|
SWITCHABLE(int, true);
|
||||||
|
SWITCHABLE(s64, false);
|
||||||
|
SWITCHABLE(u16, true);
|
||||||
|
SWITCHABLE(u32, false);
|
||||||
|
SWITCHABLE(u8, false);
|
||||||
|
SWITCHABLE(u8, true);
|
||||||
|
|
||||||
public:
|
#undef SETTING
|
||||||
/**
|
#undef SWITCHABLE
|
||||||
* Sets a default value, label, and setting value.
|
#endif
|
||||||
*
|
|
||||||
* @param default_val Initial value of the setting, and default value of the setting
|
|
||||||
* @param name Label for the setting
|
|
||||||
*/
|
|
||||||
explicit Setting(const Type& default_val, const std::string& name)
|
|
||||||
requires(!ranged)
|
|
||||||
: value{default_val}, default_value{default_val}, label{name} {}
|
|
||||||
virtual ~Setting() = default;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets a default value, minimum value, maximum value, and label.
|
|
||||||
*
|
|
||||||
* @param default_val Initial value of the setting, and default value of the setting
|
|
||||||
* @param min_val Sets the minimum allowed value of the setting
|
|
||||||
* @param max_val Sets the maximum allowed value of the setting
|
|
||||||
* @param name Label for the setting
|
|
||||||
*/
|
|
||||||
explicit Setting(const Type& default_val, const Type& min_val, const Type& max_val,
|
|
||||||
const std::string& name)
|
|
||||||
requires(ranged)
|
|
||||||
: value{default_val},
|
|
||||||
default_value{default_val}, maximum{max_val}, minimum{min_val}, label{name} {}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a reference to the setting's value.
|
|
||||||
*
|
|
||||||
* @returns A reference to the setting
|
|
||||||
*/
|
|
||||||
[[nodiscard]] virtual const Type& GetValue() const {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the setting to the given value.
|
|
||||||
*
|
|
||||||
* @param val The desired value
|
|
||||||
*/
|
|
||||||
virtual void SetValue(const Type& val) {
|
|
||||||
Type temp{ranged ? std::clamp(val, minimum, maximum) : val};
|
|
||||||
std::swap(value, temp);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the value that this setting was created with.
|
|
||||||
*
|
|
||||||
* @returns A reference to the default value
|
|
||||||
*/
|
|
||||||
[[nodiscard]] const Type& GetDefault() const {
|
|
||||||
return default_value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the label this setting was created with.
|
|
||||||
*
|
|
||||||
* @returns A reference to the label
|
|
||||||
*/
|
|
||||||
[[nodiscard]] const std::string& GetLabel() const {
|
|
||||||
return label;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Assigns a value to the setting.
|
|
||||||
*
|
|
||||||
* @param val The desired setting value
|
|
||||||
*
|
|
||||||
* @returns A reference to the setting
|
|
||||||
*/
|
|
||||||
virtual const Type& operator=(const Type& val) {
|
|
||||||
Type temp{ranged ? std::clamp(val, minimum, maximum) : val};
|
|
||||||
std::swap(value, temp);
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a reference to the setting.
|
|
||||||
*
|
|
||||||
* @returns A reference to the setting
|
|
||||||
*/
|
|
||||||
explicit virtual operator const Type&() const {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
Type value{}; ///< The setting
|
|
||||||
const Type default_value{}; ///< The default value
|
|
||||||
const Type maximum{}; ///< Maximum allowed value of the setting
|
|
||||||
const Type minimum{}; ///< Minimum allowed value of the setting
|
|
||||||
const std::string label{}; ///< The setting's label
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The SwitchableSetting class is a slightly more complex version of the Setting class. This adds a
|
|
||||||
* custom setting to switch to when a guest application specifically requires it. The effect is that
|
|
||||||
* other components of the emulator can access the setting's intended value without any need for the
|
|
||||||
* component to ask whether the custom or global setting is needed at the moment.
|
|
||||||
*
|
|
||||||
* By default, the global setting is used.
|
|
||||||
*/
|
|
||||||
template <typename Type, bool ranged = false>
|
|
||||||
class SwitchableSetting : virtual public Setting<Type, ranged> {
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
* Sets a default value, label, and setting value.
|
|
||||||
*
|
|
||||||
* @param default_val Initial value of the setting, and default value of the setting
|
|
||||||
* @param name Label for the setting
|
|
||||||
*/
|
|
||||||
explicit SwitchableSetting(const Type& default_val, const std::string& name)
|
|
||||||
requires(!ranged)
|
|
||||||
: Setting<Type>{default_val, name} {}
|
|
||||||
virtual ~SwitchableSetting() = default;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets a default value, minimum value, maximum value, and label.
|
|
||||||
*
|
|
||||||
* @param default_val Initial value of the setting, and default value of the setting
|
|
||||||
* @param min_val Sets the minimum allowed value of the setting
|
|
||||||
* @param max_val Sets the maximum allowed value of the setting
|
|
||||||
* @param name Label for the setting
|
|
||||||
*/
|
|
||||||
explicit SwitchableSetting(const Type& default_val, const Type& min_val, const Type& max_val,
|
|
||||||
const std::string& name)
|
|
||||||
requires(ranged)
|
|
||||||
: Setting<Type, true>{default_val, min_val, max_val, name} {}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tells this setting to represent either the global or custom setting when other member
|
|
||||||
* functions are used.
|
|
||||||
*
|
|
||||||
* @param to_global Whether to use the global or custom setting.
|
|
||||||
*/
|
|
||||||
void SetGlobal(bool to_global) {
|
|
||||||
use_global = to_global;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns whether this setting is using the global setting or not.
|
|
||||||
*
|
|
||||||
* @returns The global state
|
|
||||||
*/
|
|
||||||
[[nodiscard]] bool UsingGlobal() const {
|
|
||||||
return use_global;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns either the global or custom setting depending on the values of this setting's global
|
|
||||||
* state or if the global value was specifically requested.
|
|
||||||
*
|
|
||||||
* @param need_global Request global value regardless of setting's state; defaults to false
|
|
||||||
*
|
|
||||||
* @returns The required value of the setting
|
|
||||||
*/
|
|
||||||
[[nodiscard]] virtual const Type& GetValue() const override {
|
|
||||||
if (use_global) {
|
|
||||||
return this->value;
|
|
||||||
}
|
|
||||||
return custom;
|
|
||||||
}
|
|
||||||
[[nodiscard]] virtual const Type& GetValue(bool need_global) const {
|
|
||||||
if (use_global || need_global) {
|
|
||||||
return this->value;
|
|
||||||
}
|
|
||||||
return custom;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the current setting value depending on the global state.
|
|
||||||
*
|
|
||||||
* @param val The new value
|
|
||||||
*/
|
|
||||||
void SetValue(const Type& val) override {
|
|
||||||
Type temp{ranged ? std::clamp(val, this->minimum, this->maximum) : val};
|
|
||||||
if (use_global) {
|
|
||||||
std::swap(this->value, temp);
|
|
||||||
} else {
|
|
||||||
std::swap(custom, temp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Assigns the current setting value depending on the global state.
|
|
||||||
*
|
|
||||||
* @param val The new value
|
|
||||||
*
|
|
||||||
* @returns A reference to the current setting value
|
|
||||||
*/
|
|
||||||
const Type& operator=(const Type& val) override {
|
|
||||||
Type temp{ranged ? std::clamp(val, this->minimum, this->maximum) : val};
|
|
||||||
if (use_global) {
|
|
||||||
std::swap(this->value, temp);
|
|
||||||
return this->value;
|
|
||||||
}
|
|
||||||
std::swap(custom, temp);
|
|
||||||
return custom;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the current setting value depending on the global state.
|
|
||||||
*
|
|
||||||
* @returns A reference to the current setting value
|
|
||||||
*/
|
|
||||||
virtual explicit operator const Type&() const override {
|
|
||||||
if (use_global) {
|
|
||||||
return this->value;
|
|
||||||
}
|
|
||||||
return custom;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
bool use_global{true}; ///< The setting's global state
|
|
||||||
Type custom{}; ///< The custom value of the setting
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The InputSetting class allows for getting a reference to either the global or custom members.
|
* The InputSetting class allows for getting a reference to either the global or custom members.
|
||||||
|
@ -391,208 +125,388 @@ struct TouchFromButtonMap {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Values {
|
struct Values {
|
||||||
|
Linkage linkage{};
|
||||||
|
|
||||||
// Audio
|
// Audio
|
||||||
Setting<std::string> sink_id{"auto", "output_engine"};
|
Setting<AudioEngine> sink_id{linkage, AudioEngine::Auto, "output_engine", Category::Audio,
|
||||||
Setting<std::string> audio_output_device_id{"auto", "output_device"};
|
Specialization::RuntimeList};
|
||||||
Setting<std::string> audio_input_device_id{"auto", "input_device"};
|
Setting<std::string> audio_output_device_id{linkage, "auto", "output_device", Category::Audio,
|
||||||
Setting<bool> audio_muted{false, "audio_muted"};
|
Specialization::RuntimeList};
|
||||||
SwitchableSetting<u8, true> volume{100, 0, 200, "volume"};
|
Setting<std::string> audio_input_device_id{linkage, "auto", "input_device", Category::Audio,
|
||||||
Setting<bool> dump_audio_commands{false, "dump_audio_commands"};
|
Specialization::RuntimeList};
|
||||||
|
SwitchableSetting<AudioMode, true> sound_index{
|
||||||
|
linkage, AudioMode::Stereo, AudioMode::Mono, AudioMode::Surround,
|
||||||
|
"sound_index", Category::SystemAudio, Specialization::Default, true,
|
||||||
|
true};
|
||||||
|
SwitchableSetting<u8, true> volume{linkage,
|
||||||
|
100,
|
||||||
|
0,
|
||||||
|
200,
|
||||||
|
"volume",
|
||||||
|
Category::Audio,
|
||||||
|
Specialization::Scalar | Specialization::Percentage,
|
||||||
|
true,
|
||||||
|
true};
|
||||||
|
Setting<bool, false> audio_muted{
|
||||||
|
linkage, false, "audio_muted", Category::Audio, Specialization::Default, false, true};
|
||||||
|
Setting<bool, false> dump_audio_commands{
|
||||||
|
linkage, false, "dump_audio_commands", Category::Audio, Specialization::Default, false};
|
||||||
|
|
||||||
// Core
|
// Core
|
||||||
SwitchableSetting<bool> use_multi_core{true, "use_multi_core"};
|
SwitchableSetting<bool> use_multi_core{linkage, true, "use_multi_core", Category::Core};
|
||||||
SwitchableSetting<bool> use_unsafe_extended_memory_layout{false,
|
SwitchableSetting<MemoryLayout, true> memory_layout_mode{linkage,
|
||||||
"use_unsafe_extended_memory_layout"};
|
MemoryLayout::Memory_4Gb,
|
||||||
|
MemoryLayout::Memory_4Gb,
|
||||||
|
MemoryLayout::Memory_8Gb,
|
||||||
|
"memory_layout_mode",
|
||||||
|
Category::Core};
|
||||||
|
SwitchableSetting<bool> use_speed_limit{
|
||||||
|
linkage, true, "use_speed_limit", Category::Core, Specialization::Paired, false, true};
|
||||||
|
SwitchableSetting<u16, true> speed_limit{linkage,
|
||||||
|
100,
|
||||||
|
0,
|
||||||
|
9999,
|
||||||
|
"speed_limit",
|
||||||
|
Category::Core,
|
||||||
|
Specialization::Countable | Specialization::Percentage,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
&use_speed_limit};
|
||||||
|
|
||||||
// Cpu
|
// Cpu
|
||||||
SwitchableSetting<CPUAccuracy, true> cpu_accuracy{CPUAccuracy::Auto, CPUAccuracy::Auto,
|
SwitchableSetting<CpuAccuracy, true> cpu_accuracy{linkage, CpuAccuracy::Auto,
|
||||||
CPUAccuracy::Paranoid, "cpu_accuracy"};
|
CpuAccuracy::Auto, CpuAccuracy::Paranoid,
|
||||||
// TODO: remove cpu_accuracy_first_time, migration setting added 8 July 2021
|
"cpu_accuracy", Category::Cpu};
|
||||||
Setting<bool> cpu_accuracy_first_time{true, "cpu_accuracy_first_time"};
|
Setting<bool> cpu_debug_mode{linkage, false, "cpu_debug_mode", Category::CpuDebug};
|
||||||
Setting<bool> cpu_debug_mode{false, "cpu_debug_mode"};
|
|
||||||
|
|
||||||
Setting<bool> cpuopt_page_tables{true, "cpuopt_page_tables"};
|
Setting<bool> cpuopt_page_tables{linkage, true, "cpuopt_page_tables", Category::CpuDebug};
|
||||||
Setting<bool> cpuopt_block_linking{true, "cpuopt_block_linking"};
|
Setting<bool> cpuopt_block_linking{linkage, true, "cpuopt_block_linking", Category::CpuDebug};
|
||||||
Setting<bool> cpuopt_return_stack_buffer{true, "cpuopt_return_stack_buffer"};
|
Setting<bool> cpuopt_return_stack_buffer{linkage, true, "cpuopt_return_stack_buffer",
|
||||||
Setting<bool> cpuopt_fast_dispatcher{true, "cpuopt_fast_dispatcher"};
|
Category::CpuDebug};
|
||||||
Setting<bool> cpuopt_context_elimination{true, "cpuopt_context_elimination"};
|
Setting<bool> cpuopt_fast_dispatcher{linkage, true, "cpuopt_fast_dispatcher",
|
||||||
Setting<bool> cpuopt_const_prop{true, "cpuopt_const_prop"};
|
Category::CpuDebug};
|
||||||
Setting<bool> cpuopt_misc_ir{true, "cpuopt_misc_ir"};
|
Setting<bool> cpuopt_context_elimination{linkage, true, "cpuopt_context_elimination",
|
||||||
Setting<bool> cpuopt_reduce_misalign_checks{true, "cpuopt_reduce_misalign_checks"};
|
Category::CpuDebug};
|
||||||
Setting<bool> cpuopt_fastmem{true, "cpuopt_fastmem"};
|
Setting<bool> cpuopt_const_prop{linkage, true, "cpuopt_const_prop", Category::CpuDebug};
|
||||||
Setting<bool> cpuopt_fastmem_exclusives{true, "cpuopt_fastmem_exclusives"};
|
Setting<bool> cpuopt_misc_ir{linkage, true, "cpuopt_misc_ir", Category::CpuDebug};
|
||||||
Setting<bool> cpuopt_recompile_exclusives{true, "cpuopt_recompile_exclusives"};
|
Setting<bool> cpuopt_reduce_misalign_checks{linkage, true, "cpuopt_reduce_misalign_checks",
|
||||||
Setting<bool> cpuopt_ignore_memory_aborts{true, "cpuopt_ignore_memory_aborts"};
|
Category::CpuDebug};
|
||||||
|
Setting<bool> cpuopt_fastmem{linkage, true, "cpuopt_fastmem", Category::CpuDebug};
|
||||||
|
Setting<bool> cpuopt_fastmem_exclusives{linkage, true, "cpuopt_fastmem_exclusives",
|
||||||
|
Category::CpuDebug};
|
||||||
|
Setting<bool> cpuopt_recompile_exclusives{linkage, true, "cpuopt_recompile_exclusives",
|
||||||
|
Category::CpuDebug};
|
||||||
|
Setting<bool> cpuopt_ignore_memory_aborts{linkage, true, "cpuopt_ignore_memory_aborts",
|
||||||
|
Category::CpuDebug};
|
||||||
|
|
||||||
SwitchableSetting<bool> cpuopt_unsafe_unfuse_fma{true, "cpuopt_unsafe_unfuse_fma"};
|
SwitchableSetting<bool> cpuopt_unsafe_unfuse_fma{linkage, true, "cpuopt_unsafe_unfuse_fma",
|
||||||
SwitchableSetting<bool> cpuopt_unsafe_reduce_fp_error{true, "cpuopt_unsafe_reduce_fp_error"};
|
Category::CpuUnsafe};
|
||||||
|
SwitchableSetting<bool> cpuopt_unsafe_reduce_fp_error{
|
||||||
|
linkage, true, "cpuopt_unsafe_reduce_fp_error", Category::CpuUnsafe};
|
||||||
SwitchableSetting<bool> cpuopt_unsafe_ignore_standard_fpcr{
|
SwitchableSetting<bool> cpuopt_unsafe_ignore_standard_fpcr{
|
||||||
true, "cpuopt_unsafe_ignore_standard_fpcr"};
|
linkage, true, "cpuopt_unsafe_ignore_standard_fpcr", Category::CpuUnsafe};
|
||||||
SwitchableSetting<bool> cpuopt_unsafe_inaccurate_nan{true, "cpuopt_unsafe_inaccurate_nan"};
|
SwitchableSetting<bool> cpuopt_unsafe_inaccurate_nan{
|
||||||
SwitchableSetting<bool> cpuopt_unsafe_fastmem_check{true, "cpuopt_unsafe_fastmem_check"};
|
linkage, true, "cpuopt_unsafe_inaccurate_nan", Category::CpuUnsafe};
|
||||||
|
SwitchableSetting<bool> cpuopt_unsafe_fastmem_check{
|
||||||
|
linkage, true, "cpuopt_unsafe_fastmem_check", Category::CpuUnsafe};
|
||||||
SwitchableSetting<bool> cpuopt_unsafe_ignore_global_monitor{
|
SwitchableSetting<bool> cpuopt_unsafe_ignore_global_monitor{
|
||||||
true, "cpuopt_unsafe_ignore_global_monitor"};
|
linkage, true, "cpuopt_unsafe_ignore_global_monitor", Category::CpuUnsafe};
|
||||||
|
|
||||||
// Renderer
|
// Renderer
|
||||||
SwitchableSetting<RendererBackend, true> renderer_backend{
|
SwitchableSetting<RendererBackend, true> renderer_backend{
|
||||||
RendererBackend::Vulkan, RendererBackend::OpenGL, RendererBackend::Null, "backend"};
|
linkage, RendererBackend::Vulkan, RendererBackend::OpenGL, RendererBackend::Null,
|
||||||
SwitchableSetting<bool> async_presentation{false, "async_presentation"};
|
"backend", Category::Renderer};
|
||||||
SwitchableSetting<bool> renderer_force_max_clock{false, "force_max_clock"};
|
SwitchableSetting<ShaderBackend, true> shader_backend{
|
||||||
Setting<bool> renderer_debug{false, "debug"};
|
linkage, ShaderBackend::Glsl, ShaderBackend::Glsl, ShaderBackend::SpirV,
|
||||||
Setting<bool> renderer_shader_feedback{false, "shader_feedback"};
|
"shader_backend", Category::Renderer, Specialization::RuntimeList};
|
||||||
Setting<bool> enable_nsight_aftermath{false, "nsight_aftermath"};
|
SwitchableSetting<int> vulkan_device{linkage, 0, "vulkan_device", Category::Renderer,
|
||||||
Setting<bool> disable_shader_loop_safety_checks{false, "disable_shader_loop_safety_checks"};
|
Specialization::RuntimeList};
|
||||||
SwitchableSetting<int> vulkan_device{0, "vulkan_device"};
|
|
||||||
|
|
||||||
ResolutionScalingInfo resolution_info{};
|
SwitchableSetting<bool> use_disk_shader_cache{linkage, true, "use_disk_shader_cache",
|
||||||
SwitchableSetting<ResolutionSetup> resolution_setup{ResolutionSetup::Res1X, "resolution_setup"};
|
Category::Renderer};
|
||||||
SwitchableSetting<ScalingFilter> scaling_filter{ScalingFilter::Bilinear, "scaling_filter"};
|
SwitchableSetting<bool> use_asynchronous_gpu_emulation{
|
||||||
SwitchableSetting<int, true> fsr_sharpening_slider{25, 0, 200, "fsr_sharpening_slider"};
|
linkage, true, "use_asynchronous_gpu_emulation", Category::Renderer};
|
||||||
SwitchableSetting<AntiAliasing> anti_aliasing{AntiAliasing::None, "anti_aliasing"};
|
SwitchableSetting<AstcDecodeMode, true> accelerate_astc{linkage,
|
||||||
|
AstcDecodeMode::Gpu,
|
||||||
|
AstcDecodeMode::Cpu,
|
||||||
|
AstcDecodeMode::CpuAsynchronous,
|
||||||
|
"accelerate_astc",
|
||||||
|
Category::Renderer};
|
||||||
|
Setting<VSyncMode, true> vsync_mode{
|
||||||
|
linkage, VSyncMode::Fifo, VSyncMode::Immediate, VSyncMode::FifoRelaxed,
|
||||||
|
"use_vsync", Category::Renderer, Specialization::RuntimeList, true,
|
||||||
|
true};
|
||||||
|
SwitchableSetting<NvdecEmulation> nvdec_emulation{linkage, NvdecEmulation::Gpu,
|
||||||
|
"nvdec_emulation", Category::Renderer};
|
||||||
// *nix platforms may have issues with the borderless windowed fullscreen mode.
|
// *nix platforms may have issues with the borderless windowed fullscreen mode.
|
||||||
// Default to exclusive fullscreen on these platforms for now.
|
// Default to exclusive fullscreen on these platforms for now.
|
||||||
SwitchableSetting<FullscreenMode, true> fullscreen_mode{
|
SwitchableSetting<FullscreenMode, true> fullscreen_mode{linkage,
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
FullscreenMode::Borderless,
|
FullscreenMode::Borderless,
|
||||||
#else
|
#else
|
||||||
FullscreenMode::Exclusive,
|
FullscreenMode::Exclusive,
|
||||||
#endif
|
#endif
|
||||||
FullscreenMode::Borderless, FullscreenMode::Exclusive, "fullscreen_mode"};
|
FullscreenMode::Borderless,
|
||||||
SwitchableSetting<int, true> aspect_ratio{0, 0, 4, "aspect_ratio"};
|
FullscreenMode::Exclusive,
|
||||||
SwitchableSetting<int, true> max_anisotropy{0, 0, 5, "max_anisotropy"};
|
"fullscreen_mode",
|
||||||
SwitchableSetting<bool> use_speed_limit{true, "use_speed_limit"};
|
Category::Renderer,
|
||||||
SwitchableSetting<u16, true> speed_limit{100, 0, 9999, "speed_limit"};
|
Specialization::Default,
|
||||||
SwitchableSetting<bool> use_disk_shader_cache{true, "use_disk_shader_cache"};
|
true,
|
||||||
SwitchableSetting<GPUAccuracy, true> gpu_accuracy{GPUAccuracy::High, GPUAccuracy::Normal,
|
true};
|
||||||
GPUAccuracy::Extreme, "gpu_accuracy"};
|
SwitchableSetting<AspectRatio, true> aspect_ratio{linkage,
|
||||||
SwitchableSetting<bool> use_asynchronous_gpu_emulation{true, "use_asynchronous_gpu_emulation"};
|
AspectRatio::R16_9,
|
||||||
SwitchableSetting<NvdecEmulation> nvdec_emulation{NvdecEmulation::GPU, "nvdec_emulation"};
|
AspectRatio::R16_9,
|
||||||
SwitchableSetting<bool> accelerate_astc{true, "accelerate_astc"};
|
AspectRatio::Stretch,
|
||||||
SwitchableSetting<bool> async_astc{false, "async_astc"};
|
"aspect_ratio",
|
||||||
Setting<VSyncMode, true> vsync_mode{VSyncMode::FIFO, VSyncMode::Immediate,
|
Category::Renderer,
|
||||||
VSyncMode::FIFORelaxed, "use_vsync"};
|
Specialization::Default,
|
||||||
SwitchableSetting<bool> use_reactive_flushing{true, "use_reactive_flushing"};
|
true,
|
||||||
SwitchableSetting<ShaderBackend, true> shader_backend{ShaderBackend::GLSL, ShaderBackend::GLSL,
|
true};
|
||||||
ShaderBackend::SPIRV, "shader_backend"};
|
|
||||||
SwitchableSetting<bool> use_asynchronous_shaders{false, "use_asynchronous_shaders"};
|
|
||||||
SwitchableSetting<bool> use_fast_gpu_time{true, "use_fast_gpu_time"};
|
|
||||||
SwitchableSetting<bool> use_vulkan_driver_pipeline_cache{true,
|
|
||||||
"use_vulkan_driver_pipeline_cache"};
|
|
||||||
SwitchableSetting<bool> enable_compute_pipelines{false, "enable_compute_pipelines"};
|
|
||||||
SwitchableSetting<AstcRecompression, true> astc_recompression{
|
|
||||||
AstcRecompression::Uncompressed, AstcRecompression::Uncompressed, AstcRecompression::Bc3,
|
|
||||||
"astc_recompression"};
|
|
||||||
SwitchableSetting<bool> use_video_framerate{false, "use_video_framerate"};
|
|
||||||
SwitchableSetting<bool> barrier_feedback_loops{true, "barrier_feedback_loops"};
|
|
||||||
|
|
||||||
SwitchableSetting<u8> bg_red{0, "bg_red"};
|
ResolutionScalingInfo resolution_info{};
|
||||||
SwitchableSetting<u8> bg_green{0, "bg_green"};
|
SwitchableSetting<ResolutionSetup> resolution_setup{linkage, ResolutionSetup::Res1X,
|
||||||
SwitchableSetting<u8> bg_blue{0, "bg_blue"};
|
"resolution_setup", Category::Renderer};
|
||||||
|
SwitchableSetting<ScalingFilter> scaling_filter{linkage,
|
||||||
|
ScalingFilter::Bilinear,
|
||||||
|
"scaling_filter",
|
||||||
|
Category::Renderer,
|
||||||
|
Specialization::Default,
|
||||||
|
true,
|
||||||
|
true};
|
||||||
|
SwitchableSetting<AntiAliasing> anti_aliasing{linkage,
|
||||||
|
AntiAliasing::None,
|
||||||
|
"anti_aliasing",
|
||||||
|
Category::Renderer,
|
||||||
|
Specialization::Default,
|
||||||
|
true,
|
||||||
|
true};
|
||||||
|
SwitchableSetting<int, true> fsr_sharpening_slider{linkage,
|
||||||
|
25,
|
||||||
|
0,
|
||||||
|
200,
|
||||||
|
"fsr_sharpening_slider",
|
||||||
|
Category::Renderer,
|
||||||
|
Specialization::Scalar |
|
||||||
|
Specialization::Percentage,
|
||||||
|
true,
|
||||||
|
true};
|
||||||
|
|
||||||
|
SwitchableSetting<u8, false> bg_red{
|
||||||
|
linkage, 0, "bg_red", Category::Renderer, Specialization::Default, true, true};
|
||||||
|
SwitchableSetting<u8, false> bg_green{
|
||||||
|
linkage, 0, "bg_green", Category::Renderer, Specialization::Default, true, true};
|
||||||
|
SwitchableSetting<u8, false> bg_blue{
|
||||||
|
linkage, 0, "bg_blue", Category::Renderer, Specialization::Default, true, true};
|
||||||
|
|
||||||
|
SwitchableSetting<GpuAccuracy, true> gpu_accuracy{linkage,
|
||||||
|
GpuAccuracy::High,
|
||||||
|
GpuAccuracy::Normal,
|
||||||
|
GpuAccuracy::Extreme,
|
||||||
|
"gpu_accuracy",
|
||||||
|
Category::RendererAdvanced,
|
||||||
|
Specialization::Default,
|
||||||
|
true,
|
||||||
|
true};
|
||||||
|
SwitchableSetting<AnisotropyMode, true> max_anisotropy{
|
||||||
|
linkage, AnisotropyMode::Automatic, AnisotropyMode::Automatic, AnisotropyMode::X16,
|
||||||
|
"max_anisotropy", Category::RendererAdvanced};
|
||||||
|
SwitchableSetting<AstcRecompression, true> astc_recompression{linkage,
|
||||||
|
AstcRecompression::Uncompressed,
|
||||||
|
AstcRecompression::Uncompressed,
|
||||||
|
AstcRecompression::Bc3,
|
||||||
|
"astc_recompression",
|
||||||
|
Category::RendererAdvanced};
|
||||||
|
SwitchableSetting<bool> async_presentation{linkage, false, "async_presentation",
|
||||||
|
Category::RendererAdvanced};
|
||||||
|
SwitchableSetting<bool> renderer_force_max_clock{linkage, false, "force_max_clock",
|
||||||
|
Category::RendererAdvanced};
|
||||||
|
SwitchableSetting<bool> use_reactive_flushing{linkage, true, "use_reactive_flushing",
|
||||||
|
Category::RendererAdvanced};
|
||||||
|
SwitchableSetting<bool> use_asynchronous_shaders{linkage, false, "use_asynchronous_shaders",
|
||||||
|
Category::RendererAdvanced};
|
||||||
|
SwitchableSetting<bool> use_fast_gpu_time{
|
||||||
|
linkage, true, "use_fast_gpu_time", Category::RendererAdvanced, Specialization::Default,
|
||||||
|
true, true};
|
||||||
|
SwitchableSetting<bool> use_vulkan_driver_pipeline_cache{linkage,
|
||||||
|
true,
|
||||||
|
"use_vulkan_driver_pipeline_cache",
|
||||||
|
Category::RendererAdvanced,
|
||||||
|
Specialization::Default,
|
||||||
|
true,
|
||||||
|
true};
|
||||||
|
SwitchableSetting<bool> enable_compute_pipelines{linkage, false, "enable_compute_pipelines",
|
||||||
|
Category::RendererAdvanced};
|
||||||
|
SwitchableSetting<bool> use_video_framerate{linkage, false, "use_video_framerate",
|
||||||
|
Category::RendererAdvanced};
|
||||||
|
SwitchableSetting<bool> barrier_feedback_loops{linkage, true, "barrier_feedback_loops",
|
||||||
|
Category::RendererAdvanced};
|
||||||
|
|
||||||
|
Setting<bool> renderer_debug{linkage, false, "debug", Category::RendererDebug};
|
||||||
|
Setting<bool> renderer_shader_feedback{linkage, false, "shader_feedback",
|
||||||
|
Category::RendererDebug};
|
||||||
|
Setting<bool> enable_nsight_aftermath{linkage, false, "nsight_aftermath",
|
||||||
|
Category::RendererDebug};
|
||||||
|
Setting<bool> disable_shader_loop_safety_checks{
|
||||||
|
linkage, false, "disable_shader_loop_safety_checks", Category::RendererDebug};
|
||||||
|
|
||||||
// System
|
// System
|
||||||
SwitchableSetting<std::optional<u32>> rng_seed{std::optional<u32>(), "rng_seed"};
|
SwitchableSetting<Language, true> language_index{linkage,
|
||||||
Setting<std::string> device_name{"Yuzu", "device_name"};
|
Language::EnglishAmerican,
|
||||||
|
Language::Japanese,
|
||||||
|
Language::PortugueseBrazilian,
|
||||||
|
"language_index",
|
||||||
|
Category::System};
|
||||||
|
SwitchableSetting<Region, true> region_index{linkage, Region::Usa, Region::Japan,
|
||||||
|
Region::Taiwan, "region_index", Category::System};
|
||||||
|
SwitchableSetting<TimeZone, true> time_zone_index{linkage, TimeZone::Auto,
|
||||||
|
TimeZone::Auto, TimeZone::Zulu,
|
||||||
|
"time_zone_index", Category::System};
|
||||||
// Measured in seconds since epoch
|
// Measured in seconds since epoch
|
||||||
std::optional<s64> custom_rtc;
|
SwitchableSetting<bool> custom_rtc_enabled{
|
||||||
|
linkage, false, "custom_rtc_enabled", Category::System, Specialization::Paired, true, true};
|
||||||
|
SwitchableSetting<s64> custom_rtc{
|
||||||
|
linkage, 0, "custom_rtc", Category::System, Specialization::Time,
|
||||||
|
true, true, &custom_rtc_enabled};
|
||||||
// Set on game boot, reset on stop. Seconds difference between current time and `custom_rtc`
|
// Set on game boot, reset on stop. Seconds difference between current time and `custom_rtc`
|
||||||
s64 custom_rtc_differential;
|
s64 custom_rtc_differential;
|
||||||
|
SwitchableSetting<bool> rng_seed_enabled{
|
||||||
|
linkage, false, "rng_seed_enabled", Category::System, Specialization::Paired, true, true};
|
||||||
|
SwitchableSetting<u32> rng_seed{
|
||||||
|
linkage, 0, "rng_seed", Category::System, Specialization::Hex,
|
||||||
|
true, true, &rng_seed_enabled};
|
||||||
|
Setting<std::string> device_name{
|
||||||
|
linkage, "yuzu", "device_name", Category::System, Specialization::Default, true, true};
|
||||||
|
|
||||||
Setting<s32> current_user{0, "current_user"};
|
Setting<s32> current_user{linkage, 0, "current_user", Category::System};
|
||||||
SwitchableSetting<s32, true> language_index{1, 0, 17, "language_index"};
|
|
||||||
SwitchableSetting<s32, true> region_index{1, 0, 6, "region_index"};
|
SwitchableSetting<bool> use_docked_mode{linkage, true, "use_docked_mode", Category::System};
|
||||||
SwitchableSetting<s32, true> time_zone_index{0, 0, 45, "time_zone_index"};
|
|
||||||
SwitchableSetting<s32, true> sound_index{1, 0, 2, "sound_index"};
|
|
||||||
|
|
||||||
// Controls
|
// Controls
|
||||||
InputSetting<std::array<PlayerInput, 10>> players;
|
InputSetting<std::array<PlayerInput, 10>> players;
|
||||||
|
|
||||||
SwitchableSetting<bool> use_docked_mode{true, "use_docked_mode"};
|
Setting<bool> enable_raw_input{
|
||||||
|
linkage, false, "enable_raw_input", Category::Controls, Specialization::Default,
|
||||||
|
// Only read/write enable_raw_input on Windows platforms
|
||||||
|
#ifdef _WIN32
|
||||||
|
true
|
||||||
|
#else
|
||||||
|
false
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
Setting<bool> controller_navigation{linkage, true, "controller_navigation", Category::Controls};
|
||||||
|
Setting<bool> enable_joycon_driver{linkage, true, "enable_joycon_driver", Category::Controls};
|
||||||
|
Setting<bool> enable_procon_driver{linkage, false, "enable_procon_driver", Category::Controls};
|
||||||
|
|
||||||
Setting<bool> enable_raw_input{false, "enable_raw_input"};
|
SwitchableSetting<bool> vibration_enabled{linkage, true, "vibration_enabled",
|
||||||
Setting<bool> controller_navigation{true, "controller_navigation"};
|
Category::Controls};
|
||||||
Setting<bool> enable_joycon_driver{true, "enable_joycon_driver"};
|
SwitchableSetting<bool> enable_accurate_vibrations{linkage, false, "enable_accurate_vibrations",
|
||||||
Setting<bool> enable_procon_driver{false, "enable_procon_driver"};
|
Category::Controls};
|
||||||
|
|
||||||
SwitchableSetting<bool> vibration_enabled{true, "vibration_enabled"};
|
SwitchableSetting<bool> motion_enabled{linkage, true, "motion_enabled", Category::Controls};
|
||||||
SwitchableSetting<bool> enable_accurate_vibrations{false, "enable_accurate_vibrations"};
|
Setting<std::string> udp_input_servers{linkage, "127.0.0.1:26760", "udp_input_servers",
|
||||||
|
Category::Controls};
|
||||||
|
Setting<bool> enable_udp_controller{linkage, false, "enable_udp_controller",
|
||||||
|
Category::Controls};
|
||||||
|
|
||||||
SwitchableSetting<bool> motion_enabled{true, "motion_enabled"};
|
Setting<bool> pause_tas_on_load{linkage, true, "pause_tas_on_load", Category::Controls};
|
||||||
Setting<std::string> udp_input_servers{"127.0.0.1:26760", "udp_input_servers"};
|
Setting<bool> tas_enable{linkage, false, "tas_enable", Category::Controls};
|
||||||
Setting<bool> enable_udp_controller{false, "enable_udp_controller"};
|
Setting<bool> tas_loop{linkage, false, "tas_loop", Category::Controls};
|
||||||
|
|
||||||
Setting<bool> pause_tas_on_load{true, "pause_tas_on_load"};
|
Setting<bool> mouse_panning{
|
||||||
Setting<bool> tas_enable{false, "tas_enable"};
|
linkage, false, "mouse_panning", Category::Controls, Specialization::Default, false};
|
||||||
Setting<bool> tas_loop{false, "tas_loop"};
|
Setting<u8, true> mouse_panning_sensitivity{
|
||||||
|
linkage, 50, 1, 100, "mouse_panning_sensitivity", Category::Controls};
|
||||||
|
Setting<bool> mouse_enabled{linkage, false, "mouse_enabled", Category::Controls};
|
||||||
|
|
||||||
Setting<bool> mouse_panning{false, "mouse_panning"};
|
Setting<u8, true> mouse_panning_x_sensitivity{
|
||||||
Setting<u8, true> mouse_panning_x_sensitivity{50, 1, 100, "mouse_panning_x_sensitivity"};
|
linkage, 50, 1, 100, "mouse_panning_x_sensitivity", Category::Controls};
|
||||||
Setting<u8, true> mouse_panning_y_sensitivity{50, 1, 100, "mouse_panning_y_sensitivity"};
|
Setting<u8, true> mouse_panning_y_sensitivity{
|
||||||
Setting<u8, true> mouse_panning_deadzone_counterweight{20, 0, 100,
|
linkage, 50, 1, 100, "mouse_panning_y_sensitivity", Category::Controls};
|
||||||
"mouse_panning_deadzone_counterweight"};
|
Setting<u8, true> mouse_panning_deadzone_counterweight{
|
||||||
Setting<u8, true> mouse_panning_decay_strength{18, 0, 100, "mouse_panning_decay_strength"};
|
linkage, 20, 0, 100, "mouse_panning_deadzone_counterweight", Category::Controls};
|
||||||
Setting<u8, true> mouse_panning_min_decay{6, 0, 100, "mouse_panning_min_decay"};
|
Setting<u8, true> mouse_panning_decay_strength{
|
||||||
|
linkage, 18, 0, 100, "mouse_panning_decay_strength", Category::Controls};
|
||||||
|
Setting<u8, true> mouse_panning_min_decay{
|
||||||
|
linkage, 6, 0, 100, "mouse_panning_min_decay", Category::Controls};
|
||||||
|
|
||||||
Setting<bool> mouse_enabled{false, "mouse_enabled"};
|
Setting<bool> emulate_analog_keyboard{linkage, false, "emulate_analog_keyboard",
|
||||||
Setting<bool> emulate_analog_keyboard{false, "emulate_analog_keyboard"};
|
Category::Controls};
|
||||||
Setting<bool> keyboard_enabled{false, "keyboard_enabled"};
|
Setting<bool> keyboard_enabled{linkage, false, "keyboard_enabled", Category::Controls};
|
||||||
|
|
||||||
Setting<bool> debug_pad_enabled{false, "debug_pad_enabled"};
|
Setting<bool> debug_pad_enabled{linkage, false, "debug_pad_enabled", Category::Controls};
|
||||||
ButtonsRaw debug_pad_buttons;
|
ButtonsRaw debug_pad_buttons;
|
||||||
AnalogsRaw debug_pad_analogs;
|
AnalogsRaw debug_pad_analogs;
|
||||||
|
|
||||||
TouchscreenInput touchscreen;
|
TouchscreenInput touchscreen;
|
||||||
|
|
||||||
Setting<std::string> touch_device{"min_x:100,min_y:50,max_x:1800,max_y:850", "touch_device"};
|
Setting<std::string> touch_device{linkage, "min_x:100,min_y:50,max_x:1800,max_y:850",
|
||||||
Setting<int> touch_from_button_map_index{0, "touch_from_button_map"};
|
"touch_device", Category::Controls};
|
||||||
|
Setting<int> touch_from_button_map_index{linkage, 0, "touch_from_button_map",
|
||||||
|
Category::Controls};
|
||||||
std::vector<TouchFromButtonMap> touch_from_button_maps;
|
std::vector<TouchFromButtonMap> touch_from_button_maps;
|
||||||
|
|
||||||
Setting<bool> enable_ring_controller{true, "enable_ring_controller"};
|
Setting<bool> enable_ring_controller{linkage, true, "enable_ring_controller",
|
||||||
|
Category::Controls};
|
||||||
RingconRaw ringcon_analogs;
|
RingconRaw ringcon_analogs;
|
||||||
|
|
||||||
Setting<bool> enable_ir_sensor{false, "enable_ir_sensor"};
|
Setting<bool> enable_ir_sensor{linkage, false, "enable_ir_sensor", Category::Controls};
|
||||||
Setting<std::string> ir_sensor_device{"auto", "ir_sensor_device"};
|
Setting<std::string> ir_sensor_device{linkage, "auto", "ir_sensor_device", Category::Controls};
|
||||||
|
|
||||||
Setting<bool> random_amiibo_id{false, "random_amiibo_id"};
|
Setting<bool> random_amiibo_id{linkage, false, "random_amiibo_id", Category::Controls};
|
||||||
|
|
||||||
// Data Storage
|
// Data Storage
|
||||||
Setting<bool> use_virtual_sd{true, "use_virtual_sd"};
|
Setting<bool> use_virtual_sd{linkage, true, "use_virtual_sd", Category::DataStorage};
|
||||||
Setting<bool> gamecard_inserted{false, "gamecard_inserted"};
|
Setting<bool> gamecard_inserted{linkage, false, "gamecard_inserted", Category::DataStorage};
|
||||||
Setting<bool> gamecard_current_game{false, "gamecard_current_game"};
|
Setting<bool> gamecard_current_game{linkage, false, "gamecard_current_game",
|
||||||
Setting<std::string> gamecard_path{std::string(), "gamecard_path"};
|
Category::DataStorage};
|
||||||
|
Setting<std::string> gamecard_path{linkage, std::string(), "gamecard_path",
|
||||||
|
Category::DataStorage};
|
||||||
|
|
||||||
// Debugging
|
// Debugging
|
||||||
bool record_frame_times;
|
bool record_frame_times;
|
||||||
Setting<bool> use_gdbstub{false, "use_gdbstub"};
|
Setting<bool> use_gdbstub{linkage, false, "use_gdbstub", Category::Debugging};
|
||||||
Setting<u16> gdbstub_port{6543, "gdbstub_port"};
|
Setting<u16> gdbstub_port{linkage, 6543, "gdbstub_port", Category::Debugging};
|
||||||
Setting<std::string> program_args{std::string(), "program_args"};
|
Setting<std::string> program_args{linkage, std::string(), "program_args", Category::Debugging};
|
||||||
Setting<bool> dump_exefs{false, "dump_exefs"};
|
Setting<bool> dump_exefs{linkage, false, "dump_exefs", Category::Debugging};
|
||||||
Setting<bool> dump_nso{false, "dump_nso"};
|
Setting<bool> dump_nso{linkage, false, "dump_nso", Category::Debugging};
|
||||||
Setting<bool> dump_shaders{false, "dump_shaders"};
|
Setting<bool> dump_shaders{
|
||||||
Setting<bool> dump_macros{false, "dump_macros"};
|
linkage, false, "dump_shaders", Category::DebuggingGraphics, Specialization::Default,
|
||||||
Setting<bool> enable_fs_access_log{false, "enable_fs_access_log"};
|
false};
|
||||||
Setting<bool> reporting_services{false, "reporting_services"};
|
Setting<bool> dump_macros{
|
||||||
Setting<bool> quest_flag{false, "quest_flag"};
|
linkage, false, "dump_macros", Category::DebuggingGraphics, Specialization::Default, false};
|
||||||
Setting<bool> disable_macro_jit{false, "disable_macro_jit"};
|
Setting<bool> enable_fs_access_log{linkage, false, "enable_fs_access_log", Category::Debugging};
|
||||||
Setting<bool> disable_macro_hle{false, "disable_macro_hle"};
|
Setting<bool> reporting_services{
|
||||||
Setting<bool> extended_logging{false, "extended_logging"};
|
linkage, false, "reporting_services", Category::Debugging, Specialization::Default, false};
|
||||||
Setting<bool> use_debug_asserts{false, "use_debug_asserts"};
|
Setting<bool> quest_flag{linkage, false, "quest_flag", Category::Debugging};
|
||||||
Setting<bool> use_auto_stub{false, "use_auto_stub"};
|
Setting<bool> disable_macro_jit{linkage, false, "disable_macro_jit",
|
||||||
Setting<bool> enable_all_controllers{false, "enable_all_controllers"};
|
Category::DebuggingGraphics};
|
||||||
Setting<bool> create_crash_dumps{false, "create_crash_dumps"};
|
Setting<bool> disable_macro_hle{linkage, false, "disable_macro_hle",
|
||||||
Setting<bool> perform_vulkan_check{true, "perform_vulkan_check"};
|
Category::DebuggingGraphics};
|
||||||
|
Setting<bool> extended_logging{
|
||||||
|
linkage, false, "extended_logging", Category::Debugging, Specialization::Default, false};
|
||||||
|
Setting<bool> use_debug_asserts{linkage, false, "use_debug_asserts", Category::Debugging};
|
||||||
|
Setting<bool> use_auto_stub{
|
||||||
|
linkage, false, "use_auto_stub", Category::Debugging, Specialization::Default, false};
|
||||||
|
Setting<bool> enable_all_controllers{linkage, false, "enable_all_controllers",
|
||||||
|
Category::Debugging};
|
||||||
|
Setting<bool> create_crash_dumps{linkage, false, "create_crash_dumps", Category::Debugging};
|
||||||
|
Setting<bool> perform_vulkan_check{linkage, true, "perform_vulkan_check", Category::Debugging};
|
||||||
|
|
||||||
// Miscellaneous
|
// Miscellaneous
|
||||||
Setting<std::string> log_filter{"*:Info", "log_filter"};
|
Setting<std::string> log_filter{linkage, "*:Info", "log_filter", Category::Miscellaneous};
|
||||||
Setting<bool> use_dev_keys{false, "use_dev_keys"};
|
Setting<bool> use_dev_keys{linkage, false, "use_dev_keys", Category::Miscellaneous};
|
||||||
|
|
||||||
// Network
|
// Network
|
||||||
Setting<std::string> network_interface{std::string(), "network_interface"};
|
Setting<std::string> network_interface{linkage, std::string(), "network_interface",
|
||||||
|
Category::Network};
|
||||||
|
|
||||||
// WebService
|
// WebService
|
||||||
Setting<bool> enable_telemetry{true, "enable_telemetry"};
|
Setting<bool> enable_telemetry{linkage, true, "enable_telemetry", Category::WebService};
|
||||||
Setting<std::string> web_api_url{"https://api.yuzu-emu.org", "web_api_url"};
|
Setting<std::string> web_api_url{linkage, "https://api.yuzu-emu.org", "web_api_url",
|
||||||
Setting<std::string> yuzu_username{std::string(), "yuzu_username"};
|
Category::WebService};
|
||||||
Setting<std::string> yuzu_token{std::string(), "yuzu_token"};
|
Setting<std::string> yuzu_username{linkage, std::string(), "yuzu_username",
|
||||||
|
Category::WebService};
|
||||||
|
Setting<std::string> yuzu_token{linkage, std::string(), "yuzu_token", Category::WebService};
|
||||||
|
|
||||||
// Add-Ons
|
// Add-Ons
|
||||||
std::map<u64, std::vector<std::string>> disabled_addons;
|
std::map<u64, std::vector<std::string>> disabled_addons;
|
||||||
|
@ -600,9 +514,6 @@ struct Values {
|
||||||
|
|
||||||
extern Values values;
|
extern Values values;
|
||||||
|
|
||||||
bool IsConfiguringGlobal();
|
|
||||||
void SetConfiguringGlobal(bool is_global);
|
|
||||||
|
|
||||||
bool IsGPULevelExtreme();
|
bool IsGPULevelExtreme();
|
||||||
bool IsGPULevelHigh();
|
bool IsGPULevelHigh();
|
||||||
|
|
||||||
|
@ -610,7 +521,7 @@ bool IsFastmemEnabled();
|
||||||
|
|
||||||
float Volume();
|
float Volume();
|
||||||
|
|
||||||
std::string GetTimeZoneString();
|
std::string GetTimeZoneString(TimeZone time_zone);
|
||||||
|
|
||||||
void LogSettings();
|
void LogSettings();
|
||||||
|
|
||||||
|
@ -619,4 +530,7 @@ void UpdateRescalingInfo();
|
||||||
// Restore the global state of all applicable settings in the Values struct
|
// Restore the global state of all applicable settings in the Values struct
|
||||||
void RestoreGlobalState(bool is_powered_on);
|
void RestoreGlobalState(bool is_powered_on);
|
||||||
|
|
||||||
|
bool IsConfiguringGlobal();
|
||||||
|
void SetConfiguringGlobal(bool is_global);
|
||||||
|
|
||||||
} // namespace Settings
|
} // namespace Settings
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include "common/settings_common.h"
|
||||||
|
|
||||||
|
namespace Settings {
|
||||||
|
|
||||||
|
BasicSetting::BasicSetting(Linkage& linkage, const std::string& name, enum Category category_,
|
||||||
|
bool save_, bool runtime_modifiable_, u32 specialization_,
|
||||||
|
BasicSetting* other_setting_)
|
||||||
|
: label{name}, category{category_}, id{linkage.count}, save{save_},
|
||||||
|
runtime_modifiable{runtime_modifiable_}, specialization{specialization_},
|
||||||
|
other_setting{other_setting_} {
|
||||||
|
linkage.by_category[category].push_back(this);
|
||||||
|
linkage.count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
BasicSetting::~BasicSetting() = default;
|
||||||
|
|
||||||
|
std::string BasicSetting::ToStringGlobal() const {
|
||||||
|
return this->ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BasicSetting::UsingGlobal() const {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BasicSetting::SetGlobal(bool global) {}
|
||||||
|
|
||||||
|
bool BasicSetting::Save() const {
|
||||||
|
return save;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BasicSetting::RuntimeModfiable() const {
|
||||||
|
return runtime_modifiable;
|
||||||
|
}
|
||||||
|
|
||||||
|
Category BasicSetting::GetCategory() const {
|
||||||
|
return category;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 BasicSetting::Specialization() const {
|
||||||
|
return specialization;
|
||||||
|
}
|
||||||
|
|
||||||
|
BasicSetting* BasicSetting::PairedSetting() const {
|
||||||
|
return other_setting;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string& BasicSetting::GetLabel() const {
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
|
||||||
|
Linkage::Linkage(u32 initial_count) : count{initial_count} {}
|
||||||
|
Linkage::~Linkage() = default;
|
||||||
|
|
||||||
|
} // namespace Settings
|
|
@ -0,0 +1,256 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
#include <map>
|
||||||
|
#include <string>
|
||||||
|
#include <typeindex>
|
||||||
|
#include "common/common_types.h"
|
||||||
|
|
||||||
|
namespace Settings {
|
||||||
|
|
||||||
|
enum class Category : u32 {
|
||||||
|
Audio,
|
||||||
|
Core,
|
||||||
|
Cpu,
|
||||||
|
CpuDebug,
|
||||||
|
CpuUnsafe,
|
||||||
|
Renderer,
|
||||||
|
RendererAdvanced,
|
||||||
|
RendererDebug,
|
||||||
|
System,
|
||||||
|
SystemAudio,
|
||||||
|
DataStorage,
|
||||||
|
Debugging,
|
||||||
|
DebuggingGraphics,
|
||||||
|
Miscellaneous,
|
||||||
|
Network,
|
||||||
|
WebService,
|
||||||
|
AddOns,
|
||||||
|
Controls,
|
||||||
|
Ui,
|
||||||
|
UiGeneral,
|
||||||
|
UiLayout,
|
||||||
|
UiGameList,
|
||||||
|
Screenshots,
|
||||||
|
Shortcuts,
|
||||||
|
Multiplayer,
|
||||||
|
Services,
|
||||||
|
Paths,
|
||||||
|
MaxEnum,
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr u8 SpecializationTypeMask = 0xf;
|
||||||
|
constexpr u8 SpecializationAttributeMask = 0xf0;
|
||||||
|
constexpr u8 SpecializationAttributeOffset = 4;
|
||||||
|
|
||||||
|
// Scalar and countable could have better names
|
||||||
|
enum Specialization : u8 {
|
||||||
|
Default = 0,
|
||||||
|
Time = 1, // Duration or specific moment in time
|
||||||
|
Hex = 2, // Hexadecimal number
|
||||||
|
List = 3, // Setting has specific members
|
||||||
|
RuntimeList = 4, // Members of the list are determined during runtime
|
||||||
|
Scalar = 5, // Values are continuous
|
||||||
|
Countable = 6, // Can be stepped through
|
||||||
|
Paired = 7, // Another setting is associated with this setting
|
||||||
|
|
||||||
|
Percentage = (1 << SpecializationAttributeOffset), // Should be represented as a percentage
|
||||||
|
};
|
||||||
|
|
||||||
|
class BasicSetting;
|
||||||
|
|
||||||
|
class Linkage {
|
||||||
|
public:
|
||||||
|
explicit Linkage(u32 initial_count = 0);
|
||||||
|
~Linkage();
|
||||||
|
std::map<Category, std::vector<BasicSetting*>> by_category{};
|
||||||
|
std::vector<std::function<void()>> restore_functions{};
|
||||||
|
u32 count;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BasicSetting is an abstract class that only keeps track of metadata. The string methods are
|
||||||
|
* available to get data values out.
|
||||||
|
*/
|
||||||
|
class BasicSetting {
|
||||||
|
protected:
|
||||||
|
explicit BasicSetting(Linkage& linkage, const std::string& name, Category category_, bool save_,
|
||||||
|
bool runtime_modifiable_, u32 specialization,
|
||||||
|
BasicSetting* other_setting);
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual ~BasicSetting();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Data retrieval
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a string representation of the internal data. If the Setting is Switchable, it
|
||||||
|
* respects the internal global state: it is based on GetValue().
|
||||||
|
*
|
||||||
|
* @returns A string representation of the internal data.
|
||||||
|
*/
|
||||||
|
[[nodiscard]] virtual std::string ToString() const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a string representation of the global version of internal data. If the Setting is
|
||||||
|
* not Switchable, it behaves like ToString.
|
||||||
|
*
|
||||||
|
* @returns A string representation of the global version of internal data.
|
||||||
|
*/
|
||||||
|
[[nodiscard]] virtual std::string ToStringGlobal() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns A string representation of the Setting's default value.
|
||||||
|
*/
|
||||||
|
[[nodiscard]] virtual std::string DefaultToString() const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a string representation of the minimum value of the setting. If the Setting is not
|
||||||
|
* ranged, the string represents the default initialization of the data type.
|
||||||
|
*
|
||||||
|
* @returns A string representation of the minimum value of the setting.
|
||||||
|
*/
|
||||||
|
[[nodiscard]] virtual std::string MinVal() const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a string representation of the maximum value of the setting. If the Setting is not
|
||||||
|
* ranged, the string represents the default initialization of the data type.
|
||||||
|
*
|
||||||
|
* @returns A string representation of the maximum value of the setting.
|
||||||
|
*/
|
||||||
|
[[nodiscard]] virtual std::string MaxVal() const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Takes a string input, converts it to the internal data type if necessary, and then runs
|
||||||
|
* SetValue with it.
|
||||||
|
*
|
||||||
|
* @param load String of the input data.
|
||||||
|
*/
|
||||||
|
virtual void LoadString(const std::string& load) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a string representation of the data. If the data is an enum, it returns a string of
|
||||||
|
* the enum value. If the internal data type is not an enum, this is equivalent to ToString.
|
||||||
|
*
|
||||||
|
* e.g. renderer_backend.Canonicalize() == "OpenGL"
|
||||||
|
*
|
||||||
|
* @returns Canonicalized string representation of the internal data
|
||||||
|
*/
|
||||||
|
[[nodiscard]] virtual std::string Canonicalize() const = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Metadata
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns A unique identifier for the Setting's internal data type.
|
||||||
|
*/
|
||||||
|
[[nodiscard]] virtual std::type_index TypeId() const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the Setting's internal data type is an enum.
|
||||||
|
*
|
||||||
|
* @returns True if the Setting's internal data type is an enum
|
||||||
|
*/
|
||||||
|
[[nodiscard]] virtual constexpr bool IsEnum() const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the current setting is Switchable.
|
||||||
|
*
|
||||||
|
* @returns If the setting is a SwitchableSetting
|
||||||
|
*/
|
||||||
|
[[nodiscard]] virtual constexpr bool Switchable() const {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true to suggest that a frontend can read or write the setting to a configuration
|
||||||
|
* file.
|
||||||
|
*
|
||||||
|
* @returns The save preference
|
||||||
|
*/
|
||||||
|
[[nodiscard]] bool Save() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns true if the current setting can be changed while the guest is running.
|
||||||
|
*/
|
||||||
|
[[nodiscard]] bool RuntimeModfiable() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns A unique number corresponding to the setting.
|
||||||
|
*/
|
||||||
|
[[nodiscard]] constexpr u32 Id() const {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the setting's category AKA INI group.
|
||||||
|
*
|
||||||
|
* @returns The setting's category
|
||||||
|
*/
|
||||||
|
[[nodiscard]] Category GetCategory() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns Extra metadata for data representation in frontend implementations.
|
||||||
|
*/
|
||||||
|
[[nodiscard]] u32 Specialization() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns Another BasicSetting if one is paired, or nullptr otherwise.
|
||||||
|
*/
|
||||||
|
[[nodiscard]] BasicSetting* PairedSetting() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the label this setting was created with.
|
||||||
|
*
|
||||||
|
* @returns A reference to the label
|
||||||
|
*/
|
||||||
|
[[nodiscard]] const std::string& GetLabel() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns If the Setting checks input values for valid ranges.
|
||||||
|
*/
|
||||||
|
[[nodiscard]] virtual constexpr bool Ranged() const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns The index of the enum if the underlying setting type is an enum, else max of u32.
|
||||||
|
*/
|
||||||
|
[[nodiscard]] virtual constexpr u32 EnumIndex() const = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Switchable settings
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a setting's global state. True means use the normal setting, false to use a custom
|
||||||
|
* value. Has no effect if the Setting is not Switchable.
|
||||||
|
*
|
||||||
|
* @param global The desired state
|
||||||
|
*/
|
||||||
|
virtual void SetGlobal(bool global);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the setting is using the normal setting value. Always true if the setting is
|
||||||
|
* not Switchable.
|
||||||
|
*
|
||||||
|
* @returns The Setting's global state
|
||||||
|
*/
|
||||||
|
[[nodiscard]] virtual bool UsingGlobal() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
const std::string label; ///< The setting's label
|
||||||
|
const Category category; ///< The setting's category AKA INI group
|
||||||
|
const u32 id; ///< Unique integer for the setting
|
||||||
|
const bool save; ///< Suggests if the setting should be saved and read to a frontend config
|
||||||
|
const bool
|
||||||
|
runtime_modifiable; ///< Suggests if the setting can be modified while a guest is running
|
||||||
|
const u32 specialization; ///< Extra data to identify representation of a setting
|
||||||
|
BasicSetting* const other_setting; ///< A paired setting
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Settings
|
|
@ -0,0 +1,214 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <utility>
|
||||||
|
#include <vector>
|
||||||
|
#include "common/common_types.h"
|
||||||
|
|
||||||
|
namespace Settings {
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct EnumMetadata {
|
||||||
|
static constexpr std::vector<std::pair<std::string, T>> Canonicalizations();
|
||||||
|
static constexpr u32 Index();
|
||||||
|
};
|
||||||
|
|
||||||
|
#define PAIR_45(N, X, ...) {#X, N::X} __VA_OPT__(, PAIR_46(N, __VA_ARGS__))
|
||||||
|
#define PAIR_44(N, X, ...) {#X, N::X} __VA_OPT__(, PAIR_45(N, __VA_ARGS__))
|
||||||
|
#define PAIR_43(N, X, ...) {#X, N::X} __VA_OPT__(, PAIR_44(N, __VA_ARGS__))
|
||||||
|
#define PAIR_42(N, X, ...) {#X, N::X} __VA_OPT__(, PAIR_43(N, __VA_ARGS__))
|
||||||
|
#define PAIR_41(N, X, ...) {#X, N::X} __VA_OPT__(, PAIR_42(N, __VA_ARGS__))
|
||||||
|
#define PAIR_40(N, X, ...) {#X, N::X} __VA_OPT__(, PAIR_41(N, __VA_ARGS__))
|
||||||
|
#define PAIR_39(N, X, ...) {#X, N::X} __VA_OPT__(, PAIR_40(N, __VA_ARGS__))
|
||||||
|
#define PAIR_38(N, X, ...) {#X, N::X} __VA_OPT__(, PAIR_39(N, __VA_ARGS__))
|
||||||
|
#define PAIR_37(N, X, ...) {#X, N::X} __VA_OPT__(, PAIR_38(N, __VA_ARGS__))
|
||||||
|
#define PAIR_36(N, X, ...) {#X, N::X} __VA_OPT__(, PAIR_37(N, __VA_ARGS__))
|
||||||
|
#define PAIR_35(N, X, ...) {#X, N::X} __VA_OPT__(, PAIR_36(N, __VA_ARGS__))
|
||||||
|
#define PAIR_34(N, X, ...) {#X, N::X} __VA_OPT__(, PAIR_35(N, __VA_ARGS__))
|
||||||
|
#define PAIR_33(N, X, ...) {#X, N::X} __VA_OPT__(, PAIR_34(N, __VA_ARGS__))
|
||||||
|
#define PAIR_32(N, X, ...) {#X, N::X} __VA_OPT__(, PAIR_33(N, __VA_ARGS__))
|
||||||
|
#define PAIR_31(N, X, ...) {#X, N::X} __VA_OPT__(, PAIR_32(N, __VA_ARGS__))
|
||||||
|
#define PAIR_30(N, X, ...) {#X, N::X} __VA_OPT__(, PAIR_31(N, __VA_ARGS__))
|
||||||
|
#define PAIR_29(N, X, ...) {#X, N::X} __VA_OPT__(, PAIR_30(N, __VA_ARGS__))
|
||||||
|
#define PAIR_28(N, X, ...) {#X, N::X} __VA_OPT__(, PAIR_29(N, __VA_ARGS__))
|
||||||
|
#define PAIR_27(N, X, ...) {#X, N::X} __VA_OPT__(, PAIR_28(N, __VA_ARGS__))
|
||||||
|
#define PAIR_26(N, X, ...) {#X, N::X} __VA_OPT__(, PAIR_27(N, __VA_ARGS__))
|
||||||
|
#define PAIR_25(N, X, ...) {#X, N::X} __VA_OPT__(, PAIR_26(N, __VA_ARGS__))
|
||||||
|
#define PAIR_24(N, X, ...) {#X, N::X} __VA_OPT__(, PAIR_25(N, __VA_ARGS__))
|
||||||
|
#define PAIR_23(N, X, ...) {#X, N::X} __VA_OPT__(, PAIR_24(N, __VA_ARGS__))
|
||||||
|
#define PAIR_22(N, X, ...) {#X, N::X} __VA_OPT__(, PAIR_23(N, __VA_ARGS__))
|
||||||
|
#define PAIR_21(N, X, ...) {#X, N::X} __VA_OPT__(, PAIR_22(N, __VA_ARGS__))
|
||||||
|
#define PAIR_20(N, X, ...) {#X, N::X} __VA_OPT__(, PAIR_21(N, __VA_ARGS__))
|
||||||
|
#define PAIR_19(N, X, ...) {#X, N::X} __VA_OPT__(, PAIR_20(N, __VA_ARGS__))
|
||||||
|
#define PAIR_18(N, X, ...) {#X, N::X} __VA_OPT__(, PAIR_19(N, __VA_ARGS__))
|
||||||
|
#define PAIR_17(N, X, ...) {#X, N::X} __VA_OPT__(, PAIR_18(N, __VA_ARGS__))
|
||||||
|
#define PAIR_16(N, X, ...) {#X, N::X} __VA_OPT__(, PAIR_17(N, __VA_ARGS__))
|
||||||
|
#define PAIR_15(N, X, ...) {#X, N::X} __VA_OPT__(, PAIR_16(N, __VA_ARGS__))
|
||||||
|
#define PAIR_14(N, X, ...) {#X, N::X} __VA_OPT__(, PAIR_15(N, __VA_ARGS__))
|
||||||
|
#define PAIR_13(N, X, ...) {#X, N::X} __VA_OPT__(, PAIR_14(N, __VA_ARGS__))
|
||||||
|
#define PAIR_12(N, X, ...) {#X, N::X} __VA_OPT__(, PAIR_13(N, __VA_ARGS__))
|
||||||
|
#define PAIR_11(N, X, ...) {#X, N::X} __VA_OPT__(, PAIR_12(N, __VA_ARGS__))
|
||||||
|
#define PAIR_10(N, X, ...) {#X, N::X} __VA_OPT__(, PAIR_11(N, __VA_ARGS__))
|
||||||
|
#define PAIR_9(N, X, ...) {#X, N::X} __VA_OPT__(, PAIR_10(N, __VA_ARGS__))
|
||||||
|
#define PAIR_8(N, X, ...) {#X, N::X} __VA_OPT__(, PAIR_9(N, __VA_ARGS__))
|
||||||
|
#define PAIR_7(N, X, ...) {#X, N::X} __VA_OPT__(, PAIR_8(N, __VA_ARGS__))
|
||||||
|
#define PAIR_6(N, X, ...) {#X, N::X} __VA_OPT__(, PAIR_7(N, __VA_ARGS__))
|
||||||
|
#define PAIR_5(N, X, ...) {#X, N::X} __VA_OPT__(, PAIR_6(N, __VA_ARGS__))
|
||||||
|
#define PAIR_4(N, X, ...) {#X, N::X} __VA_OPT__(, PAIR_5(N, __VA_ARGS__))
|
||||||
|
#define PAIR_3(N, X, ...) {#X, N::X} __VA_OPT__(, PAIR_4(N, __VA_ARGS__))
|
||||||
|
#define PAIR_2(N, X, ...) {#X, N::X} __VA_OPT__(, PAIR_3(N, __VA_ARGS__))
|
||||||
|
#define PAIR_1(N, X, ...) {#X, N::X} __VA_OPT__(, PAIR_2(N, __VA_ARGS__))
|
||||||
|
#define PAIR(N, X, ...) {#X, N::X} __VA_OPT__(, PAIR_1(N, __VA_ARGS__))
|
||||||
|
|
||||||
|
#define ENUM(NAME, ...) \
|
||||||
|
enum class NAME : u32 { __VA_ARGS__ }; \
|
||||||
|
template <> \
|
||||||
|
constexpr std::vector<std::pair<std::string, NAME>> EnumMetadata<NAME>::Canonicalizations() { \
|
||||||
|
return {PAIR(NAME, __VA_ARGS__)}; \
|
||||||
|
} \
|
||||||
|
template <> \
|
||||||
|
constexpr u32 EnumMetadata<NAME>::Index() { \
|
||||||
|
return __COUNTER__; \
|
||||||
|
}
|
||||||
|
|
||||||
|
// AudioEngine must be specified discretely due to having existing but slightly different
|
||||||
|
// canonicalizations
|
||||||
|
// TODO (lat9nq): Remove explicit definition of AudioEngine/sink_id
|
||||||
|
enum class AudioEngine : u32 {
|
||||||
|
Auto,
|
||||||
|
Cubeb,
|
||||||
|
Sdl2,
|
||||||
|
Null,
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
constexpr std::vector<std::pair<std::string, AudioEngine>>
|
||||||
|
EnumMetadata<AudioEngine>::Canonicalizations() {
|
||||||
|
return {
|
||||||
|
{"auto", AudioEngine::Auto},
|
||||||
|
{"cubeb", AudioEngine::Cubeb},
|
||||||
|
{"sdl2", AudioEngine::Sdl2},
|
||||||
|
{"null", AudioEngine::Null},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
constexpr u32 EnumMetadata<AudioEngine>::Index() {
|
||||||
|
// This is just a sufficiently large number that is more than the number of other enums declared
|
||||||
|
// here
|
||||||
|
return 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
ENUM(AudioMode, Mono, Stereo, Surround);
|
||||||
|
|
||||||
|
ENUM(Language, Japanese, EnglishAmerican, French, German, Italian, Spanish, Chinese, Korean, Dutch,
|
||||||
|
Portuguese, Russian, Taiwanese, EnglishBritish, FrenchCanadian, SpanishLatin,
|
||||||
|
ChineseSimplified, ChineseTraditional, PortugueseBrazilian);
|
||||||
|
|
||||||
|
ENUM(Region, Japan, Usa, Europe, Australia, China, Korea, Taiwan);
|
||||||
|
|
||||||
|
ENUM(TimeZone, Auto, Default, Cet, Cst6Cdt, Cuba, Eet, Egypt, Eire, Est, Est5Edt, Gb, GbEire, Gmt,
|
||||||
|
GmtPlusZero, GmtMinusZero, GmtZero, Greenwich, Hongkong, Hst, Iceland, Iran, Israel, Jamaica,
|
||||||
|
Japan, Kwajalein, Libya, Met, Mst, Mst7Mdt, Navajo, Nz, NzChat, Poland, Portugal, Prc, Pst8Pdt,
|
||||||
|
Roc, Rok, Singapore, Turkey, Uct, Universal, Utc, WSu, Wet, Zulu);
|
||||||
|
|
||||||
|
ENUM(AnisotropyMode, Automatic, Default, X2, X4, X8, X16);
|
||||||
|
|
||||||
|
ENUM(AstcDecodeMode, Cpu, Gpu, CpuAsynchronous);
|
||||||
|
|
||||||
|
ENUM(AstcRecompression, Uncompressed, Bc1, Bc3);
|
||||||
|
|
||||||
|
ENUM(VSyncMode, Immediate, Mailbox, Fifo, FifoRelaxed);
|
||||||
|
|
||||||
|
ENUM(RendererBackend, OpenGL, Vulkan, Null);
|
||||||
|
|
||||||
|
ENUM(ShaderBackend, Glsl, Glasm, SpirV);
|
||||||
|
|
||||||
|
ENUM(GpuAccuracy, Normal, High, Extreme);
|
||||||
|
|
||||||
|
ENUM(CpuAccuracy, Auto, Accurate, Unsafe, Paranoid);
|
||||||
|
|
||||||
|
ENUM(MemoryLayout, Memory_4Gb, Memory_6Gb, Memory_8Gb);
|
||||||
|
|
||||||
|
ENUM(FullscreenMode, Borderless, Exclusive);
|
||||||
|
|
||||||
|
ENUM(NvdecEmulation, Off, Cpu, Gpu);
|
||||||
|
|
||||||
|
ENUM(ResolutionSetup, Res1_2X, Res3_4X, Res1X, Res3_2X, Res2X, Res3X, Res4X, Res5X, Res6X, Res7X,
|
||||||
|
Res8X);
|
||||||
|
|
||||||
|
ENUM(ScalingFilter, NearestNeighbor, Bilinear, Bicubic, Gaussian, ScaleForce, Fsr, MaxEnum);
|
||||||
|
|
||||||
|
ENUM(AntiAliasing, None, Fxaa, Smaa, MaxEnum);
|
||||||
|
|
||||||
|
ENUM(AspectRatio, R16_9, R4_3, R21_9, R16_10, Stretch);
|
||||||
|
|
||||||
|
template <typename Type>
|
||||||
|
constexpr std::string CanonicalizeEnum(Type id) {
|
||||||
|
const auto group = EnumMetadata<Type>::Canonicalizations();
|
||||||
|
for (auto& [name, value] : group) {
|
||||||
|
if (value == id) {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "unknown";
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Type>
|
||||||
|
constexpr Type ToEnum(const std::string& canonicalization) {
|
||||||
|
const auto group = EnumMetadata<Type>::Canonicalizations();
|
||||||
|
for (auto& [name, value] : group) {
|
||||||
|
if (name == canonicalization) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
} // namespace Settings
|
||||||
|
|
||||||
|
#undef ENUM
|
||||||
|
#undef PAIR
|
||||||
|
#undef PAIR_1
|
||||||
|
#undef PAIR_2
|
||||||
|
#undef PAIR_3
|
||||||
|
#undef PAIR_4
|
||||||
|
#undef PAIR_5
|
||||||
|
#undef PAIR_6
|
||||||
|
#undef PAIR_7
|
||||||
|
#undef PAIR_8
|
||||||
|
#undef PAIR_9
|
||||||
|
#undef PAIR_10
|
||||||
|
#undef PAIR_12
|
||||||
|
#undef PAIR_13
|
||||||
|
#undef PAIR_14
|
||||||
|
#undef PAIR_15
|
||||||
|
#undef PAIR_16
|
||||||
|
#undef PAIR_17
|
||||||
|
#undef PAIR_18
|
||||||
|
#undef PAIR_19
|
||||||
|
#undef PAIR_20
|
||||||
|
#undef PAIR_22
|
||||||
|
#undef PAIR_23
|
||||||
|
#undef PAIR_24
|
||||||
|
#undef PAIR_25
|
||||||
|
#undef PAIR_26
|
||||||
|
#undef PAIR_27
|
||||||
|
#undef PAIR_28
|
||||||
|
#undef PAIR_29
|
||||||
|
#undef PAIR_30
|
||||||
|
#undef PAIR_32
|
||||||
|
#undef PAIR_33
|
||||||
|
#undef PAIR_34
|
||||||
|
#undef PAIR_35
|
||||||
|
#undef PAIR_36
|
||||||
|
#undef PAIR_37
|
||||||
|
#undef PAIR_38
|
||||||
|
#undef PAIR_39
|
||||||
|
#undef PAIR_40
|
||||||
|
#undef PAIR_42
|
||||||
|
#undef PAIR_43
|
||||||
|
#undef PAIR_44
|
||||||
|
#undef PAIR_45
|
|
@ -0,0 +1,394 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <limits>
|
||||||
|
#include <map>
|
||||||
|
#include <optional>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <string>
|
||||||
|
#include <typeindex>
|
||||||
|
#include <typeinfo>
|
||||||
|
#include "common/common_types.h"
|
||||||
|
#include "common/settings_common.h"
|
||||||
|
#include "common/settings_enums.h"
|
||||||
|
|
||||||
|
namespace Settings {
|
||||||
|
|
||||||
|
/** The Setting class is a simple resource manager. It defines a label and default value
|
||||||
|
* alongside the actual value of the setting for simpler and less-error prone use with frontend
|
||||||
|
* configurations. Specifying a default value and label is required. A minimum and maximum range
|
||||||
|
* can be specified for sanitization.
|
||||||
|
*/
|
||||||
|
template <typename Type, bool ranged = false>
|
||||||
|
class Setting : public BasicSetting {
|
||||||
|
protected:
|
||||||
|
Setting() = default;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Sets a default value, label, and setting value.
|
||||||
|
*
|
||||||
|
* @param linkage Setting registry
|
||||||
|
* @param default_val Initial value of the setting, and default value of the setting
|
||||||
|
* @param name Label for the setting
|
||||||
|
* @param category_ Category of the setting AKA INI group
|
||||||
|
* @param specialization_ Suggestion for how frontend implementations represent this in a config
|
||||||
|
* @param save_ Suggests that this should or should not be saved to a frontend config file
|
||||||
|
* @param runtime_modifiable_ Suggests whether this is modifiable while a guest is loaded
|
||||||
|
* @param other_setting_ A second Setting to associate to this one in metadata
|
||||||
|
*/
|
||||||
|
explicit Setting(Linkage& linkage, const Type& default_val, const std::string& name,
|
||||||
|
Category category_, u32 specialization_ = Specialization::Default,
|
||||||
|
bool save_ = true, bool runtime_modifiable_ = false,
|
||||||
|
BasicSetting* other_setting_ = nullptr)
|
||||||
|
requires(!ranged)
|
||||||
|
: BasicSetting(linkage, name, category_, save_, runtime_modifiable_, specialization_,
|
||||||
|
other_setting_),
|
||||||
|
value{default_val}, default_value{default_val} {}
|
||||||
|
virtual ~Setting() = default;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a default value, minimum value, maximum value, and label.
|
||||||
|
*
|
||||||
|
* @param linkage Setting registry
|
||||||
|
* @param default_val Initial value of the setting, and default value of the setting
|
||||||
|
* @param min_val Sets the minimum allowed value of the setting
|
||||||
|
* @param max_val Sets the maximum allowed value of the setting
|
||||||
|
* @param name Label for the setting
|
||||||
|
* @param category_ Category of the setting AKA INI group
|
||||||
|
* @param specialization_ Suggestion for how frontend implementations represent this in a config
|
||||||
|
* @param save_ Suggests that this should or should not be saved to a frontend config file
|
||||||
|
* @param runtime_modifiable_ Suggests whether this is modifiable while a guest is loaded
|
||||||
|
* @param other_setting_ A second Setting to associate to this one in metadata
|
||||||
|
*/
|
||||||
|
explicit Setting(Linkage& linkage, const Type& default_val, const Type& min_val,
|
||||||
|
const Type& max_val, const std::string& name, Category category_,
|
||||||
|
u32 specialization_ = Specialization::Default, bool save_ = true,
|
||||||
|
bool runtime_modifiable_ = false, BasicSetting* other_setting_ = nullptr)
|
||||||
|
requires(ranged)
|
||||||
|
: BasicSetting(linkage, name, category_, save_, runtime_modifiable_, specialization_,
|
||||||
|
other_setting_),
|
||||||
|
value{default_val}, default_value{default_val}, maximum{max_val}, minimum{min_val} {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a reference to the setting's value.
|
||||||
|
*
|
||||||
|
* @returns A reference to the setting
|
||||||
|
*/
|
||||||
|
[[nodiscard]] virtual const Type& GetValue() const {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the setting to the given value.
|
||||||
|
*
|
||||||
|
* @param val The desired value
|
||||||
|
*/
|
||||||
|
virtual void SetValue(const Type& val) {
|
||||||
|
Type temp{ranged ? std::clamp(val, minimum, maximum) : val};
|
||||||
|
std::swap(value, temp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the value that this setting was created with.
|
||||||
|
*
|
||||||
|
* @returns A reference to the default value
|
||||||
|
*/
|
||||||
|
[[nodiscard]] const Type& GetDefault() const {
|
||||||
|
return default_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] constexpr bool IsEnum() const override {
|
||||||
|
return std::is_enum_v<Type>;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
[[nodiscard]] std::string ToString(const Type& value_) const {
|
||||||
|
if constexpr (std::is_same_v<Type, std::string>) {
|
||||||
|
return value_;
|
||||||
|
} else if constexpr (std::is_same_v<Type, std::optional<u32>>) {
|
||||||
|
return value_.has_value() ? std::to_string(*value_) : "none";
|
||||||
|
} else if constexpr (std::is_same_v<Type, bool>) {
|
||||||
|
return value_ ? "true" : "false";
|
||||||
|
} else if constexpr (std::is_same_v<Type, AudioEngine>) {
|
||||||
|
// Compatibility with old AudioEngine setting being a string
|
||||||
|
return CanonicalizeEnum(value_);
|
||||||
|
} else {
|
||||||
|
return std::to_string(static_cast<u64>(value_));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Converts the value of the setting to a std::string. Respects the global state if the setting
|
||||||
|
* has one.
|
||||||
|
*
|
||||||
|
* @returns The current setting as a std::string
|
||||||
|
*/
|
||||||
|
[[nodiscard]] std::string ToString() const override {
|
||||||
|
return ToString(this->GetValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the default value of the setting as a std::string.
|
||||||
|
*
|
||||||
|
* @returns The default value as a string.
|
||||||
|
*/
|
||||||
|
[[nodiscard]] std::string DefaultToString() const override {
|
||||||
|
return ToString(default_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assigns a value to the setting.
|
||||||
|
*
|
||||||
|
* @param val The desired setting value
|
||||||
|
*
|
||||||
|
* @returns A reference to the setting
|
||||||
|
*/
|
||||||
|
virtual const Type& operator=(const Type& val) {
|
||||||
|
Type temp{ranged ? std::clamp(val, minimum, maximum) : val};
|
||||||
|
std::swap(value, temp);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a reference to the setting.
|
||||||
|
*
|
||||||
|
* @returns A reference to the setting
|
||||||
|
*/
|
||||||
|
explicit virtual operator const Type&() const {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts the given value to the Setting's type of value. Uses SetValue to enter the setting,
|
||||||
|
* thus respecting its constraints.
|
||||||
|
*
|
||||||
|
* @param input The desired value
|
||||||
|
*/
|
||||||
|
void LoadString(const std::string& input) override final {
|
||||||
|
if (input.empty()) {
|
||||||
|
this->SetValue(this->GetDefault());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
if constexpr (std::is_same_v<Type, std::string>) {
|
||||||
|
this->SetValue(input);
|
||||||
|
} else if constexpr (std::is_same_v<Type, std::optional<u32>>) {
|
||||||
|
this->SetValue(static_cast<u32>(std::stoul(input)));
|
||||||
|
} else if constexpr (std::is_same_v<Type, bool>) {
|
||||||
|
this->SetValue(input == "true");
|
||||||
|
} else if constexpr (std::is_same_v<Type, AudioEngine>) {
|
||||||
|
this->SetValue(ToEnum<Type>(input));
|
||||||
|
} else {
|
||||||
|
this->SetValue(static_cast<Type>(std::stoll(input)));
|
||||||
|
}
|
||||||
|
} catch (std::invalid_argument&) {
|
||||||
|
this->SetValue(this->GetDefault());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] std::string constexpr Canonicalize() const override final {
|
||||||
|
if constexpr (std::is_enum_v<Type>) {
|
||||||
|
return CanonicalizeEnum(this->GetValue());
|
||||||
|
} else {
|
||||||
|
return ToString(this->GetValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gives us another way to identify the setting without having to go through a string.
|
||||||
|
*
|
||||||
|
* @returns the type_index of the setting's type
|
||||||
|
*/
|
||||||
|
[[nodiscard]] std::type_index TypeId() const override final {
|
||||||
|
return std::type_index(typeid(Type));
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] constexpr u32 EnumIndex() const override final {
|
||||||
|
if constexpr (std::is_enum_v<Type>) {
|
||||||
|
return EnumMetadata<Type>::Index();
|
||||||
|
} else {
|
||||||
|
return std::numeric_limits<u32>::max();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] std::string MinVal() const override final {
|
||||||
|
return this->ToString(minimum);
|
||||||
|
}
|
||||||
|
[[nodiscard]] std::string MaxVal() const override final {
|
||||||
|
return this->ToString(maximum);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] constexpr bool Ranged() const override {
|
||||||
|
return ranged;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Type value{}; ///< The setting
|
||||||
|
const Type default_value{}; ///< The default value
|
||||||
|
const Type maximum{}; ///< Maximum allowed value of the setting
|
||||||
|
const Type minimum{}; ///< Minimum allowed value of the setting
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The SwitchableSetting class is a slightly more complex version of the Setting class. This adds a
|
||||||
|
* custom setting to switch to when a guest application specifically requires it. The effect is that
|
||||||
|
* other components of the emulator can access the setting's intended value without any need for the
|
||||||
|
* component to ask whether the custom or global setting is needed at the moment.
|
||||||
|
*
|
||||||
|
* By default, the global setting is used.
|
||||||
|
*/
|
||||||
|
template <typename Type, bool ranged = false>
|
||||||
|
class SwitchableSetting : virtual public Setting<Type, ranged> {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Sets a default value, label, and setting value.
|
||||||
|
*
|
||||||
|
* @param linkage Setting registry
|
||||||
|
* @param default_val Initial value of the setting, and default value of the setting
|
||||||
|
* @param name Label for the setting
|
||||||
|
* @param category_ Category of the setting AKA INI group
|
||||||
|
* @param specialization_ Suggestion for how frontend implementations represent this in a config
|
||||||
|
* @param save_ Suggests that this should or should not be saved to a frontend config file
|
||||||
|
* @param runtime_modifiable_ Suggests whether this is modifiable while a guest is loaded
|
||||||
|
* @param other_setting_ A second Setting to associate to this one in metadata
|
||||||
|
*/
|
||||||
|
explicit SwitchableSetting(Linkage& linkage, const Type& default_val, const std::string& name,
|
||||||
|
Category category_, u32 specialization_ = Specialization::Default,
|
||||||
|
bool save_ = true, bool runtime_modifiable_ = false,
|
||||||
|
BasicSetting* other_setting_ = nullptr)
|
||||||
|
requires(!ranged)
|
||||||
|
: Setting<Type, false>{
|
||||||
|
linkage, default_val, name, category_, specialization_,
|
||||||
|
save_, runtime_modifiable_, other_setting_} {
|
||||||
|
linkage.restore_functions.emplace_back([this]() { this->SetGlobal(true); });
|
||||||
|
}
|
||||||
|
virtual ~SwitchableSetting() = default;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a default value, minimum value, maximum value, and label.
|
||||||
|
*
|
||||||
|
* @param linkage Setting registry
|
||||||
|
* @param default_val Initial value of the setting, and default value of the setting
|
||||||
|
* @param min_val Sets the minimum allowed value of the setting
|
||||||
|
* @param max_val Sets the maximum allowed value of the setting
|
||||||
|
* @param name Label for the setting
|
||||||
|
* @param category_ Category of the setting AKA INI group
|
||||||
|
* @param specialization_ Suggestion for how frontend implementations represent this in a config
|
||||||
|
* @param save_ Suggests that this should or should not be saved to a frontend config file
|
||||||
|
* @param runtime_modifiable_ Suggests whether this is modifiable while a guest is loaded
|
||||||
|
* @param other_setting_ A second Setting to associate to this one in metadata
|
||||||
|
*/
|
||||||
|
explicit SwitchableSetting(Linkage& linkage, const Type& default_val, const Type& min_val,
|
||||||
|
const Type& max_val, const std::string& name, Category category_,
|
||||||
|
u32 specialization_ = Specialization::Default, bool save_ = true,
|
||||||
|
bool runtime_modifiable_ = false,
|
||||||
|
BasicSetting* other_setting_ = nullptr)
|
||||||
|
requires(ranged)
|
||||||
|
: Setting<Type, true>{linkage, default_val, min_val,
|
||||||
|
max_val, name, category_,
|
||||||
|
specialization_, save_, runtime_modifiable_,
|
||||||
|
other_setting_} {
|
||||||
|
linkage.restore_functions.emplace_back([this]() { this->SetGlobal(true); });
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tells this setting to represent either the global or custom setting when other member
|
||||||
|
* functions are used.
|
||||||
|
*
|
||||||
|
* @param to_global Whether to use the global or custom setting.
|
||||||
|
*/
|
||||||
|
void SetGlobal(bool to_global) override final {
|
||||||
|
use_global = to_global;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether this setting is using the global setting or not.
|
||||||
|
*
|
||||||
|
* @returns The global state
|
||||||
|
*/
|
||||||
|
[[nodiscard]] bool UsingGlobal() const override final {
|
||||||
|
return use_global;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns either the global or custom setting depending on the values of this setting's global
|
||||||
|
* state or if the global value was specifically requested.
|
||||||
|
*
|
||||||
|
* @param need_global Request global value regardless of setting's state; defaults to false
|
||||||
|
*
|
||||||
|
* @returns The required value of the setting
|
||||||
|
*/
|
||||||
|
[[nodiscard]] const Type& GetValue() const override final {
|
||||||
|
if (use_global) {
|
||||||
|
return this->value;
|
||||||
|
}
|
||||||
|
return custom;
|
||||||
|
}
|
||||||
|
[[nodiscard]] const Type& GetValue(bool need_global) const {
|
||||||
|
if (use_global || need_global) {
|
||||||
|
return this->value;
|
||||||
|
}
|
||||||
|
return custom;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the current setting value depending on the global state.
|
||||||
|
*
|
||||||
|
* @param val The new value
|
||||||
|
*/
|
||||||
|
void SetValue(const Type& val) override final {
|
||||||
|
Type temp{ranged ? std::clamp(val, this->minimum, this->maximum) : val};
|
||||||
|
if (use_global) {
|
||||||
|
std::swap(this->value, temp);
|
||||||
|
} else {
|
||||||
|
std::swap(custom, temp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] constexpr bool Switchable() const override final {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] std::string ToStringGlobal() const override final {
|
||||||
|
return this->ToString(this->value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assigns the current setting value depending on the global state.
|
||||||
|
*
|
||||||
|
* @param val The new value
|
||||||
|
*
|
||||||
|
* @returns A reference to the current setting value
|
||||||
|
*/
|
||||||
|
const Type& operator=(const Type& val) override final {
|
||||||
|
Type temp{ranged ? std::clamp(val, this->minimum, this->maximum) : val};
|
||||||
|
if (use_global) {
|
||||||
|
std::swap(this->value, temp);
|
||||||
|
return this->value;
|
||||||
|
}
|
||||||
|
std::swap(custom, temp);
|
||||||
|
return custom;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the current setting value depending on the global state.
|
||||||
|
*
|
||||||
|
* @returns A reference to the current setting value
|
||||||
|
*/
|
||||||
|
explicit operator const Type&() const override final {
|
||||||
|
if (use_global) {
|
||||||
|
return this->value;
|
||||||
|
}
|
||||||
|
return custom;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool use_global{true}; ///< The setting's global state
|
||||||
|
Type custom{}; ///< The custom value of the setting
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Settings
|
|
@ -287,7 +287,7 @@ std::shared_ptr<Dynarmic::A32::Jit> ARM_Dynarmic_32::MakeJit(Common::PageTable*
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Unsafe optimizations
|
// Unsafe optimizations
|
||||||
if (Settings::values.cpu_accuracy.GetValue() == Settings::CPUAccuracy::Unsafe) {
|
if (Settings::values.cpu_accuracy.GetValue() == Settings::CpuAccuracy::Unsafe) {
|
||||||
config.unsafe_optimizations = true;
|
config.unsafe_optimizations = true;
|
||||||
if (Settings::values.cpuopt_unsafe_unfuse_fma) {
|
if (Settings::values.cpuopt_unsafe_unfuse_fma) {
|
||||||
config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_UnfuseFMA;
|
config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_UnfuseFMA;
|
||||||
|
@ -307,7 +307,7 @@ std::shared_ptr<Dynarmic::A32::Jit> ARM_Dynarmic_32::MakeJit(Common::PageTable*
|
||||||
}
|
}
|
||||||
|
|
||||||
// Curated optimizations
|
// Curated optimizations
|
||||||
if (Settings::values.cpu_accuracy.GetValue() == Settings::CPUAccuracy::Auto) {
|
if (Settings::values.cpu_accuracy.GetValue() == Settings::CpuAccuracy::Auto) {
|
||||||
config.unsafe_optimizations = true;
|
config.unsafe_optimizations = true;
|
||||||
config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_UnfuseFMA;
|
config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_UnfuseFMA;
|
||||||
config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_IgnoreStandardFPCRValue;
|
config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_IgnoreStandardFPCRValue;
|
||||||
|
@ -316,7 +316,7 @@ std::shared_ptr<Dynarmic::A32::Jit> ARM_Dynarmic_32::MakeJit(Common::PageTable*
|
||||||
}
|
}
|
||||||
|
|
||||||
// Paranoia mode for debugging optimizations
|
// Paranoia mode for debugging optimizations
|
||||||
if (Settings::values.cpu_accuracy.GetValue() == Settings::CPUAccuracy::Paranoid) {
|
if (Settings::values.cpu_accuracy.GetValue() == Settings::CpuAccuracy::Paranoid) {
|
||||||
config.unsafe_optimizations = false;
|
config.unsafe_optimizations = false;
|
||||||
config.optimizations = Dynarmic::no_optimizations;
|
config.optimizations = Dynarmic::no_optimizations;
|
||||||
}
|
}
|
||||||
|
|
|
@ -347,7 +347,7 @@ std::shared_ptr<Dynarmic::A64::Jit> ARM_Dynarmic_64::MakeJit(Common::PageTable*
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Unsafe optimizations
|
// Unsafe optimizations
|
||||||
if (Settings::values.cpu_accuracy.GetValue() == Settings::CPUAccuracy::Unsafe) {
|
if (Settings::values.cpu_accuracy.GetValue() == Settings::CpuAccuracy::Unsafe) {
|
||||||
config.unsafe_optimizations = true;
|
config.unsafe_optimizations = true;
|
||||||
if (Settings::values.cpuopt_unsafe_unfuse_fma) {
|
if (Settings::values.cpuopt_unsafe_unfuse_fma) {
|
||||||
config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_UnfuseFMA;
|
config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_UnfuseFMA;
|
||||||
|
@ -367,7 +367,7 @@ std::shared_ptr<Dynarmic::A64::Jit> ARM_Dynarmic_64::MakeJit(Common::PageTable*
|
||||||
}
|
}
|
||||||
|
|
||||||
// Curated optimizations
|
// Curated optimizations
|
||||||
if (Settings::values.cpu_accuracy.GetValue() == Settings::CPUAccuracy::Auto) {
|
if (Settings::values.cpu_accuracy.GetValue() == Settings::CpuAccuracy::Auto) {
|
||||||
config.unsafe_optimizations = true;
|
config.unsafe_optimizations = true;
|
||||||
config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_UnfuseFMA;
|
config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_UnfuseFMA;
|
||||||
config.fastmem_address_space_bits = 64;
|
config.fastmem_address_space_bits = 64;
|
||||||
|
@ -375,7 +375,7 @@ std::shared_ptr<Dynarmic::A64::Jit> ARM_Dynarmic_64::MakeJit(Common::PageTable*
|
||||||
}
|
}
|
||||||
|
|
||||||
// Paranoia mode for debugging optimizations
|
// Paranoia mode for debugging optimizations
|
||||||
if (Settings::values.cpu_accuracy.GetValue() == Settings::CPUAccuracy::Paranoid) {
|
if (Settings::values.cpu_accuracy.GetValue() == Settings::CpuAccuracy::Paranoid) {
|
||||||
config.unsafe_optimizations = false;
|
config.unsafe_optimizations = false;
|
||||||
config.optimizations = Dynarmic::no_optimizations;
|
config.optimizations = Dynarmic::no_optimizations;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "common/microprofile.h"
|
#include "common/microprofile.h"
|
||||||
#include "common/settings.h"
|
#include "common/settings.h"
|
||||||
|
#include "common/settings_enums.h"
|
||||||
#include "common/string_util.h"
|
#include "common/string_util.h"
|
||||||
#include "core/arm/exclusive_monitor.h"
|
#include "core/arm/exclusive_monitor.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
|
@ -140,16 +141,13 @@ struct System::Impl {
|
||||||
device_memory = std::make_unique<Core::DeviceMemory>();
|
device_memory = std::make_unique<Core::DeviceMemory>();
|
||||||
|
|
||||||
is_multicore = Settings::values.use_multi_core.GetValue();
|
is_multicore = Settings::values.use_multi_core.GetValue();
|
||||||
extended_memory_layout = Settings::values.use_unsafe_extended_memory_layout.GetValue();
|
extended_memory_layout =
|
||||||
|
Settings::values.memory_layout_mode.GetValue() != Settings::MemoryLayout::Memory_4Gb;
|
||||||
|
|
||||||
core_timing.SetMulticore(is_multicore);
|
core_timing.SetMulticore(is_multicore);
|
||||||
core_timing.Initialize([&system]() { system.RegisterHostThread(); });
|
core_timing.Initialize([&system]() { system.RegisterHostThread(); });
|
||||||
|
|
||||||
const auto posix_time = std::chrono::system_clock::now().time_since_epoch();
|
RefreshTime();
|
||||||
const auto current_time =
|
|
||||||
std::chrono::duration_cast<std::chrono::seconds>(posix_time).count();
|
|
||||||
Settings::values.custom_rtc_differential =
|
|
||||||
Settings::values.custom_rtc.value_or(current_time) - current_time;
|
|
||||||
|
|
||||||
// Create a default fs if one doesn't already exist.
|
// Create a default fs if one doesn't already exist.
|
||||||
if (virtual_filesystem == nullptr) {
|
if (virtual_filesystem == nullptr) {
|
||||||
|
@ -172,7 +170,8 @@ struct System::Impl {
|
||||||
void ReinitializeIfNecessary(System& system) {
|
void ReinitializeIfNecessary(System& system) {
|
||||||
const bool must_reinitialize =
|
const bool must_reinitialize =
|
||||||
is_multicore != Settings::values.use_multi_core.GetValue() ||
|
is_multicore != Settings::values.use_multi_core.GetValue() ||
|
||||||
extended_memory_layout != Settings::values.use_unsafe_extended_memory_layout.GetValue();
|
extended_memory_layout != (Settings::values.memory_layout_mode.GetValue() !=
|
||||||
|
Settings::MemoryLayout::Memory_4Gb);
|
||||||
|
|
||||||
if (!must_reinitialize) {
|
if (!must_reinitialize) {
|
||||||
return;
|
return;
|
||||||
|
@ -181,11 +180,22 @@ struct System::Impl {
|
||||||
LOG_DEBUG(Kernel, "Re-initializing");
|
LOG_DEBUG(Kernel, "Re-initializing");
|
||||||
|
|
||||||
is_multicore = Settings::values.use_multi_core.GetValue();
|
is_multicore = Settings::values.use_multi_core.GetValue();
|
||||||
extended_memory_layout = Settings::values.use_unsafe_extended_memory_layout.GetValue();
|
extended_memory_layout =
|
||||||
|
Settings::values.memory_layout_mode.GetValue() != Settings::MemoryLayout::Memory_4Gb;
|
||||||
|
|
||||||
Initialize(system);
|
Initialize(system);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RefreshTime() {
|
||||||
|
const auto posix_time = std::chrono::system_clock::now().time_since_epoch();
|
||||||
|
const auto current_time =
|
||||||
|
std::chrono::duration_cast<std::chrono::seconds>(posix_time).count();
|
||||||
|
Settings::values.custom_rtc_differential =
|
||||||
|
(Settings::values.custom_rtc_enabled ? Settings::values.custom_rtc.GetValue()
|
||||||
|
: current_time) -
|
||||||
|
current_time;
|
||||||
|
}
|
||||||
|
|
||||||
void Run() {
|
void Run() {
|
||||||
std::unique_lock<std::mutex> lk(suspend_guard);
|
std::unique_lock<std::mutex> lk(suspend_guard);
|
||||||
|
|
||||||
|
@ -1028,6 +1038,8 @@ void System::Exit() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void System::ApplySettings() {
|
void System::ApplySettings() {
|
||||||
|
impl->RefreshTime();
|
||||||
|
|
||||||
if (IsPoweredOn()) {
|
if (IsPoweredOn()) {
|
||||||
Renderer().RefreshBaseSettings();
|
Renderer().RefreshBaseSettings();
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,7 +68,8 @@ NACP::NACP(VirtualFile file) {
|
||||||
NACP::~NACP() = default;
|
NACP::~NACP() = default;
|
||||||
|
|
||||||
const LanguageEntry& NACP::GetLanguageEntry() const {
|
const LanguageEntry& NACP::GetLanguageEntry() const {
|
||||||
Language language = language_to_codes[Settings::values.language_index.GetValue()];
|
Language language =
|
||||||
|
language_to_codes[static_cast<s32>(Settings::values.language_index.GetValue())];
|
||||||
|
|
||||||
{
|
{
|
||||||
const auto& language_entry = raw.language_entries.at(static_cast<u8>(language));
|
const auto& language_entry = raw.language_entries.at(static_cast<u8>(language));
|
||||||
|
|
|
@ -626,8 +626,8 @@ PatchManager::Metadata PatchManager::ParseControlNCA(const NCA& nca) const {
|
||||||
auto nacp = nacp_file == nullptr ? nullptr : std::make_unique<NACP>(nacp_file);
|
auto nacp = nacp_file == nullptr ? nullptr : std::make_unique<NACP>(nacp_file);
|
||||||
|
|
||||||
// Get language code from settings
|
// Get language code from settings
|
||||||
const auto language_code =
|
const auto language_code = Service::Set::GetLanguageCodeFromIndex(
|
||||||
Service::Set::GetLanguageCodeFromIndex(Settings::values.language_index.GetValue());
|
static_cast<u32>(Settings::values.language_index.GetValue()));
|
||||||
|
|
||||||
// Convert to application language and get priority list
|
// Convert to application language and get priority list
|
||||||
const auto application_language =
|
const auto application_language =
|
||||||
|
|
|
@ -35,13 +35,27 @@ namespace {
|
||||||
using namespace Common::Literals;
|
using namespace Common::Literals;
|
||||||
|
|
||||||
u32 GetMemorySizeForInit() {
|
u32 GetMemorySizeForInit() {
|
||||||
return Settings::values.use_unsafe_extended_memory_layout ? Smc::MemorySize_8GB
|
switch (Settings::values.memory_layout_mode.GetValue()) {
|
||||||
: Smc::MemorySize_4GB;
|
case Settings::MemoryLayout::Memory_4Gb:
|
||||||
|
return Smc::MemorySize_4GB;
|
||||||
|
case Settings::MemoryLayout::Memory_6Gb:
|
||||||
|
return Smc::MemorySize_6GB;
|
||||||
|
case Settings::MemoryLayout::Memory_8Gb:
|
||||||
|
return Smc::MemorySize_8GB;
|
||||||
|
}
|
||||||
|
return Smc::MemorySize_4GB;
|
||||||
}
|
}
|
||||||
|
|
||||||
Smc::MemoryArrangement GetMemoryArrangeForInit() {
|
Smc::MemoryArrangement GetMemoryArrangeForInit() {
|
||||||
return Settings::values.use_unsafe_extended_memory_layout ? Smc::MemoryArrangement_8GB
|
switch (Settings::values.memory_layout_mode.GetValue()) {
|
||||||
: Smc::MemoryArrangement_4GB;
|
case Settings::MemoryLayout::Memory_4Gb:
|
||||||
|
return Smc::MemoryArrangement_4GB;
|
||||||
|
case Settings::MemoryLayout::Memory_6Gb:
|
||||||
|
return Smc::MemoryArrangement_6GB;
|
||||||
|
case Settings::MemoryLayout::Memory_8Gb:
|
||||||
|
return Smc::MemoryArrangement_8GB;
|
||||||
|
}
|
||||||
|
return Smc::MemoryArrangement_4GB;
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
|
|
@ -81,7 +81,8 @@ Result KProcess::Initialize(KProcess* process, Core::System& system, std::string
|
||||||
process->m_capabilities.InitializeForMetadatalessProcess();
|
process->m_capabilities.InitializeForMetadatalessProcess();
|
||||||
process->m_is_initialized = true;
|
process->m_is_initialized = true;
|
||||||
|
|
||||||
std::mt19937 rng(Settings::values.rng_seed.GetValue().value_or(std::time(nullptr)));
|
std::mt19937 rng(Settings::values.rng_seed_enabled ? Settings::values.rng_seed.GetValue()
|
||||||
|
: static_cast<u32>(std::time(nullptr)));
|
||||||
std::uniform_int_distribution<u64> distribution;
|
std::uniform_int_distribution<u64> distribution;
|
||||||
std::generate(process->m_random_entropy.begin(), process->m_random_entropy.end(),
|
std::generate(process->m_random_entropy.begin(), process->m_random_entropy.end(),
|
||||||
[&] { return distribution(rng); });
|
[&] { return distribution(rng); });
|
||||||
|
|
|
@ -409,7 +409,7 @@ ResultVal<u8> IApplicationManagerInterface::GetApplicationDesiredLanguage(
|
||||||
|
|
||||||
// Get language code from settings
|
// Get language code from settings
|
||||||
const auto language_code =
|
const auto language_code =
|
||||||
Set::GetLanguageCodeFromIndex(Settings::values.language_index.GetValue());
|
Set::GetLanguageCodeFromIndex(static_cast<s32>(Settings::values.language_index.GetValue()));
|
||||||
|
|
||||||
// Convert to application language, get priority list
|
// Convert to application language, get priority list
|
||||||
const auto application_language = ConvertToApplicationLanguage(language_code);
|
const auto application_language = ConvertToApplicationLanguage(language_code);
|
||||||
|
|
|
@ -93,7 +93,8 @@ void GetAvailableLanguageCodesImpl(HLERequestContext& ctx, std::size_t max_entri
|
||||||
}
|
}
|
||||||
|
|
||||||
void GetKeyCodeMapImpl(HLERequestContext& ctx) {
|
void GetKeyCodeMapImpl(HLERequestContext& ctx) {
|
||||||
const auto language_code = available_language_codes[Settings::values.language_index.GetValue()];
|
const auto language_code =
|
||||||
|
available_language_codes[static_cast<s32>(Settings::values.language_index.GetValue())];
|
||||||
const auto key_code =
|
const auto key_code =
|
||||||
std::find_if(language_to_layout.cbegin(), language_to_layout.cend(),
|
std::find_if(language_to_layout.cbegin(), language_to_layout.cend(),
|
||||||
[=](const auto& element) { return element.first == language_code; });
|
[=](const auto& element) { return element.first == language_code; });
|
||||||
|
@ -162,7 +163,7 @@ void SET::GetQuestFlag(HLERequestContext& ctx) {
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 3};
|
IPC::ResponseBuilder rb{ctx, 3};
|
||||||
rb.Push(ResultSuccess);
|
rb.Push(ResultSuccess);
|
||||||
rb.Push(static_cast<u32>(Settings::values.quest_flag.GetValue()));
|
rb.Push(static_cast<s32>(Settings::values.quest_flag.GetValue()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SET::GetLanguageCode(HLERequestContext& ctx) {
|
void SET::GetLanguageCode(HLERequestContext& ctx) {
|
||||||
|
@ -170,7 +171,8 @@ void SET::GetLanguageCode(HLERequestContext& ctx) {
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 4};
|
IPC::ResponseBuilder rb{ctx, 4};
|
||||||
rb.Push(ResultSuccess);
|
rb.Push(ResultSuccess);
|
||||||
rb.PushEnum(available_language_codes[Settings::values.language_index.GetValue()]);
|
rb.PushEnum(
|
||||||
|
available_language_codes[static_cast<s32>(Settings::values.language_index.GetValue())]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SET::GetRegionCode(HLERequestContext& ctx) {
|
void SET::GetRegionCode(HLERequestContext& ctx) {
|
||||||
|
@ -178,7 +180,7 @@ void SET::GetRegionCode(HLERequestContext& ctx) {
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 3};
|
IPC::ResponseBuilder rb{ctx, 3};
|
||||||
rb.Push(ResultSuccess);
|
rb.Push(ResultSuccess);
|
||||||
rb.Push(Settings::values.region_index.GetValue());
|
rb.Push(static_cast<u32>(Settings::values.region_index.GetValue()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SET::GetKeyCodeMap(HLERequestContext& ctx) {
|
void SET::GetKeyCodeMap(HLERequestContext& ctx) {
|
||||||
|
|
|
@ -19,7 +19,8 @@ namespace Service::SPL {
|
||||||
Module::Interface::Interface(Core::System& system_, std::shared_ptr<Module> module_,
|
Module::Interface::Interface(Core::System& system_, std::shared_ptr<Module> module_,
|
||||||
const char* name)
|
const char* name)
|
||||||
: ServiceFramework{system_, name}, module{std::move(module_)},
|
: ServiceFramework{system_, name}, module{std::move(module_)},
|
||||||
rng(Settings::values.rng_seed.GetValue().value_or(std::time(nullptr))) {}
|
rng(Settings::values.rng_seed_enabled ? Settings::values.rng_seed.GetValue()
|
||||||
|
: static_cast<u32>(std::time(nullptr))) {}
|
||||||
|
|
||||||
Module::Interface::~Interface() = default;
|
Module::Interface::~Interface() = default;
|
||||||
|
|
||||||
|
|
|
@ -78,7 +78,8 @@ TimeZoneContentManager::TimeZoneContentManager(Core::System& system_)
|
||||||
location_name_cache{BuildLocationNameCache(time_zone_binary)} {}
|
location_name_cache{BuildLocationNameCache(time_zone_binary)} {}
|
||||||
|
|
||||||
void TimeZoneContentManager::Initialize(TimeManager& time_manager) {
|
void TimeZoneContentManager::Initialize(TimeManager& time_manager) {
|
||||||
const auto timezone_setting = Settings::GetTimeZoneString();
|
const auto timezone_setting =
|
||||||
|
Settings::GetTimeZoneString(Settings::values.time_zone_index.GetValue());
|
||||||
|
|
||||||
if (FileSys::VirtualFile vfs_file;
|
if (FileSys::VirtualFile vfs_file;
|
||||||
GetTimeZoneInfoFile(timezone_setting, vfs_file) == ResultSuccess) {
|
GetTimeZoneInfoFile(timezone_setting, vfs_file) == ResultSuccess) {
|
||||||
|
|
|
@ -61,13 +61,13 @@ static const char* TranslateRenderer(Settings::RendererBackend backend) {
|
||||||
return "Unknown";
|
return "Unknown";
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char* TranslateGPUAccuracyLevel(Settings::GPUAccuracy backend) {
|
static const char* TranslateGPUAccuracyLevel(Settings::GpuAccuracy backend) {
|
||||||
switch (backend) {
|
switch (backend) {
|
||||||
case Settings::GPUAccuracy::Normal:
|
case Settings::GpuAccuracy::Normal:
|
||||||
return "Normal";
|
return "Normal";
|
||||||
case Settings::GPUAccuracy::High:
|
case Settings::GpuAccuracy::High:
|
||||||
return "High";
|
return "High";
|
||||||
case Settings::GPUAccuracy::Extreme:
|
case Settings::GpuAccuracy::Extreme:
|
||||||
return "Extreme";
|
return "Extreme";
|
||||||
}
|
}
|
||||||
return "Unknown";
|
return "Unknown";
|
||||||
|
@ -77,9 +77,9 @@ static const char* TranslateNvdecEmulation(Settings::NvdecEmulation backend) {
|
||||||
switch (backend) {
|
switch (backend) {
|
||||||
case Settings::NvdecEmulation::Off:
|
case Settings::NvdecEmulation::Off:
|
||||||
return "Off";
|
return "Off";
|
||||||
case Settings::NvdecEmulation::CPU:
|
case Settings::NvdecEmulation::Cpu:
|
||||||
return "CPU";
|
return "CPU";
|
||||||
case Settings::NvdecEmulation::GPU:
|
case Settings::NvdecEmulation::Gpu:
|
||||||
return "GPU";
|
return "GPU";
|
||||||
}
|
}
|
||||||
return "Unknown";
|
return "Unknown";
|
||||||
|
@ -91,14 +91,26 @@ static constexpr const char* TranslateVSyncMode(Settings::VSyncMode mode) {
|
||||||
return "Immediate";
|
return "Immediate";
|
||||||
case Settings::VSyncMode::Mailbox:
|
case Settings::VSyncMode::Mailbox:
|
||||||
return "Mailbox";
|
return "Mailbox";
|
||||||
case Settings::VSyncMode::FIFO:
|
case Settings::VSyncMode::Fifo:
|
||||||
return "FIFO";
|
return "FIFO";
|
||||||
case Settings::VSyncMode::FIFORelaxed:
|
case Settings::VSyncMode::FifoRelaxed:
|
||||||
return "FIFO Relaxed";
|
return "FIFO Relaxed";
|
||||||
}
|
}
|
||||||
return "Unknown";
|
return "Unknown";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static constexpr const char* TranslateASTCDecodeMode(Settings::AstcDecodeMode mode) {
|
||||||
|
switch (mode) {
|
||||||
|
case Settings::AstcDecodeMode::Cpu:
|
||||||
|
return "CPU";
|
||||||
|
case Settings::AstcDecodeMode::Gpu:
|
||||||
|
return "GPU";
|
||||||
|
case Settings::AstcDecodeMode::CpuAsynchronous:
|
||||||
|
return "CPU Asynchronous";
|
||||||
|
}
|
||||||
|
return "Unknown";
|
||||||
|
}
|
||||||
|
|
||||||
u64 GetTelemetryId() {
|
u64 GetTelemetryId() {
|
||||||
u64 telemetry_id{};
|
u64 telemetry_id{};
|
||||||
const auto filename = Common::FS::GetYuzuPath(Common::FS::YuzuPath::ConfigDir) / "telemetry_id";
|
const auto filename = Common::FS::GetYuzuPath(Common::FS::YuzuPath::ConfigDir) / "telemetry_id";
|
||||||
|
@ -240,7 +252,8 @@ void TelemetrySession::AddInitialInfo(Loader::AppLoader& app_loader,
|
||||||
|
|
||||||
// Log user configuration information
|
// Log user configuration information
|
||||||
constexpr auto field_type = Telemetry::FieldType::UserConfig;
|
constexpr auto field_type = Telemetry::FieldType::UserConfig;
|
||||||
AddField(field_type, "Audio_SinkId", Settings::values.sink_id.GetValue());
|
AddField(field_type, "Audio_SinkId",
|
||||||
|
Settings::CanonicalizeEnum(Settings::values.sink_id.GetValue()));
|
||||||
AddField(field_type, "Core_UseMultiCore", Settings::values.use_multi_core.GetValue());
|
AddField(field_type, "Core_UseMultiCore", Settings::values.use_multi_core.GetValue());
|
||||||
AddField(field_type, "Renderer_Backend",
|
AddField(field_type, "Renderer_Backend",
|
||||||
TranslateRenderer(Settings::values.renderer_backend.GetValue()));
|
TranslateRenderer(Settings::values.renderer_backend.GetValue()));
|
||||||
|
@ -254,7 +267,8 @@ void TelemetrySession::AddInitialInfo(Loader::AppLoader& app_loader,
|
||||||
Settings::values.use_asynchronous_gpu_emulation.GetValue());
|
Settings::values.use_asynchronous_gpu_emulation.GetValue());
|
||||||
AddField(field_type, "Renderer_NvdecEmulation",
|
AddField(field_type, "Renderer_NvdecEmulation",
|
||||||
TranslateNvdecEmulation(Settings::values.nvdec_emulation.GetValue()));
|
TranslateNvdecEmulation(Settings::values.nvdec_emulation.GetValue()));
|
||||||
AddField(field_type, "Renderer_AccelerateASTC", Settings::values.accelerate_astc.GetValue());
|
AddField(field_type, "Renderer_AccelerateASTC",
|
||||||
|
TranslateASTCDecodeMode(Settings::values.accelerate_astc.GetValue()));
|
||||||
AddField(field_type, "Renderer_UseVsync",
|
AddField(field_type, "Renderer_UseVsync",
|
||||||
TranslateVSyncMode(Settings::values.vsync_mode.GetValue()));
|
TranslateVSyncMode(Settings::values.vsync_mode.GetValue()));
|
||||||
AddField(field_type, "Renderer_ShaderBackend",
|
AddField(field_type, "Renderer_ShaderBackend",
|
||||||
|
|
|
@ -247,7 +247,7 @@ void Codec::Initialize() {
|
||||||
av_codec = avcodec_find_decoder(codec);
|
av_codec = avcodec_find_decoder(codec);
|
||||||
|
|
||||||
InitializeAvCodecContext();
|
InitializeAvCodecContext();
|
||||||
if (Settings::values.nvdec_emulation.GetValue() == Settings::NvdecEmulation::GPU) {
|
if (Settings::values.nvdec_emulation.GetValue() == Settings::NvdecEmulation::Gpu) {
|
||||||
InitializeGpuDecoder();
|
InitializeGpuDecoder();
|
||||||
}
|
}
|
||||||
if (const int res = avcodec_open2(av_codec_ctx, av_codec, nullptr); res < 0) {
|
if (const int res = avcodec_open2(av_codec_ctx, av_codec, nullptr); res < 0) {
|
||||||
|
|
|
@ -84,7 +84,7 @@ std::span<const u8> H264::ComposeFrame(const Host1x::NvdecCommon::NvdecRegisters
|
||||||
|
|
||||||
// TODO (ameerj): Where do we get this number, it seems to be particular for each stream
|
// TODO (ameerj): Where do we get this number, it seems to be particular for each stream
|
||||||
const auto nvdec_decoding = Settings::values.nvdec_emulation.GetValue();
|
const auto nvdec_decoding = Settings::values.nvdec_emulation.GetValue();
|
||||||
const bool uses_gpu_decoding = nvdec_decoding == Settings::NvdecEmulation::GPU;
|
const bool uses_gpu_decoding = nvdec_decoding == Settings::NvdecEmulation::Gpu;
|
||||||
const u32 max_num_ref_frames = uses_gpu_decoding ? 6u : 16u;
|
const u32 max_num_ref_frames = uses_gpu_decoding ? 6u : 16u;
|
||||||
writer.WriteUe(max_num_ref_frames);
|
writer.WriteUe(max_num_ref_frames);
|
||||||
writer.WriteBit(false);
|
writer.WriteBit(false);
|
||||||
|
|
|
@ -34,13 +34,13 @@ ComputePipeline::ComputePipeline(const Device& device, TextureCache& texture_cac
|
||||||
: texture_cache{texture_cache_}, buffer_cache{buffer_cache_},
|
: texture_cache{texture_cache_}, buffer_cache{buffer_cache_},
|
||||||
program_manager{program_manager_}, info{info_} {
|
program_manager{program_manager_}, info{info_} {
|
||||||
switch (device.GetShaderBackend()) {
|
switch (device.GetShaderBackend()) {
|
||||||
case Settings::ShaderBackend::GLSL:
|
case Settings::ShaderBackend::Glsl:
|
||||||
source_program = CreateProgram(code, GL_COMPUTE_SHADER);
|
source_program = CreateProgram(code, GL_COMPUTE_SHADER);
|
||||||
break;
|
break;
|
||||||
case Settings::ShaderBackend::GLASM:
|
case Settings::ShaderBackend::Glasm:
|
||||||
assembly_program = CompileProgram(code, GL_COMPUTE_PROGRAM_NV);
|
assembly_program = CompileProgram(code, GL_COMPUTE_PROGRAM_NV);
|
||||||
break;
|
break;
|
||||||
case Settings::ShaderBackend::SPIRV:
|
case Settings::ShaderBackend::SpirV:
|
||||||
source_program = CreateProgram(code_v, GL_COMPUTE_SHADER);
|
source_program = CreateProgram(code_v, GL_COMPUTE_SHADER);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -177,15 +177,15 @@ Device::Device(Core::Frontend::EmuWindow& emu_window) {
|
||||||
has_fast_buffer_sub_data = is_nvidia && !disable_fast_buffer_sub_data;
|
has_fast_buffer_sub_data = is_nvidia && !disable_fast_buffer_sub_data;
|
||||||
|
|
||||||
shader_backend = Settings::values.shader_backend.GetValue();
|
shader_backend = Settings::values.shader_backend.GetValue();
|
||||||
use_assembly_shaders = shader_backend == Settings::ShaderBackend::GLASM &&
|
use_assembly_shaders = shader_backend == Settings::ShaderBackend::Glasm &&
|
||||||
GLAD_GL_NV_gpu_program5 && GLAD_GL_NV_compute_program5 &&
|
GLAD_GL_NV_gpu_program5 && GLAD_GL_NV_compute_program5 &&
|
||||||
GLAD_GL_NV_transform_feedback && GLAD_GL_NV_transform_feedback2;
|
GLAD_GL_NV_transform_feedback && GLAD_GL_NV_transform_feedback2;
|
||||||
if (shader_backend == Settings::ShaderBackend::GLASM && !use_assembly_shaders) {
|
if (shader_backend == Settings::ShaderBackend::Glasm && !use_assembly_shaders) {
|
||||||
LOG_ERROR(Render_OpenGL, "Assembly shaders enabled but not supported");
|
LOG_ERROR(Render_OpenGL, "Assembly shaders enabled but not supported");
|
||||||
shader_backend = Settings::ShaderBackend::GLSL;
|
shader_backend = Settings::ShaderBackend::Glsl;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (shader_backend == Settings::ShaderBackend::GLSL && is_nvidia) {
|
if (shader_backend == Settings::ShaderBackend::Glsl && is_nvidia) {
|
||||||
const std::string_view driver_version = version.substr(13);
|
const std::string_view driver_version = version.substr(13);
|
||||||
const int version_major =
|
const int version_major =
|
||||||
std::atoi(driver_version.substr(0, driver_version.find(".")).data());
|
std::atoi(driver_version.substr(0, driver_version.find(".")).data());
|
||||||
|
|
|
@ -236,18 +236,18 @@ GraphicsPipeline::GraphicsPipeline(const Device& device, TextureCache& texture_c
|
||||||
force_context_flush](ShaderContext::Context*) mutable {
|
force_context_flush](ShaderContext::Context*) mutable {
|
||||||
for (size_t stage = 0; stage < 5; ++stage) {
|
for (size_t stage = 0; stage < 5; ++stage) {
|
||||||
switch (backend) {
|
switch (backend) {
|
||||||
case Settings::ShaderBackend::GLSL:
|
case Settings::ShaderBackend::Glsl:
|
||||||
if (!sources_[stage].empty()) {
|
if (!sources_[stage].empty()) {
|
||||||
source_programs[stage] = CreateProgram(sources_[stage], Stage(stage));
|
source_programs[stage] = CreateProgram(sources_[stage], Stage(stage));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Settings::ShaderBackend::GLASM:
|
case Settings::ShaderBackend::Glasm:
|
||||||
if (!sources_[stage].empty()) {
|
if (!sources_[stage].empty()) {
|
||||||
assembly_programs[stage] =
|
assembly_programs[stage] =
|
||||||
CompileProgram(sources_[stage], AssemblyStage(stage));
|
CompileProgram(sources_[stage], AssemblyStage(stage));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Settings::ShaderBackend::SPIRV:
|
case Settings::ShaderBackend::SpirV:
|
||||||
if (!sources_spirv_[stage].empty()) {
|
if (!sources_spirv_[stage].empty()) {
|
||||||
source_programs[stage] = CreateProgram(sources_spirv_[stage], Stage(stage));
|
source_programs[stage] = CreateProgram(sources_spirv_[stage], Stage(stage));
|
||||||
}
|
}
|
||||||
|
|
|
@ -522,14 +522,14 @@ std::unique_ptr<GraphicsPipeline> ShaderCache::CreateGraphicsPipeline(
|
||||||
const auto runtime_info{
|
const auto runtime_info{
|
||||||
MakeRuntimeInfo(key, program, previous_program, glasm_use_storage_buffers, use_glasm)};
|
MakeRuntimeInfo(key, program, previous_program, glasm_use_storage_buffers, use_glasm)};
|
||||||
switch (device.GetShaderBackend()) {
|
switch (device.GetShaderBackend()) {
|
||||||
case Settings::ShaderBackend::GLSL:
|
case Settings::ShaderBackend::Glsl:
|
||||||
ConvertLegacyToGeneric(program, runtime_info);
|
ConvertLegacyToGeneric(program, runtime_info);
|
||||||
sources[stage_index] = EmitGLSL(profile, runtime_info, program, binding);
|
sources[stage_index] = EmitGLSL(profile, runtime_info, program, binding);
|
||||||
break;
|
break;
|
||||||
case Settings::ShaderBackend::GLASM:
|
case Settings::ShaderBackend::Glasm:
|
||||||
sources[stage_index] = EmitGLASM(profile, runtime_info, program, binding);
|
sources[stage_index] = EmitGLASM(profile, runtime_info, program, binding);
|
||||||
break;
|
break;
|
||||||
case Settings::ShaderBackend::SPIRV:
|
case Settings::ShaderBackend::SpirV:
|
||||||
ConvertLegacyToGeneric(program, runtime_info);
|
ConvertLegacyToGeneric(program, runtime_info);
|
||||||
sources_spirv[stage_index] = EmitSPIRV(profile, runtime_info, program, binding);
|
sources_spirv[stage_index] = EmitSPIRV(profile, runtime_info, program, binding);
|
||||||
break;
|
break;
|
||||||
|
@ -582,13 +582,13 @@ std::unique_ptr<ComputePipeline> ShaderCache::CreateComputePipeline(
|
||||||
std::string code{};
|
std::string code{};
|
||||||
std::vector<u32> code_spirv;
|
std::vector<u32> code_spirv;
|
||||||
switch (device.GetShaderBackend()) {
|
switch (device.GetShaderBackend()) {
|
||||||
case Settings::ShaderBackend::GLSL:
|
case Settings::ShaderBackend::Glsl:
|
||||||
code = EmitGLSL(profile, program);
|
code = EmitGLSL(profile, program);
|
||||||
break;
|
break;
|
||||||
case Settings::ShaderBackend::GLASM:
|
case Settings::ShaderBackend::Glasm:
|
||||||
code = EmitGLASM(profile, info, program);
|
code = EmitGLASM(profile, info, program);
|
||||||
break;
|
break;
|
||||||
case Settings::ShaderBackend::SPIRV:
|
case Settings::ShaderBackend::SpirV:
|
||||||
code_spirv = EmitSPIRV(profile, program);
|
code_spirv = EmitSPIRV(profile, program);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -232,10 +232,9 @@ void ApplySwizzle(GLuint handle, PixelFormat format, std::array<SwizzleSource, 4
|
||||||
[[nodiscard]] bool CanBeAccelerated(const TextureCacheRuntime& runtime,
|
[[nodiscard]] bool CanBeAccelerated(const TextureCacheRuntime& runtime,
|
||||||
const VideoCommon::ImageInfo& info) {
|
const VideoCommon::ImageInfo& info) {
|
||||||
if (IsPixelFormatASTC(info.format) && info.size.depth == 1 && !runtime.HasNativeASTC()) {
|
if (IsPixelFormatASTC(info.format) && info.size.depth == 1 && !runtime.HasNativeASTC()) {
|
||||||
return Settings::values.accelerate_astc.GetValue() &&
|
return Settings::values.accelerate_astc.GetValue() == Settings::AstcDecodeMode::Gpu &&
|
||||||
Settings::values.astc_recompression.GetValue() ==
|
Settings::values.astc_recompression.GetValue() ==
|
||||||
Settings::AstcRecompression::Uncompressed &&
|
Settings::AstcRecompression::Uncompressed;
|
||||||
!Settings::values.async_astc.GetValue();
|
|
||||||
}
|
}
|
||||||
// Disable other accelerated uploads for now as they don't implement swizzled uploads
|
// Disable other accelerated uploads for now as they don't implement swizzled uploads
|
||||||
return false;
|
return false;
|
||||||
|
@ -267,7 +266,8 @@ void ApplySwizzle(GLuint handle, PixelFormat format, std::array<SwizzleSource, 4
|
||||||
[[nodiscard]] bool CanBeDecodedAsync(const TextureCacheRuntime& runtime,
|
[[nodiscard]] bool CanBeDecodedAsync(const TextureCacheRuntime& runtime,
|
||||||
const VideoCommon::ImageInfo& info) {
|
const VideoCommon::ImageInfo& info) {
|
||||||
if (IsPixelFormatASTC(info.format) && !runtime.HasNativeASTC()) {
|
if (IsPixelFormatASTC(info.format) && !runtime.HasNativeASTC()) {
|
||||||
return Settings::values.async_astc.GetValue();
|
return Settings::values.accelerate_astc.GetValue() ==
|
||||||
|
Settings::AstcDecodeMode::CpuAsynchronous;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -473,7 +473,7 @@ void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) {
|
||||||
glBindTextureUnit(0, screen_info.display_texture);
|
glBindTextureUnit(0, screen_info.display_texture);
|
||||||
|
|
||||||
auto anti_aliasing = Settings::values.anti_aliasing.GetValue();
|
auto anti_aliasing = Settings::values.anti_aliasing.GetValue();
|
||||||
if (anti_aliasing > Settings::AntiAliasing::LastAA) {
|
if (anti_aliasing >= Settings::AntiAliasing::MaxEnum) {
|
||||||
LOG_ERROR(Render_OpenGL, "Invalid antialiasing option selected {}", anti_aliasing);
|
LOG_ERROR(Render_OpenGL, "Invalid antialiasing option selected {}", anti_aliasing);
|
||||||
anti_aliasing = Settings::AntiAliasing::None;
|
anti_aliasing = Settings::AntiAliasing::None;
|
||||||
Settings::values.anti_aliasing.SetValue(anti_aliasing);
|
Settings::values.anti_aliasing.SetValue(anti_aliasing);
|
||||||
|
|
|
@ -45,8 +45,8 @@ static VkPresentModeKHR ChooseSwapPresentMode(bool has_imm, bool has_mailbox,
|
||||||
return mode;
|
return mode;
|
||||||
}
|
}
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case Settings::VSyncMode::FIFO:
|
case Settings::VSyncMode::Fifo:
|
||||||
case Settings::VSyncMode::FIFORelaxed:
|
case Settings::VSyncMode::FifoRelaxed:
|
||||||
if (has_mailbox) {
|
if (has_mailbox) {
|
||||||
return Settings::VSyncMode::Mailbox;
|
return Settings::VSyncMode::Mailbox;
|
||||||
} else if (has_imm) {
|
} else if (has_imm) {
|
||||||
|
@ -59,8 +59,8 @@ static VkPresentModeKHR ChooseSwapPresentMode(bool has_imm, bool has_mailbox,
|
||||||
}();
|
}();
|
||||||
if ((setting == Settings::VSyncMode::Mailbox && !has_mailbox) ||
|
if ((setting == Settings::VSyncMode::Mailbox && !has_mailbox) ||
|
||||||
(setting == Settings::VSyncMode::Immediate && !has_imm) ||
|
(setting == Settings::VSyncMode::Immediate && !has_imm) ||
|
||||||
(setting == Settings::VSyncMode::FIFORelaxed && !has_fifo_relaxed)) {
|
(setting == Settings::VSyncMode::FifoRelaxed && !has_fifo_relaxed)) {
|
||||||
setting = Settings::VSyncMode::FIFO;
|
setting = Settings::VSyncMode::Fifo;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (setting) {
|
switch (setting) {
|
||||||
|
@ -68,9 +68,9 @@ static VkPresentModeKHR ChooseSwapPresentMode(bool has_imm, bool has_mailbox,
|
||||||
return VK_PRESENT_MODE_IMMEDIATE_KHR;
|
return VK_PRESENT_MODE_IMMEDIATE_KHR;
|
||||||
case Settings::VSyncMode::Mailbox:
|
case Settings::VSyncMode::Mailbox:
|
||||||
return VK_PRESENT_MODE_MAILBOX_KHR;
|
return VK_PRESENT_MODE_MAILBOX_KHR;
|
||||||
case Settings::VSyncMode::FIFO:
|
case Settings::VSyncMode::Fifo:
|
||||||
return VK_PRESENT_MODE_FIFO_KHR;
|
return VK_PRESENT_MODE_FIFO_KHR;
|
||||||
case Settings::VSyncMode::FIFORelaxed:
|
case Settings::VSyncMode::FifoRelaxed:
|
||||||
return VK_PRESENT_MODE_FIFO_RELAXED_KHR;
|
return VK_PRESENT_MODE_FIFO_RELAXED_KHR;
|
||||||
default:
|
default:
|
||||||
return VK_PRESENT_MODE_FIFO_KHR;
|
return VK_PRESENT_MODE_FIFO_KHR;
|
||||||
|
|
|
@ -817,7 +817,7 @@ TextureCacheRuntime::TextureCacheRuntime(const Device& device_, Scheduler& sched
|
||||||
: device{device_}, scheduler{scheduler_}, memory_allocator{memory_allocator_},
|
: device{device_}, scheduler{scheduler_}, memory_allocator{memory_allocator_},
|
||||||
staging_buffer_pool{staging_buffer_pool_}, blit_image_helper{blit_image_helper_},
|
staging_buffer_pool{staging_buffer_pool_}, blit_image_helper{blit_image_helper_},
|
||||||
render_pass_cache{render_pass_cache_}, resolution{Settings::values.resolution_info} {
|
render_pass_cache{render_pass_cache_}, resolution{Settings::values.resolution_info} {
|
||||||
if (Settings::values.accelerate_astc) {
|
if (Settings::values.accelerate_astc.GetValue() == Settings::AstcDecodeMode::Gpu) {
|
||||||
astc_decoder_pass.emplace(device, scheduler, descriptor_pool, staging_buffer_pool,
|
astc_decoder_pass.emplace(device, scheduler, descriptor_pool, staging_buffer_pool,
|
||||||
compute_pass_descriptor_queue, memory_allocator);
|
compute_pass_descriptor_queue, memory_allocator);
|
||||||
}
|
}
|
||||||
|
@ -1301,13 +1301,20 @@ Image::Image(TextureCacheRuntime& runtime_, const ImageInfo& info_, GPUVAddr gpu
|
||||||
runtime->ViewFormats(info.format))),
|
runtime->ViewFormats(info.format))),
|
||||||
aspect_mask(ImageAspectMask(info.format)) {
|
aspect_mask(ImageAspectMask(info.format)) {
|
||||||
if (IsPixelFormatASTC(info.format) && !runtime->device.IsOptimalAstcSupported()) {
|
if (IsPixelFormatASTC(info.format) && !runtime->device.IsOptimalAstcSupported()) {
|
||||||
if (Settings::values.async_astc.GetValue()) {
|
switch (Settings::values.accelerate_astc.GetValue()) {
|
||||||
flags |= VideoCommon::ImageFlagBits::AsynchronousDecode;
|
case Settings::AstcDecodeMode::Gpu:
|
||||||
} else if (Settings::values.astc_recompression.GetValue() ==
|
if (Settings::values.astc_recompression.GetValue() ==
|
||||||
Settings::AstcRecompression::Uncompressed &&
|
Settings::AstcRecompression::Uncompressed &&
|
||||||
Settings::values.accelerate_astc.GetValue() && info.size.depth == 1) {
|
info.size.depth == 1) {
|
||||||
flags |= VideoCommon::ImageFlagBits::AcceleratedUpload;
|
flags |= VideoCommon::ImageFlagBits::AcceleratedUpload;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
case Settings::AstcDecodeMode::CpuAsynchronous:
|
||||||
|
flags |= VideoCommon::ImageFlagBits::AsynchronousDecode;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
flags |= VideoCommon::ImageFlagBits::Converted;
|
flags |= VideoCommon::ImageFlagBits::Converted;
|
||||||
flags |= VideoCommon::ImageFlagBits::CostlyLoad;
|
flags |= VideoCommon::ImageFlagBits::CostlyLoad;
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,12 +72,12 @@ float TSCEntry::MaxAnisotropy() const noexcept {
|
||||||
}
|
}
|
||||||
const auto anisotropic_settings = Settings::values.max_anisotropy.GetValue();
|
const auto anisotropic_settings = Settings::values.max_anisotropy.GetValue();
|
||||||
s32 added_anisotropic{};
|
s32 added_anisotropic{};
|
||||||
if (anisotropic_settings == 0) {
|
if (anisotropic_settings == Settings::AnisotropyMode::Automatic) {
|
||||||
added_anisotropic = Settings::values.resolution_info.up_scale >>
|
added_anisotropic = Settings::values.resolution_info.up_scale >>
|
||||||
Settings::values.resolution_info.down_shift;
|
Settings::values.resolution_info.down_shift;
|
||||||
added_anisotropic = std::max(added_anisotropic - 1, 0);
|
added_anisotropic = std::max(added_anisotropic - 1, 0);
|
||||||
} else {
|
} else {
|
||||||
added_anisotropic = Settings::values.max_anisotropy.GetValue() - 1U;
|
added_anisotropic = static_cast<u32>(Settings::values.max_anisotropy.GetValue()) - 1U;
|
||||||
}
|
}
|
||||||
return static_cast<float>(1U << (max_anisotropy + added_anisotropic));
|
return static_cast<float>(1U << (max_anisotropy + added_anisotropic));
|
||||||
}
|
}
|
||||||
|
|
|
@ -143,6 +143,10 @@ add_executable(yuzu
|
||||||
configuration/configure_web.ui
|
configuration/configure_web.ui
|
||||||
configuration/input_profiles.cpp
|
configuration/input_profiles.cpp
|
||||||
configuration/input_profiles.h
|
configuration/input_profiles.h
|
||||||
|
configuration/shared_translation.cpp
|
||||||
|
configuration/shared_translation.h
|
||||||
|
configuration/shared_widget.cpp
|
||||||
|
configuration/shared_widget.h
|
||||||
debugger/console.cpp
|
debugger/console.cpp
|
||||||
debugger/console.h
|
debugger/console.h
|
||||||
debugger/controller.cpp
|
debugger/controller.cpp
|
||||||
|
@ -231,6 +235,12 @@ if (WIN32 AND YUZU_CRASH_DUMPS)
|
||||||
target_compile_definitions(yuzu PRIVATE -DYUZU_DBGHELP)
|
target_compile_definitions(yuzu PRIVATE -DYUZU_DBGHELP)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||||
|
target_compile_definitions(yuzu PRIVATE
|
||||||
|
$<$<VERSION_LESS:$<CXX_COMPILER_VERSION>,15>:CANNOT_EXPLICITLY_INSTANTIATE>
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
file(GLOB COMPAT_LIST
|
file(GLOB COMPAT_LIST
|
||||||
${PROJECT_BINARY_DIR}/dist/compatibility_list/compatibility_list.qrc
|
${PROJECT_BINARY_DIR}/dist/compatibility_list/compatibility_list.qrc
|
||||||
${PROJECT_BINARY_DIR}/dist/compatibility_list/compatibility_list.json)
|
${PROJECT_BINARY_DIR}/dist/compatibility_list/compatibility_list.json)
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -52,7 +52,7 @@ public:
|
||||||
static const std::map<Settings::AntiAliasing, QString> anti_aliasing_texts_map;
|
static const std::map<Settings::AntiAliasing, QString> anti_aliasing_texts_map;
|
||||||
static const std::map<Settings::ScalingFilter, QString> scaling_filter_texts_map;
|
static const std::map<Settings::ScalingFilter, QString> scaling_filter_texts_map;
|
||||||
static const std::map<bool, QString> use_docked_mode_texts_map;
|
static const std::map<bool, QString> use_docked_mode_texts_map;
|
||||||
static const std::map<Settings::GPUAccuracy, QString> gpu_accuracy_texts_map;
|
static const std::map<Settings::GpuAccuracy, QString> gpu_accuracy_texts_map;
|
||||||
static const std::map<Settings::RendererBackend, QString> renderer_backend_texts_map;
|
static const std::map<Settings::RendererBackend, QString> renderer_backend_texts_map;
|
||||||
static const std::map<Settings::ShaderBackend, QString> shader_backend_texts_map;
|
static const std::map<Settings::ShaderBackend, QString> shader_backend_texts_map;
|
||||||
|
|
||||||
|
@ -74,7 +74,6 @@ private:
|
||||||
void ReadKeyboardValues();
|
void ReadKeyboardValues();
|
||||||
void ReadMouseValues();
|
void ReadMouseValues();
|
||||||
void ReadTouchscreenValues();
|
void ReadTouchscreenValues();
|
||||||
void ReadMousePanningValues();
|
|
||||||
void ReadMotionTouchValues();
|
void ReadMotionTouchValues();
|
||||||
void ReadHidbusValues();
|
void ReadHidbusValues();
|
||||||
void ReadIrCameraValues();
|
void ReadIrCameraValues();
|
||||||
|
@ -99,13 +98,13 @@ private:
|
||||||
void ReadUILayoutValues();
|
void ReadUILayoutValues();
|
||||||
void ReadWebServiceValues();
|
void ReadWebServiceValues();
|
||||||
void ReadMultiplayerValues();
|
void ReadMultiplayerValues();
|
||||||
|
void ReadNetworkValues();
|
||||||
|
|
||||||
void SaveValues();
|
void SaveValues();
|
||||||
void SavePlayerValue(std::size_t player_index);
|
void SavePlayerValue(std::size_t player_index);
|
||||||
void SaveDebugValues();
|
void SaveDebugValues();
|
||||||
void SaveMouseValues();
|
void SaveMouseValues();
|
||||||
void SaveTouchscreenValues();
|
void SaveTouchscreenValues();
|
||||||
void SaveMousePanningValues();
|
|
||||||
void SaveMotionTouchValues();
|
void SaveMotionTouchValues();
|
||||||
void SaveHidbusValues();
|
void SaveHidbusValues();
|
||||||
void SaveIrCameraValues();
|
void SaveIrCameraValues();
|
||||||
|
@ -140,18 +139,6 @@ private:
|
||||||
QVariant ReadSetting(const QString& name) const;
|
QVariant ReadSetting(const QString& name) const;
|
||||||
QVariant ReadSetting(const QString& name, const QVariant& default_value) const;
|
QVariant ReadSetting(const QString& name, const QVariant& default_value) const;
|
||||||
|
|
||||||
/**
|
|
||||||
* Only reads a setting from the qt_config if the current config is a global config, or if the
|
|
||||||
* current config is a custom config and the setting is overriding the global setting. Otherwise
|
|
||||||
* it does nothing.
|
|
||||||
*
|
|
||||||
* @param setting The variable to be modified
|
|
||||||
* @param name The setting's identifier
|
|
||||||
* @param default_value The value to use when the setting is not already present in the config
|
|
||||||
*/
|
|
||||||
template <typename Type>
|
|
||||||
void ReadSettingGlobal(Type& setting, const QString& name, const QVariant& default_value) const;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Writes a setting to the qt_config.
|
* Writes a setting to the qt_config.
|
||||||
*
|
*
|
||||||
|
@ -166,50 +153,20 @@ private:
|
||||||
void WriteSetting(const QString& name, const QVariant& value, const QVariant& default_value,
|
void WriteSetting(const QString& name, const QVariant& value, const QVariant& default_value,
|
||||||
bool use_global);
|
bool use_global);
|
||||||
|
|
||||||
/**
|
void ReadCategory(Settings::Category category);
|
||||||
* Reads a value from the qt_config and applies it to the setting, using its label and default
|
void WriteCategory(Settings::Category category);
|
||||||
* value. If the config is a custom config, this will also read the global state of the setting
|
void ReadSettingGeneric(Settings::BasicSetting* const setting);
|
||||||
* and apply that information to it.
|
void WriteSettingGeneric(Settings::BasicSetting* const setting) const;
|
||||||
*
|
|
||||||
* @param The setting
|
|
||||||
*/
|
|
||||||
template <typename Type, bool ranged>
|
|
||||||
void ReadGlobalSetting(Settings::SwitchableSetting<Type, ranged>& setting);
|
|
||||||
|
|
||||||
/**
|
const ConfigType type;
|
||||||
* Sets a value to the qt_config using the setting's label and default value. If the config is a
|
|
||||||
* custom config, it will apply the global state, and the custom value if needed.
|
|
||||||
*
|
|
||||||
* @param The setting
|
|
||||||
*/
|
|
||||||
template <typename Type, bool ranged>
|
|
||||||
void WriteGlobalSetting(const Settings::SwitchableSetting<Type, ranged>& setting);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reads a value from the qt_config using the setting's label and default value and applies the
|
|
||||||
* value to the setting.
|
|
||||||
*
|
|
||||||
* @param The setting
|
|
||||||
*/
|
|
||||||
template <typename Type, bool ranged>
|
|
||||||
void ReadBasicSetting(Settings::Setting<Type, ranged>& setting);
|
|
||||||
|
|
||||||
/** Sets a value from the setting in the qt_config using the setting's label and default value.
|
|
||||||
*
|
|
||||||
* @param The setting
|
|
||||||
*/
|
|
||||||
template <typename Type, bool ranged>
|
|
||||||
void WriteBasicSetting(const Settings::Setting<Type, ranged>& setting);
|
|
||||||
|
|
||||||
ConfigType type;
|
|
||||||
std::unique_ptr<QSettings> qt_config;
|
std::unique_ptr<QSettings> qt_config;
|
||||||
std::string qt_config_loc;
|
std::string qt_config_loc;
|
||||||
bool global;
|
const bool global;
|
||||||
};
|
};
|
||||||
|
|
||||||
// These metatype declarations cannot be in common/settings.h because core is devoid of QT
|
// These metatype declarations cannot be in common/settings.h because core is devoid of QT
|
||||||
Q_DECLARE_METATYPE(Settings::CPUAccuracy);
|
Q_DECLARE_METATYPE(Settings::CpuAccuracy);
|
||||||
Q_DECLARE_METATYPE(Settings::GPUAccuracy);
|
Q_DECLARE_METATYPE(Settings::GpuAccuracy);
|
||||||
Q_DECLARE_METATYPE(Settings::FullscreenMode);
|
Q_DECLARE_METATYPE(Settings::FullscreenMode);
|
||||||
Q_DECLARE_METATYPE(Settings::NvdecEmulation);
|
Q_DECLARE_METATYPE(Settings::NvdecEmulation);
|
||||||
Q_DECLARE_METATYPE(Settings::ResolutionSetup);
|
Q_DECLARE_METATYPE(Settings::ResolutionSetup);
|
||||||
|
@ -218,3 +175,4 @@ Q_DECLARE_METATYPE(Settings::AntiAliasing);
|
||||||
Q_DECLARE_METATYPE(Settings::RendererBackend);
|
Q_DECLARE_METATYPE(Settings::RendererBackend);
|
||||||
Q_DECLARE_METATYPE(Settings::ShaderBackend);
|
Q_DECLARE_METATYPE(Settings::ShaderBackend);
|
||||||
Q_DECLARE_METATYPE(Settings::AstcRecompression);
|
Q_DECLARE_METATYPE(Settings::AstcRecompression);
|
||||||
|
Q_DECLARE_METATYPE(Settings::AstcDecodeMode);
|
||||||
|
|
|
@ -1,104 +1,19 @@
|
||||||
// SPDX-FileCopyrightText: 2016 Citra Emulator Project
|
// SPDX-FileCopyrightText: 2016 Citra Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#include <QCheckBox>
|
#include <memory>
|
||||||
#include <QObject>
|
#include <type_traits>
|
||||||
#include <QString>
|
#include <vector>
|
||||||
#include "common/settings.h"
|
|
||||||
#include "yuzu/configuration/configuration_shared.h"
|
#include "yuzu/configuration/configuration_shared.h"
|
||||||
#include "yuzu/configuration/configure_per_game.h"
|
|
||||||
|
|
||||||
void ConfigurationShared::ApplyPerGameSetting(Settings::SwitchableSetting<bool>* setting,
|
namespace ConfigurationShared {
|
||||||
const QCheckBox* checkbox,
|
|
||||||
const CheckState& tracker) {
|
Tab::Tab(std::shared_ptr<std::vector<Tab*>> group, QWidget* parent) : QWidget(parent) {
|
||||||
if (Settings::IsConfiguringGlobal() && setting->UsingGlobal()) {
|
if (group != nullptr) {
|
||||||
setting->SetValue(checkbox->checkState());
|
group->push_back(this);
|
||||||
} else if (!Settings::IsConfiguringGlobal()) {
|
|
||||||
if (tracker == CheckState::Global) {
|
|
||||||
setting->SetGlobal(true);
|
|
||||||
} else {
|
|
||||||
setting->SetGlobal(false);
|
|
||||||
setting->SetValue(checkbox->checkState());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigurationShared::SetPerGameSetting(QCheckBox* checkbox,
|
Tab::~Tab() = default;
|
||||||
const Settings::SwitchableSetting<bool>* setting) {
|
|
||||||
if (setting->UsingGlobal()) {
|
|
||||||
checkbox->setCheckState(Qt::PartiallyChecked);
|
|
||||||
} else {
|
|
||||||
checkbox->setCheckState(setting->GetValue() ? Qt::Checked : Qt::Unchecked);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConfigurationShared::SetHighlight(QWidget* widget, bool highlighted) {
|
} // namespace ConfigurationShared
|
||||||
if (highlighted) {
|
|
||||||
widget->setStyleSheet(QStringLiteral("QWidget#%1 { background-color:rgba(0,203,255,0.5) }")
|
|
||||||
.arg(widget->objectName()));
|
|
||||||
} else {
|
|
||||||
widget->setStyleSheet(QStringLiteral("QWidget#%1 { background-color:rgba(0,0,0,0) }")
|
|
||||||
.arg(widget->objectName()));
|
|
||||||
}
|
|
||||||
widget->show();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConfigurationShared::SetColoredTristate(QCheckBox* checkbox,
|
|
||||||
const Settings::SwitchableSetting<bool>& setting,
|
|
||||||
CheckState& tracker) {
|
|
||||||
if (setting.UsingGlobal()) {
|
|
||||||
tracker = CheckState::Global;
|
|
||||||
} else {
|
|
||||||
tracker = (setting.GetValue() == setting.GetValue(true)) ? CheckState::On : CheckState::Off;
|
|
||||||
}
|
|
||||||
SetHighlight(checkbox, tracker != CheckState::Global);
|
|
||||||
QObject::connect(checkbox, &QCheckBox::clicked, checkbox, [checkbox, setting, &tracker] {
|
|
||||||
tracker = static_cast<CheckState>((static_cast<int>(tracker) + 1) %
|
|
||||||
static_cast<int>(CheckState::Count));
|
|
||||||
if (tracker == CheckState::Global) {
|
|
||||||
checkbox->setChecked(setting.GetValue(true));
|
|
||||||
}
|
|
||||||
SetHighlight(checkbox, tracker != CheckState::Global);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConfigurationShared::SetColoredTristate(QCheckBox* checkbox, bool global, bool state,
|
|
||||||
bool global_state, CheckState& tracker) {
|
|
||||||
if (global) {
|
|
||||||
tracker = CheckState::Global;
|
|
||||||
} else {
|
|
||||||
tracker = (state == global_state) ? CheckState::On : CheckState::Off;
|
|
||||||
}
|
|
||||||
SetHighlight(checkbox, tracker != CheckState::Global);
|
|
||||||
QObject::connect(checkbox, &QCheckBox::clicked, checkbox, [checkbox, global_state, &tracker] {
|
|
||||||
tracker = static_cast<CheckState>((static_cast<int>(tracker) + 1) %
|
|
||||||
static_cast<int>(CheckState::Count));
|
|
||||||
if (tracker == CheckState::Global) {
|
|
||||||
checkbox->setChecked(global_state);
|
|
||||||
}
|
|
||||||
SetHighlight(checkbox, tracker != CheckState::Global);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConfigurationShared::SetColoredComboBox(QComboBox* combobox, QWidget* target, int global) {
|
|
||||||
InsertGlobalItem(combobox, global);
|
|
||||||
QObject::connect(combobox, qOverload<int>(&QComboBox::activated), target,
|
|
||||||
[target](int index) { SetHighlight(target, index != 0); });
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConfigurationShared::InsertGlobalItem(QComboBox* combobox, int global_index) {
|
|
||||||
const QString use_global_text =
|
|
||||||
ConfigurePerGame::tr("Use global configuration (%1)").arg(combobox->itemText(global_index));
|
|
||||||
combobox->insertItem(ConfigurationShared::USE_GLOBAL_INDEX, use_global_text);
|
|
||||||
combobox->insertSeparator(ConfigurationShared::USE_GLOBAL_SEPARATOR_INDEX);
|
|
||||||
}
|
|
||||||
|
|
||||||
int ConfigurationShared::GetComboboxIndex(int global_setting_index, const QComboBox* combobox) {
|
|
||||||
if (Settings::IsConfiguringGlobal()) {
|
|
||||||
return combobox->currentIndex();
|
|
||||||
}
|
|
||||||
if (combobox->currentIndex() == ConfigurationShared::USE_GLOBAL_INDEX) {
|
|
||||||
return global_setting_index;
|
|
||||||
}
|
|
||||||
return combobox->currentIndex() - ConfigurationShared::USE_GLOBAL_OFFSET;
|
|
||||||
}
|
|
||||||
|
|
|
@ -3,73 +3,25 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <QCheckBox>
|
#include <memory>
|
||||||
#include <QComboBox>
|
#include <vector>
|
||||||
#include "common/settings.h"
|
#include <QString>
|
||||||
|
#include <QWidget>
|
||||||
|
#include <qobjectdefs.h>
|
||||||
|
|
||||||
|
class QObject;
|
||||||
|
|
||||||
namespace ConfigurationShared {
|
namespace ConfigurationShared {
|
||||||
|
|
||||||
constexpr int USE_GLOBAL_INDEX = 0;
|
class Tab : public QWidget {
|
||||||
constexpr int USE_GLOBAL_SEPARATOR_INDEX = 1;
|
Q_OBJECT
|
||||||
constexpr int USE_GLOBAL_OFFSET = 2;
|
|
||||||
|
|
||||||
// CheckBoxes require a tracker for their state since we emulate a tristate CheckBox
|
public:
|
||||||
enum class CheckState {
|
explicit Tab(std::shared_ptr<std::vector<Tab*>> group, QWidget* parent = nullptr);
|
||||||
Off, // Checkbox overrides to off/false
|
~Tab();
|
||||||
On, // Checkbox overrides to on/true
|
|
||||||
Global, // Checkbox defers to the global state
|
virtual void ApplyConfiguration() = 0;
|
||||||
Count, // Simply the number of states, not a valid checkbox state
|
virtual void SetConfiguration() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Global-aware apply and set functions
|
|
||||||
|
|
||||||
// ApplyPerGameSetting, given a Settings::Setting and a Qt UI element, properly applies a Setting
|
|
||||||
void ApplyPerGameSetting(Settings::SwitchableSetting<bool>* setting, const QCheckBox* checkbox,
|
|
||||||
const CheckState& tracker);
|
|
||||||
template <typename Type, bool ranged>
|
|
||||||
void ApplyPerGameSetting(Settings::SwitchableSetting<Type, ranged>* setting,
|
|
||||||
const QComboBox* combobox) {
|
|
||||||
if (Settings::IsConfiguringGlobal() && setting->UsingGlobal()) {
|
|
||||||
setting->SetValue(static_cast<Type>(combobox->currentIndex()));
|
|
||||||
} else if (!Settings::IsConfiguringGlobal()) {
|
|
||||||
if (combobox->currentIndex() == ConfigurationShared::USE_GLOBAL_INDEX) {
|
|
||||||
setting->SetGlobal(true);
|
|
||||||
} else {
|
|
||||||
setting->SetGlobal(false);
|
|
||||||
setting->SetValue(static_cast<Type>(combobox->currentIndex() -
|
|
||||||
ConfigurationShared::USE_GLOBAL_OFFSET));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sets a Qt UI element given a Settings::Setting
|
|
||||||
void SetPerGameSetting(QCheckBox* checkbox, const Settings::SwitchableSetting<bool>* setting);
|
|
||||||
|
|
||||||
template <typename Type, bool ranged>
|
|
||||||
void SetPerGameSetting(QComboBox* combobox,
|
|
||||||
const Settings::SwitchableSetting<Type, ranged>* setting) {
|
|
||||||
combobox->setCurrentIndex(setting->UsingGlobal() ? ConfigurationShared::USE_GLOBAL_INDEX
|
|
||||||
: static_cast<int>(setting->GetValue()) +
|
|
||||||
ConfigurationShared::USE_GLOBAL_OFFSET);
|
|
||||||
}
|
|
||||||
|
|
||||||
// (Un)highlights a Qt UI element
|
|
||||||
void SetHighlight(QWidget* widget, bool highlighted);
|
|
||||||
|
|
||||||
// Sets up a QCheckBox like a tristate one, given a Setting
|
|
||||||
void SetColoredTristate(QCheckBox* checkbox, const Settings::SwitchableSetting<bool>& setting,
|
|
||||||
CheckState& tracker);
|
|
||||||
void SetColoredTristate(QCheckBox* checkbox, bool global, bool state, bool global_state,
|
|
||||||
CheckState& tracker);
|
|
||||||
|
|
||||||
// Sets up coloring of a QWidget `target` based on the state of a QComboBox, and calls
|
|
||||||
// InsertGlobalItem
|
|
||||||
void SetColoredComboBox(QComboBox* combobox, QWidget* target, int global);
|
|
||||||
|
|
||||||
// Adds the "Use Global Configuration" selection and separator to the beginning of a QComboBox
|
|
||||||
void InsertGlobalItem(QComboBox* combobox, int global_index);
|
|
||||||
|
|
||||||
// Returns the correct index of a QComboBox taking into account global configuration
|
|
||||||
int GetComboboxIndex(int global_setting_index, const QComboBox* combobox);
|
|
||||||
|
|
||||||
} // namespace ConfigurationShared
|
} // namespace ConfigurationShared
|
||||||
|
|
|
@ -47,6 +47,27 @@
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="text">
|
||||||
|
<string>Some settings are only available when a game is not running.</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QDialogButtonBox" name="buttonBox">
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
<property name="standardButtons">
|
<property name="standardButtons">
|
||||||
|
@ -55,6 +76,8 @@
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<resources/>
|
<resources/>
|
||||||
<connections>
|
<connections>
|
||||||
|
|
|
@ -1,87 +1,112 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
#include <QComboBox>
|
||||||
|
|
||||||
#include "audio_core/sink/sink.h"
|
#include "audio_core/sink/sink.h"
|
||||||
#include "audio_core/sink/sink_details.h"
|
#include "audio_core/sink/sink_details.h"
|
||||||
|
#include "common/common_types.h"
|
||||||
#include "common/settings.h"
|
#include "common/settings.h"
|
||||||
|
#include "common/settings_common.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "ui_configure_audio.h"
|
#include "ui_configure_audio.h"
|
||||||
#include "yuzu/configuration/configuration_shared.h"
|
#include "yuzu/configuration/configuration_shared.h"
|
||||||
#include "yuzu/configuration/configure_audio.h"
|
#include "yuzu/configuration/configure_audio.h"
|
||||||
|
#include "yuzu/configuration/shared_translation.h"
|
||||||
|
#include "yuzu/configuration/shared_widget.h"
|
||||||
#include "yuzu/uisettings.h"
|
#include "yuzu/uisettings.h"
|
||||||
|
|
||||||
ConfigureAudio::ConfigureAudio(const Core::System& system_, QWidget* parent)
|
ConfigureAudio::ConfigureAudio(const Core::System& system_,
|
||||||
: QWidget(parent), ui(std::make_unique<Ui::ConfigureAudio>()), system{system_} {
|
std::shared_ptr<std::vector<ConfigurationShared::Tab*>> group_,
|
||||||
|
const ConfigurationShared::Builder& builder, QWidget* parent)
|
||||||
|
: Tab(group_, parent), ui(std::make_unique<Ui::ConfigureAudio>()), system{system_} {
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
Setup(builder);
|
||||||
InitializeAudioSinkComboBox();
|
|
||||||
|
|
||||||
connect(ui->volume_slider, &QSlider::valueChanged, this,
|
|
||||||
&ConfigureAudio::SetVolumeIndicatorText);
|
|
||||||
connect(ui->sink_combo_box, qOverload<int>(&QComboBox::currentIndexChanged), this,
|
|
||||||
&ConfigureAudio::UpdateAudioDevices);
|
|
||||||
|
|
||||||
ui->volume_label->setVisible(Settings::IsConfiguringGlobal());
|
|
||||||
ui->volume_combo_box->setVisible(!Settings::IsConfiguringGlobal());
|
|
||||||
|
|
||||||
SetupPerGameUI();
|
|
||||||
|
|
||||||
SetConfiguration();
|
SetConfiguration();
|
||||||
|
|
||||||
const bool is_powered_on = system_.IsPoweredOn();
|
|
||||||
ui->sink_combo_box->setEnabled(!is_powered_on);
|
|
||||||
ui->output_combo_box->setEnabled(!is_powered_on);
|
|
||||||
ui->input_combo_box->setEnabled(!is_powered_on);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ConfigureAudio::~ConfigureAudio() = default;
|
ConfigureAudio::~ConfigureAudio() = default;
|
||||||
|
|
||||||
|
void ConfigureAudio::Setup(const ConfigurationShared::Builder& builder) {
|
||||||
|
auto& layout = *ui->audio_widget->layout();
|
||||||
|
|
||||||
|
std::vector<Settings::BasicSetting*> settings;
|
||||||
|
|
||||||
|
std::map<u32, QWidget*> hold;
|
||||||
|
|
||||||
|
auto push = [&](Settings::Category category) {
|
||||||
|
for (auto* setting : Settings::values.linkage.by_category[category]) {
|
||||||
|
settings.push_back(setting);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
push(Settings::Category::Audio);
|
||||||
|
push(Settings::Category::SystemAudio);
|
||||||
|
|
||||||
|
for (auto* setting : settings) {
|
||||||
|
auto* widget = builder.BuildWidget(setting, apply_funcs);
|
||||||
|
|
||||||
|
if (widget == nullptr) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!widget->Valid()) {
|
||||||
|
widget->deleteLater();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
hold.emplace(std::pair{setting->Id(), widget});
|
||||||
|
|
||||||
|
if (setting->Id() == Settings::values.sink_id.Id()) {
|
||||||
|
// TODO (lat9nq): Let the system manage sink_id
|
||||||
|
sink_combo_box = widget->combobox;
|
||||||
|
InitializeAudioSinkComboBox();
|
||||||
|
|
||||||
|
connect(sink_combo_box, qOverload<int>(&QComboBox::currentIndexChanged), this,
|
||||||
|
&ConfigureAudio::UpdateAudioDevices);
|
||||||
|
} else if (setting->Id() == Settings::values.audio_output_device_id.Id()) {
|
||||||
|
// Keep track of output (and input) device comboboxes to populate them with system
|
||||||
|
// devices, which are determined at run time
|
||||||
|
output_device_combo_box = widget->combobox;
|
||||||
|
} else if (setting->Id() == Settings::values.audio_input_device_id.Id()) {
|
||||||
|
input_device_combo_box = widget->combobox;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto& [id, widget] : hold) {
|
||||||
|
layout.addWidget(widget);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ConfigureAudio::SetConfiguration() {
|
void ConfigureAudio::SetConfiguration() {
|
||||||
|
if (!Settings::IsConfiguringGlobal()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
SetOutputSinkFromSinkID();
|
SetOutputSinkFromSinkID();
|
||||||
|
|
||||||
// The device list cannot be pre-populated (nor listed) until the output sink is known.
|
// The device list cannot be pre-populated (nor listed) until the output sink is known.
|
||||||
UpdateAudioDevices(ui->sink_combo_box->currentIndex());
|
UpdateAudioDevices(sink_combo_box->currentIndex());
|
||||||
|
|
||||||
SetAudioDevicesFromDeviceID();
|
SetAudioDevicesFromDeviceID();
|
||||||
|
|
||||||
const auto volume_value = static_cast<int>(Settings::values.volume.GetValue());
|
|
||||||
ui->volume_slider->setValue(volume_value);
|
|
||||||
ui->toggle_background_mute->setChecked(UISettings::values.mute_when_in_background.GetValue());
|
|
||||||
|
|
||||||
if (!Settings::IsConfiguringGlobal()) {
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
ConfigurationShared::SetPerGameSetting(ui->combo_sound, &Settings::values.sound_index);
|
|
||||||
ConfigurationShared::SetHighlight(ui->mode_label,
|
|
||||||
!Settings::values.sound_index.UsingGlobal());
|
|
||||||
ConfigurationShared::SetHighlight(ui->volume_layout,
|
|
||||||
!Settings::values.volume.UsingGlobal());
|
|
||||||
} else {
|
|
||||||
ui->combo_sound->setCurrentIndex(Settings::values.sound_index.GetValue());
|
|
||||||
}
|
|
||||||
SetVolumeIndicatorText(ui->volume_slider->sliderPosition());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureAudio::SetOutputSinkFromSinkID() {
|
void ConfigureAudio::SetOutputSinkFromSinkID() {
|
||||||
[[maybe_unused]] const QSignalBlocker blocker(ui->sink_combo_box);
|
[[maybe_unused]] const QSignalBlocker blocker(sink_combo_box);
|
||||||
|
|
||||||
int new_sink_index = 0;
|
int new_sink_index = 0;
|
||||||
const QString sink_id = QString::fromStdString(Settings::values.sink_id.GetValue());
|
const QString sink_id = QString::fromStdString(Settings::values.sink_id.ToString());
|
||||||
for (int index = 0; index < ui->sink_combo_box->count(); index++) {
|
for (int index = 0; index < sink_combo_box->count(); index++) {
|
||||||
if (ui->sink_combo_box->itemText(index) == sink_id) {
|
if (sink_combo_box->itemText(index) == sink_id) {
|
||||||
new_sink_index = index;
|
new_sink_index = index;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ui->sink_combo_box->setCurrentIndex(new_sink_index);
|
sink_combo_box->setCurrentIndex(new_sink_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureAudio::SetAudioDevicesFromDeviceID() {
|
void ConfigureAudio::SetAudioDevicesFromDeviceID() {
|
||||||
|
@ -89,57 +114,42 @@ void ConfigureAudio::SetAudioDevicesFromDeviceID() {
|
||||||
|
|
||||||
const QString output_device_id =
|
const QString output_device_id =
|
||||||
QString::fromStdString(Settings::values.audio_output_device_id.GetValue());
|
QString::fromStdString(Settings::values.audio_output_device_id.GetValue());
|
||||||
for (int index = 0; index < ui->output_combo_box->count(); index++) {
|
for (int index = 0; index < output_device_combo_box->count(); index++) {
|
||||||
if (ui->output_combo_box->itemText(index) == output_device_id) {
|
if (output_device_combo_box->itemText(index) == output_device_id) {
|
||||||
new_device_index = index;
|
new_device_index = index;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ui->output_combo_box->setCurrentIndex(new_device_index);
|
output_device_combo_box->setCurrentIndex(new_device_index);
|
||||||
|
|
||||||
new_device_index = -1;
|
new_device_index = -1;
|
||||||
const QString input_device_id =
|
const QString input_device_id =
|
||||||
QString::fromStdString(Settings::values.audio_input_device_id.GetValue());
|
QString::fromStdString(Settings::values.audio_input_device_id.GetValue());
|
||||||
for (int index = 0; index < ui->input_combo_box->count(); index++) {
|
for (int index = 0; index < input_device_combo_box->count(); index++) {
|
||||||
if (ui->input_combo_box->itemText(index) == input_device_id) {
|
if (input_device_combo_box->itemText(index) == input_device_id) {
|
||||||
new_device_index = index;
|
new_device_index = index;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ui->input_combo_box->setCurrentIndex(new_device_index);
|
input_device_combo_box->setCurrentIndex(new_device_index);
|
||||||
}
|
|
||||||
|
|
||||||
void ConfigureAudio::SetVolumeIndicatorText(int percentage) {
|
|
||||||
ui->volume_indicator->setText(tr("%1%", "Volume percentage (e.g. 50%)").arg(percentage));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureAudio::ApplyConfiguration() {
|
void ConfigureAudio::ApplyConfiguration() {
|
||||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.sound_index, ui->combo_sound);
|
const bool is_powered_on = system.IsPoweredOn();
|
||||||
|
for (const auto& apply_func : apply_funcs) {
|
||||||
|
apply_func(is_powered_on);
|
||||||
|
}
|
||||||
|
|
||||||
if (Settings::IsConfiguringGlobal()) {
|
if (Settings::IsConfiguringGlobal()) {
|
||||||
Settings::values.sink_id =
|
Settings::values.sink_id.LoadString(
|
||||||
ui->sink_combo_box->itemText(ui->sink_combo_box->currentIndex()).toStdString();
|
sink_combo_box->itemText(sink_combo_box->currentIndex()).toStdString());
|
||||||
Settings::values.audio_output_device_id.SetValue(
|
Settings::values.audio_output_device_id.SetValue(
|
||||||
ui->output_combo_box->itemText(ui->output_combo_box->currentIndex()).toStdString());
|
output_device_combo_box->itemText(output_device_combo_box->currentIndex())
|
||||||
|
.toStdString());
|
||||||
Settings::values.audio_input_device_id.SetValue(
|
Settings::values.audio_input_device_id.SetValue(
|
||||||
ui->input_combo_box->itemText(ui->input_combo_box->currentIndex()).toStdString());
|
input_device_combo_box->itemText(input_device_combo_box->currentIndex()).toStdString());
|
||||||
UISettings::values.mute_when_in_background = ui->toggle_background_mute->isChecked();
|
|
||||||
|
|
||||||
// Guard if during game and set to game-specific value
|
|
||||||
if (Settings::values.volume.UsingGlobal()) {
|
|
||||||
const auto volume = static_cast<u8>(ui->volume_slider->value());
|
|
||||||
Settings::values.volume.SetValue(volume);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (ui->volume_combo_box->currentIndex() == 0) {
|
|
||||||
Settings::values.volume.SetGlobal(true);
|
|
||||||
} else {
|
|
||||||
Settings::values.volume.SetGlobal(false);
|
|
||||||
const auto volume = static_cast<u8>(ui->volume_slider->value());
|
|
||||||
Settings::values.volume.SetValue(volume);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,54 +162,31 @@ void ConfigureAudio::changeEvent(QEvent* event) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureAudio::UpdateAudioDevices(int sink_index) {
|
void ConfigureAudio::UpdateAudioDevices(int sink_index) {
|
||||||
ui->output_combo_box->clear();
|
output_device_combo_box->clear();
|
||||||
ui->output_combo_box->addItem(QString::fromUtf8(AudioCore::Sink::auto_device_name));
|
output_device_combo_box->addItem(QString::fromUtf8(AudioCore::Sink::auto_device_name));
|
||||||
|
|
||||||
const std::string sink_id = ui->sink_combo_box->itemText(sink_index).toStdString();
|
const auto sink_id =
|
||||||
|
Settings::ToEnum<Settings::AudioEngine>(sink_combo_box->itemText(sink_index).toStdString());
|
||||||
for (const auto& device : AudioCore::Sink::GetDeviceListForSink(sink_id, false)) {
|
for (const auto& device : AudioCore::Sink::GetDeviceListForSink(sink_id, false)) {
|
||||||
ui->output_combo_box->addItem(QString::fromStdString(device));
|
output_device_combo_box->addItem(QString::fromStdString(device));
|
||||||
}
|
}
|
||||||
|
|
||||||
ui->input_combo_box->clear();
|
input_device_combo_box->clear();
|
||||||
ui->input_combo_box->addItem(QString::fromUtf8(AudioCore::Sink::auto_device_name));
|
input_device_combo_box->addItem(QString::fromUtf8(AudioCore::Sink::auto_device_name));
|
||||||
for (const auto& device : AudioCore::Sink::GetDeviceListForSink(sink_id, true)) {
|
for (const auto& device : AudioCore::Sink::GetDeviceListForSink(sink_id, true)) {
|
||||||
ui->input_combo_box->addItem(QString::fromStdString(device));
|
input_device_combo_box->addItem(QString::fromStdString(device));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureAudio::InitializeAudioSinkComboBox() {
|
void ConfigureAudio::InitializeAudioSinkComboBox() {
|
||||||
ui->sink_combo_box->clear();
|
sink_combo_box->clear();
|
||||||
ui->sink_combo_box->addItem(QString::fromUtf8(AudioCore::Sink::auto_device_name));
|
sink_combo_box->addItem(QString::fromUtf8(AudioCore::Sink::auto_device_name));
|
||||||
|
|
||||||
for (const auto& id : AudioCore::Sink::GetSinkIDs()) {
|
for (const auto& id : AudioCore::Sink::GetSinkIDs()) {
|
||||||
ui->sink_combo_box->addItem(QString::fromUtf8(id.data(), static_cast<s32>(id.length())));
|
sink_combo_box->addItem(QString::fromStdString(Settings::CanonicalizeEnum(id)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureAudio::RetranslateUI() {
|
void ConfigureAudio::RetranslateUI() {
|
||||||
ui->retranslateUi(this);
|
ui->retranslateUi(this);
|
||||||
SetVolumeIndicatorText(ui->volume_slider->sliderPosition());
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConfigureAudio::SetupPerGameUI() {
|
|
||||||
if (Settings::IsConfiguringGlobal()) {
|
|
||||||
ui->combo_sound->setEnabled(Settings::values.sound_index.UsingGlobal());
|
|
||||||
ui->volume_slider->setEnabled(Settings::values.volume.UsingGlobal());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ConfigurationShared::SetColoredComboBox(ui->combo_sound, ui->mode_label,
|
|
||||||
Settings::values.sound_index.GetValue(true));
|
|
||||||
|
|
||||||
connect(ui->volume_combo_box, qOverload<int>(&QComboBox::activated), this, [this](int index) {
|
|
||||||
ui->volume_slider->setEnabled(index == 1);
|
|
||||||
ConfigurationShared::SetHighlight(ui->volume_layout, index == 1);
|
|
||||||
});
|
|
||||||
|
|
||||||
ui->sink_combo_box->setVisible(false);
|
|
||||||
ui->sink_label->setVisible(false);
|
|
||||||
ui->output_combo_box->setVisible(false);
|
|
||||||
ui->output_label->setVisible(false);
|
|
||||||
ui->input_combo_box->setVisible(false);
|
|
||||||
ui->input_label->setVisible(false);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,30 +3,35 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
#include "yuzu/configuration/configuration_shared.h"
|
||||||
|
|
||||||
|
class QComboBox;
|
||||||
|
|
||||||
namespace Core {
|
namespace Core {
|
||||||
class System;
|
class System;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace ConfigurationShared {
|
|
||||||
enum class CheckState;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class ConfigureAudio;
|
class ConfigureAudio;
|
||||||
}
|
}
|
||||||
|
|
||||||
class ConfigureAudio : public QWidget {
|
namespace ConfigurationShared {
|
||||||
Q_OBJECT
|
class Builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
class ConfigureAudio : public ConfigurationShared::Tab {
|
||||||
public:
|
public:
|
||||||
explicit ConfigureAudio(const Core::System& system_, QWidget* parent = nullptr);
|
explicit ConfigureAudio(const Core::System& system_,
|
||||||
|
std::shared_ptr<std::vector<ConfigurationShared::Tab*>> group,
|
||||||
|
const ConfigurationShared::Builder& builder, QWidget* parent = nullptr);
|
||||||
~ConfigureAudio() override;
|
~ConfigureAudio() override;
|
||||||
|
|
||||||
void ApplyConfiguration();
|
void ApplyConfiguration() override;
|
||||||
void SetConfiguration();
|
void SetConfiguration() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void changeEvent(QEvent* event) override;
|
void changeEvent(QEvent* event) override;
|
||||||
|
@ -39,11 +44,16 @@ private:
|
||||||
|
|
||||||
void SetOutputSinkFromSinkID();
|
void SetOutputSinkFromSinkID();
|
||||||
void SetAudioDevicesFromDeviceID();
|
void SetAudioDevicesFromDeviceID();
|
||||||
void SetVolumeIndicatorText(int percentage);
|
|
||||||
|
|
||||||
void SetupPerGameUI();
|
void Setup(const ConfigurationShared::Builder& builder);
|
||||||
|
|
||||||
std::unique_ptr<Ui::ConfigureAudio> ui;
|
std::unique_ptr<Ui::ConfigureAudio> ui;
|
||||||
|
|
||||||
const Core::System& system;
|
const Core::System& system;
|
||||||
|
|
||||||
|
std::vector<std::function<void(bool)>> apply_funcs{};
|
||||||
|
|
||||||
|
QComboBox* sink_combo_box;
|
||||||
|
QComboBox* output_device_combo_box;
|
||||||
|
QComboBox* input_device_combo_box;
|
||||||
};
|
};
|
||||||
|
|
|
@ -21,80 +21,14 @@
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout">
|
<layout class="QVBoxLayout">
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="engine_layout">
|
<widget class="QWidget" name="audio_widget" native="true">
|
||||||
<item>
|
<property name="maximumSize">
|
||||||
<widget class="QLabel" name="sink_label">
|
<size>
|
||||||
<property name="text">
|
<width>16777215</width>
|
||||||
<string>Output Engine:</string>
|
<height>16777213</height>
|
||||||
|
</size>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QComboBox" name="sink_combo_box"/>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<layout class="QHBoxLayout" name="output_layout">
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="output_label">
|
|
||||||
<property name="text">
|
|
||||||
<string>Output Device:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QComboBox" name="output_combo_box"/>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<layout class="QHBoxLayout" name="input_layout">
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="input_label">
|
|
||||||
<property name="text">
|
|
||||||
<string>Input Device:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QComboBox" name="input_combo_box"/>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<layout class="QHBoxLayout" name="mode_layout">
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="mode_label">
|
|
||||||
<property name="text">
|
|
||||||
<string>Sound Output Mode:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QComboBox" name="combo_sound">
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Mono</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Stereo</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Surround</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QWidget" name="volume_layout" native="true">
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
|
||||||
<property name="leftMargin">
|
<property name="leftMargin">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
|
@ -107,89 +41,9 @@
|
||||||
<property name="bottomMargin">
|
<property name="bottomMargin">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
|
||||||
<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>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<spacer name="horizontalSpacer">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>30</width>
|
|
||||||
<height>20</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QSlider" name="volume_slider">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="maximum">
|
|
||||||
<number>200</number>
|
|
||||||
</property>
|
|
||||||
<property name="pageStep">
|
|
||||||
<number>5</number>
|
|
||||||
</property>
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="volume_indicator">
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>32</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>0 %</string>
|
|
||||||
</property>
|
|
||||||
<property name="alignment">
|
|
||||||
<set>Qt::AlignCenter</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
|
||||||
<layout class="QHBoxLayout" name="mute_layout">
|
|
||||||
<item>
|
|
||||||
<widget class="QCheckBox" name="toggle_background_mute">
|
|
||||||
<property name="text">
|
|
||||||
<string>Mute audio when in background</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
|
|
@ -1,88 +1,92 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <typeinfo>
|
||||||
|
#include <vector>
|
||||||
|
#include <QComboBox>
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "common/settings.h"
|
#include "common/settings.h"
|
||||||
|
#include "common/settings_enums.h"
|
||||||
|
#include "configuration/shared_widget.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "ui_configure_cpu.h"
|
#include "ui_configure_cpu.h"
|
||||||
#include "yuzu/configuration/configuration_shared.h"
|
#include "yuzu/configuration/configuration_shared.h"
|
||||||
#include "yuzu/configuration/configure_cpu.h"
|
#include "yuzu/configuration/configure_cpu.h"
|
||||||
|
|
||||||
ConfigureCpu::ConfigureCpu(const Core::System& system_, QWidget* parent)
|
ConfigureCpu::ConfigureCpu(const Core::System& system_,
|
||||||
: QWidget(parent), ui{std::make_unique<Ui::ConfigureCpu>()}, system{system_} {
|
std::shared_ptr<std::vector<ConfigurationShared::Tab*>> group_,
|
||||||
|
const ConfigurationShared::Builder& builder, QWidget* parent)
|
||||||
|
: Tab(group_, parent), ui{std::make_unique<Ui::ConfigureCpu>()}, system{system_},
|
||||||
|
combobox_translations(builder.ComboboxTranslations()) {
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
|
||||||
SetupPerGameUI();
|
Setup(builder);
|
||||||
|
|
||||||
SetConfiguration();
|
SetConfiguration();
|
||||||
|
|
||||||
connect(ui->accuracy, qOverload<int>(&QComboBox::currentIndexChanged), this,
|
connect(accuracy_combobox, qOverload<int>(&QComboBox::currentIndexChanged), this,
|
||||||
&ConfigureCpu::UpdateGroup);
|
&ConfigureCpu::UpdateGroup);
|
||||||
}
|
}
|
||||||
|
|
||||||
ConfigureCpu::~ConfigureCpu() = default;
|
ConfigureCpu::~ConfigureCpu() = default;
|
||||||
|
|
||||||
void ConfigureCpu::SetConfiguration() {
|
void ConfigureCpu::SetConfiguration() {}
|
||||||
const bool runtime_lock = !system.IsPoweredOn();
|
void ConfigureCpu::Setup(const ConfigurationShared::Builder& builder) {
|
||||||
|
auto* accuracy_layout = ui->widget_accuracy->layout();
|
||||||
|
auto* unsafe_layout = ui->unsafe_widget->layout();
|
||||||
|
std::map<u32, QWidget*> unsafe_hold{};
|
||||||
|
|
||||||
ui->accuracy->setEnabled(runtime_lock);
|
std::vector<Settings::BasicSetting*> settings;
|
||||||
ui->cpuopt_unsafe_unfuse_fma->setEnabled(runtime_lock);
|
const auto push = [&](Settings::Category category) {
|
||||||
ui->cpuopt_unsafe_reduce_fp_error->setEnabled(runtime_lock);
|
for (const auto setting : Settings::values.linkage.by_category[category]) {
|
||||||
ui->cpuopt_unsafe_ignore_standard_fpcr->setEnabled(runtime_lock);
|
settings.push_back(setting);
|
||||||
ui->cpuopt_unsafe_inaccurate_nan->setEnabled(runtime_lock);
|
|
||||||
ui->cpuopt_unsafe_fastmem_check->setEnabled(runtime_lock);
|
|
||||||
ui->cpuopt_unsafe_ignore_global_monitor->setEnabled(runtime_lock);
|
|
||||||
|
|
||||||
ui->cpuopt_unsafe_unfuse_fma->setChecked(Settings::values.cpuopt_unsafe_unfuse_fma.GetValue());
|
|
||||||
ui->cpuopt_unsafe_reduce_fp_error->setChecked(
|
|
||||||
Settings::values.cpuopt_unsafe_reduce_fp_error.GetValue());
|
|
||||||
ui->cpuopt_unsafe_ignore_standard_fpcr->setChecked(
|
|
||||||
Settings::values.cpuopt_unsafe_ignore_standard_fpcr.GetValue());
|
|
||||||
ui->cpuopt_unsafe_inaccurate_nan->setChecked(
|
|
||||||
Settings::values.cpuopt_unsafe_inaccurate_nan.GetValue());
|
|
||||||
ui->cpuopt_unsafe_fastmem_check->setChecked(
|
|
||||||
Settings::values.cpuopt_unsafe_fastmem_check.GetValue());
|
|
||||||
ui->cpuopt_unsafe_ignore_global_monitor->setChecked(
|
|
||||||
Settings::values.cpuopt_unsafe_ignore_global_monitor.GetValue());
|
|
||||||
|
|
||||||
if (Settings::IsConfiguringGlobal()) {
|
|
||||||
ui->accuracy->setCurrentIndex(static_cast<int>(Settings::values.cpu_accuracy.GetValue()));
|
|
||||||
} else {
|
|
||||||
ConfigurationShared::SetPerGameSetting(ui->accuracy, &Settings::values.cpu_accuracy);
|
|
||||||
ConfigurationShared::SetHighlight(ui->widget_accuracy,
|
|
||||||
!Settings::values.cpu_accuracy.UsingGlobal());
|
|
||||||
}
|
}
|
||||||
UpdateGroup(ui->accuracy->currentIndex());
|
};
|
||||||
|
|
||||||
|
push(Settings::Category::Cpu);
|
||||||
|
push(Settings::Category::CpuUnsafe);
|
||||||
|
|
||||||
|
for (const auto setting : settings) {
|
||||||
|
auto* widget = builder.BuildWidget(setting, apply_funcs);
|
||||||
|
|
||||||
|
if (widget == nullptr) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!widget->Valid()) {
|
||||||
|
widget->deleteLater();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (setting->Id() == Settings::values.cpu_accuracy.Id()) {
|
||||||
|
// Keep track of cpu_accuracy combobox to display/hide the unsafe settings
|
||||||
|
accuracy_layout->addWidget(widget);
|
||||||
|
accuracy_combobox = widget->combobox;
|
||||||
|
} else {
|
||||||
|
// Presently, all other settings here are unsafe checkboxes
|
||||||
|
unsafe_hold.insert({setting->Id(), widget});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto& [label, widget] : unsafe_hold) {
|
||||||
|
unsafe_layout->addWidget(widget);
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateGroup(accuracy_combobox->currentIndex());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureCpu::UpdateGroup(int index) {
|
void ConfigureCpu::UpdateGroup(int index) {
|
||||||
if (!Settings::IsConfiguringGlobal()) {
|
const auto accuracy = static_cast<Settings::CpuAccuracy>(
|
||||||
index -= ConfigurationShared::USE_GLOBAL_OFFSET;
|
combobox_translations.at(Settings::EnumMetadata<Settings::CpuAccuracy>::Index())[index]
|
||||||
}
|
.first);
|
||||||
const auto accuracy = static_cast<Settings::CPUAccuracy>(index);
|
ui->unsafe_group->setVisible(accuracy == Settings::CpuAccuracy::Unsafe);
|
||||||
ui->unsafe_group->setVisible(accuracy == Settings::CPUAccuracy::Unsafe);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureCpu::ApplyConfiguration() {
|
void ConfigureCpu::ApplyConfiguration() {
|
||||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.cpu_accuracy, ui->accuracy);
|
const bool is_powered_on = system.IsPoweredOn();
|
||||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.cpuopt_unsafe_unfuse_fma,
|
for (const auto& apply_func : apply_funcs) {
|
||||||
ui->cpuopt_unsafe_unfuse_fma,
|
apply_func(is_powered_on);
|
||||||
cpuopt_unsafe_unfuse_fma);
|
}
|
||||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.cpuopt_unsafe_reduce_fp_error,
|
|
||||||
ui->cpuopt_unsafe_reduce_fp_error,
|
|
||||||
cpuopt_unsafe_reduce_fp_error);
|
|
||||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.cpuopt_unsafe_ignore_standard_fpcr,
|
|
||||||
ui->cpuopt_unsafe_ignore_standard_fpcr,
|
|
||||||
cpuopt_unsafe_ignore_standard_fpcr);
|
|
||||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.cpuopt_unsafe_inaccurate_nan,
|
|
||||||
ui->cpuopt_unsafe_inaccurate_nan,
|
|
||||||
cpuopt_unsafe_inaccurate_nan);
|
|
||||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.cpuopt_unsafe_fastmem_check,
|
|
||||||
ui->cpuopt_unsafe_fastmem_check,
|
|
||||||
cpuopt_unsafe_fastmem_check);
|
|
||||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.cpuopt_unsafe_ignore_global_monitor,
|
|
||||||
ui->cpuopt_unsafe_ignore_global_monitor,
|
|
||||||
cpuopt_unsafe_ignore_global_monitor);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureCpu::changeEvent(QEvent* event) {
|
void ConfigureCpu::changeEvent(QEvent* event) {
|
||||||
|
@ -96,32 +100,3 @@ void ConfigureCpu::changeEvent(QEvent* event) {
|
||||||
void ConfigureCpu::RetranslateUI() {
|
void ConfigureCpu::RetranslateUI() {
|
||||||
ui->retranslateUi(this);
|
ui->retranslateUi(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureCpu::SetupPerGameUI() {
|
|
||||||
if (Settings::IsConfiguringGlobal()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ConfigurationShared::SetColoredComboBox(
|
|
||||||
ui->accuracy, ui->widget_accuracy,
|
|
||||||
static_cast<u32>(Settings::values.cpu_accuracy.GetValue(true)));
|
|
||||||
|
|
||||||
ConfigurationShared::SetColoredTristate(ui->cpuopt_unsafe_unfuse_fma,
|
|
||||||
Settings::values.cpuopt_unsafe_unfuse_fma,
|
|
||||||
cpuopt_unsafe_unfuse_fma);
|
|
||||||
ConfigurationShared::SetColoredTristate(ui->cpuopt_unsafe_reduce_fp_error,
|
|
||||||
Settings::values.cpuopt_unsafe_reduce_fp_error,
|
|
||||||
cpuopt_unsafe_reduce_fp_error);
|
|
||||||
ConfigurationShared::SetColoredTristate(ui->cpuopt_unsafe_ignore_standard_fpcr,
|
|
||||||
Settings::values.cpuopt_unsafe_ignore_standard_fpcr,
|
|
||||||
cpuopt_unsafe_ignore_standard_fpcr);
|
|
||||||
ConfigurationShared::SetColoredTristate(ui->cpuopt_unsafe_inaccurate_nan,
|
|
||||||
Settings::values.cpuopt_unsafe_inaccurate_nan,
|
|
||||||
cpuopt_unsafe_inaccurate_nan);
|
|
||||||
ConfigurationShared::SetColoredTristate(ui->cpuopt_unsafe_fastmem_check,
|
|
||||||
Settings::values.cpuopt_unsafe_fastmem_check,
|
|
||||||
cpuopt_unsafe_fastmem_check);
|
|
||||||
ConfigurationShared::SetColoredTristate(ui->cpuopt_unsafe_ignore_global_monitor,
|
|
||||||
Settings::values.cpuopt_unsafe_ignore_global_monitor,
|
|
||||||
cpuopt_unsafe_ignore_global_monitor);
|
|
||||||
}
|
|
||||||
|
|
|
@ -4,29 +4,34 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
#include "yuzu/configuration/configuration_shared.h"
|
||||||
|
#include "yuzu/configuration/shared_translation.h"
|
||||||
|
|
||||||
|
class QComboBox;
|
||||||
|
|
||||||
namespace Core {
|
namespace Core {
|
||||||
class System;
|
class System;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace ConfigurationShared {
|
|
||||||
enum class CheckState;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class ConfigureCpu;
|
class ConfigureCpu;
|
||||||
}
|
}
|
||||||
|
|
||||||
class ConfigureCpu : public QWidget {
|
namespace ConfigurationShared {
|
||||||
Q_OBJECT
|
class Builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
class ConfigureCpu : public ConfigurationShared::Tab {
|
||||||
public:
|
public:
|
||||||
explicit ConfigureCpu(const Core::System& system_, QWidget* parent = nullptr);
|
explicit ConfigureCpu(const Core::System& system_,
|
||||||
|
std::shared_ptr<std::vector<ConfigurationShared::Tab*>> group,
|
||||||
|
const ConfigurationShared::Builder& builder, QWidget* parent = nullptr);
|
||||||
~ConfigureCpu() override;
|
~ConfigureCpu() override;
|
||||||
|
|
||||||
void ApplyConfiguration();
|
void ApplyConfiguration() override;
|
||||||
void SetConfiguration();
|
void SetConfiguration() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void changeEvent(QEvent* event) override;
|
void changeEvent(QEvent* event) override;
|
||||||
|
@ -34,16 +39,14 @@ private:
|
||||||
|
|
||||||
void UpdateGroup(int index);
|
void UpdateGroup(int index);
|
||||||
|
|
||||||
void SetupPerGameUI();
|
void Setup(const ConfigurationShared::Builder& builder);
|
||||||
|
|
||||||
std::unique_ptr<Ui::ConfigureCpu> ui;
|
std::unique_ptr<Ui::ConfigureCpu> ui;
|
||||||
|
|
||||||
ConfigurationShared::CheckState cpuopt_unsafe_unfuse_fma;
|
|
||||||
ConfigurationShared::CheckState cpuopt_unsafe_reduce_fp_error;
|
|
||||||
ConfigurationShared::CheckState cpuopt_unsafe_ignore_standard_fpcr;
|
|
||||||
ConfigurationShared::CheckState cpuopt_unsafe_inaccurate_nan;
|
|
||||||
ConfigurationShared::CheckState cpuopt_unsafe_fastmem_check;
|
|
||||||
ConfigurationShared::CheckState cpuopt_unsafe_ignore_global_monitor;
|
|
||||||
|
|
||||||
const Core::System& system;
|
const Core::System& system;
|
||||||
|
|
||||||
|
const ConfigurationShared::ComboboxTranslationMap& combobox_translations;
|
||||||
|
std::vector<std::function<void(bool)>> apply_funcs{};
|
||||||
|
|
||||||
|
QComboBox* accuracy_combobox;
|
||||||
};
|
};
|
||||||
|
|
|
@ -16,9 +16,12 @@
|
||||||
<property name="accessibleName">
|
<property name="accessibleName">
|
||||||
<string>CPU</string>
|
<string>CPU</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout">
|
<layout class="QVBoxLayout" name="vboxlayout_2" stretch="0">
|
||||||
<item>
|
<item>
|
||||||
<layout class="QVBoxLayout">
|
<layout class="QVBoxLayout" name="vboxlayout">
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QGroupBox" name="groupBox">
|
<widget class="QGroupBox" name="groupBox">
|
||||||
<property name="title">
|
<property name="title">
|
||||||
|
@ -27,38 +30,19 @@
|
||||||
<layout class="QVBoxLayout">
|
<layout class="QVBoxLayout">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QWidget" name="widget_accuracy" native="true">
|
<widget class="QWidget" name="widget_accuracy" native="true">
|
||||||
<layout class="QHBoxLayout" name="layout_accuracy">
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
<item>
|
<property name="leftMargin">
|
||||||
<widget class="QLabel" name="label_accuracy">
|
<number>0</number>
|
||||||
<property name="text">
|
|
||||||
<string>Accuracy:</string>
|
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
<property name="topMargin">
|
||||||
</item>
|
<number>0</number>
|
||||||
<item>
|
|
||||||
<widget class="QComboBox" name="accuracy">
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Auto</string>
|
|
||||||
</property>
|
</property>
|
||||||
</item>
|
<property name="rightMargin">
|
||||||
<item>
|
<number>0</number>
|
||||||
<property name="text">
|
|
||||||
<string>Accurate</string>
|
|
||||||
</property>
|
</property>
|
||||||
</item>
|
<property name="bottomMargin">
|
||||||
<item>
|
<number>0</number>
|
||||||
<property name="text">
|
|
||||||
<string>Unsafe</string>
|
|
||||||
</property>
|
</property>
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Paranoid (disables most optimizations)</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
@ -75,10 +59,6 @@
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<layout class="QVBoxLayout">
|
|
||||||
<item>
|
<item>
|
||||||
<widget class="QGroupBox" name="unsafe_group">
|
<widget class="QGroupBox" name="unsafe_group">
|
||||||
<property name="title">
|
<property name="title">
|
||||||
|
@ -96,87 +76,34 @@
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QCheckBox" name="cpuopt_unsafe_unfuse_fma">
|
<widget class="QWidget" name="unsafe_widget" native="true">
|
||||||
<property name="toolTip">
|
<layout class="QVBoxLayout" name="unsafe_layout">
|
||||||
<string>
|
<property name="leftMargin">
|
||||||
<div>This option improves speed by reducing accuracy of fused-multiply-add instructions on CPUs without native FMA support.</div>
|
<number>0</number>
|
||||||
</string>
|
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="topMargin">
|
||||||
<string>Unfuse FMA (improve performance on CPUs without FMA)</string>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
<property name="rightMargin">
|
||||||
</item>
|
<number>0</number>
|
||||||
<item>
|
|
||||||
<widget class="QCheckBox" name="cpuopt_unsafe_reduce_fp_error">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>
|
|
||||||
<div>This option improves the speed of some approximate floating-point functions by using less accurate native approximations.</div>
|
|
||||||
</string>
|
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="bottomMargin">
|
||||||
<string>Faster FRSQRTE and FRECPE</string>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QCheckBox" name="cpuopt_unsafe_ignore_standard_fpcr">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>
|
|
||||||
<div>This option improves the speed of 32 bits ASIMD floating-point functions by running with incorrect rounding modes.</div>
|
|
||||||
</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Faster ASIMD instructions (32 bits only)</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QCheckBox" name="cpuopt_unsafe_inaccurate_nan">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>
|
|
||||||
<div>This option improves speed by removing NaN checking. Please note this also reduces accuracy of certain floating-point instructions.</div>
|
|
||||||
</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Inaccurate NaN handling</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QCheckBox" name="cpuopt_unsafe_fastmem_check">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>
|
|
||||||
<div>This option improves speed by eliminating a safety check before every memory read/write in guest. Disabling it may allow a game to read/write the emulator's memory.</div>
|
|
||||||
</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Disable address space checks</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QCheckBox" name="cpuopt_unsafe_ignore_global_monitor">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>
|
|
||||||
<div>This option improves speed by relying only on the semantics of cmpxchg to ensure safety of exclusive access instructions. Please note this may result in deadlocks and other race conditions.</div>
|
|
||||||
</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Ignore global monitor</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<spacer name="verticalSpacer">
|
<spacer name="verticalSpacer">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
<enum>Qt::Vertical</enum>
|
<enum>Qt::Vertical</enum>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="sizeType">
|
||||||
|
<enum>QSizePolicy::Expanding</enum>
|
||||||
|
</property>
|
||||||
<property name="sizeHint" stdset="0">
|
<property name="sizeHint" stdset="0">
|
||||||
<size>
|
<size>
|
||||||
<width>20</width>
|
<width>20</width>
|
||||||
|
@ -185,15 +112,7 @@
|
||||||
</property>
|
</property>
|
||||||
</spacer>
|
</spacer>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
</layout>
|
||||||
<widget class="QLabel" name="label_disable_info">
|
|
||||||
<property name="text">
|
|
||||||
<string>CPU settings are available only when game is not running.</string>
|
|
||||||
</property>
|
|
||||||
<property name="wordWrap">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
|
|
|
@ -2,43 +2,119 @@
|
||||||
<ui version="4.0">
|
<ui version="4.0">
|
||||||
<class>ConfigureDebug</class>
|
<class>ConfigureDebug</class>
|
||||||
<widget class="QScrollArea" name="ConfigureDebug">
|
<widget class="QScrollArea" name="ConfigureDebug">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>831</width>
|
||||||
|
<height>760</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
<property name="widgetResizable">
|
<property name="widgetResizable">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget">
|
<widget class="QWidget" name="widget">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>829</width>
|
||||||
|
<height>758</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_1">
|
<layout class="QVBoxLayout" name="verticalLayout_1">
|
||||||
<item>
|
<item>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QGroupBox" name="groupBox">
|
<widget class="QGroupBox" name="groupBox">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>Debugger</string>
|
<string>Debugger</string>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||||
|
</property>
|
||||||
|
<property name="flat">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_11">
|
<widget class="QWidget" name="debug_widget" native="true">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<property name="sizeConstraint">
|
||||||
|
<enum>QLayout::SetDefaultConstraint</enum>
|
||||||
|
</property>
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QCheckBox" name="toggle_gdbstub">
|
<widget class="QCheckBox" name="toggle_gdbstub">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Maximum" vsizetype="Maximum">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Enable GDB Stub</string>
|
<string>Enable GDB Stub</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<spacer name="horizontalSpacer">
|
<widget class="QWidget" name="horizontalWidget_3" native="true">
|
||||||
<property name="orientation">
|
<property name="sizePolicy">
|
||||||
<enum>Qt::Horizontal</enum>
|
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
<property name="sizeHint" stdset="0">
|
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||||
<size>
|
<property name="leftMargin">
|
||||||
<width>40</width>
|
<number>0</number>
|
||||||
<height>20</height>
|
</property>
|
||||||
</size>
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="label_11">
|
<widget class="QLabel" name="label_11">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Minimum" vsizetype="Maximum">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Port:</string>
|
<string>Port:</string>
|
||||||
</property>
|
</property>
|
||||||
|
@ -46,6 +122,12 @@
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QSpinBox" name="gdbport_spinbox">
|
<widget class="QSpinBox" name="gdbport_spinbox">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
<property name="minimum">
|
<property name="minimum">
|
||||||
<number>1024</number>
|
<number>1024</number>
|
||||||
</property>
|
</property>
|
||||||
|
@ -55,22 +137,62 @@
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QGroupBox" name="groupBox_2">
|
<widget class="QGroupBox" name="groupBox_2">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>Logging</string>
|
<string>Logging</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout_1">
|
<layout class="QGridLayout" name="gridLayout_1">
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QPushButton" name="open_log_button">
|
||||||
|
<property name="text">
|
||||||
|
<string>Open Log Location</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item row="0" column="0" colspan="2">
|
<item row="0" column="0" colspan="2">
|
||||||
|
<widget class="QWidget" name="logging_widget" native="true">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_1">
|
<layout class="QHBoxLayout" name="horizontalLayout_1">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="label_1">
|
<widget class="QLabel" name="label_1">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Global Log Filter</string>
|
<string>Global Log Filter</string>
|
||||||
</property>
|
</property>
|
||||||
|
@ -80,19 +202,6 @@
|
||||||
<widget class="QLineEdit" name="log_filter_edit"/>
|
<widget class="QLineEdit" name="log_filter_edit"/>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
|
||||||
<item row="1" column="0">
|
|
||||||
<widget class="QCheckBox" name="toggle_console">
|
|
||||||
<property name="text">
|
|
||||||
<string>Show Log in Console</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="1">
|
|
||||||
<widget class="QPushButton" name="open_log_button">
|
|
||||||
<property name="text">
|
|
||||||
<string>Open Log Location</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="0">
|
<item row="2" column="0">
|
||||||
|
@ -108,9 +217,18 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QCheckBox" name="toggle_console">
|
||||||
|
<property name="text">
|
||||||
|
<string>Show Log in Console</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QGroupBox" name="groupBox_3">
|
<widget class="QGroupBox" name="groupBox_3">
|
||||||
<property name="title">
|
<property name="title">
|
||||||
|
@ -134,12 +252,63 @@
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QGroupBox" name="groupBox_4">
|
<widget class="QGroupBox" name="groupBox_4">
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>Graphics</string>
|
<string>Graphics</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout_2">
|
<layout class="QGridLayout" name="gridLayout_2">
|
||||||
|
<item row="3" column="0">
|
||||||
|
<widget class="QCheckBox" name="disable_loop_safety_checks">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>When checked, it executes shaders without loop logic changes</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Disable Loop safety checks</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="0">
|
||||||
|
<widget class="QCheckBox" name="dump_shaders">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>When checked, it will dump all the original assembler shaders from the disk shader cache or game as found</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Dump Game Shaders</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="7" column="0">
|
||||||
|
<widget class="QCheckBox" name="disable_macro_hle">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>When checked, it disables the macro HLE functions. Enabling this makes games run slower</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Disable Macro HLE</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="5" column="0">
|
||||||
|
<widget class="QCheckBox" name="disable_macro_jit">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>When checked, it disables the macro Just In Time compiler. Enabling this makes games run slower</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Disable Macro JIT</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item row="0" column="0">
|
<item row="0" column="0">
|
||||||
<widget class="QCheckBox" name="enable_graphics_debugging">
|
<widget class="QCheckBox" name="enable_graphics_debugging">
|
||||||
<property name="enabled">
|
<property name="enabled">
|
||||||
|
@ -153,30 +322,7 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="0">
|
<item row="6" column="0">
|
||||||
<widget class="QCheckBox" name="enable_nsight_aftermath">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>When checked, it enables Nsight Aftermath crash dumps</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Enable Nsight Aftermath</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="1">
|
|
||||||
<widget class="QCheckBox" name="dump_shaders">
|
|
||||||
<property name="enabled">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>When checked, it will dump all the original assembler shaders from the disk shader cache or game as found</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Dump Game Shaders</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="2">
|
|
||||||
<widget class="QCheckBox" name="dump_macros">
|
<widget class="QCheckBox" name="dump_macros">
|
||||||
<property name="enabled">
|
<property name="enabled">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
|
@ -189,32 +335,6 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="0" column="1">
|
|
||||||
<widget class="QCheckBox" name="disable_macro_jit">
|
|
||||||
<property name="enabled">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>When checked, it disables the macro Just In Time compiler. Enabling this makes games run slower</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Disable Macro JIT</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="2">
|
|
||||||
<widget class="QCheckBox" name="disable_macro_hle">
|
|
||||||
<property name="enabled">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>When checked, it disables the macro HLE functions. Enabling this makes games run slower</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Disable Macro HLE</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="0">
|
<item row="1" column="0">
|
||||||
<widget class="QCheckBox" name="enable_shader_feedback">
|
<widget class="QCheckBox" name="enable_shader_feedback">
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
|
@ -225,55 +345,31 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="1">
|
|
||||||
<widget class="QCheckBox" name="disable_loop_safety_checks">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>When checked, it executes shaders without loop logic changes</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Disable Loop safety checks</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QGroupBox" name="groupBox_5">
|
|
||||||
<property name="title">
|
|
||||||
<string>Debugging</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QGridLayout" name="gridLayout_3">
|
|
||||||
<item row="2" column="0">
|
<item row="2" column="0">
|
||||||
<widget class="QCheckBox" name="reporting_services">
|
<widget class="QCheckBox" name="enable_nsight_aftermath">
|
||||||
<property name="text">
|
|
||||||
<string>Enable Verbose Reporting Services**</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="0">
|
|
||||||
<widget class="QCheckBox" name="fs_access_log">
|
|
||||||
<property name="text">
|
|
||||||
<string>Enable FS Access Log</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="1">
|
|
||||||
<widget class="QCheckBox" name="dump_audio_commands">
|
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>Enable this to output the latest generated audio command list to the console. Only affects games using the audio renderer.</string>
|
<string>When checked, it enables Nsight Aftermath crash dumps</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Dump Audio Commands To Console**</string>
|
<string>Enable Nsight Aftermath</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="1">
|
<item row="8" column="0">
|
||||||
<widget class="QCheckBox" name="create_crash_dumps">
|
<spacer name="verticalSpacer_5">
|
||||||
<property name="text">
|
<property name="orientation">
|
||||||
<string>Create Minidump After Crash</string>
|
<enum>Qt::Vertical</enum>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
<property name="sizeType">
|
||||||
|
<enum>QSizePolicy::Preferred</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
|
@ -284,6 +380,37 @@
|
||||||
<string>Advanced</string>
|
<string>Advanced</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout_4">
|
<layout class="QGridLayout" name="gridLayout_4">
|
||||||
|
<item row="3" column="0">
|
||||||
|
<widget class="QCheckBox" name="perform_vulkan_check">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Enables yuzu to check for a working Vulkan environment when the program starts up. Disable this if this is causing issues with external programs seeing yuzu.</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Perform Startup Vulkan Check</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="0">
|
||||||
|
<widget class="QCheckBox" name="disable_web_applet">
|
||||||
|
<property name="text">
|
||||||
|
<string>Disable Web Applet</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="5" column="0">
|
||||||
|
<widget class="QCheckBox" name="enable_all_controllers">
|
||||||
|
<property name="text">
|
||||||
|
<string>Enable All Controller Types</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="6" column="0">
|
||||||
|
<widget class="QCheckBox" name="use_auto_stub">
|
||||||
|
<property name="text">
|
||||||
|
<string>Enable Auto-Stub**</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item row="0" column="0">
|
<item row="0" column="0">
|
||||||
<widget class="QCheckBox" name="quest_flag">
|
<widget class="QCheckBox" name="quest_flag">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
|
@ -305,42 +432,104 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="0" column="1">
|
<item row="7" column="0">
|
||||||
<widget class="QCheckBox" name="use_auto_stub">
|
<spacer name="verticalSpacer_4">
|
||||||
<property name="text">
|
<property name="orientation">
|
||||||
<string>Enable Auto-Stub**</string>
|
<enum>Qt::Vertical</enum>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
<property name="sizeType">
|
||||||
</item>
|
<enum>QSizePolicy::Expanding</enum>
|
||||||
<item row="1" column="1">
|
|
||||||
<widget class="QCheckBox" name="enable_all_controllers">
|
|
||||||
<property name="text">
|
|
||||||
<string>Enable All Controller Types</string>
|
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
<property name="sizeHint" stdset="0">
|
||||||
</item>
|
<size>
|
||||||
<item row="2" column="1">
|
<width>20</width>
|
||||||
<widget class="QCheckBox" name="disable_web_applet">
|
<height>0</height>
|
||||||
<property name="text">
|
</size>
|
||||||
<string>Disable Web Applet</string>
|
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</spacer>
|
||||||
</item>
|
|
||||||
<item row="3" column="0">
|
|
||||||
<widget class="QCheckBox" name="perform_vulkan_check">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>Enables yuzu to check for a working Vulkan environment when the program starts up. Disable this if this is causing issues with external programs seeing yuzu.</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Perform Startup Vulkan Check</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="groupBox_5">
|
||||||
|
<property name="title">
|
||||||
|
<string>Debugging</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout_3">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QCheckBox" name="fs_access_log">
|
||||||
|
<property name="text">
|
||||||
|
<string>Enable FS Access Log</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="0">
|
||||||
|
<widget class="QCheckBox" name="create_crash_dumps">
|
||||||
|
<property name="text">
|
||||||
|
<string>Create Minidump After Crash</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="0">
|
||||||
|
<widget class="QCheckBox" name="dump_audio_commands">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Enable this to output the latest generated audio command list to the console. Only affects games using the audio renderer.</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Dump Audio Commands To Console**</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QCheckBox" name="reporting_services">
|
||||||
|
<property name="text">
|
||||||
|
<string>Enable Verbose Reporting Services**</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="5" column="0">
|
||||||
|
<spacer name="verticalSpacer_3">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeType">
|
||||||
|
<enum>QSizePolicy::Expanding</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</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>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="label_5">
|
<widget class="QLabel" name="label_5">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
<property name="font">
|
<property name="font">
|
||||||
<font>
|
<font>
|
||||||
<italic>true</italic>
|
<italic>true</italic>
|
||||||
|
@ -366,14 +555,11 @@
|
||||||
<tabstop>enable_graphics_debugging</tabstop>
|
<tabstop>enable_graphics_debugging</tabstop>
|
||||||
<tabstop>enable_shader_feedback</tabstop>
|
<tabstop>enable_shader_feedback</tabstop>
|
||||||
<tabstop>enable_nsight_aftermath</tabstop>
|
<tabstop>enable_nsight_aftermath</tabstop>
|
||||||
<tabstop>disable_macro_jit</tabstop>
|
|
||||||
<tabstop>disable_loop_safety_checks</tabstop>
|
|
||||||
<tabstop>fs_access_log</tabstop>
|
<tabstop>fs_access_log</tabstop>
|
||||||
<tabstop>reporting_services</tabstop>
|
<tabstop>reporting_services</tabstop>
|
||||||
<tabstop>quest_flag</tabstop>
|
<tabstop>quest_flag</tabstop>
|
||||||
<tabstop>enable_cpu_debugging</tabstop>
|
<tabstop>enable_cpu_debugging</tabstop>
|
||||||
<tabstop>use_debug_asserts</tabstop>
|
<tabstop>use_debug_asserts</tabstop>
|
||||||
<tabstop>use_auto_stub</tabstop>
|
|
||||||
</tabstops>
|
</tabstops>
|
||||||
<resources/>
|
<resources/>
|
||||||
<connections/>
|
<connections/>
|
||||||
|
|
|
@ -32,21 +32,23 @@ ConfigureDialog::ConfigureDialog(QWidget* parent, HotkeyRegistry& registry_,
|
||||||
std::vector<VkDeviceInfo::Record>& vk_device_records,
|
std::vector<VkDeviceInfo::Record>& vk_device_records,
|
||||||
Core::System& system_, bool enable_web_config)
|
Core::System& system_, bool enable_web_config)
|
||||||
: QDialog(parent), ui{std::make_unique<Ui::ConfigureDialog>()},
|
: QDialog(parent), ui{std::make_unique<Ui::ConfigureDialog>()},
|
||||||
registry(registry_), system{system_}, audio_tab{std::make_unique<ConfigureAudio>(system_,
|
registry(registry_), system{system_}, builder{std::make_unique<ConfigurationShared::Builder>(
|
||||||
this)},
|
this, !system_.IsPoweredOn())},
|
||||||
cpu_tab{std::make_unique<ConfigureCpu>(system_, this)},
|
audio_tab{std::make_unique<ConfigureAudio>(system_, nullptr, *builder, this)},
|
||||||
|
cpu_tab{std::make_unique<ConfigureCpu>(system_, nullptr, *builder, this)},
|
||||||
debug_tab_tab{std::make_unique<ConfigureDebugTab>(system_, this)},
|
debug_tab_tab{std::make_unique<ConfigureDebugTab>(system_, this)},
|
||||||
filesystem_tab{std::make_unique<ConfigureFilesystem>(this)},
|
filesystem_tab{std::make_unique<ConfigureFilesystem>(this)},
|
||||||
general_tab{std::make_unique<ConfigureGeneral>(system_, this)},
|
general_tab{std::make_unique<ConfigureGeneral>(system_, nullptr, *builder, this)},
|
||||||
graphics_advanced_tab{std::make_unique<ConfigureGraphicsAdvanced>(system_, this)},
|
graphics_advanced_tab{
|
||||||
|
std::make_unique<ConfigureGraphicsAdvanced>(system_, nullptr, *builder, this)},
|
||||||
graphics_tab{std::make_unique<ConfigureGraphics>(
|
graphics_tab{std::make_unique<ConfigureGraphics>(
|
||||||
system_, vk_device_records, [&]() { graphics_advanced_tab->ExposeComputeOption(); },
|
system_, vk_device_records, [&]() { graphics_advanced_tab->ExposeComputeOption(); },
|
||||||
this)},
|
nullptr, *builder, this)},
|
||||||
hotkeys_tab{std::make_unique<ConfigureHotkeys>(system_.HIDCore(), this)},
|
hotkeys_tab{std::make_unique<ConfigureHotkeys>(system_.HIDCore(), this)},
|
||||||
input_tab{std::make_unique<ConfigureInput>(system_, this)},
|
input_tab{std::make_unique<ConfigureInput>(system_, this)},
|
||||||
network_tab{std::make_unique<ConfigureNetwork>(system_, this)},
|
network_tab{std::make_unique<ConfigureNetwork>(system_, this)},
|
||||||
profile_tab{std::make_unique<ConfigureProfileManager>(system_, this)},
|
profile_tab{std::make_unique<ConfigureProfileManager>(system_, this)},
|
||||||
system_tab{std::make_unique<ConfigureSystem>(system_, this)},
|
system_tab{std::make_unique<ConfigureSystem>(system_, nullptr, *builder, this)},
|
||||||
ui_tab{std::make_unique<ConfigureUi>(system_, this)}, web_tab{std::make_unique<ConfigureWeb>(
|
ui_tab{std::make_unique<ConfigureUi>(system_, this)}, web_tab{std::make_unique<ConfigureWeb>(
|
||||||
this)} {
|
this)} {
|
||||||
Settings::SetConfiguringGlobal(true);
|
Settings::SetConfiguringGlobal(true);
|
||||||
|
@ -95,6 +97,9 @@ ConfigureDialog::ConfigureDialog(QWidget* parent, HotkeyRegistry& registry_,
|
||||||
|
|
||||||
adjustSize();
|
adjustSize();
|
||||||
ui->selectorList->setCurrentRow(0);
|
ui->selectorList->setCurrentRow(0);
|
||||||
|
|
||||||
|
// Selects the leftmost button on the bottom bar (Cancel as of writing)
|
||||||
|
ui->buttonBox->setFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
ConfigureDialog::~ConfigureDialog() = default;
|
ConfigureDialog::~ConfigureDialog() = default;
|
||||||
|
|
|
@ -6,6 +6,9 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
|
#include "configuration/shared_widget.h"
|
||||||
|
#include "yuzu/configuration/configuration_shared.h"
|
||||||
|
#include "yuzu/configuration/shared_translation.h"
|
||||||
#include "yuzu/vk_device_info.h"
|
#include "yuzu/vk_device_info.h"
|
||||||
|
|
||||||
namespace Core {
|
namespace Core {
|
||||||
|
@ -69,6 +72,8 @@ private:
|
||||||
HotkeyRegistry& registry;
|
HotkeyRegistry& registry;
|
||||||
|
|
||||||
Core::System& system;
|
Core::System& system;
|
||||||
|
std::unique_ptr<ConfigurationShared::Builder> builder;
|
||||||
|
std::vector<ConfigurationShared::Tab*> tab_group;
|
||||||
|
|
||||||
std::unique_ptr<ConfigureAudio> audio_tab;
|
std::unique_ptr<ConfigureAudio> audio_tab;
|
||||||
std::unique_ptr<ConfigureCpu> cpu_tab;
|
std::unique_ptr<ConfigureCpu> cpu_tab;
|
||||||
|
|
|
@ -3,57 +3,60 @@
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
#include <vector>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include "common/settings.h"
|
#include "common/settings.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "ui_configure_general.h"
|
#include "ui_configure_general.h"
|
||||||
#include "yuzu/configuration/configuration_shared.h"
|
#include "yuzu/configuration/configuration_shared.h"
|
||||||
#include "yuzu/configuration/configure_general.h"
|
#include "yuzu/configuration/configure_general.h"
|
||||||
|
#include "yuzu/configuration/shared_widget.h"
|
||||||
#include "yuzu/uisettings.h"
|
#include "yuzu/uisettings.h"
|
||||||
|
|
||||||
ConfigureGeneral::ConfigureGeneral(const Core::System& system_, QWidget* parent)
|
ConfigureGeneral::ConfigureGeneral(const Core::System& system_,
|
||||||
: QWidget(parent), ui{std::make_unique<Ui::ConfigureGeneral>()}, system{system_} {
|
std::shared_ptr<std::vector<ConfigurationShared::Tab*>> group_,
|
||||||
|
const ConfigurationShared::Builder& builder, QWidget* parent)
|
||||||
|
: Tab(group_, parent), ui{std::make_unique<Ui::ConfigureGeneral>()}, system{system_} {
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
|
||||||
SetupPerGameUI();
|
Setup(builder);
|
||||||
|
|
||||||
SetConfiguration();
|
SetConfiguration();
|
||||||
|
|
||||||
if (Settings::IsConfiguringGlobal()) {
|
|
||||||
connect(ui->toggle_speed_limit, &QCheckBox::clicked, ui->speed_limit,
|
|
||||||
[this]() { ui->speed_limit->setEnabled(ui->toggle_speed_limit->isChecked()); });
|
|
||||||
}
|
|
||||||
|
|
||||||
connect(ui->button_reset_defaults, &QPushButton::clicked, this,
|
connect(ui->button_reset_defaults, &QPushButton::clicked, this,
|
||||||
&ConfigureGeneral::ResetDefaults);
|
&ConfigureGeneral::ResetDefaults);
|
||||||
|
|
||||||
|
if (!Settings::IsConfiguringGlobal()) {
|
||||||
|
ui->button_reset_defaults->setVisible(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ConfigureGeneral::~ConfigureGeneral() = default;
|
ConfigureGeneral::~ConfigureGeneral() = default;
|
||||||
|
|
||||||
void ConfigureGeneral::SetConfiguration() {
|
void ConfigureGeneral::SetConfiguration() {}
|
||||||
const bool runtime_lock = !system.IsPoweredOn();
|
|
||||||
|
|
||||||
ui->use_multi_core->setEnabled(runtime_lock);
|
void ConfigureGeneral::Setup(const ConfigurationShared::Builder& builder) {
|
||||||
ui->use_multi_core->setChecked(Settings::values.use_multi_core.GetValue());
|
QLayout& layout = *ui->general_widget->layout();
|
||||||
|
|
||||||
ui->toggle_check_exit->setChecked(UISettings::values.confirm_before_closing.GetValue());
|
std::map<u32, QWidget*> hold{};
|
||||||
ui->toggle_user_on_boot->setChecked(UISettings::values.select_user_on_boot.GetValue());
|
|
||||||
ui->toggle_background_pause->setChecked(UISettings::values.pause_when_in_background.GetValue());
|
|
||||||
ui->toggle_hide_mouse->setChecked(UISettings::values.hide_mouse.GetValue());
|
|
||||||
ui->toggle_controller_applet_disabled->setEnabled(runtime_lock);
|
|
||||||
ui->toggle_controller_applet_disabled->setChecked(
|
|
||||||
UISettings::values.controller_applet_disabled.GetValue());
|
|
||||||
|
|
||||||
ui->toggle_speed_limit->setChecked(Settings::values.use_speed_limit.GetValue());
|
for (const auto setting :
|
||||||
ui->speed_limit->setValue(Settings::values.speed_limit.GetValue());
|
UISettings::values.linkage.by_category[Settings::Category::UiGeneral]) {
|
||||||
|
auto* widget = builder.BuildWidget(setting, apply_funcs);
|
||||||
|
|
||||||
ui->button_reset_defaults->setEnabled(runtime_lock);
|
if (widget == nullptr) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!widget->Valid()) {
|
||||||
|
widget->deleteLater();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (Settings::IsConfiguringGlobal()) {
|
hold.emplace(setting->Id(), widget);
|
||||||
ui->speed_limit->setEnabled(Settings::values.use_speed_limit.GetValue());
|
}
|
||||||
} else {
|
|
||||||
ui->speed_limit->setEnabled(Settings::values.use_speed_limit.GetValue() &&
|
for (const auto& [id, widget] : hold) {
|
||||||
use_speed_limit != ConfigurationShared::CheckState::Global);
|
layout.addWidget(widget);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,32 +80,9 @@ void ConfigureGeneral::ResetDefaults() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureGeneral::ApplyConfiguration() {
|
void ConfigureGeneral::ApplyConfiguration() {
|
||||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_multi_core, ui->use_multi_core,
|
bool powered_on = system.IsPoweredOn();
|
||||||
use_multi_core);
|
for (const auto& func : apply_funcs) {
|
||||||
|
func(powered_on);
|
||||||
if (Settings::IsConfiguringGlobal()) {
|
|
||||||
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();
|
|
||||||
UISettings::values.controller_applet_disabled =
|
|
||||||
ui->toggle_controller_applet_disabled->isChecked();
|
|
||||||
|
|
||||||
// Guard if during game and set to game-specific value
|
|
||||||
if (Settings::values.use_speed_limit.UsingGlobal()) {
|
|
||||||
Settings::values.use_speed_limit.SetValue(ui->toggle_speed_limit->checkState() ==
|
|
||||||
Qt::Checked);
|
|
||||||
Settings::values.speed_limit.SetValue(ui->speed_limit->value());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
bool global_speed_limit = use_speed_limit == ConfigurationShared::CheckState::Global;
|
|
||||||
Settings::values.use_speed_limit.SetGlobal(global_speed_limit);
|
|
||||||
Settings::values.speed_limit.SetGlobal(global_speed_limit);
|
|
||||||
if (!global_speed_limit) {
|
|
||||||
Settings::values.use_speed_limit.SetValue(ui->toggle_speed_limit->checkState() ==
|
|
||||||
Qt::Checked);
|
|
||||||
Settings::values.speed_limit.SetValue(ui->speed_limit->value());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,33 +97,3 @@ void ConfigureGeneral::changeEvent(QEvent* event) {
|
||||||
void ConfigureGeneral::RetranslateUI() {
|
void ConfigureGeneral::RetranslateUI() {
|
||||||
ui->retranslateUi(this);
|
ui->retranslateUi(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureGeneral::SetupPerGameUI() {
|
|
||||||
if (Settings::IsConfiguringGlobal()) {
|
|
||||||
// Disables each setting if:
|
|
||||||
// - A game is running (thus settings in use), and
|
|
||||||
// - A non-global setting is applied.
|
|
||||||
ui->toggle_speed_limit->setEnabled(Settings::values.use_speed_limit.UsingGlobal());
|
|
||||||
ui->speed_limit->setEnabled(Settings::values.speed_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_controller_applet_disabled->setVisible(false);
|
|
||||||
|
|
||||||
ui->button_reset_defaults->setVisible(false);
|
|
||||||
|
|
||||||
ConfigurationShared::SetColoredTristate(ui->toggle_speed_limit,
|
|
||||||
Settings::values.use_speed_limit, use_speed_limit);
|
|
||||||
ConfigurationShared::SetColoredTristate(ui->use_multi_core, Settings::values.use_multi_core,
|
|
||||||
use_multi_core);
|
|
||||||
|
|
||||||
connect(ui->toggle_speed_limit, &QCheckBox::clicked, ui->speed_limit, [this]() {
|
|
||||||
ui->speed_limit->setEnabled(ui->toggle_speed_limit->isChecked() &&
|
|
||||||
(use_speed_limit != ConfigurationShared::CheckState::Global));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
|
@ -5,48 +5,49 @@
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
#include "yuzu/configuration/configuration_shared.h"
|
||||||
|
|
||||||
namespace Core {
|
namespace Core {
|
||||||
class System;
|
class System;
|
||||||
}
|
}
|
||||||
|
|
||||||
class ConfigureDialog;
|
class ConfigureDialog;
|
||||||
|
|
||||||
namespace ConfigurationShared {
|
|
||||||
enum class CheckState;
|
|
||||||
}
|
|
||||||
|
|
||||||
class HotkeyRegistry;
|
class HotkeyRegistry;
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class ConfigureGeneral;
|
class ConfigureGeneral;
|
||||||
}
|
}
|
||||||
|
|
||||||
class ConfigureGeneral : public QWidget {
|
namespace ConfigurationShared {
|
||||||
Q_OBJECT
|
class Builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
class ConfigureGeneral : public ConfigurationShared::Tab {
|
||||||
public:
|
public:
|
||||||
explicit ConfigureGeneral(const Core::System& system_, QWidget* parent = nullptr);
|
explicit ConfigureGeneral(const Core::System& system_,
|
||||||
|
std::shared_ptr<std::vector<ConfigurationShared::Tab*>> group,
|
||||||
|
const ConfigurationShared::Builder& builder,
|
||||||
|
QWidget* parent = nullptr);
|
||||||
~ConfigureGeneral() override;
|
~ConfigureGeneral() override;
|
||||||
|
|
||||||
void SetResetCallback(std::function<void()> callback);
|
void SetResetCallback(std::function<void()> callback);
|
||||||
void ResetDefaults();
|
void ResetDefaults();
|
||||||
void ApplyConfiguration();
|
void ApplyConfiguration() override;
|
||||||
void SetConfiguration();
|
void SetConfiguration() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void Setup(const ConfigurationShared::Builder& builder);
|
||||||
|
|
||||||
void changeEvent(QEvent* event) override;
|
void changeEvent(QEvent* event) override;
|
||||||
void RetranslateUI();
|
void RetranslateUI();
|
||||||
|
|
||||||
void SetupPerGameUI();
|
|
||||||
|
|
||||||
std::function<void()> reset_callback;
|
std::function<void()> reset_callback;
|
||||||
|
|
||||||
std::unique_ptr<Ui::ConfigureGeneral> ui;
|
std::unique_ptr<Ui::ConfigureGeneral> ui;
|
||||||
|
|
||||||
ConfigurationShared::CheckState use_speed_limit;
|
std::vector<std::function<void(bool)>> apply_funcs{};
|
||||||
ConfigurationShared::CheckState use_multi_core;
|
|
||||||
|
|
||||||
const Core::System& system;
|
const Core::System& system;
|
||||||
};
|
};
|
||||||
|
|
|
@ -26,78 +26,23 @@
|
||||||
</property>
|
</property>
|
||||||
<layout class="QHBoxLayout" name="GeneralHorizontalLayout">
|
<layout class="QHBoxLayout" name="GeneralHorizontalLayout">
|
||||||
<item>
|
<item>
|
||||||
|
<widget class="QWidget" name="general_widget" native="true">
|
||||||
<layout class="QVBoxLayout" name="GeneralVerticalLayout">
|
<layout class="QVBoxLayout" name="GeneralVerticalLayout">
|
||||||
<item>
|
<property name="leftMargin">
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
<number>0</number>
|
||||||
<item>
|
|
||||||
<widget class="QCheckBox" name="toggle_speed_limit">
|
|
||||||
<property name="text">
|
|
||||||
<string>Limit Speed Percent</string>
|
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
<property name="topMargin">
|
||||||
</item>
|
<number>0</number>
|
||||||
<item>
|
|
||||||
<widget class="QSpinBox" name="speed_limit">
|
|
||||||
<property name="suffix">
|
|
||||||
<string>%</string>
|
|
||||||
</property>
|
</property>
|
||||||
<property name="minimum">
|
<property name="rightMargin">
|
||||||
<number>1</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="maximum">
|
<property name="bottomMargin">
|
||||||
<number>9999</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="value">
|
|
||||||
<number>100</number>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QCheckBox" name="use_multi_core">
|
|
||||||
<property name="text">
|
|
||||||
<string>Multicore CPU Emulation</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
|
||||||
<widget class="QCheckBox" name="toggle_check_exit">
|
|
||||||
<property name="text">
|
|
||||||
<string>Confirm exit while emulation is running</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QCheckBox" name="toggle_user_on_boot">
|
|
||||||
<property name="text">
|
|
||||||
<string>Prompt for user on game boot</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QCheckBox" name="toggle_background_pause">
|
|
||||||
<property name="text">
|
|
||||||
<string>Pause emulation when in background</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QCheckBox" name="toggle_hide_mouse">
|
|
||||||
<property name="text">
|
|
||||||
<string>Hide mouse on inactivity</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QCheckBox" name="toggle_controller_applet_disabled">
|
|
||||||
<property name="text">
|
|
||||||
<string>Disable controller applet</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
|
#include <typeinfo>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <QBoxLayout>
|
#include <QBoxLayout>
|
||||||
|
@ -15,23 +16,29 @@
|
||||||
#include <QComboBox>
|
#include <QComboBox>
|
||||||
#include <QIcon>
|
#include <QIcon>
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
|
#include <QLineEdit>
|
||||||
#include <QPixmap>
|
#include <QPixmap>
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
#include <QSlider>
|
#include <QSlider>
|
||||||
#include <QStringLiteral>
|
#include <QStringLiteral>
|
||||||
#include <QtCore/qobjectdefs.h>
|
#include <QtCore/qobjectdefs.h>
|
||||||
|
#include <qabstractbutton.h>
|
||||||
|
#include <qboxlayout.h>
|
||||||
#include <qcoreevent.h>
|
#include <qcoreevent.h>
|
||||||
#include <qglobal.h>
|
#include <qglobal.h>
|
||||||
|
#include <qgridlayout.h>
|
||||||
#include <vulkan/vulkan_core.h>
|
#include <vulkan/vulkan_core.h>
|
||||||
|
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "common/dynamic_library.h"
|
#include "common/dynamic_library.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "common/settings.h"
|
#include "common/settings.h"
|
||||||
|
#include "common/settings_enums.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "ui_configure_graphics.h"
|
#include "ui_configure_graphics.h"
|
||||||
#include "yuzu/configuration/configuration_shared.h"
|
#include "yuzu/configuration/configuration_shared.h"
|
||||||
#include "yuzu/configuration/configure_graphics.h"
|
#include "yuzu/configuration/configure_graphics.h"
|
||||||
|
#include "yuzu/configuration/shared_widget.h"
|
||||||
#include "yuzu/qt_common.h"
|
#include "yuzu/qt_common.h"
|
||||||
#include "yuzu/uisettings.h"
|
#include "yuzu/uisettings.h"
|
||||||
#include "yuzu/vk_device_info.h"
|
#include "yuzu/vk_device_info.h"
|
||||||
|
@ -46,9 +53,9 @@ static constexpr VkPresentModeKHR VSyncSettingToMode(Settings::VSyncMode mode) {
|
||||||
return VK_PRESENT_MODE_IMMEDIATE_KHR;
|
return VK_PRESENT_MODE_IMMEDIATE_KHR;
|
||||||
case Settings::VSyncMode::Mailbox:
|
case Settings::VSyncMode::Mailbox:
|
||||||
return VK_PRESENT_MODE_MAILBOX_KHR;
|
return VK_PRESENT_MODE_MAILBOX_KHR;
|
||||||
case Settings::VSyncMode::FIFO:
|
case Settings::VSyncMode::Fifo:
|
||||||
return VK_PRESENT_MODE_FIFO_KHR;
|
return VK_PRESENT_MODE_FIFO_KHR;
|
||||||
case Settings::VSyncMode::FIFORelaxed:
|
case Settings::VSyncMode::FifoRelaxed:
|
||||||
return VK_PRESENT_MODE_FIFO_RELAXED_KHR;
|
return VK_PRESENT_MODE_FIFO_RELAXED_KHR;
|
||||||
default:
|
default:
|
||||||
return VK_PRESENT_MODE_FIFO_KHR;
|
return VK_PRESENT_MODE_FIFO_KHR;
|
||||||
|
@ -62,50 +69,67 @@ static constexpr Settings::VSyncMode PresentModeToSetting(VkPresentModeKHR mode)
|
||||||
case VK_PRESENT_MODE_MAILBOX_KHR:
|
case VK_PRESENT_MODE_MAILBOX_KHR:
|
||||||
return Settings::VSyncMode::Mailbox;
|
return Settings::VSyncMode::Mailbox;
|
||||||
case VK_PRESENT_MODE_FIFO_KHR:
|
case VK_PRESENT_MODE_FIFO_KHR:
|
||||||
return Settings::VSyncMode::FIFO;
|
return Settings::VSyncMode::Fifo;
|
||||||
case VK_PRESENT_MODE_FIFO_RELAXED_KHR:
|
case VK_PRESENT_MODE_FIFO_RELAXED_KHR:
|
||||||
return Settings::VSyncMode::FIFORelaxed;
|
return Settings::VSyncMode::FifoRelaxed;
|
||||||
default:
|
default:
|
||||||
return Settings::VSyncMode::FIFO;
|
return Settings::VSyncMode::Fifo;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ConfigureGraphics::ConfigureGraphics(const Core::System& system_,
|
ConfigureGraphics::ConfigureGraphics(const Core::System& system_,
|
||||||
std::vector<VkDeviceInfo::Record>& records_,
|
std::vector<VkDeviceInfo::Record>& records_,
|
||||||
const std::function<void()>& expose_compute_option_,
|
const std::function<void()>& expose_compute_option_,
|
||||||
QWidget* parent)
|
std::shared_ptr<std::vector<ConfigurationShared::Tab*>> group_,
|
||||||
: QWidget(parent), ui{std::make_unique<Ui::ConfigureGraphics>()}, records{records_},
|
const ConfigurationShared::Builder& builder, QWidget* parent)
|
||||||
expose_compute_option{expose_compute_option_}, system{system_} {
|
: ConfigurationShared::Tab(group_, parent), ui{std::make_unique<Ui::ConfigureGraphics>()},
|
||||||
|
records{records_}, expose_compute_option{expose_compute_option_}, system{system_},
|
||||||
|
combobox_translations{builder.ComboboxTranslations()},
|
||||||
|
shader_mapping{
|
||||||
|
combobox_translations.at(Settings::EnumMetadata<Settings::ShaderBackend>::Index())} {
|
||||||
vulkan_device = Settings::values.vulkan_device.GetValue();
|
vulkan_device = Settings::values.vulkan_device.GetValue();
|
||||||
RetrieveVulkanDevices();
|
RetrieveVulkanDevices();
|
||||||
|
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
|
||||||
|
Setup(builder);
|
||||||
|
|
||||||
for (const auto& device : vulkan_devices) {
|
for (const auto& device : vulkan_devices) {
|
||||||
ui->device->addItem(device);
|
vulkan_device_combobox->addItem(device);
|
||||||
}
|
}
|
||||||
|
|
||||||
ui->backend->addItem(QStringLiteral("GLSL"));
|
UpdateBackgroundColorButton(QColor::fromRgb(Settings::values.bg_red.GetValue(),
|
||||||
ui->backend->addItem(tr("GLASM (Assembly Shaders, NVIDIA Only)"));
|
Settings::values.bg_green.GetValue(),
|
||||||
ui->backend->addItem(tr("SPIR-V (Experimental, Mesa Only)"));
|
Settings::values.bg_blue.GetValue()));
|
||||||
|
UpdateAPILayout();
|
||||||
|
PopulateVSyncModeSelection(); //< must happen after UpdateAPILayout
|
||||||
|
|
||||||
SetupPerGameUI();
|
// VSync setting needs to be determined after populating the VSync combobox
|
||||||
|
if (Settings::IsConfiguringGlobal()) {
|
||||||
|
const auto vsync_mode_setting = Settings::values.vsync_mode.GetValue();
|
||||||
|
const auto vsync_mode = VSyncSettingToMode(vsync_mode_setting);
|
||||||
|
int index{};
|
||||||
|
for (const auto mode : vsync_mode_combobox_enum_map) {
|
||||||
|
if (mode == vsync_mode) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
if (static_cast<unsigned long>(index) < vsync_mode_combobox_enum_map.size()) {
|
||||||
|
vsync_mode_combobox->setCurrentIndex(index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SetConfiguration();
|
connect(api_combobox, qOverload<int>(&QComboBox::activated), this, [this] {
|
||||||
|
|
||||||
connect(ui->api, qOverload<int>(&QComboBox::currentIndexChanged), this, [this] {
|
|
||||||
UpdateAPILayout();
|
UpdateAPILayout();
|
||||||
PopulateVSyncModeSelection();
|
PopulateVSyncModeSelection();
|
||||||
if (!Settings::IsConfiguringGlobal()) {
|
|
||||||
ConfigurationShared::SetHighlight(
|
|
||||||
ui->api_widget, ui->api->currentIndex() != ConfigurationShared::USE_GLOBAL_INDEX);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
connect(ui->device, qOverload<int>(&QComboBox::activated), this, [this](int device) {
|
connect(vulkan_device_combobox, qOverload<int>(&QComboBox::activated), this,
|
||||||
|
[this](int device) {
|
||||||
UpdateDeviceSelection(device);
|
UpdateDeviceSelection(device);
|
||||||
PopulateVSyncModeSelection();
|
PopulateVSyncModeSelection();
|
||||||
});
|
});
|
||||||
connect(ui->backend, qOverload<int>(&QComboBox::activated), this,
|
connect(shader_backend_combobox, qOverload<int>(&QComboBox::activated), this,
|
||||||
[this](int backend) { UpdateShaderBackendSelection(backend); });
|
[this](int backend) { UpdateShaderBackendSelection(backend); });
|
||||||
|
|
||||||
connect(ui->bg_button, &QPushButton::clicked, this, [this] {
|
connect(ui->bg_button, &QPushButton::clicked, this, [this] {
|
||||||
|
@ -116,39 +140,45 @@ ConfigureGraphics::ConfigureGraphics(const Core::System& system_,
|
||||||
UpdateBackgroundColorButton(new_bg_color);
|
UpdateBackgroundColorButton(new_bg_color);
|
||||||
});
|
});
|
||||||
|
|
||||||
ui->api->setEnabled(!UISettings::values.has_broken_vulkan && ui->api->isEnabled());
|
api_combobox->setEnabled(!UISettings::values.has_broken_vulkan && api_combobox->isEnabled());
|
||||||
ui->api_widget->setEnabled(
|
ui->api_widget->setEnabled(
|
||||||
(!UISettings::values.has_broken_vulkan || Settings::IsConfiguringGlobal()) &&
|
(!UISettings::values.has_broken_vulkan || Settings::IsConfiguringGlobal()) &&
|
||||||
ui->api_widget->isEnabled());
|
ui->api_widget->isEnabled());
|
||||||
ui->bg_label->setVisible(Settings::IsConfiguringGlobal());
|
|
||||||
ui->bg_combobox->setVisible(!Settings::IsConfiguringGlobal());
|
|
||||||
|
|
||||||
connect(ui->fsr_sharpening_slider, &QSlider::valueChanged, this,
|
if (Settings::IsConfiguringGlobal()) {
|
||||||
&ConfigureGraphics::SetFSRIndicatorText);
|
ui->bg_widget->setEnabled(Settings::values.bg_red.UsingGlobal());
|
||||||
ui->fsr_sharpening_combobox->setVisible(!Settings::IsConfiguringGlobal());
|
}
|
||||||
ui->fsr_sharpening_label->setVisible(Settings::IsConfiguringGlobal());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureGraphics::PopulateVSyncModeSelection() {
|
void ConfigureGraphics::PopulateVSyncModeSelection() {
|
||||||
const Settings::RendererBackend backend{GetCurrentGraphicsBackend()};
|
if (!Settings::IsConfiguringGlobal()) {
|
||||||
if (backend == Settings::RendererBackend::Null) {
|
|
||||||
ui->vsync_mode_combobox->setEnabled(false);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ui->vsync_mode_combobox->setEnabled(true);
|
|
||||||
|
const Settings::RendererBackend backend{GetCurrentGraphicsBackend()};
|
||||||
|
if (backend == Settings::RendererBackend::Null) {
|
||||||
|
vsync_mode_combobox->setEnabled(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
vsync_mode_combobox->setEnabled(true);
|
||||||
|
|
||||||
const int current_index = //< current selected vsync mode from combobox
|
const int current_index = //< current selected vsync mode from combobox
|
||||||
ui->vsync_mode_combobox->currentIndex();
|
vsync_mode_combobox->currentIndex();
|
||||||
const auto current_mode = //< current selected vsync mode as a VkPresentModeKHR
|
const auto current_mode = //< current selected vsync mode as a VkPresentModeKHR
|
||||||
current_index == -1 ? VSyncSettingToMode(Settings::values.vsync_mode.GetValue())
|
current_index == -1 ? VSyncSettingToMode(Settings::values.vsync_mode.GetValue())
|
||||||
: vsync_mode_combobox_enum_map[current_index];
|
: vsync_mode_combobox_enum_map[current_index];
|
||||||
int index{};
|
int index{};
|
||||||
const int device{ui->device->currentIndex()}; //< current selected Vulkan device
|
const int device{vulkan_device_combobox->currentIndex()}; //< current selected Vulkan device
|
||||||
|
if (device == -1) {
|
||||||
|
// Invalid device
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const auto& present_modes = //< relevant vector of present modes for the selected device or API
|
const auto& present_modes = //< relevant vector of present modes for the selected device or API
|
||||||
backend == Settings::RendererBackend::Vulkan ? device_present_modes[device]
|
backend == Settings::RendererBackend::Vulkan ? device_present_modes[device]
|
||||||
: default_present_modes;
|
: default_present_modes;
|
||||||
|
|
||||||
ui->vsync_mode_combobox->clear();
|
vsync_mode_combobox->clear();
|
||||||
vsync_mode_combobox_enum_map.clear();
|
vsync_mode_combobox_enum_map.clear();
|
||||||
vsync_mode_combobox_enum_map.reserve(present_modes.size());
|
vsync_mode_combobox_enum_map.reserve(present_modes.size());
|
||||||
for (const auto present_mode : present_modes) {
|
for (const auto present_mode : present_modes) {
|
||||||
|
@ -157,10 +187,10 @@ void ConfigureGraphics::PopulateVSyncModeSelection() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
ui->vsync_mode_combobox->insertItem(index, mode_name);
|
vsync_mode_combobox->insertItem(index, mode_name);
|
||||||
vsync_mode_combobox_enum_map.push_back(present_mode);
|
vsync_mode_combobox_enum_map.push_back(present_mode);
|
||||||
if (present_mode == current_mode) {
|
if (present_mode == current_mode) {
|
||||||
ui->vsync_mode_combobox->setCurrentIndex(index);
|
vsync_mode_combobox->setCurrentIndex(index);
|
||||||
}
|
}
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
@ -186,112 +216,124 @@ void ConfigureGraphics::UpdateShaderBackendSelection(int backend) {
|
||||||
|
|
||||||
ConfigureGraphics::~ConfigureGraphics() = default;
|
ConfigureGraphics::~ConfigureGraphics() = default;
|
||||||
|
|
||||||
void ConfigureGraphics::SetConfiguration() {
|
void ConfigureGraphics::SetConfiguration() {}
|
||||||
const bool runtime_lock = !system.IsPoweredOn();
|
|
||||||
|
|
||||||
ui->api_widget->setEnabled(runtime_lock);
|
void ConfigureGraphics::Setup(const ConfigurationShared::Builder& builder) {
|
||||||
ui->use_asynchronous_gpu_emulation->setEnabled(runtime_lock);
|
QLayout* api_layout = ui->api_widget->layout();
|
||||||
ui->use_disk_shader_cache->setEnabled(runtime_lock);
|
QWidget* api_grid_widget = new QWidget(this);
|
||||||
ui->nvdec_emulation_widget->setEnabled(runtime_lock);
|
QVBoxLayout* api_grid_layout = new QVBoxLayout(api_grid_widget);
|
||||||
ui->resolution_combobox->setEnabled(runtime_lock);
|
api_grid_layout->setContentsMargins(0, 0, 0, 0);
|
||||||
ui->accelerate_astc->setEnabled(runtime_lock);
|
api_layout->addWidget(api_grid_widget);
|
||||||
ui->vsync_mode_layout->setEnabled(runtime_lock ||
|
|
||||||
Settings::values.renderer_backend.GetValue() ==
|
|
||||||
Settings::RendererBackend::Vulkan);
|
|
||||||
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());
|
|
||||||
ui->accelerate_astc->setChecked(Settings::values.accelerate_astc.GetValue());
|
|
||||||
|
|
||||||
if (Settings::IsConfiguringGlobal()) {
|
QLayout& graphics_layout = *ui->graphics_widget->layout();
|
||||||
ui->api->setCurrentIndex(static_cast<int>(Settings::values.renderer_backend.GetValue()));
|
|
||||||
ui->fullscreen_mode_combobox->setCurrentIndex(
|
std::map<u32, QWidget*> hold_graphics;
|
||||||
static_cast<int>(Settings::values.fullscreen_mode.GetValue()));
|
std::vector<QWidget*> hold_api;
|
||||||
ui->nvdec_emulation->setCurrentIndex(
|
|
||||||
static_cast<int>(Settings::values.nvdec_emulation.GetValue()));
|
for (const auto setting : Settings::values.linkage.by_category[Settings::Category::Renderer]) {
|
||||||
ui->aspect_ratio_combobox->setCurrentIndex(Settings::values.aspect_ratio.GetValue());
|
ConfigurationShared::Widget* widget = [&]() {
|
||||||
ui->resolution_combobox->setCurrentIndex(
|
if (setting->Id() == Settings::values.fsr_sharpening_slider.Id()) {
|
||||||
static_cast<int>(Settings::values.resolution_setup.GetValue()));
|
// FSR needs a reversed slider and a 0.5 multiplier
|
||||||
ui->scaling_filter_combobox->setCurrentIndex(
|
return builder.BuildWidget(
|
||||||
static_cast<int>(Settings::values.scaling_filter.GetValue()));
|
setting, apply_funcs, ConfigurationShared::RequestType::ReverseSlider, true,
|
||||||
ui->fsr_sharpening_slider->setValue(Settings::values.fsr_sharpening_slider.GetValue());
|
0.5f, nullptr, tr("%", "FSR sharpening percentage (e.g. 50%)"));
|
||||||
ui->anti_aliasing_combobox->setCurrentIndex(
|
|
||||||
static_cast<int>(Settings::values.anti_aliasing.GetValue()));
|
|
||||||
} else {
|
} else {
|
||||||
ConfigurationShared::SetPerGameSetting(ui->api, &Settings::values.renderer_backend);
|
return builder.BuildWidget(setting, apply_funcs);
|
||||||
ConfigurationShared::SetHighlight(ui->api_widget,
|
|
||||||
!Settings::values.renderer_backend.UsingGlobal());
|
|
||||||
|
|
||||||
ConfigurationShared::SetPerGameSetting(ui->nvdec_emulation,
|
|
||||||
&Settings::values.nvdec_emulation);
|
|
||||||
ConfigurationShared::SetHighlight(ui->nvdec_emulation_widget,
|
|
||||||
!Settings::values.nvdec_emulation.UsingGlobal());
|
|
||||||
|
|
||||||
ConfigurationShared::SetPerGameSetting(ui->fullscreen_mode_combobox,
|
|
||||||
&Settings::values.fullscreen_mode);
|
|
||||||
ConfigurationShared::SetHighlight(ui->fullscreen_mode_label,
|
|
||||||
!Settings::values.fullscreen_mode.UsingGlobal());
|
|
||||||
|
|
||||||
ConfigurationShared::SetPerGameSetting(ui->aspect_ratio_combobox,
|
|
||||||
&Settings::values.aspect_ratio);
|
|
||||||
ConfigurationShared::SetHighlight(ui->ar_label,
|
|
||||||
!Settings::values.aspect_ratio.UsingGlobal());
|
|
||||||
|
|
||||||
ConfigurationShared::SetPerGameSetting(ui->resolution_combobox,
|
|
||||||
&Settings::values.resolution_setup);
|
|
||||||
ConfigurationShared::SetHighlight(ui->resolution_label,
|
|
||||||
!Settings::values.resolution_setup.UsingGlobal());
|
|
||||||
|
|
||||||
ConfigurationShared::SetPerGameSetting(ui->scaling_filter_combobox,
|
|
||||||
&Settings::values.scaling_filter);
|
|
||||||
ConfigurationShared::SetHighlight(ui->scaling_filter_label,
|
|
||||||
!Settings::values.scaling_filter.UsingGlobal());
|
|
||||||
|
|
||||||
ConfigurationShared::SetPerGameSetting(ui->anti_aliasing_combobox,
|
|
||||||
&Settings::values.anti_aliasing);
|
|
||||||
ConfigurationShared::SetHighlight(ui->anti_aliasing_label,
|
|
||||||
!Settings::values.anti_aliasing.UsingGlobal());
|
|
||||||
|
|
||||||
ui->fsr_sharpening_combobox->setCurrentIndex(
|
|
||||||
Settings::values.fsr_sharpening_slider.UsingGlobal() ? 0 : 1);
|
|
||||||
ui->fsr_sharpening_slider->setEnabled(
|
|
||||||
!Settings::values.fsr_sharpening_slider.UsingGlobal());
|
|
||||||
ui->fsr_sharpening_value->setEnabled(!Settings::values.fsr_sharpening_slider.UsingGlobal());
|
|
||||||
ConfigurationShared::SetHighlight(ui->fsr_sharpening_layout,
|
|
||||||
!Settings::values.fsr_sharpening_slider.UsingGlobal());
|
|
||||||
ui->fsr_sharpening_slider->setValue(Settings::values.fsr_sharpening_slider.GetValue());
|
|
||||||
|
|
||||||
ui->bg_combobox->setCurrentIndex(Settings::values.bg_red.UsingGlobal() ? 0 : 1);
|
|
||||||
ui->bg_button->setEnabled(!Settings::values.bg_red.UsingGlobal());
|
|
||||||
ConfigurationShared::SetHighlight(ui->bg_layout, !Settings::values.bg_red.UsingGlobal());
|
|
||||||
}
|
}
|
||||||
UpdateBackgroundColorButton(QColor::fromRgb(Settings::values.bg_red.GetValue(),
|
}();
|
||||||
Settings::values.bg_green.GetValue(),
|
|
||||||
Settings::values.bg_blue.GetValue()));
|
|
||||||
UpdateAPILayout();
|
|
||||||
PopulateVSyncModeSelection(); //< must happen after UpdateAPILayout
|
|
||||||
SetFSRIndicatorText(ui->fsr_sharpening_slider->sliderPosition());
|
|
||||||
|
|
||||||
// VSync setting needs to be determined after populating the VSync combobox
|
if (widget == nullptr) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!widget->Valid()) {
|
||||||
|
widget->deleteLater();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (setting->Id() == Settings::values.renderer_backend.Id()) {
|
||||||
|
// Add the renderer combobox now so it's at the top
|
||||||
|
api_grid_layout->addWidget(widget);
|
||||||
|
api_combobox = widget->combobox;
|
||||||
|
api_restore_global_button = widget->restore_button;
|
||||||
|
|
||||||
|
if (!Settings::IsConfiguringGlobal()) {
|
||||||
|
QObject::connect(api_restore_global_button, &QAbstractButton::clicked,
|
||||||
|
[this](bool) { UpdateAPILayout(); });
|
||||||
|
|
||||||
|
// Detach API's restore button and place it where we want
|
||||||
|
// Lets us put it on the side, and it will automatically scale if there's a
|
||||||
|
// second combobox (shader_backend, vulkan_device)
|
||||||
|
widget->layout()->removeWidget(api_restore_global_button);
|
||||||
|
api_layout->addWidget(api_restore_global_button);
|
||||||
|
}
|
||||||
|
} else if (setting->Id() == Settings::values.vulkan_device.Id()) {
|
||||||
|
// Keep track of vulkan_device's combobox so we can populate it
|
||||||
|
hold_api.push_back(widget);
|
||||||
|
vulkan_device_combobox = widget->combobox;
|
||||||
|
vulkan_device_widget = widget;
|
||||||
|
} else if (setting->Id() == Settings::values.shader_backend.Id()) {
|
||||||
|
// Keep track of shader_backend's combobox so we can populate it
|
||||||
|
hold_api.push_back(widget);
|
||||||
|
shader_backend_combobox = widget->combobox;
|
||||||
|
shader_backend_widget = widget;
|
||||||
|
} else if (setting->Id() == Settings::values.vsync_mode.Id()) {
|
||||||
|
// Keep track of vsync_mode's combobox so we can populate it
|
||||||
|
vsync_mode_combobox = widget->combobox;
|
||||||
|
hold_graphics.emplace(setting->Id(), widget);
|
||||||
|
} else {
|
||||||
|
hold_graphics.emplace(setting->Id(), widget);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto& [id, widget] : hold_graphics) {
|
||||||
|
graphics_layout.addWidget(widget);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto widget : hold_api) {
|
||||||
|
api_grid_layout->addWidget(widget);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Background color is too specific to build into the new system, so we manage it here
|
||||||
|
// (3 settings, all collected into a single widget with a QColor to manage on top)
|
||||||
if (Settings::IsConfiguringGlobal()) {
|
if (Settings::IsConfiguringGlobal()) {
|
||||||
const auto vsync_mode_setting = Settings::values.vsync_mode.GetValue();
|
apply_funcs.push_back([this](bool powered_on) {
|
||||||
const auto vsync_mode = VSyncSettingToMode(vsync_mode_setting);
|
Settings::values.bg_red.SetValue(static_cast<u8>(bg_color.red()));
|
||||||
int index{};
|
Settings::values.bg_green.SetValue(static_cast<u8>(bg_color.green()));
|
||||||
for (const auto mode : vsync_mode_combobox_enum_map) {
|
Settings::values.bg_blue.SetValue(static_cast<u8>(bg_color.blue()));
|
||||||
if (mode == vsync_mode) {
|
});
|
||||||
break;
|
} else {
|
||||||
}
|
QPushButton* bg_restore_button = ConfigurationShared::Widget::CreateRestoreGlobalButton(
|
||||||
index++;
|
Settings::values.bg_red.UsingGlobal(), ui->bg_widget);
|
||||||
}
|
ui->bg_widget->layout()->addWidget(bg_restore_button);
|
||||||
if (static_cast<unsigned long>(index) < vsync_mode_combobox_enum_map.size()) {
|
|
||||||
ui->vsync_mode_combobox->setCurrentIndex(index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConfigureGraphics::SetFSRIndicatorText(int percentage) {
|
QObject::connect(bg_restore_button, &QAbstractButton::clicked,
|
||||||
ui->fsr_sharpening_value->setText(
|
[bg_restore_button, this](bool) {
|
||||||
tr("%1%", "FSR sharpening percentage (e.g. 50%)").arg(100 - (percentage / 2)));
|
const int r = Settings::values.bg_red.GetValue(true);
|
||||||
|
const int g = Settings::values.bg_green.GetValue(true);
|
||||||
|
const int b = Settings::values.bg_blue.GetValue(true);
|
||||||
|
UpdateBackgroundColorButton(QColor::fromRgb(r, g, b));
|
||||||
|
|
||||||
|
bg_restore_button->setVisible(false);
|
||||||
|
bg_restore_button->setEnabled(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
QObject::connect(ui->bg_button, &QAbstractButton::clicked, [bg_restore_button](bool) {
|
||||||
|
bg_restore_button->setVisible(true);
|
||||||
|
bg_restore_button->setEnabled(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
apply_funcs.push_back([bg_restore_button, this](bool powered_on) {
|
||||||
|
const bool using_global = !bg_restore_button->isEnabled();
|
||||||
|
Settings::values.bg_red.SetGlobal(using_global);
|
||||||
|
Settings::values.bg_green.SetGlobal(using_global);
|
||||||
|
Settings::values.bg_blue.SetGlobal(using_global);
|
||||||
|
if (!using_global) {
|
||||||
|
Settings::values.bg_red.SetValue(static_cast<u8>(bg_color.red()));
|
||||||
|
Settings::values.bg_green.SetValue(static_cast<u8>(bg_color.green()));
|
||||||
|
Settings::values.bg_blue.SetValue(static_cast<u8>(bg_color.blue()));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const QString ConfigureGraphics::TranslateVSyncMode(VkPresentModeKHR mode,
|
const QString ConfigureGraphics::TranslateVSyncMode(VkPresentModeKHR mode,
|
||||||
|
@ -315,130 +357,48 @@ const QString ConfigureGraphics::TranslateVSyncMode(VkPresentModeKHR mode,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ConfigureGraphics::FindIndex(u32 enumeration, int value) const {
|
||||||
|
for (u32 i = 0; i < combobox_translations.at(enumeration).size(); i++) {
|
||||||
|
if (combobox_translations.at(enumeration)[i].first == static_cast<u32>(value)) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
void ConfigureGraphics::ApplyConfiguration() {
|
void ConfigureGraphics::ApplyConfiguration() {
|
||||||
const auto resolution_setup = static_cast<Settings::ResolutionSetup>(
|
const bool powered_on = system.IsPoweredOn();
|
||||||
ui->resolution_combobox->currentIndex() -
|
for (const auto& func : apply_funcs) {
|
||||||
((Settings::IsConfiguringGlobal()) ? 0 : ConfigurationShared::USE_GLOBAL_OFFSET));
|
func(powered_on);
|
||||||
|
}
|
||||||
const auto scaling_filter = static_cast<Settings::ScalingFilter>(
|
|
||||||
ui->scaling_filter_combobox->currentIndex() -
|
|
||||||
((Settings::IsConfiguringGlobal()) ? 0 : ConfigurationShared::USE_GLOBAL_OFFSET));
|
|
||||||
|
|
||||||
const auto anti_aliasing = static_cast<Settings::AntiAliasing>(
|
|
||||||
ui->anti_aliasing_combobox->currentIndex() -
|
|
||||||
((Settings::IsConfiguringGlobal()) ? 0 : ConfigurationShared::USE_GLOBAL_OFFSET));
|
|
||||||
|
|
||||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.fullscreen_mode,
|
|
||||||
ui->fullscreen_mode_combobox);
|
|
||||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.aspect_ratio,
|
|
||||||
ui->aspect_ratio_combobox);
|
|
||||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_disk_shader_cache,
|
|
||||||
ui->use_disk_shader_cache, use_disk_shader_cache);
|
|
||||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_asynchronous_gpu_emulation,
|
|
||||||
ui->use_asynchronous_gpu_emulation,
|
|
||||||
use_asynchronous_gpu_emulation);
|
|
||||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.accelerate_astc, ui->accelerate_astc,
|
|
||||||
accelerate_astc);
|
|
||||||
|
|
||||||
if (Settings::IsConfiguringGlobal()) {
|
if (Settings::IsConfiguringGlobal()) {
|
||||||
// Guard if during game and set to game-specific value
|
const auto mode = vsync_mode_combobox_enum_map[vsync_mode_combobox->currentIndex()];
|
||||||
if (Settings::values.renderer_backend.UsingGlobal()) {
|
|
||||||
Settings::values.renderer_backend.SetValue(GetCurrentGraphicsBackend());
|
|
||||||
}
|
|
||||||
if (Settings::values.nvdec_emulation.UsingGlobal()) {
|
|
||||||
Settings::values.nvdec_emulation.SetValue(GetCurrentNvdecEmulation());
|
|
||||||
}
|
|
||||||
if (Settings::values.shader_backend.UsingGlobal()) {
|
|
||||||
Settings::values.shader_backend.SetValue(shader_backend);
|
|
||||||
}
|
|
||||||
if (Settings::values.vulkan_device.UsingGlobal()) {
|
|
||||||
Settings::values.vulkan_device.SetValue(vulkan_device);
|
|
||||||
}
|
|
||||||
if (Settings::values.bg_red.UsingGlobal()) {
|
|
||||||
Settings::values.bg_red.SetValue(static_cast<u8>(bg_color.red()));
|
|
||||||
Settings::values.bg_green.SetValue(static_cast<u8>(bg_color.green()));
|
|
||||||
Settings::values.bg_blue.SetValue(static_cast<u8>(bg_color.blue()));
|
|
||||||
}
|
|
||||||
if (Settings::values.resolution_setup.UsingGlobal()) {
|
|
||||||
Settings::values.resolution_setup.SetValue(resolution_setup);
|
|
||||||
}
|
|
||||||
if (Settings::values.scaling_filter.UsingGlobal()) {
|
|
||||||
Settings::values.scaling_filter.SetValue(scaling_filter);
|
|
||||||
}
|
|
||||||
if (Settings::values.anti_aliasing.UsingGlobal()) {
|
|
||||||
Settings::values.anti_aliasing.SetValue(anti_aliasing);
|
|
||||||
}
|
|
||||||
Settings::values.fsr_sharpening_slider.SetValue(ui->fsr_sharpening_slider->value());
|
|
||||||
|
|
||||||
const auto mode = vsync_mode_combobox_enum_map[ui->vsync_mode_combobox->currentIndex()];
|
|
||||||
const auto vsync_mode = PresentModeToSetting(mode);
|
const auto vsync_mode = PresentModeToSetting(mode);
|
||||||
Settings::values.vsync_mode.SetValue(vsync_mode);
|
Settings::values.vsync_mode.SetValue(vsync_mode);
|
||||||
} else {
|
|
||||||
if (ui->resolution_combobox->currentIndex() == ConfigurationShared::USE_GLOBAL_INDEX) {
|
|
||||||
Settings::values.resolution_setup.SetGlobal(true);
|
|
||||||
} else {
|
|
||||||
Settings::values.resolution_setup.SetGlobal(false);
|
|
||||||
Settings::values.resolution_setup.SetValue(resolution_setup);
|
|
||||||
}
|
}
|
||||||
if (ui->scaling_filter_combobox->currentIndex() == ConfigurationShared::USE_GLOBAL_INDEX) {
|
|
||||||
Settings::values.scaling_filter.SetGlobal(true);
|
Settings::values.vulkan_device.SetGlobal(true);
|
||||||
} else {
|
|
||||||
Settings::values.scaling_filter.SetGlobal(false);
|
|
||||||
Settings::values.scaling_filter.SetValue(scaling_filter);
|
|
||||||
}
|
|
||||||
if (ui->anti_aliasing_combobox->currentIndex() == ConfigurationShared::USE_GLOBAL_INDEX) {
|
|
||||||
Settings::values.anti_aliasing.SetGlobal(true);
|
|
||||||
} else {
|
|
||||||
Settings::values.anti_aliasing.SetGlobal(false);
|
|
||||||
Settings::values.anti_aliasing.SetValue(anti_aliasing);
|
|
||||||
}
|
|
||||||
if (ui->api->currentIndex() == ConfigurationShared::USE_GLOBAL_INDEX) {
|
|
||||||
Settings::values.renderer_backend.SetGlobal(true);
|
|
||||||
Settings::values.shader_backend.SetGlobal(true);
|
Settings::values.shader_backend.SetGlobal(true);
|
||||||
Settings::values.vulkan_device.SetGlobal(true);
|
if (Settings::IsConfiguringGlobal() ||
|
||||||
} else {
|
(!Settings::IsConfiguringGlobal() && api_restore_global_button->isEnabled())) {
|
||||||
Settings::values.renderer_backend.SetGlobal(false);
|
auto backend = static_cast<Settings::RendererBackend>(
|
||||||
Settings::values.renderer_backend.SetValue(GetCurrentGraphicsBackend());
|
combobox_translations
|
||||||
switch (GetCurrentGraphicsBackend()) {
|
.at(Settings::EnumMetadata<
|
||||||
|
Settings::RendererBackend>::Index())[api_combobox->currentIndex()]
|
||||||
|
.first);
|
||||||
|
switch (backend) {
|
||||||
case Settings::RendererBackend::OpenGL:
|
case Settings::RendererBackend::OpenGL:
|
||||||
case Settings::RendererBackend::Null:
|
Settings::values.shader_backend.SetGlobal(Settings::IsConfiguringGlobal());
|
||||||
Settings::values.shader_backend.SetGlobal(false);
|
Settings::values.shader_backend.SetValue(static_cast<Settings::ShaderBackend>(
|
||||||
Settings::values.vulkan_device.SetGlobal(true);
|
shader_mapping[shader_backend_combobox->currentIndex()].first));
|
||||||
Settings::values.shader_backend.SetValue(shader_backend);
|
|
||||||
break;
|
break;
|
||||||
case Settings::RendererBackend::Vulkan:
|
case Settings::RendererBackend::Vulkan:
|
||||||
Settings::values.shader_backend.SetGlobal(true);
|
Settings::values.vulkan_device.SetGlobal(Settings::IsConfiguringGlobal());
|
||||||
Settings::values.vulkan_device.SetGlobal(false);
|
Settings::values.vulkan_device.SetValue(vulkan_device_combobox->currentIndex());
|
||||||
Settings::values.vulkan_device.SetValue(vulkan_device);
|
break;
|
||||||
|
case Settings::RendererBackend::Null:
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ui->nvdec_emulation->currentIndex() == ConfigurationShared::USE_GLOBAL_INDEX) {
|
|
||||||
Settings::values.nvdec_emulation.SetGlobal(true);
|
|
||||||
} else {
|
|
||||||
Settings::values.nvdec_emulation.SetGlobal(false);
|
|
||||||
Settings::values.nvdec_emulation.SetValue(GetCurrentNvdecEmulation());
|
|
||||||
}
|
|
||||||
|
|
||||||
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<u8>(bg_color.red()));
|
|
||||||
Settings::values.bg_green.SetValue(static_cast<u8>(bg_color.green()));
|
|
||||||
Settings::values.bg_blue.SetValue(static_cast<u8>(bg_color.blue()));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ui->fsr_sharpening_combobox->currentIndex() == ConfigurationShared::USE_GLOBAL_INDEX) {
|
|
||||||
Settings::values.fsr_sharpening_slider.SetGlobal(true);
|
|
||||||
} else {
|
|
||||||
Settings::values.fsr_sharpening_slider.SetGlobal(false);
|
|
||||||
Settings::values.fsr_sharpening_slider.SetValue(ui->fsr_sharpening_slider->value());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -466,36 +426,26 @@ void ConfigureGraphics::UpdateBackgroundColorButton(QColor color) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureGraphics::UpdateAPILayout() {
|
void ConfigureGraphics::UpdateAPILayout() {
|
||||||
if (!Settings::IsConfiguringGlobal() &&
|
bool runtime_lock = !system.IsPoweredOn();
|
||||||
ui->api->currentIndex() == ConfigurationShared::USE_GLOBAL_INDEX) {
|
bool need_global = !(Settings::IsConfiguringGlobal() || api_restore_global_button->isEnabled());
|
||||||
vulkan_device = Settings::values.vulkan_device.GetValue(true);
|
vulkan_device = Settings::values.vulkan_device.GetValue(need_global);
|
||||||
shader_backend = Settings::values.shader_backend.GetValue(true);
|
shader_backend = Settings::values.shader_backend.GetValue(need_global);
|
||||||
ui->device_widget->setEnabled(false);
|
vulkan_device_widget->setEnabled(!need_global && runtime_lock);
|
||||||
ui->backend_widget->setEnabled(false);
|
shader_backend_widget->setEnabled(!need_global && runtime_lock);
|
||||||
} else {
|
|
||||||
vulkan_device = Settings::values.vulkan_device.GetValue();
|
|
||||||
shader_backend = Settings::values.shader_backend.GetValue();
|
|
||||||
ui->device_widget->setEnabled(true);
|
|
||||||
ui->backend_widget->setEnabled(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (GetCurrentGraphicsBackend()) {
|
const auto current_backend = GetCurrentGraphicsBackend();
|
||||||
case Settings::RendererBackend::OpenGL:
|
const bool is_opengl = current_backend == Settings::RendererBackend::OpenGL;
|
||||||
ui->backend->setCurrentIndex(static_cast<u32>(shader_backend));
|
const bool is_vulkan = current_backend == Settings::RendererBackend::Vulkan;
|
||||||
ui->device_widget->setVisible(false);
|
|
||||||
ui->backend_widget->setVisible(true);
|
vulkan_device_widget->setVisible(is_vulkan);
|
||||||
break;
|
shader_backend_widget->setVisible(is_opengl);
|
||||||
case Settings::RendererBackend::Vulkan:
|
|
||||||
if (static_cast<int>(vulkan_device) < ui->device->count()) {
|
if (is_opengl) {
|
||||||
ui->device->setCurrentIndex(vulkan_device);
|
shader_backend_combobox->setCurrentIndex(
|
||||||
}
|
FindIndex(Settings::EnumMetadata<Settings::ShaderBackend>::Index(),
|
||||||
ui->device_widget->setVisible(true);
|
static_cast<int>(shader_backend)));
|
||||||
ui->backend_widget->setVisible(false);
|
} else if (is_vulkan && static_cast<int>(vulkan_device) < vulkan_device_combobox->count()) {
|
||||||
break;
|
vulkan_device_combobox->setCurrentIndex(vulkan_device);
|
||||||
case Settings::RendererBackend::Null:
|
|
||||||
ui->device_widget->setVisible(false);
|
|
||||||
ui->backend_widget->setVisible(false);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -515,92 +465,11 @@ void ConfigureGraphics::RetrieveVulkanDevices() {
|
||||||
}
|
}
|
||||||
|
|
||||||
Settings::RendererBackend ConfigureGraphics::GetCurrentGraphicsBackend() const {
|
Settings::RendererBackend ConfigureGraphics::GetCurrentGraphicsBackend() const {
|
||||||
if (Settings::IsConfiguringGlobal()) {
|
if (!Settings::IsConfiguringGlobal() && !api_restore_global_button->isEnabled()) {
|
||||||
return static_cast<Settings::RendererBackend>(ui->api->currentIndex());
|
return Settings::values.renderer_backend.GetValue(true);
|
||||||
}
|
}
|
||||||
|
return static_cast<Settings::RendererBackend>(
|
||||||
if (ui->api->currentIndex() == ConfigurationShared::USE_GLOBAL_INDEX) {
|
combobox_translations.at(Settings::EnumMetadata<Settings::RendererBackend>::Index())
|
||||||
Settings::values.renderer_backend.SetGlobal(true);
|
.at(api_combobox->currentIndex())
|
||||||
return Settings::values.renderer_backend.GetValue();
|
.first);
|
||||||
}
|
|
||||||
Settings::values.renderer_backend.SetGlobal(false);
|
|
||||||
return static_cast<Settings::RendererBackend>(ui->api->currentIndex() -
|
|
||||||
ConfigurationShared::USE_GLOBAL_OFFSET);
|
|
||||||
}
|
|
||||||
|
|
||||||
Settings::NvdecEmulation ConfigureGraphics::GetCurrentNvdecEmulation() const {
|
|
||||||
if (Settings::IsConfiguringGlobal()) {
|
|
||||||
return static_cast<Settings::NvdecEmulation>(ui->nvdec_emulation->currentIndex());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ui->nvdec_emulation->currentIndex() == ConfigurationShared::USE_GLOBAL_INDEX) {
|
|
||||||
Settings::values.nvdec_emulation.SetGlobal(true);
|
|
||||||
return Settings::values.nvdec_emulation.GetValue();
|
|
||||||
}
|
|
||||||
Settings::values.nvdec_emulation.SetGlobal(false);
|
|
||||||
return static_cast<Settings::NvdecEmulation>(ui->nvdec_emulation->currentIndex() -
|
|
||||||
ConfigurationShared::USE_GLOBAL_OFFSET);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConfigureGraphics::SetupPerGameUI() {
|
|
||||||
if (Settings::IsConfiguringGlobal()) {
|
|
||||||
ui->api->setEnabled(Settings::values.renderer_backend.UsingGlobal());
|
|
||||||
ui->device->setEnabled(Settings::values.renderer_backend.UsingGlobal());
|
|
||||||
ui->fullscreen_mode_combobox->setEnabled(Settings::values.fullscreen_mode.UsingGlobal());
|
|
||||||
ui->aspect_ratio_combobox->setEnabled(Settings::values.aspect_ratio.UsingGlobal());
|
|
||||||
ui->resolution_combobox->setEnabled(Settings::values.resolution_setup.UsingGlobal());
|
|
||||||
ui->scaling_filter_combobox->setEnabled(Settings::values.scaling_filter.UsingGlobal());
|
|
||||||
ui->fsr_sharpening_slider->setEnabled(Settings::values.fsr_sharpening_slider.UsingGlobal());
|
|
||||||
ui->anti_aliasing_combobox->setEnabled(Settings::values.anti_aliasing.UsingGlobal());
|
|
||||||
ui->use_asynchronous_gpu_emulation->setEnabled(
|
|
||||||
Settings::values.use_asynchronous_gpu_emulation.UsingGlobal());
|
|
||||||
ui->nvdec_emulation->setEnabled(Settings::values.nvdec_emulation.UsingGlobal());
|
|
||||||
ui->accelerate_astc->setEnabled(Settings::values.accelerate_astc.UsingGlobal());
|
|
||||||
ui->use_disk_shader_cache->setEnabled(Settings::values.use_disk_shader_cache.UsingGlobal());
|
|
||||||
ui->bg_button->setEnabled(Settings::values.bg_red.UsingGlobal());
|
|
||||||
ui->fsr_slider_layout->setEnabled(Settings::values.fsr_sharpening_slider.UsingGlobal());
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
connect(ui->bg_combobox, qOverload<int>(&QComboBox::activated), this, [this](int index) {
|
|
||||||
ui->bg_button->setEnabled(index == 1);
|
|
||||||
ConfigurationShared::SetHighlight(ui->bg_layout, index == 1);
|
|
||||||
});
|
|
||||||
|
|
||||||
connect(ui->fsr_sharpening_combobox, qOverload<int>(&QComboBox::activated), this,
|
|
||||||
[this](int index) {
|
|
||||||
ui->fsr_sharpening_slider->setEnabled(index == 1);
|
|
||||||
ui->fsr_sharpening_value->setEnabled(index == 1);
|
|
||||||
ConfigurationShared::SetHighlight(ui->fsr_sharpening_layout, index == 1);
|
|
||||||
});
|
|
||||||
|
|
||||||
ConfigurationShared::SetColoredTristate(
|
|
||||||
ui->use_disk_shader_cache, Settings::values.use_disk_shader_cache, use_disk_shader_cache);
|
|
||||||
ConfigurationShared::SetColoredTristate(ui->accelerate_astc, Settings::values.accelerate_astc,
|
|
||||||
accelerate_astc);
|
|
||||||
ConfigurationShared::SetColoredTristate(ui->use_asynchronous_gpu_emulation,
|
|
||||||
Settings::values.use_asynchronous_gpu_emulation,
|
|
||||||
use_asynchronous_gpu_emulation);
|
|
||||||
|
|
||||||
ConfigurationShared::SetColoredComboBox(ui->aspect_ratio_combobox, ui->ar_label,
|
|
||||||
Settings::values.aspect_ratio.GetValue(true));
|
|
||||||
ConfigurationShared::SetColoredComboBox(
|
|
||||||
ui->fullscreen_mode_combobox, ui->fullscreen_mode_label,
|
|
||||||
static_cast<int>(Settings::values.fullscreen_mode.GetValue(true)));
|
|
||||||
ConfigurationShared::SetColoredComboBox(
|
|
||||||
ui->resolution_combobox, ui->resolution_label,
|
|
||||||
static_cast<int>(Settings::values.resolution_setup.GetValue(true)));
|
|
||||||
ConfigurationShared::SetColoredComboBox(
|
|
||||||
ui->scaling_filter_combobox, ui->scaling_filter_label,
|
|
||||||
static_cast<int>(Settings::values.scaling_filter.GetValue(true)));
|
|
||||||
ConfigurationShared::SetColoredComboBox(
|
|
||||||
ui->anti_aliasing_combobox, ui->anti_aliasing_label,
|
|
||||||
static_cast<int>(Settings::values.anti_aliasing.GetValue(true)));
|
|
||||||
ConfigurationShared::InsertGlobalItem(
|
|
||||||
ui->api, static_cast<int>(Settings::values.renderer_backend.GetValue(true)));
|
|
||||||
ConfigurationShared::InsertGlobalItem(
|
|
||||||
ui->nvdec_emulation, static_cast<int>(Settings::values.nvdec_emulation.GetValue(true)));
|
|
||||||
|
|
||||||
ui->vsync_mode_layout->setVisible(false);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <type_traits>
|
||||||
|
#include <typeindex>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <QColor>
|
#include <QColor>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
@ -12,10 +14,14 @@
|
||||||
#include <qobjectdefs.h>
|
#include <qobjectdefs.h>
|
||||||
#include <vulkan/vulkan_core.h>
|
#include <vulkan/vulkan_core.h>
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
#include "configuration/shared_translation.h"
|
||||||
#include "vk_device_info.h"
|
#include "vk_device_info.h"
|
||||||
|
#include "yuzu/configuration/configuration_shared.h"
|
||||||
|
|
||||||
|
class QPushButton;
|
||||||
class QEvent;
|
class QEvent;
|
||||||
class QObject;
|
class QObject;
|
||||||
|
class QComboBox;
|
||||||
|
|
||||||
namespace Settings {
|
namespace Settings {
|
||||||
enum class NvdecEmulation : u32;
|
enum class NvdecEmulation : u32;
|
||||||
|
@ -27,31 +33,33 @@ namespace Core {
|
||||||
class System;
|
class System;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace ConfigurationShared {
|
|
||||||
enum class CheckState;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class ConfigureGraphics;
|
class ConfigureGraphics;
|
||||||
}
|
}
|
||||||
|
|
||||||
class ConfigureGraphics : public QWidget {
|
namespace ConfigurationShared {
|
||||||
Q_OBJECT
|
class Builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
class ConfigureGraphics : public ConfigurationShared::Tab {
|
||||||
public:
|
public:
|
||||||
explicit ConfigureGraphics(const Core::System& system_,
|
explicit ConfigureGraphics(const Core::System& system_,
|
||||||
std::vector<VkDeviceInfo::Record>& records,
|
std::vector<VkDeviceInfo::Record>& records,
|
||||||
const std::function<void()>& expose_compute_option_,
|
const std::function<void()>& expose_compute_option_,
|
||||||
|
std::shared_ptr<std::vector<ConfigurationShared::Tab*>> group,
|
||||||
|
const ConfigurationShared::Builder& builder,
|
||||||
QWidget* parent = nullptr);
|
QWidget* parent = nullptr);
|
||||||
~ConfigureGraphics() override;
|
~ConfigureGraphics() override;
|
||||||
|
|
||||||
void ApplyConfiguration();
|
void ApplyConfiguration() override;
|
||||||
void SetConfiguration();
|
void SetConfiguration() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void changeEvent(QEvent* event) override;
|
void changeEvent(QEvent* event) override;
|
||||||
void RetranslateUI();
|
void RetranslateUI();
|
||||||
|
|
||||||
|
void Setup(const ConfigurationShared::Builder& builder);
|
||||||
|
|
||||||
void PopulateVSyncModeSelection();
|
void PopulateVSyncModeSelection();
|
||||||
void UpdateBackgroundColorButton(QColor color);
|
void UpdateBackgroundColorButton(QColor color);
|
||||||
void UpdateAPILayout();
|
void UpdateAPILayout();
|
||||||
|
@ -60,34 +68,40 @@ private:
|
||||||
|
|
||||||
void RetrieveVulkanDevices();
|
void RetrieveVulkanDevices();
|
||||||
|
|
||||||
void SetFSRIndicatorText(int percentage);
|
|
||||||
/* Turns a Vulkan present mode into a textual string for a UI
|
/* Turns a Vulkan present mode into a textual string for a UI
|
||||||
* (and eventually for a human to read) */
|
* (and eventually for a human to read) */
|
||||||
const QString TranslateVSyncMode(VkPresentModeKHR mode,
|
const QString TranslateVSyncMode(VkPresentModeKHR mode,
|
||||||
Settings::RendererBackend backend) const;
|
Settings::RendererBackend backend) const;
|
||||||
|
|
||||||
void SetupPerGameUI();
|
|
||||||
|
|
||||||
Settings::RendererBackend GetCurrentGraphicsBackend() const;
|
Settings::RendererBackend GetCurrentGraphicsBackend() const;
|
||||||
Settings::NvdecEmulation GetCurrentNvdecEmulation() const;
|
|
||||||
|
int FindIndex(u32 enumeration, int value) const;
|
||||||
|
|
||||||
std::unique_ptr<Ui::ConfigureGraphics> ui;
|
std::unique_ptr<Ui::ConfigureGraphics> ui;
|
||||||
QColor bg_color;
|
QColor bg_color;
|
||||||
|
|
||||||
ConfigurationShared::CheckState use_nvdec_emulation;
|
std::vector<std::function<void(bool)>> apply_funcs{};
|
||||||
ConfigurationShared::CheckState accelerate_astc;
|
|
||||||
ConfigurationShared::CheckState use_disk_shader_cache;
|
|
||||||
ConfigurationShared::CheckState use_asynchronous_gpu_emulation;
|
|
||||||
|
|
||||||
std::vector<VkDeviceInfo::Record>& records;
|
std::vector<VkDeviceInfo::Record>& records;
|
||||||
std::vector<QString> vulkan_devices;
|
std::vector<QString> vulkan_devices;
|
||||||
std::vector<std::vector<VkPresentModeKHR>> device_present_modes;
|
std::vector<std::vector<VkPresentModeKHR>> device_present_modes;
|
||||||
std::vector<VkPresentModeKHR>
|
std::vector<VkPresentModeKHR>
|
||||||
vsync_mode_combobox_enum_map; //< Keeps track of which present mode corresponds to which
|
vsync_mode_combobox_enum_map{}; //< Keeps track of which present mode corresponds to which
|
||||||
// selection in the combobox
|
// selection in the combobox
|
||||||
u32 vulkan_device{};
|
u32 vulkan_device{};
|
||||||
Settings::ShaderBackend shader_backend{};
|
Settings::ShaderBackend shader_backend{};
|
||||||
const std::function<void()>& expose_compute_option;
|
const std::function<void()>& expose_compute_option;
|
||||||
|
|
||||||
const Core::System& system;
|
const Core::System& system;
|
||||||
|
const ConfigurationShared::ComboboxTranslationMap& combobox_translations;
|
||||||
|
const std::vector<std::pair<u32, QString>>& shader_mapping;
|
||||||
|
|
||||||
|
QPushButton* api_restore_global_button;
|
||||||
|
QComboBox* vulkan_device_combobox;
|
||||||
|
QComboBox* api_combobox;
|
||||||
|
QComboBox* shader_backend_combobox;
|
||||||
|
QComboBox* vsync_mode_combobox;
|
||||||
|
QWidget* vulkan_device_widget;
|
||||||
|
QWidget* api_widget;
|
||||||
|
QWidget* shader_backend_widget;
|
||||||
};
|
};
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QWidget" name="api_widget" native="true">
|
<widget class="QWidget" name="api_widget" native="true">
|
||||||
<layout class="QGridLayout" name="gridLayout">
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
<property name="leftMargin">
|
<property name="leftMargin">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
|
@ -40,115 +40,6 @@
|
||||||
<property name="bottomMargin">
|
<property name="bottomMargin">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="horizontalSpacing">
|
|
||||||
<number>6</number>
|
|
||||||
</property>
|
|
||||||
<item row="4" column="0">
|
|
||||||
<widget class="QWidget" name="backend_widget" native="true">
|
|
||||||
<layout class="QHBoxLayout" name="backend_layout">
|
|
||||||
<property name="leftMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="topMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="rightMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="bottomMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="backend_label">
|
|
||||||
<property name="text">
|
|
||||||
<string>Shader Backend:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QComboBox" name="backend"/>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="0">
|
|
||||||
<widget class="QWidget" name="device_widget" native="true">
|
|
||||||
<layout class="QHBoxLayout" name="device_layout">
|
|
||||||
<property name="leftMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="topMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="rightMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="bottomMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="device_label">
|
|
||||||
<property name="text">
|
|
||||||
<string>Device:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QComboBox" name="device"/>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="0">
|
|
||||||
<widget class="QWidget" name="api_layout_2" native="true">
|
|
||||||
<layout class="QHBoxLayout" name="api_layout">
|
|
||||||
<property name="leftMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="topMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="rightMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="bottomMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="api_label">
|
|
||||||
<property name="text">
|
|
||||||
<string>API:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QComboBox" name="api">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string notr="true">OpenGL</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string notr="true">Vulkan</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>None</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
@ -168,29 +59,26 @@
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QCheckBox" name="use_disk_shader_cache">
|
<widget class="QWidget" name="graphics_widget" native="true">
|
||||||
<property name="text">
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
<string>Use disk pipeline cache</string>
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QCheckBox" name="use_asynchronous_gpu_emulation">
|
<widget class="QWidget" name="bg_widget" native="true">
|
||||||
<property name="text">
|
<layout class="QHBoxLayout" name="bg_layout">
|
||||||
<string>Use asynchronous GPU emulation</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QCheckBox" name="accelerate_astc">
|
|
||||||
<property name="text">
|
|
||||||
<string>Accelerate ASTC texture decoding</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QWidget" name="vsync_mode_layout" native="true">
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
|
||||||
<property name="leftMargin">
|
<property name="leftMargin">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
|
@ -204,573 +92,35 @@
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="vsync_mode_label">
|
<widget class="QLabel" name="label">
|
||||||
<property name="text">
|
|
||||||
<string>VSync Mode:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QComboBox" name="vsync_mode_combobox">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>FIFO (VSync) does not drop frames or exhibit tearing but is limited by the screen refresh rate.
|
|
||||||
FIFO Relaxed is similar to FIFO but allows tearing as it recovers from a slow down.
|
|
||||||
Mailbox can have lower latency than FIFO and does not tear but may drop frames.
|
|
||||||
Immediate (no synchronization) just presents whatever is available and can exhibit tearing.</string>
|
|
||||||
</property>
|
|
||||||
<property name="currentText">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QWidget" name="nvdec_emulation_widget" native="true">
|
|
||||||
<layout class="QHBoxLayout" name="nvdec_emulation_layout">
|
|
||||||
<property name="leftMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="topMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="rightMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="bottomMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="nvdec_emulation_label">
|
|
||||||
<property name="text">
|
|
||||||
<string>NVDEC emulation:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QComboBox" name="nvdec_emulation">
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>No Video Output</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>CPU Video Decoding</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>GPU Video Decoding (Default)</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QWidget" name="fullscreen_mode_layout" native="true">
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_1">
|
|
||||||
<property name="leftMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="topMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="rightMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="bottomMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="fullscreen_mode_label">
|
|
||||||
<property name="text">
|
|
||||||
<string>Fullscreen Mode:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QComboBox" name="fullscreen_mode_combobox">
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Borderless Windowed</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Exclusive Fullscreen</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QWidget" name="aspect_ratio_layout" native="true">
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
|
||||||
<property name="leftMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="topMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="rightMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="bottomMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="ar_label">
|
|
||||||
<property name="text">
|
|
||||||
<string>Aspect Ratio:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QComboBox" name="aspect_ratio_combobox">
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Default (16:9)</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Force 4:3</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Force 21:9</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Force 16:10</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Stretch to Window</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QWidget" name="resolution_layout" native="true">
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
|
||||||
<property name="leftMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="topMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="rightMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="bottomMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="resolution_label">
|
|
||||||
<property name="text">
|
|
||||||
<string>Resolution:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QComboBox" name="resolution_combobox">
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>0.5X (360p/540p) [EXPERIMENTAL]</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>0.75X (540p/810p) [EXPERIMENTAL]</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>1X (720p/1080p)</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>1.5X (1080p/1620p) [EXPERIMENTAL]</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>2X (1440p/2160p)</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>3X (2160p/3240p)</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>4X (2880p/4320p)</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>5X (3600p/5400p)</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>6X (4320p/6480p)</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>7X (5040p/7560p)</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>8X (5760p/8640p)</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QWidget" name="scaling_filter_layout" native="true">
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_6">
|
|
||||||
<property name="leftMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="topMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="rightMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="bottomMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="scaling_filter_label">
|
|
||||||
<property name="text">
|
|
||||||
<string>Window Adapting Filter:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QComboBox" name="scaling_filter_combobox">
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Nearest Neighbor</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Bilinear</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Bicubic</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Gaussian</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>ScaleForce</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>AMD FidelityFX™️ Super Resolution</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QWidget" name="anti_aliasing_layout" native="true">
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_7">
|
|
||||||
<property name="leftMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="topMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="rightMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="bottomMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="anti_aliasing_label">
|
|
||||||
<property name="text">
|
|
||||||
<string>Anti-Aliasing Method:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QComboBox" name="anti_aliasing_combobox">
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>None</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>FXAA</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>SMAA</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QWidget" name="fsr_sharpening_layout" native="true">
|
|
||||||
<property name="enabled">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||||
<horstretch>0</horstretch>
|
<horstretch>0</horstretch>
|
||||||
<verstretch>0</verstretch>
|
<verstretch>0</verstretch>
|
||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
|
||||||
<property name="spacing">
|
|
||||||
<number>6</number>
|
|
||||||
</property>
|
|
||||||
<property name="sizeConstraint">
|
|
||||||
<enum>QLayout::SetDefaultConstraint</enum>
|
|
||||||
</property>
|
|
||||||
<property name="leftMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="topMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="rightMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="bottomMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<layout class="QHBoxLayout" name="fsr_sharpening_label_group">
|
|
||||||
<property name="rightMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="bottomMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<widget class="QComboBox" name="fsr_sharpening_combobox">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Use global FSR Sharpness</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Set FSR Sharpness</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="fsr_sharpening_label">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>FSR Sharpness:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<spacer name="horizontalSpacer_2">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>40</width>
|
|
||||||
<height>20</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<layout class="QHBoxLayout" name="fsr_slider_layout">
|
|
||||||
<property name="spacing">
|
|
||||||
<number>6</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<widget class="QSlider" name="fsr_sharpening_slider">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="baseSize">
|
|
||||||
<size>
|
|
||||||
<width>0</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="maximum">
|
|
||||||
<number>200</number>
|
|
||||||
</property>
|
|
||||||
<property name="sliderPosition">
|
|
||||||
<number>25</number>
|
|
||||||
</property>
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="invertedAppearance">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="fsr_sharpening_value">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>32</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>100%</string>
|
|
||||||
</property>
|
|
||||||
<property name="alignment">
|
|
||||||
<set>Qt::AlignCenter</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QWidget" name="bg_layout" native="true">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
|
||||||
<property name="spacing">
|
|
||||||
<number>6</number>
|
|
||||||
</property>
|
|
||||||
<property name="leftMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="topMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="rightMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="bottomMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<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">
|
<property name="text">
|
||||||
<string>Background Color:</string>
|
<string>Background Color:</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</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>
|
<item>
|
||||||
<widget class="QPushButton" name="bg_button">
|
<widget class="QPushButton" name="bg_button">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
<property name="maximumSize">
|
<property name="maximumSize">
|
||||||
<size>
|
<size>
|
||||||
<width>40</width>
|
<width>40</width>
|
||||||
<height>16777215</height>
|
<height>16777215</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
|
|
|
@ -1,104 +1,68 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <qnamespace.h>
|
||||||
#include "common/settings.h"
|
#include "common/settings.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "ui_configure_graphics_advanced.h"
|
#include "ui_configure_graphics_advanced.h"
|
||||||
#include "yuzu/configuration/configuration_shared.h"
|
#include "yuzu/configuration/configuration_shared.h"
|
||||||
#include "yuzu/configuration/configure_graphics_advanced.h"
|
#include "yuzu/configuration/configure_graphics_advanced.h"
|
||||||
|
#include "yuzu/configuration/shared_translation.h"
|
||||||
|
#include "yuzu/configuration/shared_widget.h"
|
||||||
|
|
||||||
ConfigureGraphicsAdvanced::ConfigureGraphicsAdvanced(const Core::System& system_, QWidget* parent)
|
ConfigureGraphicsAdvanced::ConfigureGraphicsAdvanced(
|
||||||
: QWidget(parent), ui{std::make_unique<Ui::ConfigureGraphicsAdvanced>()}, system{system_} {
|
const Core::System& system_, std::shared_ptr<std::vector<ConfigurationShared::Tab*>> group_,
|
||||||
|
const ConfigurationShared::Builder& builder, QWidget* parent)
|
||||||
|
: Tab(group_, parent), ui{std::make_unique<Ui::ConfigureGraphicsAdvanced>()}, system{system_} {
|
||||||
|
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
|
||||||
SetupPerGameUI();
|
Setup(builder);
|
||||||
|
|
||||||
SetConfiguration();
|
SetConfiguration();
|
||||||
|
|
||||||
ui->enable_compute_pipelines_checkbox->setVisible(false);
|
checkbox_enable_compute_pipelines->setVisible(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
ConfigureGraphicsAdvanced::~ConfigureGraphicsAdvanced() = default;
|
ConfigureGraphicsAdvanced::~ConfigureGraphicsAdvanced() = default;
|
||||||
|
|
||||||
void ConfigureGraphicsAdvanced::SetConfiguration() {
|
void ConfigureGraphicsAdvanced::SetConfiguration() {}
|
||||||
const bool runtime_lock = !system.IsPoweredOn();
|
|
||||||
ui->use_reactive_flushing->setEnabled(runtime_lock);
|
|
||||||
ui->async_present->setEnabled(runtime_lock);
|
|
||||||
ui->renderer_force_max_clock->setEnabled(runtime_lock);
|
|
||||||
ui->async_astc->setEnabled(runtime_lock);
|
|
||||||
ui->astc_recompression_combobox->setEnabled(runtime_lock);
|
|
||||||
ui->use_asynchronous_shaders->setEnabled(runtime_lock);
|
|
||||||
ui->anisotropic_filtering_combobox->setEnabled(runtime_lock);
|
|
||||||
ui->enable_compute_pipelines_checkbox->setEnabled(runtime_lock);
|
|
||||||
|
|
||||||
ui->async_present->setChecked(Settings::values.async_presentation.GetValue());
|
void ConfigureGraphicsAdvanced::Setup(const ConfigurationShared::Builder& builder) {
|
||||||
ui->renderer_force_max_clock->setChecked(Settings::values.renderer_force_max_clock.GetValue());
|
auto& layout = *ui->populate_target->layout();
|
||||||
ui->use_reactive_flushing->setChecked(Settings::values.use_reactive_flushing.GetValue());
|
std::map<u32, QWidget*> hold{}; // A map will sort the data for us
|
||||||
ui->async_astc->setChecked(Settings::values.async_astc.GetValue());
|
|
||||||
ui->use_asynchronous_shaders->setChecked(Settings::values.use_asynchronous_shaders.GetValue());
|
|
||||||
ui->use_fast_gpu_time->setChecked(Settings::values.use_fast_gpu_time.GetValue());
|
|
||||||
ui->use_vulkan_driver_pipeline_cache->setChecked(
|
|
||||||
Settings::values.use_vulkan_driver_pipeline_cache.GetValue());
|
|
||||||
ui->enable_compute_pipelines_checkbox->setChecked(
|
|
||||||
Settings::values.enable_compute_pipelines.GetValue());
|
|
||||||
ui->use_video_framerate_checkbox->setChecked(Settings::values.use_video_framerate.GetValue());
|
|
||||||
ui->barrier_feedback_loops_checkbox->setChecked(
|
|
||||||
Settings::values.barrier_feedback_loops.GetValue());
|
|
||||||
|
|
||||||
if (Settings::IsConfiguringGlobal()) {
|
for (auto setting :
|
||||||
ui->gpu_accuracy->setCurrentIndex(
|
Settings::values.linkage.by_category[Settings::Category::RendererAdvanced]) {
|
||||||
static_cast<int>(Settings::values.gpu_accuracy.GetValue()));
|
ConfigurationShared::Widget* widget = builder.BuildWidget(setting, apply_funcs);
|
||||||
ui->anisotropic_filtering_combobox->setCurrentIndex(
|
|
||||||
Settings::values.max_anisotropy.GetValue());
|
if (widget == nullptr) {
|
||||||
ui->astc_recompression_combobox->setCurrentIndex(
|
continue;
|
||||||
static_cast<int>(Settings::values.astc_recompression.GetValue()));
|
}
|
||||||
} else {
|
if (!widget->Valid()) {
|
||||||
ConfigurationShared::SetPerGameSetting(ui->gpu_accuracy, &Settings::values.gpu_accuracy);
|
widget->deleteLater();
|
||||||
ConfigurationShared::SetPerGameSetting(ui->anisotropic_filtering_combobox,
|
continue;
|
||||||
&Settings::values.max_anisotropy);
|
}
|
||||||
ConfigurationShared::SetPerGameSetting(ui->astc_recompression_combobox,
|
|
||||||
&Settings::values.astc_recompression);
|
hold.emplace(setting->Id(), widget);
|
||||||
ConfigurationShared::SetHighlight(ui->label_gpu_accuracy,
|
|
||||||
!Settings::values.gpu_accuracy.UsingGlobal());
|
// Keep track of enable_compute_pipelines so we can display it when needed
|
||||||
ConfigurationShared::SetHighlight(ui->af_label,
|
if (setting->Id() == Settings::values.enable_compute_pipelines.Id()) {
|
||||||
!Settings::values.max_anisotropy.UsingGlobal());
|
checkbox_enable_compute_pipelines = widget;
|
||||||
ConfigurationShared::SetHighlight(ui->label_astc_recompression,
|
}
|
||||||
!Settings::values.astc_recompression.UsingGlobal());
|
}
|
||||||
|
for (const auto& [id, widget] : hold) {
|
||||||
|
layout.addWidget(widget);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureGraphicsAdvanced::ApplyConfiguration() {
|
void ConfigureGraphicsAdvanced::ApplyConfiguration() {
|
||||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.gpu_accuracy, ui->gpu_accuracy);
|
const bool is_powered_on = system.IsPoweredOn();
|
||||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.async_presentation,
|
for (const auto& func : apply_funcs) {
|
||||||
ui->async_present, async_present);
|
func(is_powered_on);
|
||||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.renderer_force_max_clock,
|
}
|
||||||
ui->renderer_force_max_clock,
|
|
||||||
renderer_force_max_clock);
|
|
||||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.max_anisotropy,
|
|
||||||
ui->anisotropic_filtering_combobox);
|
|
||||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_reactive_flushing,
|
|
||||||
ui->use_reactive_flushing, use_reactive_flushing);
|
|
||||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.async_astc, ui->async_astc,
|
|
||||||
async_astc);
|
|
||||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.astc_recompression,
|
|
||||||
ui->astc_recompression_combobox);
|
|
||||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_asynchronous_shaders,
|
|
||||||
ui->use_asynchronous_shaders,
|
|
||||||
use_asynchronous_shaders);
|
|
||||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_fast_gpu_time,
|
|
||||||
ui->use_fast_gpu_time, use_fast_gpu_time);
|
|
||||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_vulkan_driver_pipeline_cache,
|
|
||||||
ui->use_vulkan_driver_pipeline_cache,
|
|
||||||
use_vulkan_driver_pipeline_cache);
|
|
||||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.enable_compute_pipelines,
|
|
||||||
ui->enable_compute_pipelines_checkbox,
|
|
||||||
enable_compute_pipelines);
|
|
||||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_video_framerate,
|
|
||||||
ui->use_video_framerate_checkbox, use_video_framerate);
|
|
||||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.barrier_feedback_loops,
|
|
||||||
ui->barrier_feedback_loops_checkbox,
|
|
||||||
barrier_feedback_loops);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureGraphicsAdvanced::changeEvent(QEvent* event) {
|
void ConfigureGraphicsAdvanced::changeEvent(QEvent* event) {
|
||||||
|
@ -113,71 +77,6 @@ void ConfigureGraphicsAdvanced::RetranslateUI() {
|
||||||
ui->retranslateUi(this);
|
ui->retranslateUi(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureGraphicsAdvanced::SetupPerGameUI() {
|
|
||||||
// Disable if not global (only happens during game)
|
|
||||||
if (Settings::IsConfiguringGlobal()) {
|
|
||||||
ui->gpu_accuracy->setEnabled(Settings::values.gpu_accuracy.UsingGlobal());
|
|
||||||
ui->async_present->setEnabled(Settings::values.async_presentation.UsingGlobal());
|
|
||||||
ui->renderer_force_max_clock->setEnabled(
|
|
||||||
Settings::values.renderer_force_max_clock.UsingGlobal());
|
|
||||||
ui->use_reactive_flushing->setEnabled(Settings::values.use_reactive_flushing.UsingGlobal());
|
|
||||||
ui->async_astc->setEnabled(Settings::values.async_astc.UsingGlobal());
|
|
||||||
ui->astc_recompression_combobox->setEnabled(
|
|
||||||
Settings::values.astc_recompression.UsingGlobal());
|
|
||||||
ui->use_asynchronous_shaders->setEnabled(
|
|
||||||
Settings::values.use_asynchronous_shaders.UsingGlobal());
|
|
||||||
ui->use_fast_gpu_time->setEnabled(Settings::values.use_fast_gpu_time.UsingGlobal());
|
|
||||||
ui->use_vulkan_driver_pipeline_cache->setEnabled(
|
|
||||||
Settings::values.use_vulkan_driver_pipeline_cache.UsingGlobal());
|
|
||||||
ui->anisotropic_filtering_combobox->setEnabled(
|
|
||||||
Settings::values.max_anisotropy.UsingGlobal());
|
|
||||||
ui->enable_compute_pipelines_checkbox->setEnabled(
|
|
||||||
Settings::values.enable_compute_pipelines.UsingGlobal());
|
|
||||||
ui->use_video_framerate_checkbox->setEnabled(
|
|
||||||
Settings::values.use_video_framerate.UsingGlobal());
|
|
||||||
ui->barrier_feedback_loops_checkbox->setEnabled(
|
|
||||||
Settings::values.barrier_feedback_loops.UsingGlobal());
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ConfigurationShared::SetColoredTristate(ui->async_present, Settings::values.async_presentation,
|
|
||||||
async_present);
|
|
||||||
ConfigurationShared::SetColoredTristate(ui->renderer_force_max_clock,
|
|
||||||
Settings::values.renderer_force_max_clock,
|
|
||||||
renderer_force_max_clock);
|
|
||||||
ConfigurationShared::SetColoredTristate(
|
|
||||||
ui->use_reactive_flushing, Settings::values.use_reactive_flushing, use_reactive_flushing);
|
|
||||||
ConfigurationShared::SetColoredTristate(ui->async_astc, Settings::values.async_astc,
|
|
||||||
async_astc);
|
|
||||||
ConfigurationShared::SetColoredTristate(ui->use_asynchronous_shaders,
|
|
||||||
Settings::values.use_asynchronous_shaders,
|
|
||||||
use_asynchronous_shaders);
|
|
||||||
ConfigurationShared::SetColoredTristate(ui->use_fast_gpu_time,
|
|
||||||
Settings::values.use_fast_gpu_time, use_fast_gpu_time);
|
|
||||||
ConfigurationShared::SetColoredTristate(ui->use_vulkan_driver_pipeline_cache,
|
|
||||||
Settings::values.use_vulkan_driver_pipeline_cache,
|
|
||||||
use_vulkan_driver_pipeline_cache);
|
|
||||||
ConfigurationShared::SetColoredTristate(ui->enable_compute_pipelines_checkbox,
|
|
||||||
Settings::values.enable_compute_pipelines,
|
|
||||||
enable_compute_pipelines);
|
|
||||||
ConfigurationShared::SetColoredTristate(ui->use_video_framerate_checkbox,
|
|
||||||
Settings::values.use_video_framerate,
|
|
||||||
use_video_framerate);
|
|
||||||
ConfigurationShared::SetColoredTristate(ui->barrier_feedback_loops_checkbox,
|
|
||||||
Settings::values.barrier_feedback_loops,
|
|
||||||
barrier_feedback_loops);
|
|
||||||
ConfigurationShared::SetColoredComboBox(
|
|
||||||
ui->gpu_accuracy, ui->label_gpu_accuracy,
|
|
||||||
static_cast<int>(Settings::values.gpu_accuracy.GetValue(true)));
|
|
||||||
ConfigurationShared::SetColoredComboBox(
|
|
||||||
ui->anisotropic_filtering_combobox, ui->af_label,
|
|
||||||
static_cast<int>(Settings::values.max_anisotropy.GetValue(true)));
|
|
||||||
ConfigurationShared::SetColoredComboBox(
|
|
||||||
ui->astc_recompression_combobox, ui->label_astc_recompression,
|
|
||||||
static_cast<int>(Settings::values.astc_recompression.GetValue(true)));
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConfigureGraphicsAdvanced::ExposeComputeOption() {
|
void ConfigureGraphicsAdvanced::ExposeComputeOption() {
|
||||||
ui->enable_compute_pipelines_checkbox->setVisible(true);
|
checkbox_enable_compute_pipelines->setVisible(true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,51 +4,44 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
#include "yuzu/configuration/configuration_shared.h"
|
||||||
|
|
||||||
namespace Core {
|
namespace Core {
|
||||||
class System;
|
class System;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace ConfigurationShared {
|
|
||||||
enum class CheckState;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class ConfigureGraphicsAdvanced;
|
class ConfigureGraphicsAdvanced;
|
||||||
}
|
}
|
||||||
|
|
||||||
class ConfigureGraphicsAdvanced : public QWidget {
|
namespace ConfigurationShared {
|
||||||
Q_OBJECT
|
class Builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
class ConfigureGraphicsAdvanced : public ConfigurationShared::Tab {
|
||||||
public:
|
public:
|
||||||
explicit ConfigureGraphicsAdvanced(const Core::System& system_, QWidget* parent = nullptr);
|
explicit ConfigureGraphicsAdvanced(
|
||||||
|
const Core::System& system_, std::shared_ptr<std::vector<ConfigurationShared::Tab*>> group,
|
||||||
|
const ConfigurationShared::Builder& builder, QWidget* parent = nullptr);
|
||||||
~ConfigureGraphicsAdvanced() override;
|
~ConfigureGraphicsAdvanced() override;
|
||||||
|
|
||||||
void ApplyConfiguration();
|
void ApplyConfiguration() override;
|
||||||
void SetConfiguration();
|
void SetConfiguration() override;
|
||||||
|
|
||||||
void ExposeComputeOption();
|
void ExposeComputeOption();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void Setup(const ConfigurationShared::Builder& builder);
|
||||||
void changeEvent(QEvent* event) override;
|
void changeEvent(QEvent* event) override;
|
||||||
void RetranslateUI();
|
void RetranslateUI();
|
||||||
|
|
||||||
void SetupPerGameUI();
|
|
||||||
|
|
||||||
std::unique_ptr<Ui::ConfigureGraphicsAdvanced> ui;
|
std::unique_ptr<Ui::ConfigureGraphicsAdvanced> ui;
|
||||||
|
|
||||||
ConfigurationShared::CheckState async_present;
|
|
||||||
ConfigurationShared::CheckState renderer_force_max_clock;
|
|
||||||
ConfigurationShared::CheckState use_vsync;
|
|
||||||
ConfigurationShared::CheckState async_astc;
|
|
||||||
ConfigurationShared::CheckState use_reactive_flushing;
|
|
||||||
ConfigurationShared::CheckState use_asynchronous_shaders;
|
|
||||||
ConfigurationShared::CheckState use_fast_gpu_time;
|
|
||||||
ConfigurationShared::CheckState use_vulkan_driver_pipeline_cache;
|
|
||||||
ConfigurationShared::CheckState enable_compute_pipelines;
|
|
||||||
ConfigurationShared::CheckState use_video_framerate;
|
|
||||||
ConfigurationShared::CheckState barrier_feedback_loops;
|
|
||||||
|
|
||||||
const Core::System& system;
|
const Core::System& system;
|
||||||
|
|
||||||
|
std::vector<std::function<void(bool)>> apply_funcs;
|
||||||
|
|
||||||
|
QWidget* checkbox_enable_compute_pipelines{};
|
||||||
};
|
};
|
||||||
|
|
|
@ -26,8 +26,8 @@
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QWidget" name="gpu_accuracy_layout" native="true">
|
<widget class="QWidget" name="populate_target" native="true">
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
<property name="leftMargin">
|
<property name="leftMargin">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
|
@ -40,233 +40,6 @@
|
||||||
<property name="bottomMargin">
|
<property name="bottomMargin">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="label_gpu_accuracy">
|
|
||||||
<property name="text">
|
|
||||||
<string>Accuracy Level:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QComboBox" name="gpu_accuracy">
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string notr="true">Normal</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string notr="true">High</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string notr="true">Extreme(very slow)</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QWidget" name="astc_recompression_layout" native="true">
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
|
||||||
<property name="leftMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="topMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="rightMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="bottomMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="label_astc_recompression">
|
|
||||||
<property name="text">
|
|
||||||
<string>ASTC recompression:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QComboBox" name="astc_recompression_combobox">
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Uncompressed (Best quality)</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>BC1 (Low quality)</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>BC3 (Medium quality)</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QCheckBox" name="async_present">
|
|
||||||
<property name="text">
|
|
||||||
<string>Enable asynchronous presentation (Vulkan only)</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QCheckBox" name="renderer_force_max_clock">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>Runs work in the background while waiting for graphics commands to keep the GPU from lowering its clock speed.</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Force maximum clocks (Vulkan only)</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QCheckBox" name="async_astc">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>Enables asynchronous ASTC texture decoding, which may reduce load time stutter. This feature is experimental.</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Decode ASTC textures asynchronously (Hack)</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QCheckBox" name="use_reactive_flushing">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>Uses reactive flushing instead of predictive flushing. Allowing a more accurate syncing of memory.</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Enable Reactive Flushing</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QCheckBox" name="use_asynchronous_shaders">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>Enables asynchronous shader compilation, which may reduce shader stutter. This feature is experimental.</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Use asynchronous shader building (Hack)</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QCheckBox" name="use_fast_gpu_time">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>Enables Fast GPU Time. This option will force most games to run at their highest native resolution.</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Use Fast GPU Time (Hack)</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QCheckBox" name="use_vulkan_driver_pipeline_cache">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>Enables GPU vendor-specific pipeline cache. This option can improve shader loading time significantly in cases where the Vulkan driver does not store pipeline cache files internally.</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Use Vulkan pipeline cache</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QCheckBox" name="enable_compute_pipelines_checkbox">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>Enable compute pipelines, required by some games. This setting only exists for Intel proprietary drivers, and may crash if enabled.
|
|
||||||
Compute pipelines are always enabled on all other drivers.</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Enable Compute Pipelines (Intel Vulkan only)</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QCheckBox" name="use_video_framerate_checkbox">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>Run the game at normal speed during video playback, even when the framerate is unlocked.</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Sync to framerate of video playback</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QCheckBox" name="barrier_feedback_loops_checkbox">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>Improves rendering of transparency effects in specific games.</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Barrier feedback loops</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QWidget" name="af_layout" native="true">
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_1">
|
|
||||||
<property name="leftMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="topMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="rightMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="bottomMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="af_label">
|
|
||||||
<property name="text">
|
|
||||||
<string>Anisotropic Filtering:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QComboBox" name="anisotropic_filtering_combobox">
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Automatic</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Default</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>2x</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>4x</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>8x</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>16x</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
|
||||||
#include "common/fs/fs_util.h"
|
#include "common/fs/fs_util.h"
|
||||||
|
#include "configuration/shared_widget.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "core/file_sys/control_metadata.h"
|
#include "core/file_sys/control_metadata.h"
|
||||||
#include "core/file_sys/patch_manager.h"
|
#include "core/file_sys/patch_manager.h"
|
||||||
|
@ -24,9 +25,9 @@
|
||||||
#include "core/loader/loader.h"
|
#include "core/loader/loader.h"
|
||||||
#include "ui_configure_per_game.h"
|
#include "ui_configure_per_game.h"
|
||||||
#include "yuzu/configuration/config.h"
|
#include "yuzu/configuration/config.h"
|
||||||
|
#include "yuzu/configuration/configuration_shared.h"
|
||||||
#include "yuzu/configuration/configure_audio.h"
|
#include "yuzu/configuration/configure_audio.h"
|
||||||
#include "yuzu/configuration/configure_cpu.h"
|
#include "yuzu/configuration/configure_cpu.h"
|
||||||
#include "yuzu/configuration/configure_general.h"
|
|
||||||
#include "yuzu/configuration/configure_graphics.h"
|
#include "yuzu/configuration/configure_graphics.h"
|
||||||
#include "yuzu/configuration/configure_graphics_advanced.h"
|
#include "yuzu/configuration/configure_graphics_advanced.h"
|
||||||
#include "yuzu/configuration/configure_input_per_game.h"
|
#include "yuzu/configuration/configure_input_per_game.h"
|
||||||
|
@ -41,26 +42,28 @@ ConfigurePerGame::ConfigurePerGame(QWidget* parent, u64 title_id_, const std::st
|
||||||
std::vector<VkDeviceInfo::Record>& vk_device_records,
|
std::vector<VkDeviceInfo::Record>& vk_device_records,
|
||||||
Core::System& system_)
|
Core::System& system_)
|
||||||
: QDialog(parent),
|
: QDialog(parent),
|
||||||
ui(std::make_unique<Ui::ConfigurePerGame>()), title_id{title_id_}, system{system_} {
|
ui(std::make_unique<Ui::ConfigurePerGame>()), title_id{title_id_}, system{system_},
|
||||||
|
builder{std::make_unique<ConfigurationShared::Builder>(this, !system_.IsPoweredOn())},
|
||||||
|
tab_group{std::make_shared<std::vector<ConfigurationShared::Tab*>>()} {
|
||||||
const auto file_path = std::filesystem::path(Common::FS::ToU8String(file_name));
|
const auto file_path = std::filesystem::path(Common::FS::ToU8String(file_name));
|
||||||
const auto config_file_name = title_id == 0 ? Common::FS::PathToUTF8String(file_path.filename())
|
const auto config_file_name = title_id == 0 ? Common::FS::PathToUTF8String(file_path.filename())
|
||||||
: fmt::format("{:016X}", title_id);
|
: fmt::format("{:016X}", title_id);
|
||||||
game_config = std::make_unique<Config>(config_file_name, Config::ConfigType::PerGameConfig);
|
game_config = std::make_unique<Config>(config_file_name, Config::ConfigType::PerGameConfig);
|
||||||
|
|
||||||
addons_tab = std::make_unique<ConfigurePerGameAddons>(system_, this);
|
addons_tab = std::make_unique<ConfigurePerGameAddons>(system_, this);
|
||||||
audio_tab = std::make_unique<ConfigureAudio>(system_, this);
|
audio_tab = std::make_unique<ConfigureAudio>(system_, tab_group, *builder, this);
|
||||||
cpu_tab = std::make_unique<ConfigureCpu>(system_, this);
|
cpu_tab = std::make_unique<ConfigureCpu>(system_, tab_group, *builder, this);
|
||||||
general_tab = std::make_unique<ConfigureGeneral>(system_, this);
|
graphics_advanced_tab =
|
||||||
graphics_advanced_tab = std::make_unique<ConfigureGraphicsAdvanced>(system_, this);
|
std::make_unique<ConfigureGraphicsAdvanced>(system_, tab_group, *builder, this);
|
||||||
graphics_tab = std::make_unique<ConfigureGraphics>(
|
graphics_tab = std::make_unique<ConfigureGraphics>(
|
||||||
system_, vk_device_records, [&]() { graphics_advanced_tab->ExposeComputeOption(); }, this);
|
system_, vk_device_records, [&]() { graphics_advanced_tab->ExposeComputeOption(); },
|
||||||
|
tab_group, *builder, this);
|
||||||
input_tab = std::make_unique<ConfigureInputPerGame>(system_, game_config.get(), this);
|
input_tab = std::make_unique<ConfigureInputPerGame>(system_, game_config.get(), this);
|
||||||
system_tab = std::make_unique<ConfigureSystem>(system_, this);
|
system_tab = std::make_unique<ConfigureSystem>(system_, tab_group, *builder, this);
|
||||||
|
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
|
||||||
ui->tabWidget->addTab(addons_tab.get(), tr("Add-Ons"));
|
ui->tabWidget->addTab(addons_tab.get(), tr("Add-Ons"));
|
||||||
ui->tabWidget->addTab(general_tab.get(), tr("General"));
|
|
||||||
ui->tabWidget->addTab(system_tab.get(), tr("System"));
|
ui->tabWidget->addTab(system_tab.get(), tr("System"));
|
||||||
ui->tabWidget->addTab(cpu_tab.get(), tr("CPU"));
|
ui->tabWidget->addTab(cpu_tab.get(), tr("CPU"));
|
||||||
ui->tabWidget->addTab(graphics_tab.get(), tr("Graphics"));
|
ui->tabWidget->addTab(graphics_tab.get(), tr("Graphics"));
|
||||||
|
@ -88,13 +91,10 @@ ConfigurePerGame::ConfigurePerGame(QWidget* parent, u64 title_id_, const std::st
|
||||||
ConfigurePerGame::~ConfigurePerGame() = default;
|
ConfigurePerGame::~ConfigurePerGame() = default;
|
||||||
|
|
||||||
void ConfigurePerGame::ApplyConfiguration() {
|
void ConfigurePerGame::ApplyConfiguration() {
|
||||||
|
for (const auto tab : *tab_group) {
|
||||||
|
tab->ApplyConfiguration();
|
||||||
|
}
|
||||||
addons_tab->ApplyConfiguration();
|
addons_tab->ApplyConfiguration();
|
||||||
general_tab->ApplyConfiguration();
|
|
||||||
cpu_tab->ApplyConfiguration();
|
|
||||||
system_tab->ApplyConfiguration();
|
|
||||||
graphics_tab->ApplyConfiguration();
|
|
||||||
graphics_advanced_tab->ApplyConfiguration();
|
|
||||||
audio_tab->ApplyConfiguration();
|
|
||||||
input_tab->ApplyConfiguration();
|
input_tab->ApplyConfiguration();
|
||||||
|
|
||||||
system.ApplySettings();
|
system.ApplySettings();
|
||||||
|
|
|
@ -10,9 +10,12 @@
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
#include <QList>
|
#include <QList>
|
||||||
|
|
||||||
|
#include "configuration/shared_widget.h"
|
||||||
#include "core/file_sys/vfs_types.h"
|
#include "core/file_sys/vfs_types.h"
|
||||||
#include "vk_device_info.h"
|
#include "vk_device_info.h"
|
||||||
#include "yuzu/configuration/config.h"
|
#include "yuzu/configuration/config.h"
|
||||||
|
#include "yuzu/configuration/configuration_shared.h"
|
||||||
|
#include "yuzu/configuration/shared_translation.h"
|
||||||
|
|
||||||
namespace Core {
|
namespace Core {
|
||||||
class System;
|
class System;
|
||||||
|
@ -25,7 +28,6 @@ class InputSubsystem;
|
||||||
class ConfigurePerGameAddons;
|
class ConfigurePerGameAddons;
|
||||||
class ConfigureAudio;
|
class ConfigureAudio;
|
||||||
class ConfigureCpu;
|
class ConfigureCpu;
|
||||||
class ConfigureGeneral;
|
|
||||||
class ConfigureGraphics;
|
class ConfigureGraphics;
|
||||||
class ConfigureGraphicsAdvanced;
|
class ConfigureGraphicsAdvanced;
|
||||||
class ConfigureInputPerGame;
|
class ConfigureInputPerGame;
|
||||||
|
@ -73,11 +75,12 @@ private:
|
||||||
std::unique_ptr<Config> game_config;
|
std::unique_ptr<Config> game_config;
|
||||||
|
|
||||||
Core::System& system;
|
Core::System& system;
|
||||||
|
std::unique_ptr<ConfigurationShared::Builder> builder;
|
||||||
|
std::shared_ptr<std::vector<ConfigurationShared::Tab*>> tab_group;
|
||||||
|
|
||||||
std::unique_ptr<ConfigurePerGameAddons> addons_tab;
|
std::unique_ptr<ConfigurePerGameAddons> addons_tab;
|
||||||
std::unique_ptr<ConfigureAudio> audio_tab;
|
std::unique_ptr<ConfigureAudio> audio_tab;
|
||||||
std::unique_ptr<ConfigureCpu> cpu_tab;
|
std::unique_ptr<ConfigureCpu> cpu_tab;
|
||||||
std::unique_ptr<ConfigureGeneral> general_tab;
|
|
||||||
std::unique_ptr<ConfigureGraphicsAdvanced> graphics_advanced_tab;
|
std::unique_ptr<ConfigureGraphicsAdvanced> graphics_advanced_tab;
|
||||||
std::unique_ptr<ConfigureGraphics> graphics_tab;
|
std::unique_ptr<ConfigureGraphics> graphics_tab;
|
||||||
std::unique_ptr<ConfigureInputPerGame> input_tab;
|
std::unique_ptr<ConfigureInputPerGame> input_tab;
|
||||||
|
|
|
@ -2,6 +2,14 @@
|
||||||
<ui version="4.0">
|
<ui version="4.0">
|
||||||
<class>ConfigurePerGame</class>
|
<class>ConfigurePerGame</class>
|
||||||
<widget class="QDialog" name="ConfigurePerGame">
|
<widget class="QDialog" name="ConfigurePerGame">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>900</width>
|
||||||
|
<height>607</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
<property name="minimumSize">
|
<property name="minimumSize">
|
||||||
<size>
|
<size>
|
||||||
<width>900</width>
|
<width>900</width>
|
||||||
|
@ -224,6 +232,15 @@
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_8">
|
||||||
|
<property name="text">
|
||||||
|
<string>Some settings are only available when a game is not running.</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QDialogButtonBox" name="buttonBox">
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
|
@ -241,6 +258,8 @@
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<resources/>
|
<resources/>
|
||||||
<connections>
|
<connections>
|
||||||
|
|
|
@ -3,16 +3,23 @@
|
||||||
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <QCheckBox>
|
||||||
|
#include <QComboBox>
|
||||||
|
#include <QDateTimeEdit>
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
#include <QGraphicsItem>
|
#include <QGraphicsItem>
|
||||||
|
#include <QLineEdit>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include "common/settings.h"
|
#include "common/settings.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "core/hle/service/time/time_manager.h"
|
#include "core/hle/service/time/time_manager.h"
|
||||||
#include "ui_configure_system.h"
|
#include "ui_configure_system.h"
|
||||||
|
#include "yuzu/configuration/config.h"
|
||||||
#include "yuzu/configuration/configuration_shared.h"
|
#include "yuzu/configuration/configuration_shared.h"
|
||||||
#include "yuzu/configuration/configure_system.h"
|
#include "yuzu/configuration/configure_system.h"
|
||||||
|
#include "yuzu/configuration/shared_widget.h"
|
||||||
|
|
||||||
constexpr std::array<u32, 7> LOCALE_BLOCKLIST{
|
constexpr std::array<u32, 7> LOCALE_BLOCKLIST{
|
||||||
// pzzefezrpnkzeidfej
|
// pzzefezrpnkzeidfej
|
||||||
|
@ -37,44 +44,32 @@ static bool IsValidLocale(u32 region_index, u32 language_index) {
|
||||||
return ((LOCALE_BLOCKLIST.at(region_index) >> language_index) & 1) == 0;
|
return ((LOCALE_BLOCKLIST.at(region_index) >> language_index) & 1) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ConfigureSystem::ConfigureSystem(Core::System& system_, QWidget* parent)
|
ConfigureSystem::ConfigureSystem(Core::System& system_,
|
||||||
: QWidget(parent), ui{std::make_unique<Ui::ConfigureSystem>()}, system{system_} {
|
std::shared_ptr<std::vector<ConfigurationShared::Tab*>> group_,
|
||||||
|
const ConfigurationShared::Builder& builder, QWidget* parent)
|
||||||
|
: Tab(group_, parent), ui{std::make_unique<Ui::ConfigureSystem>()}, system{system_} {
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
|
||||||
connect(ui->rng_seed_checkbox, &QCheckBox::stateChanged, this, [this](int state) {
|
Setup(builder);
|
||||||
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](int state) {
|
const auto locale_check = [this]() {
|
||||||
ui->custom_rtc_edit->setEnabled(state == Qt::Checked);
|
const auto region_index = combo_region->currentIndex();
|
||||||
if (state != Qt::Checked) {
|
const auto language_index = combo_language->currentIndex();
|
||||||
ui->custom_rtc_edit->setDateTime(QDateTime::currentDateTime());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const auto locale_check = [this](int index) {
|
|
||||||
const auto region_index = ConfigurationShared::GetComboboxIndex(
|
|
||||||
Settings::values.region_index.GetValue(true), ui->combo_region);
|
|
||||||
const auto language_index = ConfigurationShared::GetComboboxIndex(
|
|
||||||
Settings::values.language_index.GetValue(true), ui->combo_language);
|
|
||||||
const bool valid_locale = IsValidLocale(region_index, language_index);
|
const bool valid_locale = IsValidLocale(region_index, language_index);
|
||||||
ui->label_warn_invalid_locale->setVisible(!valid_locale);
|
ui->label_warn_invalid_locale->setVisible(!valid_locale);
|
||||||
if (!valid_locale) {
|
if (!valid_locale) {
|
||||||
ui->label_warn_invalid_locale->setText(
|
ui->label_warn_invalid_locale->setText(
|
||||||
tr("Warning: \"%1\" is not a valid language for region \"%2\"")
|
tr("Warning: \"%1\" is not a valid language for region \"%2\"")
|
||||||
.arg(ui->combo_language->currentText())
|
.arg(combo_language->currentText())
|
||||||
.arg(ui->combo_region->currentText()));
|
.arg(combo_region->currentText()));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
connect(ui->combo_language, qOverload<int>(&QComboBox::currentIndexChanged), this,
|
connect(combo_language, qOverload<int>(&QComboBox::currentIndexChanged), this, locale_check);
|
||||||
locale_check);
|
connect(combo_region, qOverload<int>(&QComboBox::currentIndexChanged), this, locale_check);
|
||||||
connect(ui->combo_region, qOverload<int>(&QComboBox::currentIndexChanged), this, locale_check);
|
|
||||||
|
|
||||||
SetupPerGameUI();
|
ui->label_warn_invalid_locale->setVisible(false);
|
||||||
|
locale_check();
|
||||||
|
|
||||||
SetConfiguration();
|
SetConfiguration();
|
||||||
}
|
}
|
||||||
|
@ -93,137 +88,66 @@ void ConfigureSystem::RetranslateUI() {
|
||||||
ui->retranslateUi(this);
|
ui->retranslateUi(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureSystem::SetConfiguration() {
|
void ConfigureSystem::Setup(const ConfigurationShared::Builder& builder) {
|
||||||
enabled = !system.IsPoweredOn();
|
auto& core_layout = *ui->core_widget->layout();
|
||||||
const auto rng_seed =
|
auto& system_layout = *ui->system_widget->layout();
|
||||||
QStringLiteral("%1")
|
|
||||||
.arg(Settings::values.rng_seed.GetValue().value_or(0), 8, 16, QLatin1Char{'0'})
|
|
||||||
.toUpper();
|
|
||||||
const auto rtc_time = Settings::values.custom_rtc.value_or(QDateTime::currentSecsSinceEpoch());
|
|
||||||
|
|
||||||
ui->rng_seed_checkbox->setChecked(Settings::values.rng_seed.GetValue().has_value());
|
std::map<u32, QWidget*> core_hold{};
|
||||||
ui->rng_seed_edit->setEnabled(Settings::values.rng_seed.GetValue().has_value() &&
|
std::map<u32, QWidget*> system_hold{};
|
||||||
Settings::values.rng_seed.UsingGlobal());
|
|
||||||
ui->rng_seed_edit->setText(rng_seed);
|
|
||||||
|
|
||||||
ui->custom_rtc_checkbox->setChecked(Settings::values.custom_rtc.has_value());
|
std::vector<Settings::BasicSetting*> settings;
|
||||||
ui->custom_rtc_edit->setEnabled(Settings::values.custom_rtc.has_value());
|
auto push = [&settings](auto& list) {
|
||||||
ui->custom_rtc_edit->setDateTime(QDateTime::fromSecsSinceEpoch(rtc_time));
|
for (auto setting : list) {
|
||||||
ui->device_name_edit->setText(
|
settings.push_back(setting);
|
||||||
QString::fromUtf8(Settings::values.device_name.GetValue().c_str()));
|
}
|
||||||
ui->use_unsafe_extended_memory_layout->setEnabled(enabled);
|
};
|
||||||
ui->use_unsafe_extended_memory_layout->setChecked(
|
|
||||||
Settings::values.use_unsafe_extended_memory_layout.GetValue());
|
|
||||||
|
|
||||||
if (Settings::IsConfiguringGlobal()) {
|
push(Settings::values.linkage.by_category[Settings::Category::Core]);
|
||||||
ui->combo_language->setCurrentIndex(Settings::values.language_index.GetValue());
|
push(Settings::values.linkage.by_category[Settings::Category::System]);
|
||||||
ui->combo_region->setCurrentIndex(Settings::values.region_index.GetValue());
|
|
||||||
ui->combo_time_zone->setCurrentIndex(Settings::values.time_zone_index.GetValue());
|
|
||||||
} 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::SetHighlight(ui->label_language,
|
for (auto setting : settings) {
|
||||||
!Settings::values.language_index.UsingGlobal());
|
ConfigurationShared::Widget* widget = builder.BuildWidget(setting, apply_funcs);
|
||||||
ConfigurationShared::SetHighlight(ui->label_region,
|
|
||||||
!Settings::values.region_index.UsingGlobal());
|
if (widget == nullptr) {
|
||||||
ConfigurationShared::SetHighlight(ui->label_timezone,
|
continue;
|
||||||
!Settings::values.time_zone_index.UsingGlobal());
|
}
|
||||||
|
if (!widget->Valid()) {
|
||||||
|
widget->deleteLater();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (setting->Id() == Settings::values.region_index.Id()) {
|
||||||
|
// Keep track of the region_index (and langauge_index) combobox to validate the selected
|
||||||
|
// settings
|
||||||
|
combo_region = widget->combobox;
|
||||||
|
} else if (setting->Id() == Settings::values.language_index.Id()) {
|
||||||
|
combo_language = widget->combobox;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (setting->GetCategory()) {
|
||||||
|
case Settings::Category::Core:
|
||||||
|
core_hold.emplace(setting->Id(), widget);
|
||||||
|
break;
|
||||||
|
case Settings::Category::System:
|
||||||
|
system_hold.emplace(setting->Id(), widget);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
widget->deleteLater();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (const auto& [label, widget] : core_hold) {
|
||||||
|
core_layout.addWidget(widget);
|
||||||
|
}
|
||||||
|
for (const auto& [id, widget] : system_hold) {
|
||||||
|
system_layout.addWidget(widget);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureSystem::ReadSystemSettings() {}
|
void ConfigureSystem::SetConfiguration() {}
|
||||||
|
|
||||||
void ConfigureSystem::ApplyConfiguration() {
|
void ConfigureSystem::ApplyConfiguration() {
|
||||||
// Allow setting custom RTC even if system is powered on,
|
const bool powered_on = system.IsPoweredOn();
|
||||||
// to allow in-game time to be fast forwarded
|
for (const auto& func : apply_funcs) {
|
||||||
if (Settings::IsConfiguringGlobal()) {
|
func(powered_on);
|
||||||
if (ui->custom_rtc_checkbox->isChecked()) {
|
|
||||||
Settings::values.custom_rtc = ui->custom_rtc_edit->dateTime().toSecsSinceEpoch();
|
|
||||||
if (system.IsPoweredOn()) {
|
|
||||||
const s64 posix_time{*Settings::values.custom_rtc};
|
|
||||||
system.GetTimeManager().UpdateLocalSystemClockTime(posix_time);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Settings::values.custom_rtc = std::nullopt;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Settings::values.device_name = ui->device_name_edit->text().toStdString();
|
|
||||||
|
|
||||||
if (!enabled) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
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.use_unsafe_extended_memory_layout,
|
|
||||||
ui->use_unsafe_extended_memory_layout,
|
|
||||||
use_unsafe_extended_memory_layout);
|
|
||||||
|
|
||||||
if (Settings::IsConfiguringGlobal()) {
|
|
||||||
// Guard if during game and set to game-specific value
|
|
||||||
if (Settings::values.rng_seed.UsingGlobal()) {
|
|
||||||
if (ui->rng_seed_checkbox->isChecked()) {
|
|
||||||
Settings::values.rng_seed.SetValue(ui->rng_seed_edit->text().toUInt(nullptr, 16));
|
|
||||||
} else {
|
|
||||||
Settings::values.rng_seed.SetValue(std::nullopt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
switch (use_rng_seed) {
|
|
||||||
case ConfigurationShared::CheckState::On:
|
|
||||||
case ConfigurationShared::CheckState::Off:
|
|
||||||
Settings::values.rng_seed.SetGlobal(false);
|
|
||||||
if (ui->rng_seed_checkbox->isChecked()) {
|
|
||||||
Settings::values.rng_seed.SetValue(ui->rng_seed_edit->text().toUInt(nullptr, 16));
|
|
||||||
} else {
|
|
||||||
Settings::values.rng_seed.SetValue(std::nullopt);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case ConfigurationShared::CheckState::Global:
|
|
||||||
Settings::values.rng_seed.SetGlobal(false);
|
|
||||||
Settings::values.rng_seed.SetValue(std::nullopt);
|
|
||||||
Settings::values.rng_seed.SetGlobal(true);
|
|
||||||
break;
|
|
||||||
case ConfigurationShared::CheckState::Count:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConfigureSystem::SetupPerGameUI() {
|
|
||||||
if (Settings::IsConfiguringGlobal()) {
|
|
||||||
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->rng_seed_checkbox->setEnabled(Settings::values.rng_seed.UsingGlobal());
|
|
||||||
ui->rng_seed_edit->setEnabled(Settings::values.rng_seed.UsingGlobal());
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ConfigurationShared::SetColoredComboBox(ui->combo_language, ui->label_language,
|
|
||||||
Settings::values.language_index.GetValue(true));
|
|
||||||
ConfigurationShared::SetColoredComboBox(ui->combo_region, ui->label_region,
|
|
||||||
Settings::values.region_index.GetValue(true));
|
|
||||||
ConfigurationShared::SetColoredComboBox(ui->combo_time_zone, ui->label_timezone,
|
|
||||||
Settings::values.time_zone_index.GetValue(true));
|
|
||||||
|
|
||||||
ConfigurationShared::SetColoredTristate(
|
|
||||||
ui->rng_seed_checkbox, Settings::values.rng_seed.UsingGlobal(),
|
|
||||||
Settings::values.rng_seed.GetValue().has_value(),
|
|
||||||
Settings::values.rng_seed.GetValue(true).has_value(), use_rng_seed);
|
|
||||||
|
|
||||||
ConfigurationShared::SetColoredTristate(ui->use_unsafe_extended_memory_layout,
|
|
||||||
Settings::values.use_unsafe_extended_memory_layout,
|
|
||||||
use_unsafe_extended_memory_layout);
|
|
||||||
|
|
||||||
ui->custom_rtc_checkbox->setVisible(false);
|
|
||||||
ui->custom_rtc_edit->setVisible(false);
|
|
||||||
}
|
|
||||||
|
|
|
@ -3,45 +3,53 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
#include "yuzu/configuration/configuration_shared.h"
|
||||||
|
|
||||||
|
class QCheckBox;
|
||||||
|
class QLineEdit;
|
||||||
|
class QComboBox;
|
||||||
|
class QDateTimeEdit;
|
||||||
namespace Core {
|
namespace Core {
|
||||||
class System;
|
class System;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace ConfigurationShared {
|
|
||||||
enum class CheckState;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class ConfigureSystem;
|
class ConfigureSystem;
|
||||||
}
|
}
|
||||||
|
|
||||||
class ConfigureSystem : public QWidget {
|
namespace ConfigurationShared {
|
||||||
Q_OBJECT
|
class Builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
class ConfigureSystem : public ConfigurationShared::Tab {
|
||||||
public:
|
public:
|
||||||
explicit ConfigureSystem(Core::System& system_, QWidget* parent = nullptr);
|
explicit ConfigureSystem(Core::System& system_,
|
||||||
|
std::shared_ptr<std::vector<ConfigurationShared::Tab*>> group,
|
||||||
|
const ConfigurationShared::Builder& builder,
|
||||||
|
QWidget* parent = nullptr);
|
||||||
~ConfigureSystem() override;
|
~ConfigureSystem() override;
|
||||||
|
|
||||||
void ApplyConfiguration();
|
void ApplyConfiguration() override;
|
||||||
void SetConfiguration();
|
void SetConfiguration() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void changeEvent(QEvent* event) override;
|
void changeEvent(QEvent* event) override;
|
||||||
void RetranslateUI();
|
void RetranslateUI();
|
||||||
|
|
||||||
void ReadSystemSettings();
|
void Setup(const ConfigurationShared::Builder& builder);
|
||||||
|
|
||||||
void SetupPerGameUI();
|
std::vector<std::function<void(bool)>> apply_funcs{};
|
||||||
|
|
||||||
std::unique_ptr<Ui::ConfigureSystem> ui;
|
std::unique_ptr<Ui::ConfigureSystem> ui;
|
||||||
bool enabled = false;
|
bool enabled = false;
|
||||||
|
|
||||||
ConfigurationShared::CheckState use_rng_seed;
|
|
||||||
ConfigurationShared::CheckState use_unsafe_extended_memory_layout;
|
|
||||||
|
|
||||||
Core::System& system;
|
Core::System& system;
|
||||||
|
|
||||||
|
QComboBox* combo_region;
|
||||||
|
QComboBox* combo_language;
|
||||||
};
|
};
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>366</width>
|
<width>605</width>
|
||||||
<height>483</height>
|
<height>483</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
|
@ -22,470 +22,63 @@
|
||||||
<item>
|
<item>
|
||||||
<widget class="QGroupBox" name="group_system_settings">
|
<widget class="QGroupBox" name="group_system_settings">
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>System Settings</string>
|
<string>System</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
<item>
|
<item>
|
||||||
<layout class="QGridLayout" name="gridLayout_2">
|
<widget class="QWidget" name="system_widget" native="true">
|
||||||
<item row="1" column="0">
|
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||||
<widget class="QLabel" name="label_region">
|
<property name="leftMargin">
|
||||||
<property name="text">
|
<number>0</number>
|
||||||
<string>Region:</string>
|
|
||||||
</property>
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="1">
|
|
||||||
<widget class="QComboBox" name="combo_time_zone">
|
|
||||||
<item>
|
<item>
|
||||||
|
<widget class="QLabel" name="label_warn_invalid_locale">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Auto</string>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
</item>
|
<property name="wordWrap">
|
||||||
<item>
|
<bool>true</bool>
|
||||||
<property name="text">
|
|
||||||
<string>Default</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>CET</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>CST6CDT</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Cuba</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>EET</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Egypt</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Eire</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>EST</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>EST5EDT</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>GB</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>GB-Eire</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>GMT</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>GMT+0</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>GMT-0</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>GMT0</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Greenwich</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Hongkong</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>HST</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Iceland</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Iran</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Israel</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Jamaica</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Japan</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Kwajalein</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Libya</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>MET</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>MST</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>MST7MDT</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Navajo</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>NZ</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>NZ-CHAT</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Poland</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Portugal</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>PRC</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>PST8PDT</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>ROC</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>ROK</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Singapore</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Turkey</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>UCT</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Universal</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>UTC</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>W-SU</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>WET</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Zulu</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="1">
|
|
||||||
<widget class="QComboBox" name="combo_region">
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Japan</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>USA</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Europe</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Australia</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>China</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Korea</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Taiwan</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="0">
|
|
||||||
<widget class="QLabel" name="label_timezone">
|
|
||||||
<property name="text">
|
|
||||||
<string>Time Zone:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="1">
|
|
||||||
<widget class="QComboBox" name="combo_language">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>Note: this can be overridden when region setting is auto-select</string>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Japanese (日本語)</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>American English</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>French (français)</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>German (Deutsch)</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Italian (italiano)</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Spanish (español)</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Chinese</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Korean (한국어)</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Dutch (Nederlands)</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Portuguese (português)</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Russian (Русский)</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Taiwanese</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>British English</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Canadian French</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Latin American Spanish</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Simplified Chinese</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Traditional Chinese (正體中文)</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Brazilian Portuguese (português do Brasil)</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="4" column="0">
|
|
||||||
<widget class="QCheckBox" name="custom_rtc_checkbox">
|
|
||||||
<property name="text">
|
|
||||||
<string>Custom RTC</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="0">
|
|
||||||
<widget class="QLabel" name="label_language">
|
|
||||||
<property name="text">
|
|
||||||
<string>Language</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="5" column="0">
|
|
||||||
<widget class="QCheckBox" name="rng_seed_checkbox">
|
|
||||||
<property name="text">
|
|
||||||
<string>RNG Seed</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="6" column="0">
|
|
||||||
<widget class="QLabel" name="device_name_label">
|
|
||||||
<property name="text">
|
|
||||||
<string>Device Name</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="4" column="1">
|
|
||||||
<widget class="QDateTimeEdit" name="custom_rtc_edit">
|
|
||||||
<property name="minimumDate">
|
|
||||||
<date>
|
|
||||||
<year>1970</year>
|
|
||||||
<month>1</month>
|
|
||||||
<day>1</day>
|
|
||||||
</date>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="6" column="1">
|
|
||||||
<widget class="QLineEdit" name="device_name_edit">
|
|
||||||
<property name="maxLength">
|
|
||||||
<number>128</number>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="5" column="1">
|
|
||||||
<widget class="QLineEdit" name="rng_seed_edit">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="font">
|
|
||||||
<font>
|
|
||||||
<family>Lucida Console</family>
|
|
||||||
</font>
|
|
||||||
</property>
|
|
||||||
<property name="inputMask">
|
|
||||||
<string notr="true">HHHHHHHH</string>
|
|
||||||
</property>
|
|
||||||
<property name="maxLength">
|
|
||||||
<number>8</number>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="7" column="0">
|
|
||||||
<widget class="QCheckBox" name="use_unsafe_extended_memory_layout">
|
|
||||||
<property name="text">
|
|
||||||
<string>Unsafe extended memory layout (8GB DRAM)</string>
|
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="groupBox">
|
||||||
|
<property name="title">
|
||||||
|
<string>Core</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_6">
|
||||||
|
<item>
|
||||||
|
<widget class="QWidget" name="core_widget" native="true">
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
|
@ -503,26 +96,6 @@
|
||||||
</property>
|
</property>
|
||||||
</spacer>
|
</spacer>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="label_warn_invalid_locale">
|
|
||||||
<property name="text">
|
|
||||||
<string></string>
|
|
||||||
</property>
|
|
||||||
<property name="wordWrap">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="label_disable_info">
|
|
||||||
<property name="text">
|
|
||||||
<string>System settings are available only when game is not running.</string>
|
|
||||||
</property>
|
|
||||||
<property name="wordWrap">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
|
|
|
@ -0,0 +1,388 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include "common/time_zone.h"
|
||||||
|
#include "yuzu/configuration/shared_translation.h"
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <memory>
|
||||||
|
#include <tuple>
|
||||||
|
#include <utility>
|
||||||
|
#include <QWidget>
|
||||||
|
#include "common/settings.h"
|
||||||
|
#include "common/settings_enums.h"
|
||||||
|
#include "common/settings_setting.h"
|
||||||
|
#include "yuzu/uisettings.h"
|
||||||
|
|
||||||
|
namespace ConfigurationShared {
|
||||||
|
|
||||||
|
std::unique_ptr<TranslationMap> InitializeTranslations(QWidget* parent) {
|
||||||
|
std::unique_ptr<TranslationMap> translations = std::make_unique<TranslationMap>();
|
||||||
|
const auto& tr = [parent](const char* text) -> QString { return parent->tr(text); };
|
||||||
|
|
||||||
|
#define INSERT(SETTINGS, ID, NAME, TOOLTIP) \
|
||||||
|
translations->insert(std::pair{SETTINGS::values.ID.Id(), std::pair{tr((NAME)), tr((TOOLTIP))}})
|
||||||
|
|
||||||
|
// A setting can be ignored by giving it a blank name
|
||||||
|
|
||||||
|
// Audio
|
||||||
|
INSERT(Settings, sink_id, "Output Engine:", "");
|
||||||
|
INSERT(Settings, audio_output_device_id, "Output Device:", "");
|
||||||
|
INSERT(Settings, audio_input_device_id, "Input Device:", "");
|
||||||
|
INSERT(Settings, audio_muted, "Mute audio when in background", "");
|
||||||
|
INSERT(Settings, volume, "Volume:", "");
|
||||||
|
INSERT(Settings, dump_audio_commands, "", "");
|
||||||
|
|
||||||
|
// Core
|
||||||
|
INSERT(Settings, use_multi_core, "Multicore CPU Emulation", "");
|
||||||
|
INSERT(Settings, memory_layout_mode, "Memory Layout", "");
|
||||||
|
INSERT(Settings, use_speed_limit, "", "");
|
||||||
|
INSERT(Settings, speed_limit, "Limit Speed Percent", "");
|
||||||
|
|
||||||
|
// Cpu
|
||||||
|
INSERT(Settings, cpu_accuracy, "Accuracy:", "");
|
||||||
|
|
||||||
|
// Cpu Debug
|
||||||
|
|
||||||
|
// Cpu Unsafe
|
||||||
|
INSERT(Settings, cpuopt_unsafe_unfuse_fma,
|
||||||
|
"Unfuse FMA (improve performance on CPUs without FMA)",
|
||||||
|
"This option improves speed by reducing accuracy of fused-multiply-add instructions on "
|
||||||
|
"CPUs without native FMA support.");
|
||||||
|
INSERT(Settings, cpuopt_unsafe_reduce_fp_error, "Faster FRSQRTE and FRECPE",
|
||||||
|
"This option improves the speed of some approximate floating-point functions by using "
|
||||||
|
"less accurate native approximations.");
|
||||||
|
INSERT(Settings, cpuopt_unsafe_ignore_standard_fpcr, "Faster ASIMD instructions (32 bits only)",
|
||||||
|
"This option improves the speed of 32 bits ASIMD floating-point functions by running "
|
||||||
|
"with incorrect rounding modes.");
|
||||||
|
INSERT(Settings, cpuopt_unsafe_inaccurate_nan, "Inaccurate NaN handling",
|
||||||
|
"This option improves speed by removing NaN checking. Please note this also reduces "
|
||||||
|
"accuracy of certain floating-point instructions.");
|
||||||
|
INSERT(
|
||||||
|
Settings, cpuopt_unsafe_fastmem_check, "Disable address space checks",
|
||||||
|
"This option improves speed by eliminating a safety check before every memory read/write "
|
||||||
|
"in guest. Disabling it may allow a game to read/write the emulator's memory.");
|
||||||
|
INSERT(Settings, cpuopt_unsafe_ignore_global_monitor, "Ignore global monitor",
|
||||||
|
"This option improves speed by relying only on the semantics of cmpxchg to ensure "
|
||||||
|
"safety of exclusive access instructions. Please note this may result in deadlocks and "
|
||||||
|
"other race conditions.");
|
||||||
|
|
||||||
|
// Renderer
|
||||||
|
INSERT(Settings, renderer_backend, "API:", "");
|
||||||
|
INSERT(Settings, vulkan_device, "Device:", "");
|
||||||
|
INSERT(Settings, shader_backend, "Shader Backend:", "");
|
||||||
|
INSERT(Settings, resolution_setup, "Resolution:", "");
|
||||||
|
INSERT(Settings, scaling_filter, "Window Adapting Filter:", "");
|
||||||
|
INSERT(Settings, fsr_sharpening_slider, "FSR Sharpness:", "");
|
||||||
|
INSERT(Settings, anti_aliasing, "Anti-Aliasing Method:", "");
|
||||||
|
INSERT(Settings, fullscreen_mode, "Fullscreen Mode:", "");
|
||||||
|
INSERT(Settings, aspect_ratio, "Aspect Ratio:", "");
|
||||||
|
INSERT(Settings, use_disk_shader_cache, "Use disk pipeline cache", "");
|
||||||
|
INSERT(Settings, use_asynchronous_gpu_emulation, "Use asynchronous GPU emulation", "");
|
||||||
|
INSERT(Settings, nvdec_emulation, "NVDEC emulation:", "");
|
||||||
|
INSERT(Settings, accelerate_astc, "ASTC Decoding Method:", "");
|
||||||
|
INSERT(Settings, astc_recompression, "ASTC Recompression Method:", "");
|
||||||
|
INSERT(Settings, vsync_mode, "VSync Mode:",
|
||||||
|
"FIFO (VSync) does not drop frames or exhibit tearing but is limited by the screen "
|
||||||
|
"refresh rate.\nFIFO Relaxed is similar to FIFO but allows tearing as it recovers from "
|
||||||
|
"a slow down.\nMailbox can have lower latency than FIFO and does not tear but may drop "
|
||||||
|
"frames.\nImmediate (no synchronization) just presents whatever is available and can "
|
||||||
|
"exhibit tearing.");
|
||||||
|
INSERT(Settings, bg_red, "", "");
|
||||||
|
INSERT(Settings, bg_green, "", "");
|
||||||
|
INSERT(Settings, bg_blue, "", "");
|
||||||
|
|
||||||
|
// Renderer (Advanced Graphics)
|
||||||
|
INSERT(Settings, async_presentation, "Enable asynchronous presentation (Vulkan only)", "");
|
||||||
|
INSERT(Settings, renderer_force_max_clock, "Force maximum clocks (Vulkan only)",
|
||||||
|
"Runs work in the background while waiting for graphics commands to keep the GPU from "
|
||||||
|
"lowering its clock speed.");
|
||||||
|
INSERT(Settings, max_anisotropy, "Anisotropic Filtering:", "");
|
||||||
|
INSERT(Settings, gpu_accuracy, "Accuracy Level:", "");
|
||||||
|
INSERT(Settings, use_asynchronous_shaders, "Use asynchronous shader building (Hack)",
|
||||||
|
"Enables asynchronous shader compilation, which may reduce shader stutter. This feature "
|
||||||
|
"is experimental.");
|
||||||
|
INSERT(Settings, use_fast_gpu_time, "Use Fast GPU Time (Hack)",
|
||||||
|
"Enables Fast GPU Time. This option will force most games to run at their highest "
|
||||||
|
"native resolution.");
|
||||||
|
INSERT(Settings, use_vulkan_driver_pipeline_cache, "Use Vulkan pipeline cache",
|
||||||
|
"Enables GPU vendor-specific pipeline cache. This option can improve shader loading "
|
||||||
|
"time significantly in cases where the Vulkan driver does not store pipeline cache "
|
||||||
|
"files internally.");
|
||||||
|
INSERT(Settings, enable_compute_pipelines, "Enable Compute Pipelines (Intel Vulkan Only)",
|
||||||
|
"Enable compute pipelines, required by some games.\nThis setting only exists for Intel "
|
||||||
|
"proprietary drivers, and may crash if enabled.\nCompute pipelines are always enabled "
|
||||||
|
"on all other drivers.");
|
||||||
|
INSERT(Settings, use_reactive_flushing, "Enable Reactive Flushing",
|
||||||
|
"Uses reactive flushing instead of predictive flushing, allowing more accurate memory "
|
||||||
|
"syncing.");
|
||||||
|
INSERT(Settings, use_video_framerate, "Sync to framerate of video playback",
|
||||||
|
"Run the game at normal speed during video playback, even when the framerate is "
|
||||||
|
"unlocked.");
|
||||||
|
INSERT(Settings, barrier_feedback_loops, "Barrier feedback loops",
|
||||||
|
"Improves rendering of transparency effects in specific games.");
|
||||||
|
|
||||||
|
// Renderer (Debug)
|
||||||
|
|
||||||
|
// System
|
||||||
|
INSERT(Settings, rng_seed, "RNG Seed", "");
|
||||||
|
INSERT(Settings, rng_seed_enabled, "", "");
|
||||||
|
INSERT(Settings, device_name, "Device Name", "");
|
||||||
|
INSERT(Settings, custom_rtc, "Custom RTC", "");
|
||||||
|
INSERT(Settings, custom_rtc_enabled, "", "");
|
||||||
|
INSERT(Settings, language_index,
|
||||||
|
"Language:", "Note: this can be overridden when region setting is auto-select");
|
||||||
|
INSERT(Settings, region_index, "Region:", "");
|
||||||
|
INSERT(Settings, time_zone_index, "Time Zone:", "");
|
||||||
|
INSERT(Settings, sound_index, "Sound Output Mode:", "");
|
||||||
|
INSERT(Settings, use_docked_mode, "", "");
|
||||||
|
INSERT(Settings, current_user, "", "");
|
||||||
|
|
||||||
|
// Controls
|
||||||
|
|
||||||
|
// Data Storage
|
||||||
|
|
||||||
|
// Debugging
|
||||||
|
|
||||||
|
// Debugging Graphics
|
||||||
|
|
||||||
|
// Network
|
||||||
|
|
||||||
|
// Web Service
|
||||||
|
|
||||||
|
// Ui
|
||||||
|
|
||||||
|
// Ui General
|
||||||
|
INSERT(UISettings, select_user_on_boot, "Prompt for user on game boot", "");
|
||||||
|
INSERT(UISettings, pause_when_in_background, "Pause emulation when in background", "");
|
||||||
|
INSERT(UISettings, confirm_before_closing, "Confirm exit while emulation is running", "");
|
||||||
|
INSERT(UISettings, hide_mouse, "Hide mouse on inactivity", "");
|
||||||
|
INSERT(UISettings, controller_applet_disabled, "Disable controller applet", "");
|
||||||
|
|
||||||
|
// Ui Debugging
|
||||||
|
|
||||||
|
// Ui Multiplayer
|
||||||
|
|
||||||
|
// Ui Games list
|
||||||
|
|
||||||
|
#undef INSERT
|
||||||
|
|
||||||
|
return translations;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<ComboboxTranslationMap> ComboboxEnumeration(QWidget* parent) {
|
||||||
|
std::unique_ptr<ComboboxTranslationMap> translations =
|
||||||
|
std::make_unique<ComboboxTranslationMap>();
|
||||||
|
const auto& tr = [&](const char* text, const char* context = "") {
|
||||||
|
return parent->tr(text, context);
|
||||||
|
};
|
||||||
|
|
||||||
|
#define PAIR(ENUM, VALUE, TRANSLATION) \
|
||||||
|
{ static_cast<u32>(Settings::ENUM::VALUE), tr(TRANSLATION) }
|
||||||
|
#define CTX_PAIR(ENUM, VALUE, TRANSLATION, CONTEXT) \
|
||||||
|
{ static_cast<u32>(Settings::ENUM::VALUE), tr(TRANSLATION, CONTEXT) }
|
||||||
|
|
||||||
|
// Intentionally skipping VSyncMode to let the UI fill that one out
|
||||||
|
|
||||||
|
translations->insert({Settings::EnumMetadata<Settings::AstcDecodeMode>::Index(),
|
||||||
|
{
|
||||||
|
PAIR(AstcDecodeMode, Cpu, "CPU"),
|
||||||
|
PAIR(AstcDecodeMode, Gpu, "GPU"),
|
||||||
|
PAIR(AstcDecodeMode, CpuAsynchronous, "CPU Asynchronous"),
|
||||||
|
}});
|
||||||
|
translations->insert({Settings::EnumMetadata<Settings::AstcRecompression>::Index(),
|
||||||
|
{
|
||||||
|
PAIR(AstcRecompression, Uncompressed, "Uncompressed (Best quality)"),
|
||||||
|
PAIR(AstcRecompression, Bc1, "BC1 (Low quality)"),
|
||||||
|
PAIR(AstcRecompression, Bc3, "BC3 (Medium quality)"),
|
||||||
|
}});
|
||||||
|
translations->insert({Settings::EnumMetadata<Settings::RendererBackend>::Index(),
|
||||||
|
{
|
||||||
|
#ifdef HAS_OPENGL
|
||||||
|
PAIR(RendererBackend, OpenGL, "OpenGL"),
|
||||||
|
#endif
|
||||||
|
PAIR(RendererBackend, Vulkan, "Vulkan"),
|
||||||
|
PAIR(RendererBackend, Null, "Null"),
|
||||||
|
}});
|
||||||
|
translations->insert({Settings::EnumMetadata<Settings::ShaderBackend>::Index(),
|
||||||
|
{
|
||||||
|
PAIR(ShaderBackend, Glsl, "GLSL"),
|
||||||
|
PAIR(ShaderBackend, Glasm, "GLASM (Assembly Shaders, NVIDIA Only)"),
|
||||||
|
PAIR(ShaderBackend, SpirV, "SPIR-V (Experimental, Mesa Only)"),
|
||||||
|
}});
|
||||||
|
translations->insert({Settings::EnumMetadata<Settings::GpuAccuracy>::Index(),
|
||||||
|
{
|
||||||
|
PAIR(GpuAccuracy, Normal, "Normal"),
|
||||||
|
PAIR(GpuAccuracy, High, "High"),
|
||||||
|
PAIR(GpuAccuracy, Extreme, "Extreme"),
|
||||||
|
}});
|
||||||
|
translations->insert({Settings::EnumMetadata<Settings::CpuAccuracy>::Index(),
|
||||||
|
{
|
||||||
|
PAIR(CpuAccuracy, Auto, "Auto"),
|
||||||
|
PAIR(CpuAccuracy, Accurate, "Accurate"),
|
||||||
|
PAIR(CpuAccuracy, Unsafe, "Unsafe"),
|
||||||
|
PAIR(CpuAccuracy, Paranoid, "Paranoid (disables most optimizations)"),
|
||||||
|
}});
|
||||||
|
translations->insert({Settings::EnumMetadata<Settings::FullscreenMode>::Index(),
|
||||||
|
{
|
||||||
|
PAIR(FullscreenMode, Borderless, "Borderless Windowed"),
|
||||||
|
PAIR(FullscreenMode, Exclusive, "Exclusive Fullscreen"),
|
||||||
|
}});
|
||||||
|
translations->insert({Settings::EnumMetadata<Settings::NvdecEmulation>::Index(),
|
||||||
|
{
|
||||||
|
PAIR(NvdecEmulation, Off, "No Video Output"),
|
||||||
|
PAIR(NvdecEmulation, Cpu, "CPU Video Decoding"),
|
||||||
|
PAIR(NvdecEmulation, Gpu, "GPU Video Decoding (Default)"),
|
||||||
|
}});
|
||||||
|
translations->insert({Settings::EnumMetadata<Settings::ResolutionSetup>::Index(),
|
||||||
|
{
|
||||||
|
PAIR(ResolutionSetup, Res1_2X, "0.5X (360p/540p) [EXPERIMENTAL]"),
|
||||||
|
PAIR(ResolutionSetup, Res3_4X, "0.75X (540p/810p) [EXPERIMENTAL]"),
|
||||||
|
PAIR(ResolutionSetup, Res1X, "1X (720p/1080p)"),
|
||||||
|
PAIR(ResolutionSetup, Res3_2X, "1.5X (1080p/1620p) [EXPERIMENTAL]"),
|
||||||
|
PAIR(ResolutionSetup, Res2X, "2X (1440p/2160p)"),
|
||||||
|
PAIR(ResolutionSetup, Res3X, "3X (2160p/3240p)"),
|
||||||
|
PAIR(ResolutionSetup, Res4X, "4X (2880p/4320p)"),
|
||||||
|
PAIR(ResolutionSetup, Res5X, "5X (3600p/5400p)"),
|
||||||
|
PAIR(ResolutionSetup, Res6X, "6X (4320p/6480p)"),
|
||||||
|
PAIR(ResolutionSetup, Res7X, "7X (5040p/7560p)"),
|
||||||
|
PAIR(ResolutionSetup, Res8X, "8X (5760p/8640p)"),
|
||||||
|
}});
|
||||||
|
translations->insert({Settings::EnumMetadata<Settings::ScalingFilter>::Index(),
|
||||||
|
{
|
||||||
|
PAIR(ScalingFilter, NearestNeighbor, "Nearest Neighbor"),
|
||||||
|
PAIR(ScalingFilter, Bilinear, "Bilinear"),
|
||||||
|
PAIR(ScalingFilter, Bicubic, "Bicubic"),
|
||||||
|
PAIR(ScalingFilter, Gaussian, "Gaussian"),
|
||||||
|
PAIR(ScalingFilter, ScaleForce, "ScaleForce"),
|
||||||
|
PAIR(ScalingFilter, Fsr, "AMD FidelityFX™️ Super Resolution"),
|
||||||
|
}});
|
||||||
|
translations->insert({Settings::EnumMetadata<Settings::AntiAliasing>::Index(),
|
||||||
|
{
|
||||||
|
PAIR(AntiAliasing, None, "None"),
|
||||||
|
PAIR(AntiAliasing, Fxaa, "FXAA"),
|
||||||
|
PAIR(AntiAliasing, Smaa, "SMAA"),
|
||||||
|
}});
|
||||||
|
translations->insert({Settings::EnumMetadata<Settings::AspectRatio>::Index(),
|
||||||
|
{
|
||||||
|
PAIR(AspectRatio, R16_9, "Default (16:9)"),
|
||||||
|
PAIR(AspectRatio, R4_3, "Force 4:3"),
|
||||||
|
PAIR(AspectRatio, R21_9, "Force 21:9"),
|
||||||
|
PAIR(AspectRatio, R16_10, "Force 16:10"),
|
||||||
|
PAIR(AspectRatio, Stretch, "Stretch to Window"),
|
||||||
|
}});
|
||||||
|
translations->insert({Settings::EnumMetadata<Settings::AnisotropyMode>::Index(),
|
||||||
|
{
|
||||||
|
PAIR(AnisotropyMode, Automatic, "Automatic"),
|
||||||
|
PAIR(AnisotropyMode, Default, "Default"),
|
||||||
|
PAIR(AnisotropyMode, X2, "2x"),
|
||||||
|
PAIR(AnisotropyMode, X4, "4x"),
|
||||||
|
PAIR(AnisotropyMode, X8, "8x"),
|
||||||
|
PAIR(AnisotropyMode, X16, "16x"),
|
||||||
|
}});
|
||||||
|
translations->insert(
|
||||||
|
{Settings::EnumMetadata<Settings::Language>::Index(),
|
||||||
|
{
|
||||||
|
PAIR(Language, Japanese, "Japanese (日本語)"),
|
||||||
|
PAIR(Language, EnglishAmerican, "American English"),
|
||||||
|
PAIR(Language, French, "French (français)"),
|
||||||
|
PAIR(Language, German, "German (Deutsch)"),
|
||||||
|
PAIR(Language, Italian, "Italian (italiano)"),
|
||||||
|
PAIR(Language, Spanish, "Spanish (español)"),
|
||||||
|
PAIR(Language, Chinese, "Chinese"),
|
||||||
|
PAIR(Language, Korean, "Korean (한국어)"),
|
||||||
|
PAIR(Language, Dutch, "Dutch (Nederlands)"),
|
||||||
|
PAIR(Language, Portuguese, "Portuguese (português)"),
|
||||||
|
PAIR(Language, Russian, "Russian (Русский)"),
|
||||||
|
PAIR(Language, Taiwanese, "Taiwanese"),
|
||||||
|
PAIR(Language, EnglishBritish, "British English"),
|
||||||
|
PAIR(Language, FrenchCanadian, "Canadian French"),
|
||||||
|
PAIR(Language, SpanishLatin, "Latin American Spanish"),
|
||||||
|
PAIR(Language, ChineseSimplified, "Simplified Chinese"),
|
||||||
|
PAIR(Language, ChineseTraditional, "Traditional Chinese (正體中文)"),
|
||||||
|
PAIR(Language, PortugueseBrazilian, "Brazilian Portuguese (português do Brasil)"),
|
||||||
|
}});
|
||||||
|
translations->insert({Settings::EnumMetadata<Settings::Region>::Index(),
|
||||||
|
{
|
||||||
|
PAIR(Region, Japan, "Japan"),
|
||||||
|
PAIR(Region, Usa, "USA"),
|
||||||
|
PAIR(Region, Europe, "Europe"),
|
||||||
|
PAIR(Region, Australia, "Australia"),
|
||||||
|
PAIR(Region, China, "China"),
|
||||||
|
PAIR(Region, Korea, "Korea"),
|
||||||
|
PAIR(Region, Taiwan, "Taiwan"),
|
||||||
|
}});
|
||||||
|
translations->insert(
|
||||||
|
{Settings::EnumMetadata<Settings::TimeZone>::Index(),
|
||||||
|
{
|
||||||
|
{static_cast<u32>(Settings::TimeZone::Auto),
|
||||||
|
tr("Auto (%1)", "Auto select time zone")
|
||||||
|
.arg(QString::fromStdString(
|
||||||
|
Settings::GetTimeZoneString(Settings::TimeZone::Auto)))},
|
||||||
|
{static_cast<u32>(Settings::TimeZone::Default),
|
||||||
|
tr("Default (%1)", "Default time zone")
|
||||||
|
.arg(QString::fromStdString(Common::TimeZone::GetDefaultTimeZone()))},
|
||||||
|
PAIR(TimeZone, Cet, "CET"),
|
||||||
|
PAIR(TimeZone, Cst6Cdt, "CST6CDT"),
|
||||||
|
PAIR(TimeZone, Cuba, "Cuba"),
|
||||||
|
PAIR(TimeZone, Eet, "EET"),
|
||||||
|
PAIR(TimeZone, Egypt, "Egypt"),
|
||||||
|
PAIR(TimeZone, Eire, "Eire"),
|
||||||
|
PAIR(TimeZone, Est, "EST"),
|
||||||
|
PAIR(TimeZone, Est5Edt, "EST5EDT"),
|
||||||
|
PAIR(TimeZone, Gb, "GB"),
|
||||||
|
PAIR(TimeZone, GbEire, "GB-Eire"),
|
||||||
|
PAIR(TimeZone, Gmt, "GMT"),
|
||||||
|
PAIR(TimeZone, GmtPlusZero, "GMT+0"),
|
||||||
|
PAIR(TimeZone, GmtMinusZero, "GMT-0"),
|
||||||
|
PAIR(TimeZone, GmtZero, "GMT0"),
|
||||||
|
PAIR(TimeZone, Greenwich, "Greenwich"),
|
||||||
|
PAIR(TimeZone, Hongkong, "Hongkong"),
|
||||||
|
PAIR(TimeZone, Hst, "HST"),
|
||||||
|
PAIR(TimeZone, Iceland, "Iceland"),
|
||||||
|
PAIR(TimeZone, Iran, "Iran"),
|
||||||
|
PAIR(TimeZone, Israel, "Israel"),
|
||||||
|
PAIR(TimeZone, Jamaica, "Jamaica"),
|
||||||
|
PAIR(TimeZone, Japan, "Japan"),
|
||||||
|
PAIR(TimeZone, Kwajalein, "Kwajalein"),
|
||||||
|
PAIR(TimeZone, Libya, "Libya"),
|
||||||
|
PAIR(TimeZone, Met, "MET"),
|
||||||
|
PAIR(TimeZone, Mst, "MST"),
|
||||||
|
PAIR(TimeZone, Mst7Mdt, "MST7MDT"),
|
||||||
|
PAIR(TimeZone, Navajo, "Navajo"),
|
||||||
|
PAIR(TimeZone, Nz, "NZ"),
|
||||||
|
PAIR(TimeZone, NzChat, "NZ-CHAT"),
|
||||||
|
PAIR(TimeZone, Poland, "Poland"),
|
||||||
|
PAIR(TimeZone, Portugal, "Portugal"),
|
||||||
|
PAIR(TimeZone, Prc, "PRC"),
|
||||||
|
PAIR(TimeZone, Pst8Pdt, "PST8PDT"),
|
||||||
|
PAIR(TimeZone, Roc, "ROC"),
|
||||||
|
PAIR(TimeZone, Rok, "ROK"),
|
||||||
|
PAIR(TimeZone, Singapore, "Singapore"),
|
||||||
|
PAIR(TimeZone, Turkey, "Turkey"),
|
||||||
|
PAIR(TimeZone, Uct, "UCT"),
|
||||||
|
PAIR(TimeZone, Universal, "Universal"),
|
||||||
|
PAIR(TimeZone, Utc, "UTC"),
|
||||||
|
PAIR(TimeZone, WSu, "W-SU"),
|
||||||
|
PAIR(TimeZone, Wet, "WET"),
|
||||||
|
PAIR(TimeZone, Zulu, "Zulu"),
|
||||||
|
}});
|
||||||
|
translations->insert({Settings::EnumMetadata<Settings::AudioMode>::Index(),
|
||||||
|
{
|
||||||
|
PAIR(AudioMode, Mono, "Mono"),
|
||||||
|
PAIR(AudioMode, Stereo, "Stereo"),
|
||||||
|
PAIR(AudioMode, Surround, "Surround"),
|
||||||
|
}});
|
||||||
|
translations->insert({Settings::EnumMetadata<Settings::MemoryLayout>::Index(),
|
||||||
|
{
|
||||||
|
PAIR(MemoryLayout, Memory_4Gb, "4GB DRAM (Default)"),
|
||||||
|
PAIR(MemoryLayout, Memory_6Gb, "6GB DRAM (Unsafe)"),
|
||||||
|
PAIR(MemoryLayout, Memory_8Gb, "8GB DRAM (Unsafe)"),
|
||||||
|
}});
|
||||||
|
|
||||||
|
#undef PAIR
|
||||||
|
#undef CTX_PAIR
|
||||||
|
|
||||||
|
return translations;
|
||||||
|
}
|
||||||
|
} // namespace ConfigurationShared
|
|
@ -0,0 +1,25 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <memory>
|
||||||
|
#include <typeindex>
|
||||||
|
#include <utility>
|
||||||
|
#include <vector>
|
||||||
|
#include <QString>
|
||||||
|
#include "common/common_types.h"
|
||||||
|
|
||||||
|
class QWidget;
|
||||||
|
|
||||||
|
namespace ConfigurationShared {
|
||||||
|
using TranslationMap = std::map<u32, std::pair<QString, QString>>;
|
||||||
|
using ComboboxTranslations = std::vector<std::pair<u32, QString>>;
|
||||||
|
using ComboboxTranslationMap = std::map<u32, ComboboxTranslations>;
|
||||||
|
|
||||||
|
std::unique_ptr<TranslationMap> InitializeTranslations(QWidget* parent);
|
||||||
|
|
||||||
|
std::unique_ptr<ComboboxTranslationMap> ComboboxEnumeration(QWidget* parent);
|
||||||
|
|
||||||
|
} // namespace ConfigurationShared
|
|
@ -0,0 +1,642 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include "yuzu/configuration/shared_widget.h"
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
#include <limits>
|
||||||
|
#include <typeindex>
|
||||||
|
#include <typeinfo>
|
||||||
|
#include <utility>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <QAbstractButton>
|
||||||
|
#include <QAbstractSlider>
|
||||||
|
#include <QBoxLayout>
|
||||||
|
#include <QCheckBox>
|
||||||
|
#include <QComboBox>
|
||||||
|
#include <QDateTime>
|
||||||
|
#include <QDateTimeEdit>
|
||||||
|
#include <QIcon>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QLayout>
|
||||||
|
#include <QLineEdit>
|
||||||
|
#include <QObject>
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QRegularExpression>
|
||||||
|
#include <QSizePolicy>
|
||||||
|
#include <QSlider>
|
||||||
|
#include <QSpinBox>
|
||||||
|
#include <QStyle>
|
||||||
|
#include <QValidator>
|
||||||
|
#include <QVariant>
|
||||||
|
#include <QtCore/qglobal.h>
|
||||||
|
#include <QtCore/qobjectdefs.h>
|
||||||
|
#include <fmt/core.h>
|
||||||
|
#include <qglobal.h>
|
||||||
|
#include <qnamespace.h>
|
||||||
|
|
||||||
|
#include "common/assert.h"
|
||||||
|
#include "common/common_types.h"
|
||||||
|
#include "common/logging/log.h"
|
||||||
|
#include "common/settings.h"
|
||||||
|
#include "common/settings_common.h"
|
||||||
|
#include "yuzu/configuration/shared_translation.h"
|
||||||
|
|
||||||
|
namespace ConfigurationShared {
|
||||||
|
|
||||||
|
static int restore_button_count = 0;
|
||||||
|
|
||||||
|
static std::string RelevantDefault(const Settings::BasicSetting& setting) {
|
||||||
|
return Settings::IsConfiguringGlobal() ? setting.DefaultToString() : setting.ToStringGlobal();
|
||||||
|
}
|
||||||
|
|
||||||
|
static QString DefaultSuffix(QWidget* parent, Settings::BasicSetting& setting) {
|
||||||
|
const auto tr = [parent](const char* text, const char* context) {
|
||||||
|
return parent->tr(text, context);
|
||||||
|
};
|
||||||
|
|
||||||
|
if ((setting.Specialization() & Settings::SpecializationAttributeMask) ==
|
||||||
|
Settings::Specialization::Percentage) {
|
||||||
|
std::string context{fmt::format("{} percentage (e.g. 50%)", setting.GetLabel())};
|
||||||
|
return tr("%", context.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
return QStringLiteral("");
|
||||||
|
}
|
||||||
|
|
||||||
|
QPushButton* Widget::CreateRestoreGlobalButton(bool using_global, QWidget* parent) {
|
||||||
|
restore_button_count++;
|
||||||
|
|
||||||
|
QStyle* style = parent->style();
|
||||||
|
QIcon* icon = new QIcon(style->standardIcon(QStyle::SP_LineEditClearButton));
|
||||||
|
QPushButton* restore_button = new QPushButton(*icon, QStringLiteral(""), parent);
|
||||||
|
restore_button->setObjectName(QStringLiteral("RestoreButton%1").arg(restore_button_count));
|
||||||
|
restore_button->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
|
||||||
|
|
||||||
|
// Workaround for dark theme causing min-width to be much larger than 0
|
||||||
|
restore_button->setStyleSheet(
|
||||||
|
QStringLiteral("QAbstractButton#%1 { min-width: 0px }").arg(restore_button->objectName()));
|
||||||
|
|
||||||
|
QSizePolicy sp_retain = restore_button->sizePolicy();
|
||||||
|
sp_retain.setRetainSizeWhenHidden(true);
|
||||||
|
restore_button->setSizePolicy(sp_retain);
|
||||||
|
|
||||||
|
restore_button->setEnabled(!using_global);
|
||||||
|
restore_button->setVisible(!using_global);
|
||||||
|
|
||||||
|
return restore_button;
|
||||||
|
}
|
||||||
|
|
||||||
|
QLabel* Widget::CreateLabel(const QString& text) {
|
||||||
|
QLabel* qt_label = new QLabel(text, this->parent);
|
||||||
|
qt_label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
|
||||||
|
return qt_label;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget* Widget::CreateCheckBox(Settings::BasicSetting* bool_setting, const QString& label,
|
||||||
|
std::function<std::string()>& serializer,
|
||||||
|
std::function<void()>& restore_func,
|
||||||
|
const std::function<void()>& touch) {
|
||||||
|
checkbox = new QCheckBox(label, this);
|
||||||
|
checkbox->setCheckState(bool_setting->ToString() == "true" ? Qt::CheckState::Checked
|
||||||
|
: Qt::CheckState::Unchecked);
|
||||||
|
checkbox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
|
||||||
|
|
||||||
|
if (!bool_setting->Save() && !Settings::IsConfiguringGlobal() && runtime_lock) {
|
||||||
|
checkbox->setEnabled(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
serializer = [this]() {
|
||||||
|
return checkbox->checkState() == Qt::CheckState::Checked ? "true" : "false";
|
||||||
|
};
|
||||||
|
|
||||||
|
restore_func = [this, bool_setting]() {
|
||||||
|
checkbox->setCheckState(RelevantDefault(*bool_setting) == "true" ? Qt::Checked
|
||||||
|
: Qt::Unchecked);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!Settings::IsConfiguringGlobal()) {
|
||||||
|
QObject::connect(checkbox, &QCheckBox::clicked, [touch]() { touch(); });
|
||||||
|
}
|
||||||
|
|
||||||
|
return checkbox;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget* Widget::CreateCombobox(std::function<std::string()>& serializer,
|
||||||
|
std::function<void()>& restore_func,
|
||||||
|
const std::function<void()>& touch) {
|
||||||
|
const auto type = setting.EnumIndex();
|
||||||
|
|
||||||
|
combobox = new QComboBox(this);
|
||||||
|
combobox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
|
||||||
|
|
||||||
|
const ComboboxTranslations* enumeration{nullptr};
|
||||||
|
if (combobox_enumerations.contains(type)) {
|
||||||
|
enumeration = &combobox_enumerations.at(type);
|
||||||
|
for (const auto& [id, name] : *enumeration) {
|
||||||
|
combobox->addItem(name);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return combobox;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto find_index = [=](u32 value) -> int {
|
||||||
|
for (u32 i = 0; i < enumeration->size(); i++) {
|
||||||
|
if (enumeration->at(i).first == value) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
};
|
||||||
|
|
||||||
|
const u32 setting_value = std::stoi(setting.ToString());
|
||||||
|
combobox->setCurrentIndex(find_index(setting_value));
|
||||||
|
|
||||||
|
serializer = [this, enumeration]() {
|
||||||
|
int current = combobox->currentIndex();
|
||||||
|
return std::to_string(enumeration->at(current).first);
|
||||||
|
};
|
||||||
|
|
||||||
|
restore_func = [this, find_index]() {
|
||||||
|
const u32 global_value = std::stoi(RelevantDefault(setting));
|
||||||
|
combobox->setCurrentIndex(find_index(global_value));
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!Settings::IsConfiguringGlobal()) {
|
||||||
|
QObject::connect(combobox, QOverload<int>::of(&QComboBox::activated),
|
||||||
|
[touch]() { touch(); });
|
||||||
|
}
|
||||||
|
|
||||||
|
return combobox;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget* Widget::CreateLineEdit(std::function<std::string()>& serializer,
|
||||||
|
std::function<void()>& restore_func,
|
||||||
|
const std::function<void()>& touch, bool managed) {
|
||||||
|
const QString text = QString::fromStdString(setting.ToString());
|
||||||
|
line_edit = new QLineEdit(this);
|
||||||
|
line_edit->setText(text);
|
||||||
|
|
||||||
|
serializer = [this]() { return line_edit->text().toStdString(); };
|
||||||
|
|
||||||
|
if (!managed) {
|
||||||
|
return line_edit;
|
||||||
|
}
|
||||||
|
|
||||||
|
restore_func = [this]() {
|
||||||
|
line_edit->setText(QString::fromStdString(RelevantDefault(setting)));
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!Settings::IsConfiguringGlobal()) {
|
||||||
|
QObject::connect(line_edit, &QLineEdit::textChanged, [touch]() { touch(); });
|
||||||
|
}
|
||||||
|
|
||||||
|
return line_edit;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget* Widget::CreateSlider(bool reversed, float multiplier, const QString& given_suffix,
|
||||||
|
std::function<std::string()>& serializer,
|
||||||
|
std::function<void()>& restore_func,
|
||||||
|
const std::function<void()>& touch) {
|
||||||
|
if (!setting.Ranged()) {
|
||||||
|
LOG_ERROR(Frontend, "\"{}\" is not a ranged setting, but a slider was requested.",
|
||||||
|
setting.GetLabel());
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget* container = new QWidget(this);
|
||||||
|
QHBoxLayout* layout = new QHBoxLayout(container);
|
||||||
|
|
||||||
|
slider = new QSlider(Qt::Horizontal, this);
|
||||||
|
QLabel* feedback = new QLabel(this);
|
||||||
|
|
||||||
|
layout->addWidget(slider);
|
||||||
|
layout->addWidget(feedback);
|
||||||
|
|
||||||
|
container->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
|
||||||
|
|
||||||
|
layout->setContentsMargins(0, 0, 0, 0);
|
||||||
|
|
||||||
|
int max_val = std::stoi(setting.MaxVal());
|
||||||
|
|
||||||
|
QString suffix =
|
||||||
|
given_suffix == QStringLiteral("") ? DefaultSuffix(this, setting) : given_suffix;
|
||||||
|
|
||||||
|
const QString use_format = QStringLiteral("%1").append(suffix);
|
||||||
|
|
||||||
|
QObject::connect(slider, &QAbstractSlider::valueChanged, [=](int value) {
|
||||||
|
int present = (reversed ? max_val - value : value) * multiplier + 0.5f;
|
||||||
|
feedback->setText(use_format.arg(QVariant::fromValue(present).value<QString>()));
|
||||||
|
});
|
||||||
|
|
||||||
|
slider->setMinimum(std::stoi(setting.MinVal()));
|
||||||
|
slider->setMaximum(max_val);
|
||||||
|
slider->setValue(std::stoi(setting.ToString()));
|
||||||
|
|
||||||
|
slider->setInvertedAppearance(reversed);
|
||||||
|
|
||||||
|
serializer = [this]() { return std::to_string(slider->value()); };
|
||||||
|
restore_func = [this]() { slider->setValue(std::stoi(RelevantDefault(setting))); };
|
||||||
|
|
||||||
|
if (!Settings::IsConfiguringGlobal()) {
|
||||||
|
QObject::connect(slider, &QAbstractSlider::actionTriggered, [touch]() { touch(); });
|
||||||
|
}
|
||||||
|
|
||||||
|
return container;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget* Widget::CreateSpinBox(const QString& given_suffix,
|
||||||
|
std::function<std::string()>& serializer,
|
||||||
|
std::function<void()>& restore_func,
|
||||||
|
const std::function<void()>& touch) {
|
||||||
|
const int min_val =
|
||||||
|
setting.Ranged() ? std::stoi(setting.MinVal()) : std::numeric_limits<int>::min();
|
||||||
|
const int max_val =
|
||||||
|
setting.Ranged() ? std::stoi(setting.MaxVal()) : std::numeric_limits<int>::max();
|
||||||
|
const int default_val = std::stoi(setting.ToString());
|
||||||
|
|
||||||
|
QString suffix =
|
||||||
|
given_suffix == QStringLiteral("") ? DefaultSuffix(this, setting) : given_suffix;
|
||||||
|
|
||||||
|
spinbox = new QSpinBox(this);
|
||||||
|
spinbox->setRange(min_val, max_val);
|
||||||
|
spinbox->setValue(default_val);
|
||||||
|
spinbox->setSuffix(suffix);
|
||||||
|
spinbox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
|
||||||
|
|
||||||
|
serializer = [this]() { return std::to_string(spinbox->value()); };
|
||||||
|
|
||||||
|
restore_func = [this]() {
|
||||||
|
auto value{std::stol(RelevantDefault(setting))};
|
||||||
|
spinbox->setValue(value);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!Settings::IsConfiguringGlobal()) {
|
||||||
|
QObject::connect(spinbox, QOverload<int>::of(&QSpinBox::valueChanged), [this, touch]() {
|
||||||
|
if (spinbox->value() != std::stoi(setting.ToStringGlobal())) {
|
||||||
|
touch();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return spinbox;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget* Widget::CreateHexEdit(std::function<std::string()>& serializer,
|
||||||
|
std::function<void()>& restore_func,
|
||||||
|
const std::function<void()>& touch) {
|
||||||
|
auto* data_component = CreateLineEdit(serializer, restore_func, touch, false);
|
||||||
|
if (data_component == nullptr) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto to_hex = [=](const std::string& input) {
|
||||||
|
return QString::fromStdString(fmt::format("{:08x}", std::stoul(input)));
|
||||||
|
};
|
||||||
|
|
||||||
|
QRegularExpressionValidator* regex = new QRegularExpressionValidator(
|
||||||
|
QRegularExpression{QStringLiteral("^[0-9a-fA-F]{0,8}$")}, line_edit);
|
||||||
|
|
||||||
|
const QString default_val = to_hex(setting.ToString());
|
||||||
|
|
||||||
|
line_edit->setText(default_val);
|
||||||
|
line_edit->setMaxLength(8);
|
||||||
|
line_edit->setValidator(regex);
|
||||||
|
|
||||||
|
auto hex_to_dec = [this]() -> std::string {
|
||||||
|
return std::to_string(std::stoul(line_edit->text().toStdString(), nullptr, 16));
|
||||||
|
};
|
||||||
|
|
||||||
|
serializer = [hex_to_dec]() { return hex_to_dec(); };
|
||||||
|
|
||||||
|
restore_func = [this, to_hex]() { line_edit->setText(to_hex(RelevantDefault(setting))); };
|
||||||
|
|
||||||
|
if (!Settings::IsConfiguringGlobal()) {
|
||||||
|
|
||||||
|
QObject::connect(line_edit, &QLineEdit::textChanged, [touch]() { touch(); });
|
||||||
|
}
|
||||||
|
|
||||||
|
return line_edit;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget* Widget::CreateDateTimeEdit(bool disabled, bool restrict,
|
||||||
|
std::function<std::string()>& serializer,
|
||||||
|
std::function<void()>& restore_func,
|
||||||
|
const std::function<void()>& touch) {
|
||||||
|
const long long current_time = QDateTime::currentSecsSinceEpoch();
|
||||||
|
const s64 the_time = disabled ? current_time : std::stoll(setting.ToString());
|
||||||
|
const auto default_val = QDateTime::fromSecsSinceEpoch(the_time);
|
||||||
|
|
||||||
|
date_time_edit = new QDateTimeEdit(this);
|
||||||
|
date_time_edit->setDateTime(default_val);
|
||||||
|
date_time_edit->setMinimumDateTime(QDateTime::fromSecsSinceEpoch(0));
|
||||||
|
date_time_edit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
|
||||||
|
|
||||||
|
serializer = [this]() { return std::to_string(date_time_edit->dateTime().toSecsSinceEpoch()); };
|
||||||
|
|
||||||
|
auto get_clear_val = [this, restrict, current_time]() {
|
||||||
|
return QDateTime::fromSecsSinceEpoch([this, restrict, current_time]() {
|
||||||
|
if (restrict && checkbox->checkState() == Qt::Checked) {
|
||||||
|
return std::stoll(RelevantDefault(setting));
|
||||||
|
}
|
||||||
|
return current_time;
|
||||||
|
}());
|
||||||
|
};
|
||||||
|
|
||||||
|
restore_func = [this, get_clear_val]() { date_time_edit->setDateTime(get_clear_val()); };
|
||||||
|
|
||||||
|
if (!Settings::IsConfiguringGlobal()) {
|
||||||
|
QObject::connect(date_time_edit, &QDateTimeEdit::editingFinished,
|
||||||
|
[this, get_clear_val, touch]() {
|
||||||
|
if (date_time_edit->dateTime() != get_clear_val()) {
|
||||||
|
touch();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return date_time_edit;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Widget::SetupComponent(const QString& label, std::function<void()>& load_func, bool managed,
|
||||||
|
RequestType request, float multiplier,
|
||||||
|
Settings::BasicSetting* other_setting, const QString& suffix) {
|
||||||
|
created = true;
|
||||||
|
const auto type = setting.TypeId();
|
||||||
|
|
||||||
|
QLayout* layout = new QHBoxLayout(this);
|
||||||
|
layout->setContentsMargins(0, 0, 0, 0);
|
||||||
|
|
||||||
|
if (other_setting == nullptr) {
|
||||||
|
other_setting = setting.PairedSetting();
|
||||||
|
}
|
||||||
|
|
||||||
|
const bool require_checkbox =
|
||||||
|
other_setting != nullptr && other_setting->TypeId() == typeid(bool);
|
||||||
|
|
||||||
|
if (other_setting != nullptr && other_setting->TypeId() != typeid(bool)) {
|
||||||
|
LOG_WARNING(
|
||||||
|
Frontend,
|
||||||
|
"Extra setting \"{}\" specified but is not bool, refusing to create checkbox for it.",
|
||||||
|
other_setting->GetLabel());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::function<std::string()> checkbox_serializer = []() -> std::string { return {}; };
|
||||||
|
std::function<void()> checkbox_restore_func = []() {};
|
||||||
|
|
||||||
|
std::function<void()> touch = []() {};
|
||||||
|
std::function<std::string()> serializer = []() -> std::string { return {}; };
|
||||||
|
std::function<void()> restore_func = []() {};
|
||||||
|
|
||||||
|
QWidget* data_component{nullptr};
|
||||||
|
|
||||||
|
request = [&]() {
|
||||||
|
if (request != RequestType::Default) {
|
||||||
|
return request;
|
||||||
|
}
|
||||||
|
switch (setting.Specialization() & Settings::SpecializationTypeMask) {
|
||||||
|
case Settings::Specialization::Default:
|
||||||
|
return RequestType::Default;
|
||||||
|
case Settings::Specialization::Time:
|
||||||
|
return RequestType::DateTimeEdit;
|
||||||
|
case Settings::Specialization::Hex:
|
||||||
|
return RequestType::HexEdit;
|
||||||
|
case Settings::Specialization::RuntimeList:
|
||||||
|
managed = false;
|
||||||
|
[[fallthrough]];
|
||||||
|
case Settings::Specialization::List:
|
||||||
|
return RequestType::ComboBox;
|
||||||
|
case Settings::Specialization::Scalar:
|
||||||
|
return RequestType::Slider;
|
||||||
|
case Settings::Specialization::Countable:
|
||||||
|
return RequestType::SpinBox;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return request;
|
||||||
|
}();
|
||||||
|
|
||||||
|
if (!Settings::IsConfiguringGlobal() && managed) {
|
||||||
|
restore_button = CreateRestoreGlobalButton(setting.UsingGlobal(), this);
|
||||||
|
|
||||||
|
touch = [this]() {
|
||||||
|
LOG_DEBUG(Frontend, "Enabling custom setting for \"{}\"", setting.GetLabel());
|
||||||
|
restore_button->setEnabled(true);
|
||||||
|
restore_button->setVisible(true);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (require_checkbox) {
|
||||||
|
QWidget* lhs =
|
||||||
|
CreateCheckBox(other_setting, label, checkbox_serializer, checkbox_restore_func, touch);
|
||||||
|
layout->addWidget(lhs);
|
||||||
|
} else if (setting.TypeId() != typeid(bool)) {
|
||||||
|
QLabel* qt_label = CreateLabel(label);
|
||||||
|
layout->addWidget(qt_label);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (setting.TypeId() == typeid(bool)) {
|
||||||
|
data_component = CreateCheckBox(&setting, label, serializer, restore_func, touch);
|
||||||
|
} else if (setting.IsEnum()) {
|
||||||
|
data_component = CreateCombobox(serializer, restore_func, touch);
|
||||||
|
} else if (type == typeid(u32) || type == typeid(int) || type == typeid(u16) ||
|
||||||
|
type == typeid(s64) || type == typeid(u8)) {
|
||||||
|
switch (request) {
|
||||||
|
case RequestType::Slider:
|
||||||
|
case RequestType::ReverseSlider:
|
||||||
|
data_component = CreateSlider(request == RequestType::ReverseSlider, multiplier, suffix,
|
||||||
|
serializer, restore_func, touch);
|
||||||
|
break;
|
||||||
|
case RequestType::Default:
|
||||||
|
case RequestType::LineEdit:
|
||||||
|
data_component = CreateLineEdit(serializer, restore_func, touch);
|
||||||
|
break;
|
||||||
|
case RequestType::DateTimeEdit:
|
||||||
|
data_component = CreateDateTimeEdit(other_setting->ToString() != "true", true,
|
||||||
|
serializer, restore_func, touch);
|
||||||
|
break;
|
||||||
|
case RequestType::SpinBox:
|
||||||
|
data_component = CreateSpinBox(suffix, serializer, restore_func, touch);
|
||||||
|
break;
|
||||||
|
case RequestType::HexEdit:
|
||||||
|
data_component = CreateHexEdit(serializer, restore_func, touch);
|
||||||
|
break;
|
||||||
|
case RequestType::ComboBox:
|
||||||
|
data_component = CreateCombobox(serializer, restore_func, touch);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
UNIMPLEMENTED();
|
||||||
|
}
|
||||||
|
} else if (type == typeid(std::string)) {
|
||||||
|
switch (request) {
|
||||||
|
case RequestType::Default:
|
||||||
|
case RequestType::LineEdit:
|
||||||
|
data_component = CreateLineEdit(serializer, restore_func, touch);
|
||||||
|
break;
|
||||||
|
case RequestType::ComboBox:
|
||||||
|
data_component = CreateCombobox(serializer, restore_func, touch);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
UNIMPLEMENTED();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data_component == nullptr) {
|
||||||
|
LOG_ERROR(Frontend, "Failed to create widget for \"{}\"", setting.GetLabel());
|
||||||
|
created = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
layout->addWidget(data_component);
|
||||||
|
|
||||||
|
if (!managed) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Settings::IsConfiguringGlobal()) {
|
||||||
|
load_func = [this, serializer, checkbox_serializer, require_checkbox, other_setting]() {
|
||||||
|
if (require_checkbox && other_setting->UsingGlobal()) {
|
||||||
|
other_setting->LoadString(checkbox_serializer());
|
||||||
|
}
|
||||||
|
if (setting.UsingGlobal()) {
|
||||||
|
setting.LoadString(serializer());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
layout->addWidget(restore_button);
|
||||||
|
|
||||||
|
QObject::connect(restore_button, &QAbstractButton::clicked,
|
||||||
|
[this, restore_func, checkbox_restore_func](bool) {
|
||||||
|
LOG_DEBUG(Frontend, "Restore global state for \"{}\"",
|
||||||
|
setting.GetLabel());
|
||||||
|
|
||||||
|
restore_button->setEnabled(false);
|
||||||
|
restore_button->setVisible(false);
|
||||||
|
|
||||||
|
checkbox_restore_func();
|
||||||
|
restore_func();
|
||||||
|
});
|
||||||
|
|
||||||
|
load_func = [this, serializer, require_checkbox, checkbox_serializer, other_setting]() {
|
||||||
|
bool using_global = !restore_button->isEnabled();
|
||||||
|
setting.SetGlobal(using_global);
|
||||||
|
if (!using_global) {
|
||||||
|
setting.LoadString(serializer());
|
||||||
|
}
|
||||||
|
if (require_checkbox) {
|
||||||
|
other_setting->SetGlobal(using_global);
|
||||||
|
if (!using_global) {
|
||||||
|
other_setting->LoadString(checkbox_serializer());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (other_setting != nullptr) {
|
||||||
|
const auto reset = [restore_func, data_component](int state) {
|
||||||
|
data_component->setEnabled(state == Qt::Checked);
|
||||||
|
if (state != Qt::Checked) {
|
||||||
|
restore_func();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
connect(checkbox, &QCheckBox::stateChanged, reset);
|
||||||
|
reset(checkbox->checkState());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Widget::Valid() const {
|
||||||
|
return created;
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget::~Widget() = default;
|
||||||
|
|
||||||
|
Widget::Widget(Settings::BasicSetting* setting_, const TranslationMap& translations_,
|
||||||
|
const ComboboxTranslationMap& combobox_translations_, QWidget* parent_,
|
||||||
|
bool runtime_lock_, std::vector<std::function<void(bool)>>& apply_funcs_,
|
||||||
|
RequestType request, bool managed, float multiplier,
|
||||||
|
Settings::BasicSetting* other_setting, const QString& suffix)
|
||||||
|
: QWidget(parent_), parent{parent_}, translations{translations_},
|
||||||
|
combobox_enumerations{combobox_translations_}, setting{*setting_}, apply_funcs{apply_funcs_},
|
||||||
|
runtime_lock{runtime_lock_} {
|
||||||
|
if (!Settings::IsConfiguringGlobal() && !setting.Switchable()) {
|
||||||
|
LOG_DEBUG(Frontend, "\"{}\" is not switchable, skipping...", setting.GetLabel());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int id = setting.Id();
|
||||||
|
|
||||||
|
const auto [label, tooltip] = [&]() {
|
||||||
|
const auto& setting_label = setting.GetLabel();
|
||||||
|
if (translations.contains(id)) {
|
||||||
|
return std::pair{translations.at(id).first, translations.at(id).second};
|
||||||
|
}
|
||||||
|
LOG_WARNING(Frontend, "Translation table lacks entry for \"{}\"", setting_label);
|
||||||
|
return std::pair{QString::fromStdString(setting_label), QStringLiteral("")};
|
||||||
|
}();
|
||||||
|
|
||||||
|
if (label == QStringLiteral("")) {
|
||||||
|
LOG_DEBUG(Frontend, "Translation table has empty entry for \"{}\", skipping...",
|
||||||
|
setting.GetLabel());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::function<void()> load_func = []() {};
|
||||||
|
|
||||||
|
SetupComponent(label, load_func, managed, request, multiplier, other_setting, suffix);
|
||||||
|
|
||||||
|
if (!created) {
|
||||||
|
LOG_WARNING(Frontend, "No widget was created for \"{}\"", setting.GetLabel());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
apply_funcs.push_back([load_func, setting_](bool powered_on) {
|
||||||
|
if (setting_->RuntimeModfiable() || !powered_on) {
|
||||||
|
load_func();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
bool enable = runtime_lock || setting.RuntimeModfiable();
|
||||||
|
if (setting.Switchable() && Settings::IsConfiguringGlobal() && !runtime_lock) {
|
||||||
|
enable &= setting.UsingGlobal();
|
||||||
|
}
|
||||||
|
this->setEnabled(enable);
|
||||||
|
|
||||||
|
this->setToolTip(tooltip);
|
||||||
|
}
|
||||||
|
|
||||||
|
Builder::Builder(QWidget* parent_, bool runtime_lock_)
|
||||||
|
: translations{InitializeTranslations(parent_)},
|
||||||
|
combobox_translations{ComboboxEnumeration(parent_)}, parent{parent_}, runtime_lock{
|
||||||
|
runtime_lock_} {}
|
||||||
|
|
||||||
|
Builder::~Builder() = default;
|
||||||
|
|
||||||
|
Widget* Builder::BuildWidget(Settings::BasicSetting* setting,
|
||||||
|
std::vector<std::function<void(bool)>>& apply_funcs,
|
||||||
|
RequestType request, bool managed, float multiplier,
|
||||||
|
Settings::BasicSetting* other_setting, const QString& suffix) const {
|
||||||
|
if (!Settings::IsConfiguringGlobal() && !setting->Switchable()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (setting->Specialization() == Settings::Specialization::Paired) {
|
||||||
|
LOG_DEBUG(Frontend, "\"{}\" has specialization Paired: ignoring", setting->GetLabel());
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Widget(setting, *translations, *combobox_translations, parent, runtime_lock,
|
||||||
|
apply_funcs, request, managed, multiplier, other_setting, suffix);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget* Builder::BuildWidget(Settings::BasicSetting* setting,
|
||||||
|
std::vector<std::function<void(bool)>>& apply_funcs,
|
||||||
|
Settings::BasicSetting* other_setting, RequestType request,
|
||||||
|
const QString& suffix) const {
|
||||||
|
return BuildWidget(setting, apply_funcs, request, true, 1.0f, other_setting, suffix);
|
||||||
|
}
|
||||||
|
|
||||||
|
const ComboboxTranslationMap& Builder::ComboboxTranslations() const {
|
||||||
|
return *combobox_translations;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ConfigurationShared
|
|
@ -0,0 +1,161 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <QString>
|
||||||
|
#include <QStringLiteral>
|
||||||
|
#include <QWidget>
|
||||||
|
#include <qobjectdefs.h>
|
||||||
|
#include "yuzu/configuration/shared_translation.h"
|
||||||
|
|
||||||
|
class QCheckBox;
|
||||||
|
class QComboBox;
|
||||||
|
class QDateTimeEdit;
|
||||||
|
class QLabel;
|
||||||
|
class QLineEdit;
|
||||||
|
class QObject;
|
||||||
|
class QPushButton;
|
||||||
|
class QSlider;
|
||||||
|
class QSpinBox;
|
||||||
|
|
||||||
|
namespace Settings {
|
||||||
|
class BasicSetting;
|
||||||
|
} // namespace Settings
|
||||||
|
|
||||||
|
namespace ConfigurationShared {
|
||||||
|
|
||||||
|
enum class RequestType {
|
||||||
|
Default,
|
||||||
|
ComboBox,
|
||||||
|
SpinBox,
|
||||||
|
Slider,
|
||||||
|
ReverseSlider,
|
||||||
|
LineEdit,
|
||||||
|
HexEdit,
|
||||||
|
DateTimeEdit,
|
||||||
|
MaxEnum,
|
||||||
|
};
|
||||||
|
|
||||||
|
class Widget : public QWidget {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @param setting The primary Setting to create the Widget for
|
||||||
|
* @param translations Map of translations to display on the left side label/checkbox
|
||||||
|
* @param combobox_translations Map of translations for enumerating combo boxes
|
||||||
|
* @param parent Qt parent
|
||||||
|
* @param runtime_lock Emulated guest powered on state, for use on settings that should be
|
||||||
|
* configured during guest execution
|
||||||
|
* @param apply_funcs_ List to append, functions to run to apply the widget state to the setting
|
||||||
|
* @param request What type of data representation component to create -- not always respected
|
||||||
|
* for the Setting data type
|
||||||
|
* @param managed Set true if the caller will set up component data and handling
|
||||||
|
* @param multiplier Value to multiply the slider feedback label
|
||||||
|
* @param other_setting Second setting to modify, to replace the label with a checkbox
|
||||||
|
* @param suffix Set to specify formats for Slider feedback labels or SpinBox
|
||||||
|
*/
|
||||||
|
explicit Widget(Settings::BasicSetting* setting, const TranslationMap& translations,
|
||||||
|
const ComboboxTranslationMap& combobox_translations, QWidget* parent,
|
||||||
|
bool runtime_lock, std::vector<std::function<void(bool)>>& apply_funcs_,
|
||||||
|
RequestType request = RequestType::Default, bool managed = true,
|
||||||
|
float multiplier = 1.0f, Settings::BasicSetting* other_setting = nullptr,
|
||||||
|
const QString& suffix = QStringLiteral(""));
|
||||||
|
virtual ~Widget();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns True if the Widget successfully created the components for the setting
|
||||||
|
*/
|
||||||
|
bool Valid() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a button to appear when a setting has been modified. This exists for custom
|
||||||
|
* configurations and wasn't designed to work for the global configuration. It has public access
|
||||||
|
* for settings that need to be unmanaged but can be custom.
|
||||||
|
*
|
||||||
|
* @param using_global The global state of the setting this button is for
|
||||||
|
* @param parent QWidget parent
|
||||||
|
*/
|
||||||
|
[[nodiscard]] static QPushButton* CreateRestoreGlobalButton(bool using_global, QWidget* parent);
|
||||||
|
|
||||||
|
// Direct handles to sub components created
|
||||||
|
QPushButton* restore_button{}; ///< Restore button for custom configurations
|
||||||
|
QLineEdit* line_edit{}; ///< QLineEdit, used for LineEdit and HexEdit
|
||||||
|
QSpinBox* spinbox{};
|
||||||
|
QCheckBox* checkbox{};
|
||||||
|
QSlider* slider{};
|
||||||
|
QComboBox* combobox{};
|
||||||
|
QDateTimeEdit* date_time_edit{};
|
||||||
|
|
||||||
|
private:
|
||||||
|
void SetupComponent(const QString& label, std::function<void()>& load_func, bool managed,
|
||||||
|
RequestType request, float multiplier,
|
||||||
|
Settings::BasicSetting* other_setting, const QString& suffix);
|
||||||
|
|
||||||
|
QLabel* CreateLabel(const QString& text);
|
||||||
|
QWidget* CreateCheckBox(Settings::BasicSetting* bool_setting, const QString& label,
|
||||||
|
std::function<std::string()>& serializer,
|
||||||
|
std::function<void()>& restore_func,
|
||||||
|
const std::function<void()>& touch);
|
||||||
|
|
||||||
|
QWidget* CreateCombobox(std::function<std::string()>& serializer,
|
||||||
|
std::function<void()>& restore_func,
|
||||||
|
const std::function<void()>& touch);
|
||||||
|
QWidget* CreateLineEdit(std::function<std::string()>& serializer,
|
||||||
|
std::function<void()>& restore_func, const std::function<void()>& touch,
|
||||||
|
bool managed = true);
|
||||||
|
QWidget* CreateHexEdit(std::function<std::string()>& serializer,
|
||||||
|
std::function<void()>& restore_func, const std::function<void()>& touch);
|
||||||
|
QWidget* CreateSlider(bool reversed, float multiplier, const QString& suffix,
|
||||||
|
std::function<std::string()>& serializer,
|
||||||
|
std::function<void()>& restore_func, const std::function<void()>& touch);
|
||||||
|
QWidget* CreateDateTimeEdit(bool disabled, bool restrict,
|
||||||
|
std::function<std::string()>& serializer,
|
||||||
|
std::function<void()>& restore_func,
|
||||||
|
const std::function<void()>& touch);
|
||||||
|
QWidget* CreateSpinBox(const QString& suffix, std::function<std::string()>& serializer,
|
||||||
|
std::function<void()>& restore_func, const std::function<void()>& touch);
|
||||||
|
|
||||||
|
QWidget* parent;
|
||||||
|
const TranslationMap& translations;
|
||||||
|
const ComboboxTranslationMap& combobox_enumerations;
|
||||||
|
Settings::BasicSetting& setting;
|
||||||
|
std::vector<std::function<void(bool)>>& apply_funcs;
|
||||||
|
|
||||||
|
bool created{false};
|
||||||
|
bool runtime_lock{false};
|
||||||
|
};
|
||||||
|
|
||||||
|
class Builder {
|
||||||
|
public:
|
||||||
|
explicit Builder(QWidget* parent, bool runtime_lock);
|
||||||
|
~Builder();
|
||||||
|
|
||||||
|
Widget* BuildWidget(Settings::BasicSetting* setting,
|
||||||
|
std::vector<std::function<void(bool)>>& apply_funcs,
|
||||||
|
RequestType request = RequestType::Default, bool managed = true,
|
||||||
|
float multiplier = 1.0f, Settings::BasicSetting* other_setting = nullptr,
|
||||||
|
const QString& suffix = QStringLiteral("")) const;
|
||||||
|
|
||||||
|
Widget* BuildWidget(Settings::BasicSetting* setting,
|
||||||
|
std::vector<std::function<void(bool)>>& apply_funcs,
|
||||||
|
Settings::BasicSetting* other_setting,
|
||||||
|
RequestType request = RequestType::Default,
|
||||||
|
const QString& suffix = QStringLiteral("")) const;
|
||||||
|
|
||||||
|
const ComboboxTranslationMap& ComboboxTranslations() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::unique_ptr<TranslationMap> translations;
|
||||||
|
std::unique_ptr<ComboboxTranslationMap> combobox_translations;
|
||||||
|
|
||||||
|
QWidget* parent;
|
||||||
|
const bool runtime_lock;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ConfigurationShared
|
|
@ -24,6 +24,7 @@
|
||||||
#include "applets/qt_software_keyboard.h"
|
#include "applets/qt_software_keyboard.h"
|
||||||
#include "applets/qt_web_browser.h"
|
#include "applets/qt_web_browser.h"
|
||||||
#include "common/nvidia_flags.h"
|
#include "common/nvidia_flags.h"
|
||||||
|
#include "common/settings_enums.h"
|
||||||
#include "configuration/configure_input.h"
|
#include "configuration/configure_input.h"
|
||||||
#include "configuration/configure_per_game.h"
|
#include "configuration/configure_per_game.h"
|
||||||
#include "configuration/configure_tas.h"
|
#include "configuration/configure_tas.h"
|
||||||
|
@ -1095,10 +1096,9 @@ void GMainWindow::InitializeWidgets() {
|
||||||
aa_status_button->setFocusPolicy(Qt::NoFocus);
|
aa_status_button->setFocusPolicy(Qt::NoFocus);
|
||||||
connect(aa_status_button, &QPushButton::clicked, [&] {
|
connect(aa_status_button, &QPushButton::clicked, [&] {
|
||||||
auto aa_mode = Settings::values.anti_aliasing.GetValue();
|
auto aa_mode = Settings::values.anti_aliasing.GetValue();
|
||||||
if (aa_mode == Settings::AntiAliasing::LastAA) {
|
|
||||||
aa_mode = Settings::AntiAliasing::None;
|
|
||||||
} else {
|
|
||||||
aa_mode = static_cast<Settings::AntiAliasing>(static_cast<u32>(aa_mode) + 1);
|
aa_mode = static_cast<Settings::AntiAliasing>(static_cast<u32>(aa_mode) + 1);
|
||||||
|
if (aa_mode == Settings::AntiAliasing::MaxEnum) {
|
||||||
|
aa_mode = Settings::AntiAliasing::None;
|
||||||
}
|
}
|
||||||
Settings::values.anti_aliasing.SetValue(aa_mode);
|
Settings::values.anti_aliasing.SetValue(aa_mode);
|
||||||
aa_status_button->setChecked(true);
|
aa_status_button->setChecked(true);
|
||||||
|
@ -1183,7 +1183,7 @@ void GMainWindow::InitializeWidgets() {
|
||||||
QMenu context_menu;
|
QMenu context_menu;
|
||||||
|
|
||||||
for (auto const& gpu_accuracy_pair : Config::gpu_accuracy_texts_map) {
|
for (auto const& gpu_accuracy_pair : Config::gpu_accuracy_texts_map) {
|
||||||
if (gpu_accuracy_pair.first == Settings::GPUAccuracy::Extreme) {
|
if (gpu_accuracy_pair.first == Settings::GpuAccuracy::Extreme) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
context_menu.addAction(gpu_accuracy_pair.second, [this, gpu_accuracy_pair] {
|
context_menu.addAction(gpu_accuracy_pair.second, [this, gpu_accuracy_pair] {
|
||||||
|
@ -3651,14 +3651,14 @@ void GMainWindow::OnToggleDockedMode() {
|
||||||
|
|
||||||
void GMainWindow::OnToggleGpuAccuracy() {
|
void GMainWindow::OnToggleGpuAccuracy() {
|
||||||
switch (Settings::values.gpu_accuracy.GetValue()) {
|
switch (Settings::values.gpu_accuracy.GetValue()) {
|
||||||
case Settings::GPUAccuracy::High: {
|
case Settings::GpuAccuracy::High: {
|
||||||
Settings::values.gpu_accuracy.SetValue(Settings::GPUAccuracy::Normal);
|
Settings::values.gpu_accuracy.SetValue(Settings::GpuAccuracy::Normal);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Settings::GPUAccuracy::Normal:
|
case Settings::GpuAccuracy::Normal:
|
||||||
case Settings::GPUAccuracy::Extreme:
|
case Settings::GpuAccuracy::Extreme:
|
||||||
default: {
|
default: {
|
||||||
Settings::values.gpu_accuracy.SetValue(Settings::GPUAccuracy::High);
|
Settings::values.gpu_accuracy.SetValue(Settings::GpuAccuracy::High);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3702,10 +3702,9 @@ void GMainWindow::OnIncreaseVolume() {
|
||||||
|
|
||||||
void GMainWindow::OnToggleAdaptingFilter() {
|
void GMainWindow::OnToggleAdaptingFilter() {
|
||||||
auto filter = Settings::values.scaling_filter.GetValue();
|
auto filter = Settings::values.scaling_filter.GetValue();
|
||||||
if (filter == Settings::ScalingFilter::LastFilter) {
|
|
||||||
filter = Settings::ScalingFilter::NearestNeighbor;
|
|
||||||
} else {
|
|
||||||
filter = static_cast<Settings::ScalingFilter>(static_cast<u32>(filter) + 1);
|
filter = static_cast<Settings::ScalingFilter>(static_cast<u32>(filter) + 1);
|
||||||
|
if (filter == Settings::ScalingFilter::MaxEnum) {
|
||||||
|
filter = Settings::ScalingFilter::NearestNeighbor;
|
||||||
}
|
}
|
||||||
Settings::values.scaling_filter.SetValue(filter);
|
Settings::values.scaling_filter.SetValue(filter);
|
||||||
filter_status_button->setChecked(true);
|
filter_status_button->setChecked(true);
|
||||||
|
@ -4071,7 +4070,7 @@ void GMainWindow::UpdateGPUAccuracyButton() {
|
||||||
const auto gpu_accuracy = Settings::values.gpu_accuracy.GetValue();
|
const auto gpu_accuracy = Settings::values.gpu_accuracy.GetValue();
|
||||||
const auto gpu_accuracy_text = Config::gpu_accuracy_texts_map.find(gpu_accuracy)->second;
|
const auto gpu_accuracy_text = Config::gpu_accuracy_texts_map.find(gpu_accuracy)->second;
|
||||||
gpu_accuracy_button->setText(gpu_accuracy_text.toUpper());
|
gpu_accuracy_button->setText(gpu_accuracy_text.toUpper());
|
||||||
gpu_accuracy_button->setChecked(gpu_accuracy != Settings::GPUAccuracy::Normal);
|
gpu_accuracy_button->setChecked(gpu_accuracy != Settings::GpuAccuracy::Normal);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GMainWindow::UpdateDockedButton() {
|
void GMainWindow::UpdateDockedButton() {
|
||||||
|
|
|
@ -34,13 +34,14 @@ DirectConnectWindow::DirectConnectWindow(Core::System& system_, QWidget* parent)
|
||||||
connect(watcher, &QFutureWatcher<void>::finished, this, &DirectConnectWindow::OnConnection);
|
connect(watcher, &QFutureWatcher<void>::finished, this, &DirectConnectWindow::OnConnection);
|
||||||
|
|
||||||
ui->nickname->setValidator(validation.GetNickname());
|
ui->nickname->setValidator(validation.GetNickname());
|
||||||
ui->nickname->setText(UISettings::values.multiplayer_nickname.GetValue());
|
ui->nickname->setText(
|
||||||
|
QString::fromStdString(UISettings::values.multiplayer_nickname.GetValue()));
|
||||||
if (ui->nickname->text().isEmpty() && !Settings::values.yuzu_username.GetValue().empty()) {
|
if (ui->nickname->text().isEmpty() && !Settings::values.yuzu_username.GetValue().empty()) {
|
||||||
// Use yuzu Web Service user name as nickname by default
|
// Use yuzu Web Service user name as nickname by default
|
||||||
ui->nickname->setText(QString::fromStdString(Settings::values.yuzu_username.GetValue()));
|
ui->nickname->setText(QString::fromStdString(Settings::values.yuzu_username.GetValue()));
|
||||||
}
|
}
|
||||||
ui->ip->setValidator(validation.GetIP());
|
ui->ip->setValidator(validation.GetIP());
|
||||||
ui->ip->setText(UISettings::values.multiplayer_ip.GetValue());
|
ui->ip->setText(QString::fromStdString(UISettings::values.multiplayer_ip.GetValue()));
|
||||||
ui->port->setValidator(validation.GetPort());
|
ui->port->setValidator(validation.GetPort());
|
||||||
ui->port->setText(QString::number(UISettings::values.multiplayer_port.GetValue()));
|
ui->port->setText(QString::number(UISettings::values.multiplayer_port.GetValue()));
|
||||||
|
|
||||||
|
@ -91,8 +92,8 @@ void DirectConnectWindow::Connect() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store settings
|
// Store settings
|
||||||
UISettings::values.multiplayer_nickname = ui->nickname->text();
|
UISettings::values.multiplayer_nickname = ui->nickname->text().toStdString();
|
||||||
UISettings::values.multiplayer_ip = ui->ip->text();
|
UISettings::values.multiplayer_ip = ui->ip->text().toStdString();
|
||||||
if (ui->port->isModified() && !ui->port->text().isEmpty()) {
|
if (ui->port->isModified() && !ui->port->text().isEmpty()) {
|
||||||
UISettings::values.multiplayer_port = ui->port->text().toInt();
|
UISettings::values.multiplayer_port = ui->port->text().toInt();
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -55,12 +55,14 @@ HostRoomWindow::HostRoomWindow(QWidget* parent, QStandardItemModel* list,
|
||||||
connect(ui->host, &QPushButton::clicked, this, &HostRoomWindow::Host);
|
connect(ui->host, &QPushButton::clicked, this, &HostRoomWindow::Host);
|
||||||
|
|
||||||
// Restore the settings:
|
// Restore the settings:
|
||||||
ui->username->setText(UISettings::values.multiplayer_room_nickname.GetValue());
|
ui->username->setText(
|
||||||
|
QString::fromStdString(UISettings::values.multiplayer_room_nickname.GetValue()));
|
||||||
if (ui->username->text().isEmpty() && !Settings::values.yuzu_username.GetValue().empty()) {
|
if (ui->username->text().isEmpty() && !Settings::values.yuzu_username.GetValue().empty()) {
|
||||||
// Use yuzu Web Service user name as nickname by default
|
// Use yuzu Web Service user name as nickname by default
|
||||||
ui->username->setText(QString::fromStdString(Settings::values.yuzu_username.GetValue()));
|
ui->username->setText(QString::fromStdString(Settings::values.yuzu_username.GetValue()));
|
||||||
}
|
}
|
||||||
ui->room_name->setText(UISettings::values.multiplayer_room_name.GetValue());
|
ui->room_name->setText(
|
||||||
|
QString::fromStdString(UISettings::values.multiplayer_room_name.GetValue()));
|
||||||
ui->port->setText(QString::number(UISettings::values.multiplayer_room_port.GetValue()));
|
ui->port->setText(QString::number(UISettings::values.multiplayer_room_port.GetValue()));
|
||||||
ui->max_player->setValue(UISettings::values.multiplayer_max_player.GetValue());
|
ui->max_player->setValue(UISettings::values.multiplayer_max_player.GetValue());
|
||||||
int index = UISettings::values.multiplayer_host_type.GetValue();
|
int index = UISettings::values.multiplayer_host_type.GetValue();
|
||||||
|
@ -72,7 +74,8 @@ HostRoomWindow::HostRoomWindow(QWidget* parent, QStandardItemModel* list,
|
||||||
if (index != -1) {
|
if (index != -1) {
|
||||||
ui->game_list->setCurrentIndex(index);
|
ui->game_list->setCurrentIndex(index);
|
||||||
}
|
}
|
||||||
ui->room_description->setText(UISettings::values.multiplayer_room_description.GetValue());
|
ui->room_description->setText(
|
||||||
|
QString::fromStdString(UISettings::values.multiplayer_room_description.GetValue()));
|
||||||
}
|
}
|
||||||
|
|
||||||
HostRoomWindow::~HostRoomWindow() = default;
|
HostRoomWindow::~HostRoomWindow() = default;
|
||||||
|
@ -218,8 +221,8 @@ void HostRoomWindow::Host() {
|
||||||
Network::NoPreferredIP, password, token);
|
Network::NoPreferredIP, password, token);
|
||||||
|
|
||||||
// Store settings
|
// Store settings
|
||||||
UISettings::values.multiplayer_room_nickname = ui->username->text();
|
UISettings::values.multiplayer_room_nickname = ui->username->text().toStdString();
|
||||||
UISettings::values.multiplayer_room_name = ui->room_name->text();
|
UISettings::values.multiplayer_room_name = ui->room_name->text().toStdString();
|
||||||
UISettings::values.multiplayer_game_id =
|
UISettings::values.multiplayer_game_id =
|
||||||
ui->game_list->currentData(GameListItemPath::ProgramIdRole).toLongLong();
|
ui->game_list->currentData(GameListItemPath::ProgramIdRole).toLongLong();
|
||||||
UISettings::values.multiplayer_max_player = ui->max_player->value();
|
UISettings::values.multiplayer_max_player = ui->max_player->value();
|
||||||
|
@ -230,7 +233,8 @@ void HostRoomWindow::Host() {
|
||||||
} else {
|
} else {
|
||||||
UISettings::values.multiplayer_room_port = Network::DefaultRoomPort;
|
UISettings::values.multiplayer_room_port = Network::DefaultRoomPort;
|
||||||
}
|
}
|
||||||
UISettings::values.multiplayer_room_description = ui->room_description->toPlainText();
|
UISettings::values.multiplayer_room_description =
|
||||||
|
ui->room_description->toPlainText().toStdString();
|
||||||
ui->host->setEnabled(true);
|
ui->host->setEnabled(true);
|
||||||
emit SaveConfig();
|
emit SaveConfig();
|
||||||
close();
|
close();
|
||||||
|
|
|
@ -60,7 +60,8 @@ Lobby::Lobby(QWidget* parent, QStandardItemModel* list,
|
||||||
ui->room_list->setContextMenuPolicy(Qt::CustomContextMenu);
|
ui->room_list->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||||
|
|
||||||
ui->nickname->setValidator(validation.GetNickname());
|
ui->nickname->setValidator(validation.GetNickname());
|
||||||
ui->nickname->setText(UISettings::values.multiplayer_nickname.GetValue());
|
ui->nickname->setText(
|
||||||
|
QString::fromStdString(UISettings::values.multiplayer_nickname.GetValue()));
|
||||||
|
|
||||||
// Try find the best nickname by default
|
// Try find the best nickname by default
|
||||||
if (ui->nickname->text().isEmpty() || ui->nickname->text() == QStringLiteral("yuzu")) {
|
if (ui->nickname->text().isEmpty() || ui->nickname->text() == QStringLiteral("yuzu")) {
|
||||||
|
@ -202,9 +203,9 @@ void Lobby::OnJoinRoom(const QModelIndex& source) {
|
||||||
// TODO(jroweboy): disable widgets and display a connecting while we wait
|
// TODO(jroweboy): disable widgets and display a connecting while we wait
|
||||||
|
|
||||||
// Save settings
|
// Save settings
|
||||||
UISettings::values.multiplayer_nickname = ui->nickname->text();
|
UISettings::values.multiplayer_nickname = ui->nickname->text().toStdString();
|
||||||
UISettings::values.multiplayer_ip =
|
UISettings::values.multiplayer_ip =
|
||||||
proxy->data(connection_index, LobbyItemHost::HostIPRole).toString();
|
proxy->data(connection_index, LobbyItemHost::HostIPRole).value<QString>().toStdString();
|
||||||
UISettings::values.multiplayer_port =
|
UISettings::values.multiplayer_port =
|
||||||
proxy->data(connection_index, LobbyItemHost::HostPortRole).toInt();
|
proxy->data(connection_index, LobbyItemHost::HostPortRole).toInt();
|
||||||
emit SaveConfig();
|
emit SaveConfig();
|
||||||
|
|
|
@ -3,6 +3,18 @@
|
||||||
|
|
||||||
#include "yuzu/uisettings.h"
|
#include "yuzu/uisettings.h"
|
||||||
|
|
||||||
|
#ifndef CANNOT_EXPLICITLY_INSTANTIATE
|
||||||
|
namespace Settings {
|
||||||
|
template class Setting<bool>;
|
||||||
|
template class Setting<std::string>;
|
||||||
|
template class Setting<u16, true>;
|
||||||
|
template class Setting<u32>;
|
||||||
|
template class Setting<u8, true>;
|
||||||
|
template class Setting<u8>;
|
||||||
|
template class Setting<unsigned long long>;
|
||||||
|
} // namespace Settings
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace UISettings {
|
namespace UISettings {
|
||||||
|
|
||||||
const Themes themes{{
|
const Themes themes{{
|
||||||
|
|
|
@ -14,6 +14,21 @@
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "common/settings.h"
|
#include "common/settings.h"
|
||||||
|
|
||||||
|
using Settings::Category;
|
||||||
|
using Settings::Setting;
|
||||||
|
|
||||||
|
#ifndef CANNOT_EXPLICITLY_INSTANTIATE
|
||||||
|
namespace Settings {
|
||||||
|
extern template class Setting<bool>;
|
||||||
|
extern template class Setting<std::string>;
|
||||||
|
extern template class Setting<u16, true>;
|
||||||
|
extern template class Setting<u32>;
|
||||||
|
extern template class Setting<u8, true>;
|
||||||
|
extern template class Setting<u8>;
|
||||||
|
extern template class Setting<unsigned long long>;
|
||||||
|
} // namespace Settings
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace UISettings {
|
namespace UISettings {
|
||||||
|
|
||||||
bool IsDarkTheme();
|
bool IsDarkTheme();
|
||||||
|
@ -56,6 +71,8 @@ struct GameDir {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Values {
|
struct Values {
|
||||||
|
Settings::Linkage linkage{1000};
|
||||||
|
|
||||||
QByteArray geometry;
|
QByteArray geometry;
|
||||||
QByteArray state;
|
QByteArray state;
|
||||||
|
|
||||||
|
@ -64,30 +81,54 @@ struct Values {
|
||||||
QByteArray gamelist_header_state;
|
QByteArray gamelist_header_state;
|
||||||
|
|
||||||
QByteArray microprofile_geometry;
|
QByteArray microprofile_geometry;
|
||||||
Settings::Setting<bool> microprofile_visible{false, "microProfileDialogVisible"};
|
Setting<bool> microprofile_visible{linkage, false, "microProfileDialogVisible",
|
||||||
|
Category::UiLayout};
|
||||||
|
|
||||||
Settings::Setting<bool> single_window_mode{true, "singleWindowMode"};
|
Setting<bool> single_window_mode{linkage, true, "singleWindowMode", Category::Ui};
|
||||||
Settings::Setting<bool> fullscreen{false, "fullscreen"};
|
Setting<bool> fullscreen{linkage, false, "fullscreen", Category::Ui};
|
||||||
Settings::Setting<bool> display_titlebar{true, "displayTitleBars"};
|
Setting<bool> display_titlebar{linkage, true, "displayTitleBars", Category::Ui};
|
||||||
Settings::Setting<bool> show_filter_bar{true, "showFilterBar"};
|
Setting<bool> show_filter_bar{linkage, true, "showFilterBar", Category::Ui};
|
||||||
Settings::Setting<bool> show_status_bar{true, "showStatusBar"};
|
Setting<bool> show_status_bar{linkage, true, "showStatusBar", Category::Ui};
|
||||||
|
|
||||||
Settings::Setting<bool> confirm_before_closing{true, "confirmClose"};
|
|
||||||
Settings::Setting<bool> first_start{true, "firstStart"};
|
|
||||||
Settings::Setting<bool> pause_when_in_background{false, "pauseWhenInBackground"};
|
|
||||||
Settings::Setting<bool> mute_when_in_background{false, "muteWhenInBackground"};
|
|
||||||
Settings::Setting<bool> hide_mouse{true, "hideInactiveMouse"};
|
|
||||||
Settings::Setting<bool> controller_applet_disabled{false, "disableControllerApplet"};
|
|
||||||
|
|
||||||
|
Setting<bool> confirm_before_closing{
|
||||||
|
linkage, true, "confirmClose", Category::UiGeneral, Settings::Specialization::Default,
|
||||||
|
true, true};
|
||||||
|
Setting<bool> first_start{linkage, true, "firstStart", Category::Ui};
|
||||||
|
Setting<bool> pause_when_in_background{linkage,
|
||||||
|
false,
|
||||||
|
"pauseWhenInBackground",
|
||||||
|
Category::UiGeneral,
|
||||||
|
Settings::Specialization::Default,
|
||||||
|
true,
|
||||||
|
true};
|
||||||
|
Setting<bool> mute_when_in_background{
|
||||||
|
linkage, false, "muteWhenInBackground", Category::Ui, Settings::Specialization::Default,
|
||||||
|
true, true};
|
||||||
|
Setting<bool> hide_mouse{
|
||||||
|
linkage, true, "hideInactiveMouse", Category::UiGeneral, Settings::Specialization::Default,
|
||||||
|
true, true};
|
||||||
|
Setting<bool> controller_applet_disabled{linkage, false, "disableControllerApplet",
|
||||||
|
Category::UiGeneral};
|
||||||
// Set when Vulkan is known to crash the application
|
// Set when Vulkan is known to crash the application
|
||||||
bool has_broken_vulkan = false;
|
bool has_broken_vulkan = false;
|
||||||
|
|
||||||
Settings::Setting<bool> select_user_on_boot{false, "select_user_on_boot"};
|
Setting<bool> select_user_on_boot{linkage,
|
||||||
|
false,
|
||||||
|
"select_user_on_boot",
|
||||||
|
Category::UiGeneral,
|
||||||
|
Settings::Specialization::Default,
|
||||||
|
true,
|
||||||
|
true};
|
||||||
|
Setting<bool> disable_web_applet{linkage, true, "disable_web_applet", Category::Ui};
|
||||||
|
|
||||||
// Discord RPC
|
// Discord RPC
|
||||||
Settings::Setting<bool> enable_discord_presence{true, "enable_discord_presence"};
|
Setting<bool> enable_discord_presence{linkage, true, "enable_discord_presence", Category::Ui};
|
||||||
|
|
||||||
Settings::Setting<bool> enable_screenshot_save_as{true, "enable_screenshot_save_as"};
|
// logging
|
||||||
|
Setting<bool> show_console{linkage, false, "showConsole", Category::Ui};
|
||||||
|
|
||||||
|
Setting<bool> enable_screenshot_save_as{linkage, true, "enable_screenshot_save_as",
|
||||||
|
Category::Screenshots};
|
||||||
|
|
||||||
QString roms_path;
|
QString roms_path;
|
||||||
QString symbols_path;
|
QString symbols_path;
|
||||||
|
@ -102,47 +143,46 @@ struct Values {
|
||||||
// Shortcut name <Shortcut, context>
|
// Shortcut name <Shortcut, context>
|
||||||
std::vector<Shortcut> shortcuts;
|
std::vector<Shortcut> shortcuts;
|
||||||
|
|
||||||
Settings::Setting<uint32_t> callout_flags{0, "calloutFlags"};
|
Setting<u32> callout_flags{linkage, 0, "calloutFlags", Category::Ui};
|
||||||
|
|
||||||
// multiplayer settings
|
// multiplayer settings
|
||||||
Settings::Setting<QString> multiplayer_nickname{{}, "nickname"};
|
Setting<std::string> multiplayer_nickname{linkage, {}, "nickname", Category::Multiplayer};
|
||||||
Settings::Setting<QString> multiplayer_ip{{}, "ip"};
|
Setting<std::string> multiplayer_ip{linkage, {}, "ip", Category::Multiplayer};
|
||||||
Settings::SwitchableSetting<uint, true> multiplayer_port{24872, 0, UINT16_MAX, "port"};
|
Setting<u16, true> multiplayer_port{linkage, 24872, 0,
|
||||||
Settings::Setting<QString> multiplayer_room_nickname{{}, "room_nickname"};
|
UINT16_MAX, "port", Category::Multiplayer};
|
||||||
Settings::Setting<QString> multiplayer_room_name{{}, "room_name"};
|
Setting<std::string> multiplayer_room_nickname{
|
||||||
Settings::SwitchableSetting<uint, true> multiplayer_max_player{8, 0, 8, "max_player"};
|
linkage, {}, "room_nickname", Category::Multiplayer};
|
||||||
Settings::SwitchableSetting<uint, true> multiplayer_room_port{24872, 0, UINT16_MAX,
|
Setting<std::string> multiplayer_room_name{linkage, {}, "room_name", Category::Multiplayer};
|
||||||
"room_port"};
|
Setting<u8, true> multiplayer_max_player{linkage, 8, 0, 8, "max_player", Category::Multiplayer};
|
||||||
Settings::SwitchableSetting<uint, true> multiplayer_host_type{0, 0, 1, "host_type"};
|
Setting<u16, true> multiplayer_room_port{linkage, 24872, 0,
|
||||||
Settings::Setting<qulonglong> multiplayer_game_id{{}, "game_id"};
|
UINT16_MAX, "room_port", Category::Multiplayer};
|
||||||
Settings::Setting<QString> multiplayer_room_description{{}, "room_description"};
|
Setting<u8, true> multiplayer_host_type{linkage, 0, 0, 1, "host_type", Category::Multiplayer};
|
||||||
|
Setting<unsigned long long> multiplayer_game_id{linkage, {}, "game_id", Category::Multiplayer};
|
||||||
|
Setting<std::string> multiplayer_room_description{
|
||||||
|
linkage, {}, "room_description", Category::Multiplayer};
|
||||||
std::pair<std::vector<std::string>, std::vector<std::string>> multiplayer_ban_list;
|
std::pair<std::vector<std::string>, std::vector<std::string>> multiplayer_ban_list;
|
||||||
|
|
||||||
// logging
|
|
||||||
Settings::Setting<bool> show_console{false, "showConsole"};
|
|
||||||
|
|
||||||
// Game List
|
// Game List
|
||||||
Settings::Setting<bool> show_add_ons{true, "show_add_ons"};
|
Setting<bool> show_add_ons{linkage, true, "show_add_ons", Category::UiGameList};
|
||||||
Settings::Setting<uint32_t> game_icon_size{64, "game_icon_size"};
|
Setting<u32> game_icon_size{linkage, 64, "game_icon_size", Category::UiGameList};
|
||||||
Settings::Setting<uint32_t> folder_icon_size{48, "folder_icon_size"};
|
Setting<u32> folder_icon_size{linkage, 48, "folder_icon_size", Category::UiGameList};
|
||||||
Settings::Setting<uint8_t> row_1_text_id{3, "row_1_text_id"};
|
Setting<u8> row_1_text_id{linkage, 3, "row_1_text_id", Category::UiGameList};
|
||||||
Settings::Setting<uint8_t> row_2_text_id{2, "row_2_text_id"};
|
Setting<u8> row_2_text_id{linkage, 2, "row_2_text_id", Category::UiGameList};
|
||||||
std::atomic_bool is_game_list_reload_pending{false};
|
std::atomic_bool is_game_list_reload_pending{false};
|
||||||
Settings::Setting<bool> cache_game_list{true, "cache_game_list"};
|
Setting<bool> cache_game_list{linkage, true, "cache_game_list", Category::UiGameList};
|
||||||
Settings::Setting<bool> favorites_expanded{true, "favorites_expanded"};
|
Setting<bool> favorites_expanded{linkage, true, "favorites_expanded", Category::UiGameList};
|
||||||
QVector<u64> favorited_ids;
|
QVector<u64> favorited_ids;
|
||||||
|
|
||||||
// Compatibility List
|
// Compatibility List
|
||||||
Settings::Setting<bool> show_compat{false, "show_compat"};
|
Setting<bool> show_compat{linkage, false, "show_compat", Category::UiGameList};
|
||||||
|
|
||||||
// Size & File Types Column
|
// Size & File Types Column
|
||||||
Settings::Setting<bool> show_size{true, "show_size"};
|
Setting<bool> show_size{linkage, true, "show_size", Category::UiGameList};
|
||||||
Settings::Setting<bool> show_types{true, "show_types"};
|
Setting<bool> show_types{linkage, true, "show_types", Category::UiGameList};
|
||||||
|
|
||||||
bool configuration_applied;
|
bool configuration_applied;
|
||||||
bool reset_to_defaults;
|
bool reset_to_defaults;
|
||||||
bool shortcut_already_warned{false};
|
bool shortcut_already_warned{false};
|
||||||
Settings::Setting<bool> disable_web_applet{true, "disable_web_applet"};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern Values values;
|
extern Values values;
|
||||||
|
|
|
@ -98,8 +98,26 @@ void Config::ReadSetting(const std::string& group, Settings::Setting<Type, range
|
||||||
static_cast<long>(setting.GetDefault())));
|
static_cast<long>(setting.GetDefault())));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Config::ReadCategory(Settings::Category category) {
|
||||||
|
for (const auto setting : Settings::values.linkage.by_category[category]) {
|
||||||
|
const char* category_name = [&]() {
|
||||||
|
if (category == Settings::Category::Controls) {
|
||||||
|
// For compatibility with older configs
|
||||||
|
return "ControlsGeneral";
|
||||||
|
} else {
|
||||||
|
return Settings::TranslateCategory(category);
|
||||||
|
}
|
||||||
|
}();
|
||||||
|
std::string setting_value =
|
||||||
|
sdl2_config->Get(category_name, setting->GetLabel(), setting->DefaultToString());
|
||||||
|
setting->LoadString(setting_value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Config::ReadValues() {
|
void Config::ReadValues() {
|
||||||
// Controls
|
// Controls
|
||||||
|
ReadCategory(Settings::Category::Controls);
|
||||||
|
|
||||||
for (std::size_t p = 0; p < Settings::values.players.GetValue().size(); ++p) {
|
for (std::size_t p = 0; p < Settings::values.players.GetValue().size(); ++p) {
|
||||||
auto& player = Settings::values.players.GetValue()[p];
|
auto& player = Settings::values.players.GetValue()[p];
|
||||||
|
|
||||||
|
@ -139,13 +157,6 @@ void Config::ReadValues() {
|
||||||
player.connected = sdl2_config->GetBoolean(group, "connected", false);
|
player.connected = sdl2_config->GetBoolean(group, "connected", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
ReadSetting("ControlsGeneral", Settings::values.mouse_enabled);
|
|
||||||
|
|
||||||
ReadSetting("ControlsGeneral", Settings::values.touch_device);
|
|
||||||
|
|
||||||
ReadSetting("ControlsGeneral", Settings::values.keyboard_enabled);
|
|
||||||
|
|
||||||
ReadSetting("ControlsGeneral", Settings::values.debug_pad_enabled);
|
|
||||||
for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) {
|
for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) {
|
||||||
std::string default_param = InputCommon::GenerateKeyboardParam(default_buttons[i]);
|
std::string default_param = InputCommon::GenerateKeyboardParam(default_buttons[i]);
|
||||||
Settings::values.debug_pad_buttons[i] = sdl2_config->Get(
|
Settings::values.debug_pad_buttons[i] = sdl2_config->Get(
|
||||||
|
@ -166,14 +177,6 @@ void Config::ReadValues() {
|
||||||
Settings::values.debug_pad_analogs[i] = default_param;
|
Settings::values.debug_pad_analogs[i] = default_param;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReadSetting("ControlsGeneral", Settings::values.enable_raw_input);
|
|
||||||
ReadSetting("ControlsGeneral", Settings::values.enable_joycon_driver);
|
|
||||||
ReadSetting("ControlsGeneral", Settings::values.enable_procon_driver);
|
|
||||||
ReadSetting("ControlsGeneral", Settings::values.random_amiibo_id);
|
|
||||||
ReadSetting("ControlsGeneral", Settings::values.emulate_analog_keyboard);
|
|
||||||
ReadSetting("ControlsGeneral", Settings::values.vibration_enabled);
|
|
||||||
ReadSetting("ControlsGeneral", Settings::values.enable_accurate_vibrations);
|
|
||||||
ReadSetting("ControlsGeneral", Settings::values.motion_enabled);
|
|
||||||
Settings::values.touchscreen.enabled =
|
Settings::values.touchscreen.enabled =
|
||||||
sdl2_config->GetBoolean("ControlsGeneral", "touch_enabled", true);
|
sdl2_config->GetBoolean("ControlsGeneral", "touch_enabled", true);
|
||||||
Settings::values.touchscreen.rotation_angle =
|
Settings::values.touchscreen.rotation_angle =
|
||||||
|
@ -217,10 +220,24 @@ void Config::ReadValues() {
|
||||||
Settings::values.touch_from_button_map_index = std::clamp(
|
Settings::values.touch_from_button_map_index = std::clamp(
|
||||||
Settings::values.touch_from_button_map_index.GetValue(), 0, num_touch_from_button_maps - 1);
|
Settings::values.touch_from_button_map_index.GetValue(), 0, num_touch_from_button_maps - 1);
|
||||||
|
|
||||||
ReadSetting("ControlsGeneral", Settings::values.udp_input_servers);
|
ReadCategory(Settings::Category::Audio);
|
||||||
|
ReadCategory(Settings::Category::Core);
|
||||||
|
ReadCategory(Settings::Category::Cpu);
|
||||||
|
ReadCategory(Settings::Category::CpuDebug);
|
||||||
|
ReadCategory(Settings::Category::CpuUnsafe);
|
||||||
|
ReadCategory(Settings::Category::Renderer);
|
||||||
|
ReadCategory(Settings::Category::RendererAdvanced);
|
||||||
|
ReadCategory(Settings::Category::RendererDebug);
|
||||||
|
ReadCategory(Settings::Category::System);
|
||||||
|
ReadCategory(Settings::Category::SystemAudio);
|
||||||
|
ReadCategory(Settings::Category::DataStorage);
|
||||||
|
ReadCategory(Settings::Category::Debugging);
|
||||||
|
ReadCategory(Settings::Category::DebuggingGraphics);
|
||||||
|
ReadCategory(Settings::Category::Miscellaneous);
|
||||||
|
ReadCategory(Settings::Category::Network);
|
||||||
|
ReadCategory(Settings::Category::WebService);
|
||||||
|
|
||||||
// Data Storage
|
// Data Storage
|
||||||
ReadSetting("Data Storage", Settings::values.use_virtual_sd);
|
|
||||||
FS::SetYuzuPath(FS::YuzuPath::NANDDir,
|
FS::SetYuzuPath(FS::YuzuPath::NANDDir,
|
||||||
sdl2_config->Get("Data Storage", "nand_directory",
|
sdl2_config->Get("Data Storage", "nand_directory",
|
||||||
FS::GetYuzuPathString(FS::YuzuPath::NANDDir)));
|
FS::GetYuzuPathString(FS::YuzuPath::NANDDir)));
|
||||||
|
@ -233,124 +250,10 @@ void Config::ReadValues() {
|
||||||
FS::SetYuzuPath(FS::YuzuPath::DumpDir,
|
FS::SetYuzuPath(FS::YuzuPath::DumpDir,
|
||||||
sdl2_config->Get("Data Storage", "dump_directory",
|
sdl2_config->Get("Data Storage", "dump_directory",
|
||||||
FS::GetYuzuPathString(FS::YuzuPath::DumpDir)));
|
FS::GetYuzuPathString(FS::YuzuPath::DumpDir)));
|
||||||
ReadSetting("Data Storage", Settings::values.gamecard_inserted);
|
|
||||||
ReadSetting("Data Storage", Settings::values.gamecard_current_game);
|
|
||||||
ReadSetting("Data Storage", Settings::values.gamecard_path);
|
|
||||||
|
|
||||||
// System
|
|
||||||
ReadSetting("System", Settings::values.use_docked_mode);
|
|
||||||
|
|
||||||
ReadSetting("System", Settings::values.current_user);
|
|
||||||
Settings::values.current_user = std::clamp<int>(Settings::values.current_user.GetValue(), 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.SetValue(sdl2_config->GetInteger("System", "rng_seed", 0));
|
|
||||||
} else {
|
|
||||||
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 = sdl2_config->GetInteger("System", "custom_rtc", 0);
|
|
||||||
} else {
|
|
||||||
Settings::values.custom_rtc = std::nullopt;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReadSetting("System", Settings::values.language_index);
|
|
||||||
ReadSetting("System", Settings::values.region_index);
|
|
||||||
ReadSetting("System", Settings::values.time_zone_index);
|
|
||||||
ReadSetting("System", Settings::values.sound_index);
|
|
||||||
|
|
||||||
// Core
|
|
||||||
ReadSetting("Core", Settings::values.use_multi_core);
|
|
||||||
ReadSetting("Core", Settings::values.use_unsafe_extended_memory_layout);
|
|
||||||
|
|
||||||
// Cpu
|
|
||||||
ReadSetting("Cpu", Settings::values.cpu_accuracy);
|
|
||||||
ReadSetting("Cpu", Settings::values.cpu_debug_mode);
|
|
||||||
ReadSetting("Cpu", Settings::values.cpuopt_page_tables);
|
|
||||||
ReadSetting("Cpu", Settings::values.cpuopt_block_linking);
|
|
||||||
ReadSetting("Cpu", Settings::values.cpuopt_return_stack_buffer);
|
|
||||||
ReadSetting("Cpu", Settings::values.cpuopt_fast_dispatcher);
|
|
||||||
ReadSetting("Cpu", Settings::values.cpuopt_context_elimination);
|
|
||||||
ReadSetting("Cpu", Settings::values.cpuopt_const_prop);
|
|
||||||
ReadSetting("Cpu", Settings::values.cpuopt_misc_ir);
|
|
||||||
ReadSetting("Cpu", Settings::values.cpuopt_reduce_misalign_checks);
|
|
||||||
ReadSetting("Cpu", Settings::values.cpuopt_fastmem);
|
|
||||||
ReadSetting("Cpu", Settings::values.cpuopt_fastmem_exclusives);
|
|
||||||
ReadSetting("Cpu", Settings::values.cpuopt_recompile_exclusives);
|
|
||||||
ReadSetting("Cpu", Settings::values.cpuopt_ignore_memory_aborts);
|
|
||||||
ReadSetting("Cpu", Settings::values.cpuopt_unsafe_unfuse_fma);
|
|
||||||
ReadSetting("Cpu", Settings::values.cpuopt_unsafe_reduce_fp_error);
|
|
||||||
ReadSetting("Cpu", Settings::values.cpuopt_unsafe_ignore_standard_fpcr);
|
|
||||||
ReadSetting("Cpu", Settings::values.cpuopt_unsafe_inaccurate_nan);
|
|
||||||
ReadSetting("Cpu", Settings::values.cpuopt_unsafe_fastmem_check);
|
|
||||||
ReadSetting("Cpu", Settings::values.cpuopt_unsafe_ignore_global_monitor);
|
|
||||||
|
|
||||||
// Renderer
|
|
||||||
ReadSetting("Renderer", Settings::values.renderer_backend);
|
|
||||||
ReadSetting("Renderer", Settings::values.async_presentation);
|
|
||||||
ReadSetting("Renderer", Settings::values.renderer_force_max_clock);
|
|
||||||
ReadSetting("Renderer", Settings::values.renderer_debug);
|
|
||||||
ReadSetting("Renderer", Settings::values.renderer_shader_feedback);
|
|
||||||
ReadSetting("Renderer", Settings::values.enable_nsight_aftermath);
|
|
||||||
ReadSetting("Renderer", Settings::values.disable_shader_loop_safety_checks);
|
|
||||||
ReadSetting("Renderer", Settings::values.vulkan_device);
|
|
||||||
|
|
||||||
ReadSetting("Renderer", Settings::values.resolution_setup);
|
|
||||||
ReadSetting("Renderer", Settings::values.scaling_filter);
|
|
||||||
ReadSetting("Renderer", Settings::values.fsr_sharpening_slider);
|
|
||||||
ReadSetting("Renderer", Settings::values.anti_aliasing);
|
|
||||||
ReadSetting("Renderer", Settings::values.fullscreen_mode);
|
|
||||||
ReadSetting("Renderer", Settings::values.aspect_ratio);
|
|
||||||
ReadSetting("Renderer", Settings::values.max_anisotropy);
|
|
||||||
ReadSetting("Renderer", Settings::values.use_speed_limit);
|
|
||||||
ReadSetting("Renderer", Settings::values.speed_limit);
|
|
||||||
ReadSetting("Renderer", Settings::values.use_disk_shader_cache);
|
|
||||||
ReadSetting("Renderer", Settings::values.gpu_accuracy);
|
|
||||||
ReadSetting("Renderer", Settings::values.use_asynchronous_gpu_emulation);
|
|
||||||
ReadSetting("Renderer", Settings::values.vsync_mode);
|
|
||||||
ReadSetting("Renderer", Settings::values.shader_backend);
|
|
||||||
ReadSetting("Renderer", Settings::values.use_reactive_flushing);
|
|
||||||
ReadSetting("Renderer", Settings::values.use_asynchronous_shaders);
|
|
||||||
ReadSetting("Renderer", Settings::values.nvdec_emulation);
|
|
||||||
ReadSetting("Renderer", Settings::values.accelerate_astc);
|
|
||||||
ReadSetting("Renderer", Settings::values.async_astc);
|
|
||||||
ReadSetting("Renderer", Settings::values.astc_recompression);
|
|
||||||
ReadSetting("Renderer", Settings::values.use_fast_gpu_time);
|
|
||||||
ReadSetting("Renderer", Settings::values.use_vulkan_driver_pipeline_cache);
|
|
||||||
|
|
||||||
ReadSetting("Renderer", Settings::values.bg_red);
|
|
||||||
ReadSetting("Renderer", Settings::values.bg_green);
|
|
||||||
ReadSetting("Renderer", Settings::values.bg_blue);
|
|
||||||
|
|
||||||
// Audio
|
|
||||||
ReadSetting("Audio", Settings::values.sink_id);
|
|
||||||
ReadSetting("Audio", Settings::values.audio_output_device_id);
|
|
||||||
ReadSetting("Audio", Settings::values.volume);
|
|
||||||
|
|
||||||
// Miscellaneous
|
|
||||||
// log_filter has a different default here than from common
|
|
||||||
Settings::values.log_filter =
|
|
||||||
sdl2_config->Get("Miscellaneous", Settings::values.log_filter.GetLabel(), "*:Trace");
|
|
||||||
ReadSetting("Miscellaneous", Settings::values.use_dev_keys);
|
|
||||||
|
|
||||||
// Debugging
|
// Debugging
|
||||||
Settings::values.record_frame_times =
|
Settings::values.record_frame_times =
|
||||||
sdl2_config->GetBoolean("Debugging", "record_frame_times", false);
|
sdl2_config->GetBoolean("Debugging", "record_frame_times", false);
|
||||||
ReadSetting("Debugging", Settings::values.dump_exefs);
|
|
||||||
ReadSetting("Debugging", Settings::values.dump_nso);
|
|
||||||
ReadSetting("Debugging", Settings::values.enable_fs_access_log);
|
|
||||||
ReadSetting("Debugging", Settings::values.reporting_services);
|
|
||||||
ReadSetting("Debugging", Settings::values.quest_flag);
|
|
||||||
ReadSetting("Debugging", Settings::values.use_debug_asserts);
|
|
||||||
ReadSetting("Debugging", Settings::values.use_auto_stub);
|
|
||||||
ReadSetting("Debugging", Settings::values.disable_macro_jit);
|
|
||||||
ReadSetting("Debugging", Settings::values.disable_macro_hle);
|
|
||||||
ReadSetting("Debugging", Settings::values.use_gdbstub);
|
|
||||||
ReadSetting("Debugging", Settings::values.gdbstub_port);
|
|
||||||
|
|
||||||
const auto title_list = sdl2_config->Get("AddOns", "title_ids", "");
|
const auto title_list = sdl2_config->Get("AddOns", "title_ids", "");
|
||||||
std::stringstream ss(title_list);
|
std::stringstream ss(title_list);
|
||||||
|
@ -368,15 +271,6 @@ void Config::ReadValues() {
|
||||||
|
|
||||||
Settings::values.disabled_addons.insert_or_assign(title_id, out);
|
Settings::values.disabled_addons.insert_or_assign(title_id, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Web Service
|
|
||||||
ReadSetting("WebService", Settings::values.enable_telemetry);
|
|
||||||
ReadSetting("WebService", Settings::values.web_api_url);
|
|
||||||
ReadSetting("WebService", Settings::values.yuzu_username);
|
|
||||||
ReadSetting("WebService", Settings::values.yuzu_token);
|
|
||||||
|
|
||||||
// Network
|
|
||||||
ReadSetting("Network", Settings::values.network_interface);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Config::Reload() {
|
void Config::Reload() {
|
||||||
|
|
|
@ -34,4 +34,5 @@ private:
|
||||||
*/
|
*/
|
||||||
template <typename Type, bool ranged>
|
template <typename Type, bool ranged>
|
||||||
void ReadSetting(const std::string& group, Settings::Setting<Type, ranged>& setting);
|
void ReadSetting(const std::string& group, Settings::Setting<Type, ranged>& setting);
|
||||||
|
void ReadCategory(Settings::Category category);
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue