diff options
Diffstat (limited to 'src/yuzu_cmd')
-rw-r--r-- | src/yuzu_cmd/config.cpp | 26 | ||||
-rw-r--r-- | src/yuzu_cmd/default_ini.h | 102 | ||||
-rw-r--r-- | src/yuzu_cmd/emu_window/emu_window_sdl2.cpp | 52 | ||||
-rw-r--r-- | src/yuzu_cmd/emu_window/emu_window_sdl2.h | 12 | ||||
-rw-r--r-- | src/yuzu_cmd/yuzu.cpp | 63 |
5 files changed, 164 insertions, 91 deletions
diff --git a/src/yuzu_cmd/config.cpp b/src/yuzu_cmd/config.cpp index 527017282..c5bc472ca 100644 --- a/src/yuzu_cmd/config.cpp +++ b/src/yuzu_cmd/config.cpp @@ -4,18 +4,8 @@ #include <memory> #include <optional> #include <sstream> - -// 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 <INIReader.h> +#include <SDL.h> #include "common/fs/file.h" #include "common/fs/fs.h" #include "common/fs/path_util.h" @@ -176,6 +166,11 @@ void Config::ReadValues() { 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); @@ -270,7 +265,7 @@ void Config::ReadValues() { // Core ReadSetting("Core", Settings::values.use_multi_core); - ReadSetting("Core", Settings::values.use_extended_memory_layout); + ReadSetting("Core", Settings::values.use_unsafe_extended_memory_layout); // Cpu ReadSetting("Cpu", Settings::values.cpu_accuracy); @@ -296,6 +291,7 @@ void Config::ReadValues() { // 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); @@ -315,13 +311,15 @@ void Config::ReadValues() { 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.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_pessimistic_flushes); ReadSetting("Renderer", Settings::values.use_vulkan_driver_pipeline_cache); ReadSetting("Renderer", Settings::values.bg_red); diff --git a/src/yuzu_cmd/default_ini.h b/src/yuzu_cmd/default_ini.h index 6fcf04e1b..119e22183 100644 --- a/src/yuzu_cmd/default_ini.h +++ b/src/yuzu_cmd/default_ini.h @@ -5,8 +5,8 @@ namespace DefaultINI { -const char* sdl2_config_file = R"( - +const char* sdl2_config_file = + R"( [ControlsP0] # The input devices and parameters for each Switch native input # The config section determines the player number where the config will be applied on. For example "ControlsP0", "ControlsP1", ... @@ -14,6 +14,7 @@ const char* sdl2_config_file = R"( # Escape characters $0 (for ':'), $1 (for ',') and $2 (for '$') can be used in values # Indicates if this player should be connected at boot +# 0 (default): Disabled, 1: Enabled connected= # for button input, the following devices are available: @@ -94,6 +95,18 @@ motionright= # 0 (default): Disabled, 1: Enabled debug_pad_enabled = +# Enable sdl raw input. Allows to configure up to 8 xinput controllers. +# 0 (default): Disabled, 1: Enabled +enable_raw_input = + +# Enable yuzu joycon driver instead of SDL drive. +# 0: Disabled, 1 (default): Enabled +enable_joycon_driver = + +# Emulates an analog input from buttons. Allowing to dial any angle. +# 0 (default): Disabled, 1: Enabled +emulate_analog_keyboard = + # Whether to enable or disable vibration # 0: Disabled, 1 (default): Enabled vibration_enabled= @@ -127,9 +140,29 @@ udp_input_servers = # 0 (default): Off, 1: On mouse_panning = -# Set mouse sensitivity. -# Default: 1.0 -mouse_panning_sensitivity = +# Set mouse panning horizontal sensitivity. +# Default: 50.0 +mouse_panning_x_sensitivity = + +# Set mouse panning vertical sensitivity. +# Default: 50.0 +mouse_panning_y_sensitivity = + +# Set mouse panning deadzone horizontal counterweight. +# Default: 0.0 +mouse_panning_deadzone_x_counterweight = + +# Set mouse panning deadzone vertical counterweight. +# Default: 0.0 +mouse_panning_deadzone_y_counterweight = + +# Set mouse panning stick decay strength. +# Default: 22.0 +mouse_panning_decay_strength = + +# Set mouse panning stick minimum decay. +# Default: 5.0 +mouse_panning_minimum_decay = # Emulate an analog control stick from keyboard inputs. # 0 (default): Disabled, 1: Enabled @@ -143,14 +176,16 @@ mouse_enabled = # 0 (default): Disabled, 1: Enabled keyboard_enabled = +)" + R"( [Core] # Whether to use multi-core for CPU emulation # 0: Disabled, 1 (default): Enabled use_multi_core = -# Enable extended guest system memory layout (6GB DRAM) +# Enable unsafe extended guest system memory layout (8GB DRAM) # 0 (default): Disabled, 1: Enabled -use_extended_memory_layout = +use_unsafe_extended_memory_layout = [Cpu] # Adjusts various optimizations. @@ -242,11 +277,17 @@ cpuopt_unsafe_fastmem_check = # 0: Disabled, 1 (default): Enabled cpuopt_unsafe_ignore_global_monitor = +)" + R"( [Renderer] # Which backend API to use. # 0: OpenGL, 1 (default): Vulkan backend = +# Whether to enable asynchronous presentation (Vulkan only) +# 0 (default): Off, 1: On +async_presentation = + # Enable graphics API debugging mode. # 0 (default): Disabled, 1: Enabled debug = @@ -269,11 +310,14 @@ vulkan_device = # 0: 0.5x (360p/540p) [EXPERIMENTAL] # 1: 0.75x (540p/810p) [EXPERIMENTAL] # 2 (default): 1x (720p/1080p) -# 3: 2x (1440p/2160p) -# 4: 3x (2160p/3240p) -# 5: 4x (2880p/4320p) -# 6: 5x (3600p/5400p) -# 7: 6x (4320p/6480p) +# 3: 1.5x (1080p/1620p) [EXPERIMENTAL] +# 4: 2x (1440p/2160p) +# 5: 3x (2160p/3240p) +# 6: 4x (2880p/4320p) +# 7: 5x (3600p/5400p) +# 8: 6x (4320p/6480p) +# 9: 7x (5040p/7560p) +# 10: 8x (5760/8640p) resolution_setup = # Pixel filter to use when up- or down-sampling rendered frames. @@ -282,11 +326,11 @@ resolution_setup = # 2: Bicubic # 3: Gaussian # 4: ScaleForce -# 5: AMD FidelityFX™️ Super Resolution [Vulkan Only] +# 5: AMD FidelityFX™️ Super Resolution scaling_filter = # Anti-Aliasing (AA) -# 0 (default): None, 1: FXAA +# 0 (default): None, 1: FXAA, 2: SMAA anti_aliasing = # Whether to use fullscreen or borderless window mode @@ -294,15 +338,21 @@ anti_aliasing = fullscreen_mode = # Aspect ratio -# 0: Default (16:9), 1: Force 4:3, 2: Force 21:9, 3: Stretch to Window +# 0: Default (16:9), 1: Force 4:3, 2: Force 21:9, 3: Force 16:10, 4: Stretch to Window aspect_ratio = # Anisotropic filtering # 0: Default, 1: 2x, 2: 4x, 3: 8x, 4: 16x max_anisotropy = -# Whether to enable V-Sync (caps the framerate at 60FPS) or not. -# 0 (default): Off, 1: On +# Whether to enable VSync or not. +# OpenGL: Values other than 0 enable VSync +# Vulkan: FIFO is selected if the requested mode is not supported by the driver. +# 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. +# 0: Immediate (Off), 1: Mailbox, 2 (Default): FIFO (On), 3: FIFO Relaxed use_vsync = # Selects the OpenGL shader backend. NV_gpu_program5 is required for GLASM. If NV_gpu_program5 is @@ -310,6 +360,10 @@ use_vsync = # 0: GLSL, 1 (default): GLASM, 2: SPIR-V shader_backend = +# Uses reactive flushing instead of predictive flushing. Allowing a more accurate syncing of memory. +# 0: Off, 1 (default): On +use_reactive_flushing = + # Whether to allow asynchronous shader building. # 0 (default): Off, 1: On use_asynchronous_shaders = @@ -322,6 +376,14 @@ nvdec_emulation = # 0: Off, 1 (default): On accelerate_astc = +# Decode ASTC textures asynchronously. +# 0 (default): Off, 1: On +async_astc = + +# Recompress ASTC textures to a different format. +# 0 (default): Uncompressed, 1: BC1 (Low quality), 2: BC3: (Medium quality) +async_astc = + # Turns on the speed limiter, which will limit the emulation speed to the desired speed limit value # 0: Off, 1: On (default) use_speed_limit = @@ -346,10 +408,6 @@ use_asynchronous_gpu_emulation = # 0: Off, 1 (default): On use_fast_gpu_time = -# Force unmodified buffers to be flushed, which can cost performance. -# 0: Off (default), 1: On -use_pessimistic_flushes = - # Whether to use garbage collection or not for GPU caches. # 0 (default): Off, 1: On use_caches_gc = @@ -360,6 +418,8 @@ bg_red = bg_blue = bg_green = +)" + R"( [Audio] # Which audio output engine to use. # auto (default): Auto-select diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp index 31f28a507..5153cdb79 100644 --- a/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp +++ b/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp @@ -18,11 +18,11 @@ 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) { + input_subsystem->Initialize(); + if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER) < 0) { LOG_CRITICAL(Frontend, "Failed to initialize SDL2! Exiting..."); exit(1); } - input_subsystem->Initialize(); SDL_SetMainReady(); } @@ -32,10 +32,6 @@ EmuWindow_SDL2::~EmuWindow_SDL2() { SDL_Quit(); } -void EmuWindow_SDL2::OnMouseMotion(s32 x, s32 y) { - input_subsystem->GetMouse()->MouseMove(x, y, 0, 0, 0, 0); -} - InputCommon::MouseButton EmuWindow_SDL2::SDLButtonToMouseButton(u32 button) const { switch (button) { case SDL_BUTTON_LEFT: @@ -53,44 +49,40 @@ InputCommon::MouseButton EmuWindow_SDL2::SDLButtonToMouseButton(u32 button) cons } } +std::pair<float, float> EmuWindow_SDL2::MouseToTouchPos(s32 touch_x, s32 touch_y) const { + int w, h; + SDL_GetWindowSize(render_window, &w, &h); + const float fx = static_cast<float>(touch_x) / w; + const float fy = static_cast<float>(touch_y) / h; + + return {std::clamp<float>(fx, 0.0f, 1.0f), std::clamp<float>(fy, 0.0f, 1.0f)}; +} + void EmuWindow_SDL2::OnMouseButton(u32 button, u8 state, s32 x, s32 y) { const auto mouse_button = SDLButtonToMouseButton(button); if (state == SDL_PRESSED) { - input_subsystem->GetMouse()->PressButton(x, y, 0, 0, mouse_button); + const auto [touch_x, touch_y] = MouseToTouchPos(x, y); + input_subsystem->GetMouse()->PressButton(x, y, mouse_button); + input_subsystem->GetMouse()->PressMouseButton(mouse_button); + input_subsystem->GetMouse()->PressTouchButton(touch_x, touch_y, mouse_button); } else { input_subsystem->GetMouse()->ReleaseButton(mouse_button); } } -std::pair<unsigned, unsigned> EmuWindow_SDL2::TouchToPixelPos(float touch_x, float touch_y) const { - int w, h; - SDL_GetWindowSize(render_window, &w, &h); - - touch_x *= w; - touch_y *= h; - - return {static_cast<unsigned>(std::max(std::round(touch_x), 0.0f)), - static_cast<unsigned>(std::max(std::round(touch_y), 0.0f))}; +void EmuWindow_SDL2::OnMouseMotion(s32 x, s32 y) { + const auto [touch_x, touch_y] = MouseToTouchPos(x, y); + input_subsystem->GetMouse()->Move(x, y, 0, 0); + input_subsystem->GetMouse()->MouseMove(touch_x, touch_y); + input_subsystem->GetMouse()->TouchMove(touch_x, touch_y); } void EmuWindow_SDL2::OnFingerDown(float x, float y, std::size_t id) { - int width, height; - SDL_GetWindowSize(render_window, &width, &height); - const auto [px, py] = TouchToPixelPos(x, y); - const float fx = px * 1.0f / width; - const float fy = py * 1.0f / height; - - input_subsystem->GetTouchScreen()->TouchPressed(fx, fy, id); + input_subsystem->GetTouchScreen()->TouchPressed(x, y, id); } void EmuWindow_SDL2::OnFingerMotion(float x, float y, std::size_t id) { - int width, height; - SDL_GetWindowSize(render_window, &width, &height); - const auto [px, py] = TouchToPixelPos(x, y); - const float fx = px * 1.0f / width; - const float fy = py * 1.0f / height; - - input_subsystem->GetTouchScreen()->TouchMoved(fx, fy, id); + input_subsystem->GetTouchScreen()->TouchMoved(x, y, id); } void EmuWindow_SDL2::OnFingerUp() { diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2.h b/src/yuzu_cmd/emu_window/emu_window_sdl2.h index 25c23e2a5..4ad05e0e1 100644 --- a/src/yuzu_cmd/emu_window/emu_window_sdl2.h +++ b/src/yuzu_cmd/emu_window/emu_window_sdl2.h @@ -4,7 +4,9 @@ #pragma once #include <utility> + #include "core/frontend/emu_window.h" +#include "core/frontend/graphics_context.h" struct SDL_Window; @@ -38,17 +40,17 @@ protected: /// Called by WaitEvent when a key is pressed or released. void OnKeyEvent(int key, u8 state); - /// Called by WaitEvent when the mouse moves. - void OnMouseMotion(s32 x, s32 y); - /// Converts a SDL mouse button into MouseInput mouse button InputCommon::MouseButton SDLButtonToMouseButton(u32 button) const; + /// Translates pixel position to float position + std::pair<float, float> MouseToTouchPos(s32 touch_x, s32 touch_y) const; + /// Called by WaitEvent when a mouse button is pressed or released void OnMouseButton(u32 button, u8 state, s32 x, s32 y); - /// Translates pixel position (0..1) to pixel positions - std::pair<unsigned, unsigned> TouchToPixelPos(float touch_x, float touch_y) const; + /// Called by WaitEvent when the mouse moves. + void OnMouseMotion(s32 x, s32 y); /// Called by WaitEvent when a finger starts touching the touchscreen void OnFingerDown(float x, float y, std::size_t id); diff --git a/src/yuzu_cmd/yuzu.cpp b/src/yuzu_cmd/yuzu.cpp index 91133569d..7b6d49c63 100644 --- a/src/yuzu_cmd/yuzu.cpp +++ b/src/yuzu_cmd/yuzu.cpp @@ -42,6 +42,8 @@ #include <windows.h> #include <shellapi.h> + +#include "common/windows/timer_resolution.h" #endif #undef _UNICODE @@ -62,13 +64,15 @@ __declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1; static void PrintHelp(const char* argv0) { std::cout << "Usage: " << argv0 << " [options] <filename>\n" - "-m, --multiplayer=nick:password@address:port" - " Nickname, password, address and port for multiplayer\n" + "-c, --config Load the specified configuration file\n" "-f, --fullscreen Start in fullscreen mode\n" + "-g, --game File path of the game to load\n" "-h, --help Display this help and exit\n" - "-v, --version Output version information and exit\n" + "-m, --multiplayer=nick:password@address:port" + " Nickname, password, address and port for multiplayer\n" "-p, --program Pass following string as arguments to executable\n" - "-c, --config Load the specified configuration file\n"; + "-u, --user Select a specific user profile from 0 to 7\n" + "-v, --version Output version information and exit\n"; } static void PrintVersion() { @@ -199,6 +203,7 @@ int main(int argc, char** argv) { std::string filepath; std::optional<std::string> config_path; std::string program_args; + std::optional<int> selected_user; bool use_multiplayer = false; bool fullscreen = false; @@ -209,20 +214,37 @@ int main(int argc, char** argv) { static struct option long_options[] = { // clang-format off - {"multiplayer", required_argument, 0, 'm'}, + {"config", required_argument, 0, 'c'}, {"fullscreen", no_argument, 0, 'f'}, {"help", no_argument, 0, 'h'}, - {"version", no_argument, 0, 'v'}, + {"game", required_argument, 0, 'g'}, + {"multiplayer", required_argument, 0, 'm'}, {"program", optional_argument, 0, 'p'}, - {"config", required_argument, 0, 'c'}, + {"user", required_argument, 0, 'u'}, + {"version", no_argument, 0, 'v'}, {0, 0, 0, 0}, // clang-format on }; while (optind < argc) { - int arg = getopt_long(argc, argv, "g:fhvp::c:", long_options, &option_index); + int arg = getopt_long(argc, argv, "g:fhvp::c:u:", long_options, &option_index); if (arg != -1) { switch (static_cast<char>(arg)) { + case 'c': + config_path = optarg; + break; + case 'f': + fullscreen = true; + LOG_INFO(Frontend, "Starting in fullscreen mode..."); + break; + case 'h': + PrintHelp(argv[0]); + return 0; + case 'g': { + const std::string str_arg(optarg); + filepath = str_arg; + break; + } case 'm': { use_multiplayer = true; const std::string str_arg(optarg); @@ -255,23 +277,16 @@ int main(int argc, char** argv) { } break; } - case 'f': - fullscreen = true; - LOG_INFO(Frontend, "Starting in fullscreen mode..."); - break; - case 'h': - PrintHelp(argv[0]); - return 0; - case 'v': - PrintVersion(); - return 0; case 'p': program_args = argv[optind]; ++optind; break; - case 'c': - config_path = optarg; + case 'u': + selected_user = atoi(optarg); break; + case 'v': + PrintVersion(); + return 0; } } else { #ifdef _WIN32 @@ -295,8 +310,14 @@ int main(int argc, char** argv) { Settings::values.program_args = program_args; } + if (selected_user.has_value()) { + Settings::values.current_user = std::clamp(*selected_user, 0, 7); + } + #ifdef _WIN32 LocalFree(argv_w); + + Common::Windows::SetCurrentTimerResolutionToMaximum(); #endif MicroProfileOnThreadCreate("EmuThread"); @@ -388,7 +409,7 @@ int main(int argc, char** argv) { if (Settings::values.use_disk_shader_cache.GetValue()) { system.Renderer().ReadRasterizer()->LoadDiskResources( - system.GetCurrentProcessProgramID(), std::stop_token{}, + system.GetApplicationProcessProgramID(), std::stop_token{}, [](VideoCore::LoadCallbackStage, size_t value, size_t total) {}); } |