summaryrefslogtreecommitdiffstats
path: root/src/yuzu_cmd
diff options
context:
space:
mode:
Diffstat (limited to 'src/yuzu_cmd')
-rw-r--r--src/yuzu_cmd/CMakeLists.txt5
-rw-r--r--src/yuzu_cmd/config.cpp221
-rw-r--r--src/yuzu_cmd/config.h12
-rw-r--r--src/yuzu_cmd/default_ini.h177
-rw-r--r--src/yuzu_cmd/emu_window/emu_window_sdl2.cpp58
-rw-r--r--src/yuzu_cmd/emu_window/emu_window_sdl2.h5
-rw-r--r--src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp13
-rw-r--r--src/yuzu_cmd/emu_window/emu_window_sdl2_gl.h7
-rw-r--r--src/yuzu_cmd/emu_window/emu_window_sdl2_vk.cpp37
-rw-r--r--src/yuzu_cmd/emu_window/emu_window_sdl2_vk.h3
-rw-r--r--src/yuzu_cmd/yuzu.cpp14
11 files changed, 321 insertions, 231 deletions
diff --git a/src/yuzu_cmd/CMakeLists.txt b/src/yuzu_cmd/CMakeLists.txt
index 4bf25727b..e55a19649 100644
--- a/src/yuzu_cmd/CMakeLists.txt
+++ b/src/yuzu_cmd/CMakeLists.txt
@@ -38,6 +38,11 @@ target_include_directories(yuzu-cmd PRIVATE ${RESOURCES_DIR})
target_include_directories(yuzu-cmd PRIVATE ../../externals/Vulkan-Headers/include)
+if (YUZU_USE_EXTERNAL_SDL2)
+ target_compile_definitions(yuzu-cmd PRIVATE -DYUZU_USE_EXTERNAL_SDL2)
+ target_include_directories(yuzu-cmd PRIVATE ${PROJECT_BINARY_DIR}/externals/SDL/include)
+endif()
+
if(UNIX AND NOT APPLE)
install(TARGETS yuzu-cmd RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}/bin")
endif()
diff --git a/src/yuzu_cmd/config.cpp b/src/yuzu_cmd/config.cpp
index 60bf66ec0..064ecaafa 100644
--- a/src/yuzu_cmd/config.cpp
+++ b/src/yuzu_cmd/config.cpp
@@ -241,6 +241,22 @@ static const std::array<int, 8> keyboard_mods{
SDL_SCANCODE_RCTRL, SDL_SCANCODE_RSHIFT, SDL_SCANCODE_RALT, SDL_SCANCODE_RGUI,
};
+template <>
+void Config::ReadSetting(const std::string& group, Settings::BasicSetting<std::string>& setting) {
+ setting = sdl2_config->Get(group, setting.GetLabel(), setting.GetDefault());
+}
+
+template <>
+void Config::ReadSetting(const std::string& group, Settings::BasicSetting<bool>& setting) {
+ setting = sdl2_config->GetBoolean(group, setting.GetLabel(), setting.GetDefault());
+}
+
+template <typename Type>
+void Config::ReadSetting(const std::string& group, Settings::BasicSetting<Type>& setting) {
+ setting = static_cast<Type>(sdl2_config->GetInteger(group, setting.GetLabel(),
+ static_cast<long>(setting.GetDefault())));
+}
+
void Config::ReadValues() {
// Controls
for (std::size_t p = 0; p < Settings::values.players.GetValue().size(); ++p) {
@@ -264,8 +280,7 @@ void Config::ReadValues() {
}
}
- Settings::values.mouse_enabled =
- sdl2_config->GetBoolean("ControlsGeneral", "mouse_enabled", false);
+ ReadSetting("ControlsGeneral", Settings::values.mouse_enabled);
for (int i = 0; i < Settings::NativeMouseButton::NumMouseButtons; ++i) {
std::string default_param = InputCommon::GenerateKeyboardParam(default_mouse_buttons[i]);
Settings::values.mouse_buttons[i] = sdl2_config->Get(
@@ -275,14 +290,13 @@ void Config::ReadValues() {
Settings::values.mouse_buttons[i] = default_param;
}
- Settings::values.motion_device = sdl2_config->Get(
- "ControlsGeneral", "motion_device", "engine:motion_emu,update_period:100,sensitivity:0.01");
+ ReadSetting("ControlsGeneral", Settings::values.motion_device);
+
+ ReadSetting("ControlsGeneral", Settings::values.touch_device);
- Settings::values.keyboard_enabled =
- sdl2_config->GetBoolean("ControlsGeneral", "keyboard_enabled", false);
+ ReadSetting("ControlsGeneral", Settings::values.keyboard_enabled);
- Settings::values.debug_pad_enabled =
- sdl2_config->GetBoolean("ControlsGeneral", "debug_pad_enabled", false);
+ ReadSetting("ControlsGeneral", Settings::values.debug_pad_enabled);
for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) {
std::string default_param = InputCommon::GenerateKeyboardParam(default_buttons[i]);
Settings::values.debug_pad_buttons[i] = sdl2_config->Get(
@@ -303,12 +317,9 @@ void Config::ReadValues() {
Settings::values.debug_pad_analogs[i] = default_param;
}
- Settings::values.vibration_enabled.SetValue(
- sdl2_config->GetBoolean("ControlsGeneral", "vibration_enabled", true));
- Settings::values.enable_accurate_vibrations.SetValue(
- sdl2_config->GetBoolean("ControlsGeneral", "enable_accurate_vibrations", false));
- Settings::values.motion_enabled.SetValue(
- sdl2_config->GetBoolean("ControlsGeneral", "motion_enabled", true));
+ ReadSetting("ControlsGeneral", Settings::values.vibration_enabled);
+ ReadSetting("ControlsGeneral", Settings::values.enable_accurate_vibrations);
+ ReadSetting("ControlsGeneral", Settings::values.motion_enabled);
Settings::values.touchscreen.enabled =
sdl2_config->GetBoolean("ControlsGeneral", "touch_enabled", true);
Settings::values.touchscreen.rotation_angle =
@@ -349,13 +360,11 @@ void Config::ReadValues() {
Settings::TouchFromButtonMap{"default", {}});
num_touch_from_button_maps = 1;
}
- Settings::values.use_touch_from_button =
- sdl2_config->GetBoolean("ControlsGeneral", "use_touch_from_button", false);
- Settings::values.touch_from_button_map_index =
- std::clamp(Settings::values.touch_from_button_map_index, 0, num_touch_from_button_maps - 1);
+ ReadSetting("ControlsGeneral", Settings::values.use_touch_from_button);
+ 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.udp_input_servers =
- sdl2_config->Get("Controls", "udp_input_address", InputCommon::CemuhookUDP::DEFAULT_SRV);
+ ReadSetting("ControlsGeneral", Settings::values.udp_input_servers);
std::transform(keyboard_keys.begin(), keyboard_keys.end(),
Settings::values.keyboard_keys.begin(), InputCommon::GenerateKeyboardParam);
@@ -367,8 +376,7 @@ void Config::ReadValues() {
Settings::values.keyboard_mods.begin(), InputCommon::GenerateKeyboardParam);
// Data Storage
- Settings::values.use_virtual_sd =
- sdl2_config->GetBoolean("Data Storage", "use_virtual_sd", true);
+ ReadSetting("Data Storage", Settings::values.use_virtual_sd);
FS::SetYuzuPath(FS::YuzuPath::NANDDir,
sdl2_config->Get("Data Storage", "nand_directory",
FS::GetYuzuPathString(FS::YuzuPath::NANDDir)));
@@ -381,18 +389,16 @@ void Config::ReadValues() {
FS::SetYuzuPath(FS::YuzuPath::DumpDir,
sdl2_config->Get("Data Storage", "dump_directory",
FS::GetYuzuPathString(FS::YuzuPath::DumpDir)));
- Settings::values.gamecard_inserted =
- sdl2_config->GetBoolean("Data Storage", "gamecard_inserted", false);
- Settings::values.gamecard_current_game =
- sdl2_config->GetBoolean("Data Storage", "gamecard_current_game", false);
- Settings::values.gamecard_path = sdl2_config->Get("Data Storage", "gamecard_path", "");
+ ReadSetting("Data Storage", Settings::values.gamecard_inserted);
+ ReadSetting("Data Storage", Settings::values.gamecard_current_game);
+ ReadSetting("Data Storage", Settings::values.gamecard_path);
// System
- Settings::values.use_docked_mode.SetValue(
- sdl2_config->GetBoolean("System", "use_docked_mode", true));
+ ReadSetting("System", Settings::values.use_docked_mode);
- Settings::values.current_user = std::clamp<int>(
- sdl2_config->GetInteger("System", "current_user", 0), 0, Service::Account::MAX_USERS - 1);
+ 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) {
@@ -409,89 +415,85 @@ void Config::ReadValues() {
Settings::values.custom_rtc = std::nullopt;
}
- Settings::values.language_index.SetValue(
- sdl2_config->GetInteger("System", "language_index", 1));
- Settings::values.time_zone_index.SetValue(
- sdl2_config->GetInteger("System", "time_zone_index", 0));
+ 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
- Settings::values.use_multi_core.SetValue(
- sdl2_config->GetBoolean("Core", "use_multi_core", true));
+ ReadSetting("Core", Settings::values.use_multi_core);
+
+ // 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_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);
// Renderer
- const int renderer_backend = sdl2_config->GetInteger(
- "Renderer", "backend", static_cast<int>(Settings::RendererBackend::OpenGL));
- Settings::values.renderer_backend.SetValue(
- static_cast<Settings::RendererBackend>(renderer_backend));
- Settings::values.renderer_debug = sdl2_config->GetBoolean("Renderer", "debug", false);
- Settings::values.vulkan_device.SetValue(
- sdl2_config->GetInteger("Renderer", "vulkan_device", 0));
-
- Settings::values.aspect_ratio.SetValue(
- static_cast<int>(sdl2_config->GetInteger("Renderer", "aspect_ratio", 0)));
- Settings::values.max_anisotropy.SetValue(
- static_cast<int>(sdl2_config->GetInteger("Renderer", "max_anisotropy", 0)));
- Settings::values.use_frame_limit.SetValue(
- sdl2_config->GetBoolean("Renderer", "use_frame_limit", true));
- Settings::values.frame_limit.SetValue(
- static_cast<u16>(sdl2_config->GetInteger("Renderer", "frame_limit", 100)));
- Settings::values.use_disk_shader_cache.SetValue(
- sdl2_config->GetBoolean("Renderer", "use_disk_shader_cache", false));
- const int gpu_accuracy_level = sdl2_config->GetInteger("Renderer", "gpu_accuracy", 1);
- Settings::values.gpu_accuracy.SetValue(static_cast<Settings::GPUAccuracy>(gpu_accuracy_level));
- Settings::values.use_asynchronous_gpu_emulation.SetValue(
- sdl2_config->GetBoolean("Renderer", "use_asynchronous_gpu_emulation", true));
- Settings::values.use_vsync.SetValue(
- static_cast<u16>(sdl2_config->GetInteger("Renderer", "use_vsync", 1)));
- Settings::values.disable_fps_limit.SetValue(
- sdl2_config->GetBoolean("Renderer", "disable_fps_limit", false));
- Settings::values.use_assembly_shaders.SetValue(
- sdl2_config->GetBoolean("Renderer", "use_assembly_shaders", true));
- Settings::values.use_asynchronous_shaders.SetValue(
- sdl2_config->GetBoolean("Renderer", "use_asynchronous_shaders", false));
- Settings::values.use_nvdec_emulation.SetValue(
- sdl2_config->GetBoolean("Renderer", "use_nvdec_emulation", true));
- Settings::values.accelerate_astc.SetValue(
- sdl2_config->GetBoolean("Renderer", "accelerate_astc", true));
- Settings::values.use_fast_gpu_time.SetValue(
- sdl2_config->GetBoolean("Renderer", "use_fast_gpu_time", true));
-
- Settings::values.bg_red.SetValue(
- static_cast<float>(sdl2_config->GetReal("Renderer", "bg_red", 0.0)));
- Settings::values.bg_green.SetValue(
- static_cast<float>(sdl2_config->GetReal("Renderer", "bg_green", 0.0)));
- Settings::values.bg_blue.SetValue(
- static_cast<float>(sdl2_config->GetReal("Renderer", "bg_blue", 0.0)));
+ ReadSetting("Renderer", Settings::values.renderer_backend);
+ 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.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.use_vsync);
+ ReadSetting("Renderer", Settings::values.fps_cap);
+ ReadSetting("Renderer", Settings::values.disable_fps_limit);
+ ReadSetting("Renderer", Settings::values.shader_backend);
+ ReadSetting("Renderer", Settings::values.use_asynchronous_shaders);
+ ReadSetting("Renderer", Settings::values.use_nvdec_emulation);
+ ReadSetting("Renderer", Settings::values.accelerate_astc);
+ ReadSetting("Renderer", Settings::values.use_fast_gpu_time);
+ ReadSetting("Renderer", Settings::values.use_caches_gc);
+
+ ReadSetting("Renderer", Settings::values.bg_red);
+ ReadSetting("Renderer", Settings::values.bg_green);
+ ReadSetting("Renderer", Settings::values.bg_blue);
// Audio
- Settings::values.sink_id = sdl2_config->Get("Audio", "output_engine", "auto");
- Settings::values.enable_audio_stretching.SetValue(
- sdl2_config->GetBoolean("Audio", "enable_audio_stretching", true));
- Settings::values.audio_device_id = sdl2_config->Get("Audio", "output_device", "auto");
- Settings::values.volume.SetValue(
- static_cast<float>(sdl2_config->GetReal("Audio", "volume", 1)));
+ ReadSetting("Audio", Settings::values.sink_id);
+ ReadSetting("Audio", Settings::values.enable_audio_stretching);
+ ReadSetting("Audio", Settings::values.audio_device_id);
+ ReadSetting("Audio", Settings::values.volume);
// Miscellaneous
- Settings::values.log_filter = sdl2_config->Get("Miscellaneous", "log_filter", "*:Trace");
- Settings::values.use_dev_keys = sdl2_config->GetBoolean("Miscellaneous", "use_dev_keys", false);
+ // 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
Settings::values.record_frame_times =
sdl2_config->GetBoolean("Debugging", "record_frame_times", false);
- Settings::values.program_args = sdl2_config->Get("Debugging", "program_args", "");
- Settings::values.dump_exefs = sdl2_config->GetBoolean("Debugging", "dump_exefs", false);
- Settings::values.dump_nso = sdl2_config->GetBoolean("Debugging", "dump_nso", false);
- Settings::values.enable_fs_access_log =
- sdl2_config->GetBoolean("Debugging", "enable_fs_access_log", false);
- Settings::values.reporting_services =
- sdl2_config->GetBoolean("Debugging", "reporting_services", false);
- Settings::values.quest_flag = sdl2_config->GetBoolean("Debugging", "quest_flag", false);
- Settings::values.use_debug_asserts =
- sdl2_config->GetBoolean("Debugging", "use_debug_asserts", false);
- Settings::values.use_auto_stub = sdl2_config->GetBoolean("Debugging", "use_auto_stub", false);
-
- Settings::values.disable_macro_jit =
- sdl2_config->GetBoolean("Debugging", "disable_macro_jit", 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);
const auto title_list = sdl2_config->Get("AddOns", "title_ids", "");
std::stringstream ss(title_list);
@@ -511,17 +513,14 @@ void Config::ReadValues() {
}
// Web Service
- Settings::values.enable_telemetry =
- sdl2_config->GetBoolean("WebService", "enable_telemetry", true);
- Settings::values.web_api_url =
- sdl2_config->Get("WebService", "web_api_url", "https://api.yuzu-emu.org");
- Settings::values.yuzu_username = sdl2_config->Get("WebService", "yuzu_username", "");
- Settings::values.yuzu_token = sdl2_config->Get("WebService", "yuzu_token", "");
+ 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);
// Services
- Settings::values.bcat_backend = sdl2_config->Get("Services", "bcat_backend", "none");
- Settings::values.bcat_boxcat_local =
- sdl2_config->GetBoolean("Services", "bcat_boxcat_local", false);
+ ReadSetting("Services", Settings::values.bcat_backend);
+ ReadSetting("Services", Settings::values.bcat_boxcat_local);
}
void Config::Reload() {
diff --git a/src/yuzu_cmd/config.h b/src/yuzu_cmd/config.h
index 807199278..1ee932be2 100644
--- a/src/yuzu_cmd/config.h
+++ b/src/yuzu_cmd/config.h
@@ -8,6 +8,8 @@
#include <memory>
#include <string>
+#include "common/settings.h"
+
class INIReader;
class Config {
@@ -22,4 +24,14 @@ public:
~Config();
void Reload();
+
+private:
+ /**
+ * Applies a value read from the sdl2_config to a BasicSetting.
+ *
+ * @param group The name of the INI group
+ * @param setting The yuzu setting to modify
+ */
+ template <typename Type>
+ void ReadSetting(const std::string& group, Settings::BasicSetting<Type>& setting);
};
diff --git a/src/yuzu_cmd/default_ini.h b/src/yuzu_cmd/default_ini.h
index cc9850aad..e02eceb99 100644
--- a/src/yuzu_cmd/default_ini.h
+++ b/src/yuzu_cmd/default_ini.h
@@ -65,6 +65,13 @@ button_screenshot=
lstick=
rstick=
+# To use the debug_pad, prepend `debug_pad_` before each button setting above.
+# i.e. debug_pad_button_a=
+
+# Enable debug pad inputs to the guest
+# 0 (default): Disabled, 1: Enabled
+debug_pad_enabled =
+
# Whether to enable or disable vibration
# 0: Disabled, 1 (default): Enabled
vibration_enabled=
@@ -73,6 +80,10 @@ vibration_enabled=
# 0 (default): Disabled, 1: Enabled
enable_accurate_vibrations=
+# Enables controller motion inputs
+# 0: Disabled, 1 (default): Enabled
+motion_enabled =
+
# for motion input, the following devices are available:
# - "motion_emu" (default) for emulating motion input from mouse input. Required parameters:
# - "update_period": update period in milliseconds (default to 100)
@@ -98,19 +109,30 @@ use_touch_from_button=
#touch_from_button_maps_0_bind_1=bar
# etc.
-# Most desktop operating systems do not expose a way to poll the motion state of the controllers
-# so as a way around it, cemuhook created a udp client/server protocol to broadcast the data directly
-# from a controller device to the client program. Citra has a client that can connect and read
-# from any cemuhook compatible motion program.
+# List of Cemuhook UDP servers, delimited by ','.
+# Default: 127.0.0.1:26760
+# Example: 127.0.0.1:26760,123.4.5.67:26761
+udp_input_servers =
-# IPv4 address of the udp input server (Default "127.0.0.1")
-udp_input_address=127.0.0.1
+# Enable controlling an axis via a mouse input.
+# 0 (default): Off, 1: On
+mouse_panning =
+
+# Set mouse sensitivity.
+# Default: 1.0
+mouse_panning_sensitivity =
-# Port of the udp input server. (Default 26760)
-udp_input_port=
+# Emulate an analog control stick from keyboard inputs.
+# 0 (default): Disabled, 1: Enabled
+emulate_analog_keyboard =
+
+# Enable mouse inputs to the guest
+# 0 (default): Disabled, 1: Enabled
+mouse_enabled =
-# The pad to request data on. Should be between 0 (Pad 1) and 3 (Pad 4). (Default 0)
-udp_pad_index=
+# Enable keyboard inputs to the guest
+# 0 (default): Disabled, 1: Enabled
+keyboard_enabled =
[Core]
# Whether to use multi-core for CPU emulation
@@ -118,6 +140,17 @@ udp_pad_index=
use_multi_core=
[Cpu]
+# Adjusts various optimizations.
+# Auto-select mode enables choice unsafe optimizations.
+# Accurate enables only safe optimizations.
+# Unsafe allows any unsafe optimizations.
+# 0 (default): Auto-select, 1: Accurate, 2: Enable unsafe optimizations
+cpu_accuracy =
+
+# Allow disabling safe optimizations.
+# 0 (default): Disabled, 1: Enabled
+cpu_debug_mode =
+
# Enable inline page tables optimization (faster guest memory access)
# 0: Disabled, 1 (default): Enabled
cpuopt_page_tables =
@@ -154,6 +187,31 @@ cpuopt_reduce_misalign_checks =
# 0: Disabled, 1 (default): Enabled
cpuopt_fastmem =
+# Enable unfuse FMA (improve performance on CPUs without FMA)
+# Only enabled if cpu_accuracy is set to Unsafe. Automatically chosen with cpu_accuracy = Auto-select.
+# 0: Disabled, 1 (default): Enabled
+cpuopt_unsafe_unfuse_fma =
+
+# Enable faster FRSQRTE and FRECPE
+# Only enabled if cpu_accuracy is set to Unsafe.
+# 0: Disabled, 1 (default): Enabled
+cpuopt_unsafe_reduce_fp_error =
+
+# Enable faster ASIMD instructions (32 bits only)
+# Only enabled if cpu_accuracy is set to Unsafe. Automatically chosen with cpu_accuracy = Auto-select.
+# 0: Disabled, 1 (default): Enabled
+cpuopt_unsafe_ignore_standard_fpcr =
+
+# Enable inaccurate NaN handling
+# Only enabled if cpu_accuracy is set to Unsafe. Automatically chosen with cpu_accuracy = Auto-select.
+# 0: Disabled, 1 (default): Enabled
+cpuopt_unsafe_inaccurate_nan =
+
+# Disable address space checks (64 bits only)
+# Only enabled if cpu_accuracy is set to Unsafe. Automatically chosen with cpu_accuracy = Auto-select.
+# 0: Disabled, 1 (default): Enabled
+cpuopt_unsafe_fastmem_check =
+
[Renderer]
# Which backend API to use.
# 0 (default): OpenGL, 1: Vulkan
@@ -163,16 +221,24 @@ backend =
# 0 (default): Disabled, 1: Enabled
debug =
+# Enable shader feedback.
+# 0 (default): Disabled, 1: Enabled
+renderer_shader_feedback =
+
+# Enable Nsight Aftermath crash dumps
+# 0 (default): Disabled, 1: Enabled
+nsight_aftermath =
+
+# Disable shader loop safety checks, executing the shader without loop logic changes
+# 0 (default): Disabled, 1: Enabled
+disable_shader_loop_safety_checks =
+
# Which Vulkan physical device to use (defaults to 0)
vulkan_device =
-# Whether to use software or hardware rendering.
-# 0: Software, 1 (default): Hardware
-use_hw_renderer =
-
-# Whether to use the Just-In-Time (JIT) compiler for shader emulation
-# 0: Interpreter (slow), 1 (default): JIT (fast)
-use_shader_jit =
+# Whether to use fullscreen or borderless window mode
+# 0 (Windows default): Borderless window, 1 (All other default): Exclusive fullscreen
+fullscreen_mode =
# Aspect ratio
# 0: Default (16:9), 1: Force 4:3, 2: Force 21:9, 3: Stretch to Window
@@ -186,9 +252,10 @@ max_anisotropy =
# 0 (default): Off, 1: On
use_vsync =
-# Whether to use OpenGL assembly shaders or not. NV_gpu_program5 is required.
-# 0: Off, 1 (default): On
-use_assembly_shaders =
+# Selects the OpenGL shader backend. NV_gpu_program5 is required for GLASM. If NV_gpu_program5 is
+# not available and GLASM is selected, GLSL will be used.
+# 0: GLSL, 1 (default): GLASM, 2: SPIR-V
+shader_backend =
# Whether to allow asynchronous shader building.
# 0 (default): Off, 1: On
@@ -202,65 +269,43 @@ use_nvdec_emulation =
# 0: Off, 1 (default): On
accelerate_astc =
-# Turns on the frame limiter, which will limit frames output to the target game speed
+# Turns on the speed limiter, which will limit the emulation speed to the desired speed limit value
# 0: Off, 1: On (default)
-use_frame_limit =
+use_speed_limit =
# Limits the speed of the game to run no faster than this value as a percentage of target speed
# 1 - 9999: Speed limit as a percentage of target game speed. 100 (default)
-frame_limit =
+speed_limit =
# Whether to use disk based shader cache
-# 0 (default): Off, 1 : On
+# 0: Off, 1 (default): On
use_disk_shader_cache =
# Which gpu accuracy level to use
-# 0 (Normal), 1 (High), 2 (Extreme)
+# 0: Normal, 1 (default): High, 2: Extreme (Very slow)
gpu_accuracy =
# Whether to use asynchronous GPU emulation
# 0 : Off (slow), 1 (default): On (fast)
use_asynchronous_gpu_emulation =
-# Forces VSync on the display thread. Usually doesn't impact performance, but on some drivers it can
-# so only turn this off if you notice a speed difference.
+# Inform the guest that GPU operations completed more quickly than they did.
# 0: Off, 1 (default): On
-use_vsync =
+use_fast_gpu_time =
# Whether to use garbage collection or not for GPU caches.
# 0 (default): Off, 1: On
use_caches_gc =
# The clear color for the renderer. What shows up on the sides of the bottom screen.
-# Must be in range of 0.0-1.0. Defaults to 1.0 for all.
+# Must be in range of 0-255. Defaults to 0 for all.
bg_red =
bg_blue =
bg_green =
-[Layout]
-# Layout for the screen inside the render window.
-# 0 (default): Default Top Bottom Screen, 1: Single Screen Only, 2: Large Screen Small Screen
-layout_option =
-
-# Toggle custom layout (using the settings below) on or off.
-# 0 (default): Off, 1: On
-custom_layout =
-
-# Screen placement when using Custom layout option
-# 0x, 0y is the top left corner of the render window.
-custom_top_left =
-custom_top_top =
-custom_top_right =
-custom_top_bottom =
-custom_bottom_left =
-custom_bottom_top =
-custom_bottom_right =
-custom_bottom_bottom =
-
-# Swaps the prominent screen with the other screen.
-# For example, if Single Screen is chosen, setting this to 1 will display the bottom screen instead of the top screen.
-# 0 (default): Top Screen is prominent, 1: Bottom Screen is prominent
-swap_screen =
+# Caps the unlocked framerate to a multiple of the title's target FPS.
+# 1 - 1000: Target FPS multiple cap. 1000 (default)
+fps_cap =
[Audio]
# Which audio output engine to use.
@@ -281,7 +326,7 @@ enable_audio_stretching =
output_device =
# Output volume.
-# 1.0 (default): 100%, 0.0; mute
+# 100 (default): 100%, 0; mute
volume =
[Data Storage]
@@ -308,10 +353,6 @@ gamecard_path =
# 1 (default): Yes, 0: No
use_docked_mode =
-# Allow the use of NFC in games
-# 1 (default): Yes, 0 : No
-enable_nfc =
-
# Sets the seed for the RNG generator built into the switch
# rng_seed will be ignored and randomly generated if rng_seed_enabled is false
rng_seed_enabled =
@@ -323,29 +364,33 @@ rng_seed =
custom_rtc_enabled =
custom_rtc =
-# Sets the account username, max length is 32 characters
-# yuzu (default)
-username = yuzu
-
# Sets the systems language index
# 0: Japanese, 1: English (default), 2: French, 3: German, 4: Italian, 5: Spanish, 6: Chinese,
# 7: Korean, 8: Dutch, 9: Portuguese, 10: Russian, 11: Taiwanese, 12: British English, 13: Canadian French,
-# 14: Latin American Spanish, 15: Simplified Chinese, 16: Traditional Chinese
+# 14: Latin American Spanish, 15: Simplified Chinese, 16: Traditional Chinese, 17: Brazilian Portuguese
language_index =
# The system region that yuzu will use during emulation
# -1: Auto-select (default), 0: Japan, 1: USA, 2: Europe, 3: Australia, 4: China, 5: Korea, 6: Taiwan
-region_value =
+region_index =
# The system time zone that yuzu will use during emulation
# 0: Auto-select (default), 1: Default (system archive value), Others: Index for specified time zone
time_zone_index =
+# Sets the sound output mode.
+# 0: Mono, 1 (default): Stereo, 2: Surround
+sound_index =
+
[Miscellaneous]
# A filter which removes logs below a certain logging level.
# Examples: *:Debug Kernel.SVC:Trace Service.*:Critical
log_filter = *:Trace
+# Use developer keys
+# 0 (default): Disabled, 1: Enabled
+use_dev_keys =
+
[Debugging]
# Record frame time data, can be found in the log directory. Boolean value
record_frame_times =
@@ -355,6 +400,8 @@ dump_exefs=false
dump_nso=false
# Determines whether or not yuzu will save the filesystem access log.
enable_fs_access_log=false
+# Enables verbose reporting services
+reporting_services =
# Determines whether or not yuzu will report to the game that the emulated console is in Kiosk Mode
# false: Retail/Normal Mode (default), true: Kiosk Mode
quest_flag =
@@ -393,4 +440,4 @@ title_ids =
# For each title ID, have a key/value pair called `disabled_<title_id>` equal to the names of the add-ons to disable (sep. by '|')
# e.x. disabled_0100000000010000 = Update|DLC <- disables Updates and DLC on Super Mario Odyssey
)";
-}
+} // namespace DefaultINI
diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp
index 06b20c975..f643a4b0b 100644
--- a/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp
+++ b/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp
@@ -2,18 +2,11 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
-// Ignore -Wimplicit-fallthrough due to https://github.com/libsdl-org/SDL/issues/4307
-#ifdef __clang__
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wimplicit-fallthrough"
-#endif
#include <SDL.h>
-#ifdef __clang__
-#pragma clang diagnostic pop
-#endif
#include "common/logging/log.h"
#include "common/scm_rev.h"
+#include "common/settings.h"
#include "core/core.h"
#include "core/perf_stats.h"
#include "input_common/keyboard.h"
@@ -23,8 +16,8 @@
#include "yuzu_cmd/emu_window/emu_window_sdl2.h"
#include "yuzu_cmd/yuzu_icon.h"
-EmuWindow_SDL2::EmuWindow_SDL2(InputCommon::InputSubsystem* input_subsystem_)
- : input_subsystem{input_subsystem_} {
+EmuWindow_SDL2::EmuWindow_SDL2(InputCommon::InputSubsystem* input_subsystem_, Core::System& system_)
+ : input_subsystem{input_subsystem_}, system{system_} {
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK) < 0) {
LOG_CRITICAL(Frontend, "Failed to initialize SDL2! Exiting...");
exit(1);
@@ -130,24 +123,37 @@ void EmuWindow_SDL2::OnResize() {
}
void EmuWindow_SDL2::Fullscreen() {
- if (SDL_SetWindowFullscreen(render_window, SDL_WINDOW_FULLSCREEN) == 0) {
- return;
- }
-
- LOG_ERROR(Frontend, "Fullscreening failed: {}", SDL_GetError());
+ switch (Settings::values.fullscreen_mode.GetValue()) {
+ case Settings::FullscreenMode::Exclusive:
+ // Set window size to render size before entering fullscreen -- SDL does not resize to
+ // display dimensions in this mode.
+ // TODO: Multiply the window size by resolution_factor (for both docked modes)
+ if (Settings::values.use_docked_mode) {
+ SDL_SetWindowSize(render_window, Layout::ScreenDocked::Width,
+ Layout::ScreenDocked::Height);
+ }
- // Try a different fullscreening method
- LOG_INFO(Frontend, "Attempting to use borderless fullscreen...");
- if (SDL_SetWindowFullscreen(render_window, SDL_WINDOW_FULLSCREEN_DESKTOP) == 0) {
- return;
- }
+ if (SDL_SetWindowFullscreen(render_window, SDL_WINDOW_FULLSCREEN) == 0) {
+ return;
+ }
- LOG_ERROR(Frontend, "Borderless fullscreening failed: {}", SDL_GetError());
+ LOG_ERROR(Frontend, "Fullscreening failed: {}", SDL_GetError());
+ LOG_INFO(Frontend, "Attempting to use borderless fullscreen...");
+ [[fallthrough]];
+ case Settings::FullscreenMode::Borderless:
+ if (SDL_SetWindowFullscreen(render_window, SDL_WINDOW_FULLSCREEN_DESKTOP) == 0) {
+ return;
+ }
- // Fallback algorithm: Maximise window.
- // Works on all systems (unless something is seriously wrong), so no fallback for this one.
- LOG_INFO(Frontend, "Falling back on a maximised window...");
- SDL_MaximizeWindow(render_window);
+ LOG_ERROR(Frontend, "Borderless fullscreening failed: {}", SDL_GetError());
+ [[fallthrough]];
+ default:
+ // Fallback algorithm: Maximise window.
+ // Works on all systems (unless something is seriously wrong), so no fallback for this one.
+ LOG_INFO(Frontend, "Falling back on a maximised window...");
+ SDL_MaximizeWindow(render_window);
+ break;
+ }
}
void EmuWindow_SDL2::WaitEvent() {
@@ -212,7 +218,7 @@ void EmuWindow_SDL2::WaitEvent() {
const u32 current_time = SDL_GetTicks();
if (current_time > last_time + 2000) {
- const auto results = Core::System::GetInstance().GetAndResetPerfStats();
+ const auto results = system.GetAndResetPerfStats();
const auto title =
fmt::format("yuzu {} | {}-{} | FPS: {:.0f} ({:.0f}%)", Common::g_build_fullname,
Common::g_scm_branch, Common::g_scm_desc, results.average_game_fps,
diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2.h b/src/yuzu_cmd/emu_window/emu_window_sdl2.h
index 1b9ab5b93..aa0d52ae4 100644
--- a/src/yuzu_cmd/emu_window/emu_window_sdl2.h
+++ b/src/yuzu_cmd/emu_window/emu_window_sdl2.h
@@ -24,7 +24,7 @@ enum class MouseButton;
class EmuWindow_SDL2 : public Core::Frontend::EmuWindow {
public:
- explicit EmuWindow_SDL2(InputCommon::InputSubsystem* input_subsystem);
+ explicit EmuWindow_SDL2(InputCommon::InputSubsystem* input_subsystem, Core::System& system_);
~EmuWindow_SDL2();
/// Whether the window is still open, and a close request hasn't yet been sent
@@ -87,4 +87,7 @@ protected:
/// Input subsystem to use with this window.
InputCommon::InputSubsystem* input_subsystem;
+
+ /// yuzu core instance
+ Core::System& system;
};
diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp
index 837a44be7..5b98c255b 100644
--- a/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp
+++ b/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp
@@ -7,15 +7,7 @@
#include <string>
#define SDL_MAIN_HANDLED
-// Ignore -Wimplicit-fallthrough due to https://github.com/libsdl-org/SDL/issues/4307
-#ifdef __clang__
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wimplicit-fallthrough"
-#endif
#include <SDL.h>
-#ifdef __clang__
-#pragma clang diagnostic pop
-#endif
#include <fmt/format.h>
#include <glad/glad.h>
@@ -84,8 +76,9 @@ bool EmuWindow_SDL2_GL::SupportsRequiredGLExtensions() {
return unsupported_ext.empty();
}
-EmuWindow_SDL2_GL::EmuWindow_SDL2_GL(InputCommon::InputSubsystem* input_subsystem, bool fullscreen)
- : EmuWindow_SDL2{input_subsystem} {
+EmuWindow_SDL2_GL::EmuWindow_SDL2_GL(InputCommon::InputSubsystem* input_subsystem,
+ Core::System& system_, bool fullscreen)
+ : EmuWindow_SDL2{input_subsystem, system_} {
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 6);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY);
diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.h b/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.h
index 9e694d985..d7f2c83d8 100644
--- a/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.h
+++ b/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.h
@@ -8,13 +8,18 @@
#include "core/frontend/emu_window.h"
#include "yuzu_cmd/emu_window/emu_window_sdl2.h"
+namespace Core {
+class System;
+}
+
namespace InputCommon {
class InputSubsystem;
}
class EmuWindow_SDL2_GL final : public EmuWindow_SDL2 {
public:
- explicit EmuWindow_SDL2_GL(InputCommon::InputSubsystem* input_subsystem, bool fullscreen);
+ explicit EmuWindow_SDL2_GL(InputCommon::InputSubsystem* input_subsystem, Core::System& system_,
+ bool fullscreen);
~EmuWindow_SDL2_GL();
std::unique_ptr<Core::Frontend::GraphicsContext> CreateSharedContext() const override;
diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.cpp
index 3401ad4b4..cdda375d8 100644
--- a/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.cpp
+++ b/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.cpp
@@ -15,20 +15,18 @@
#include "video_core/renderer_vulkan/renderer_vulkan.h"
#include "yuzu_cmd/emu_window/emu_window_sdl2_vk.h"
-// Include these late to avoid polluting everything with Xlib macros
-// Ignore -Wimplicit-fallthrough due to https://github.com/libsdl-org/SDL/issues/4307
-#ifdef __clang__
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wimplicit-fallthrough"
+#ifdef YUZU_USE_EXTERNAL_SDL2
+// Include this before SDL.h to prevent the external from including a dummy
+#define USING_GENERATED_CONFIG_H
+#include <SDL_config.h>
#endif
+
#include <SDL.h>
-#ifdef __clang__
-#pragma clang diagnostic pop
-#endif
#include <SDL_syswm.h>
-EmuWindow_SDL2_VK::EmuWindow_SDL2_VK(InputCommon::InputSubsystem* input_subsystem)
- : EmuWindow_SDL2{input_subsystem} {
+EmuWindow_SDL2_VK::EmuWindow_SDL2_VK(InputCommon::InputSubsystem* input_subsystem,
+ Core::System& system_, bool fullscreen)
+ : EmuWindow_SDL2{input_subsystem, system_} {
const std::string window_title = fmt::format("yuzu {} | {}-{} (Vulkan)", Common::g_build_name,
Common::g_scm_branch, Common::g_scm_desc);
render_window =
@@ -45,12 +43,21 @@ EmuWindow_SDL2_VK::EmuWindow_SDL2_VK(InputCommon::InputSubsystem* input_subsyste
SetWindowIcon();
+ if (fullscreen) {
+ Fullscreen();
+ }
+
switch (wm.subsystem) {
#ifdef SDL_VIDEO_DRIVER_WINDOWS
case SDL_SYSWM_TYPE::SDL_SYSWM_WINDOWS:
window_info.type = Core::Frontend::WindowSystemType::Windows;
window_info.render_surface = reinterpret_cast<void*>(wm.info.win.window);
break;
+#else
+ case SDL_SYSWM_TYPE::SDL_SYSWM_WINDOWS:
+ LOG_CRITICAL(Frontend, "Window manager subsystem Windows not compiled");
+ std::exit(EXIT_FAILURE);
+ break;
#endif
#ifdef SDL_VIDEO_DRIVER_X11
case SDL_SYSWM_TYPE::SDL_SYSWM_X11:
@@ -58,6 +65,11 @@ EmuWindow_SDL2_VK::EmuWindow_SDL2_VK(InputCommon::InputSubsystem* input_subsyste
window_info.display_connection = wm.info.x11.display;
window_info.render_surface = reinterpret_cast<void*>(wm.info.x11.window);
break;
+#else
+ case SDL_SYSWM_TYPE::SDL_SYSWM_X11:
+ LOG_CRITICAL(Frontend, "Window manager subsystem X11 not compiled");
+ std::exit(EXIT_FAILURE);
+ break;
#endif
#ifdef SDL_VIDEO_DRIVER_WAYLAND
case SDL_SYSWM_TYPE::SDL_SYSWM_WAYLAND:
@@ -65,6 +77,11 @@ EmuWindow_SDL2_VK::EmuWindow_SDL2_VK(InputCommon::InputSubsystem* input_subsyste
window_info.display_connection = wm.info.wl.display;
window_info.render_surface = wm.info.wl.surface;
break;
+#else
+ case SDL_SYSWM_TYPE::SDL_SYSWM_WAYLAND:
+ LOG_CRITICAL(Frontend, "Window manager subsystem Wayland not compiled");
+ std::exit(EXIT_FAILURE);
+ break;
#endif
default:
LOG_CRITICAL(Frontend, "Window manager subsystem not implemented");
diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.h b/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.h
index bdfdc3c6f..3ea521b2a 100644
--- a/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.h
+++ b/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.h
@@ -19,7 +19,8 @@ class InputSubsystem;
class EmuWindow_SDL2_VK final : public EmuWindow_SDL2 {
public:
- explicit EmuWindow_SDL2_VK(InputCommon::InputSubsystem* input_subsystem);
+ explicit EmuWindow_SDL2_VK(InputCommon::InputSubsystem* input_subsystem, Core::System& system,
+ bool fullscreen);
~EmuWindow_SDL2_VK() override;
std::unique_ptr<Core::Frontend::GraphicsContext> CreateSharedContext() const override;
diff --git a/src/yuzu_cmd/yuzu.cpp b/src/yuzu_cmd/yuzu.cpp
index 50e388312..c10093820 100644
--- a/src/yuzu_cmd/yuzu.cpp
+++ b/src/yuzu_cmd/yuzu.cpp
@@ -78,7 +78,7 @@ static void InitializeLogging() {
using namespace Common;
Log::Filter log_filter(Log::Level::Debug);
- log_filter.ParseFilterString(Settings::values.log_filter);
+ log_filter.ParseFilterString(static_cast<std::string>(Settings::values.log_filter));
Log::SetGlobalFilter(log_filter);
Log::AddBackend(std::make_unique<Log::ColorConsoleBackend>());
@@ -172,10 +172,10 @@ int main(int argc, char** argv) {
std::unique_ptr<EmuWindow_SDL2> emu_window;
switch (Settings::values.renderer_backend.GetValue()) {
case Settings::RendererBackend::OpenGL:
- emu_window = std::make_unique<EmuWindow_SDL2_GL>(&input_subsystem, fullscreen);
+ emu_window = std::make_unique<EmuWindow_SDL2_GL>(&input_subsystem, system, fullscreen);
break;
case Settings::RendererBackend::Vulkan:
- emu_window = std::make_unique<EmuWindow_SDL2_VK>(&input_subsystem);
+ emu_window = std::make_unique<EmuWindow_SDL2_VK>(&input_subsystem, system, fullscreen);
break;
}
@@ -218,9 +218,11 @@ int main(int argc, char** argv) {
// Core is loaded, start the GPU (makes the GPU contexts current to this thread)
system.GPU().Start();
- system.Renderer().ReadRasterizer()->LoadDiskResources(
- system.CurrentProcess()->GetTitleID(), std::stop_token{},
- [](VideoCore::LoadCallbackStage, size_t value, size_t total) {});
+ if (Settings::values.use_disk_shader_cache.GetValue()) {
+ system.Renderer().ReadRasterizer()->LoadDiskResources(
+ system.CurrentProcess()->GetTitleID(), std::stop_token{},
+ [](VideoCore::LoadCallbackStage, size_t value, size_t total) {});
+ }
void(system.Run());
while (emu_window->IsOpen()) {