summaryrefslogtreecommitdiff
path: root/src/yuzu_cmd
diff options
context:
space:
mode:
Diffstat (limited to 'src/yuzu_cmd')
-rw-r--r--src/yuzu_cmd/CMakeLists.txt2
-rw-r--r--src/yuzu_cmd/config.cpp160
-rw-r--r--src/yuzu_cmd/default_ini.h68
-rw-r--r--src/yuzu_cmd/emu_window/emu_window_sdl2.cpp24
-rw-r--r--src/yuzu_cmd/emu_window/emu_window_sdl2.h15
-rw-r--r--src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp17
-rw-r--r--src/yuzu_cmd/emu_window/emu_window_sdl2_gl.h8
-rw-r--r--src/yuzu_cmd/emu_window/emu_window_sdl2_vk.cpp11
-rw-r--r--src/yuzu_cmd/emu_window/emu_window_sdl2_vk.h12
-rw-r--r--src/yuzu_cmd/yuzu.cpp30
-rw-r--r--src/yuzu_cmd/yuzu.rc2
11 files changed, 209 insertions, 140 deletions
diff --git a/src/yuzu_cmd/CMakeLists.txt b/src/yuzu_cmd/CMakeLists.txt
index a15719a0f..57f9916f6 100644
--- a/src/yuzu_cmd/CMakeLists.txt
+++ b/src/yuzu_cmd/CMakeLists.txt
@@ -39,7 +39,5 @@ endif()
39 39
40if (MSVC) 40if (MSVC)
41 include(CopyYuzuSDLDeps) 41 include(CopyYuzuSDLDeps)
42 include(CopyYuzuUnicornDeps)
43 copy_yuzu_SDL_deps(yuzu-cmd) 42 copy_yuzu_SDL_deps(yuzu-cmd)
44 copy_yuzu_unicorn_deps(yuzu-cmd)
45endif() 43endif()
diff --git a/src/yuzu_cmd/config.cpp b/src/yuzu_cmd/config.cpp
index f4cd905c9..e1adbbf2b 100644
--- a/src/yuzu_cmd/config.cpp
+++ b/src/yuzu_cmd/config.cpp
@@ -16,9 +16,11 @@
16#include "yuzu_cmd/config.h" 16#include "yuzu_cmd/config.h"
17#include "yuzu_cmd/default_ini.h" 17#include "yuzu_cmd/default_ini.h"
18 18
19namespace FS = Common::FS;
20
19Config::Config() { 21Config::Config() {
20 // TODO: Don't hardcode the path; let the frontend decide where to put the config files. 22 // TODO: Don't hardcode the path; let the frontend decide where to put the config files.
21 sdl2_config_loc = FileUtil::GetUserPath(FileUtil::UserPath::ConfigDir) + "sdl2-config.ini"; 23 sdl2_config_loc = FS::GetUserPath(FS::UserPath::ConfigDir) + "sdl2-config.ini";
22 sdl2_config = std::make_unique<INIReader>(sdl2_config_loc); 24 sdl2_config = std::make_unique<INIReader>(sdl2_config_loc);
23 25
24 Reload(); 26 Reload();
@@ -31,8 +33,8 @@ bool Config::LoadINI(const std::string& default_contents, bool retry) {
31 if (sdl2_config->ParseError() < 0) { 33 if (sdl2_config->ParseError() < 0) {
32 if (retry) { 34 if (retry) {
33 LOG_WARNING(Config, "Failed to load {}. Creating file from defaults...", location); 35 LOG_WARNING(Config, "Failed to load {}. Creating file from defaults...", location);
34 FileUtil::CreateFullPath(location); 36 FS::CreateFullPath(location);
35 FileUtil::WriteStringToFile(true, location, default_contents); 37 FS::WriteStringToFile(true, location, default_contents);
36 sdl2_config = std::make_unique<INIReader>(location); // Reopen file 38 sdl2_config = std::make_unique<INIReader>(location); // Reopen file
37 39
38 return LoadINI(default_contents, false); 40 return LoadINI(default_contents, false);
@@ -226,24 +228,24 @@ static const std::array<int, 8> keyboard_mods{
226 228
227void Config::ReadValues() { 229void Config::ReadValues() {
228 // Controls 230 // Controls
229 for (std::size_t p = 0; p < Settings::values.players.size(); ++p) { 231 for (std::size_t p = 0; p < Settings::values.players.GetValue().size(); ++p) {
230 const auto group = fmt::format("ControlsP{}", p); 232 const auto group = fmt::format("ControlsP{}", p);
231 for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) { 233 for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) {
232 std::string default_param = InputCommon::GenerateKeyboardParam(default_buttons[i]); 234 std::string default_param = InputCommon::GenerateKeyboardParam(default_buttons[i]);
233 Settings::values.players[p].buttons[i] = 235 Settings::values.players.GetValue()[p].buttons[i] =
234 sdl2_config->Get(group, Settings::NativeButton::mapping[i], default_param); 236 sdl2_config->Get(group, Settings::NativeButton::mapping[i], default_param);
235 if (Settings::values.players[p].buttons[i].empty()) 237 if (Settings::values.players.GetValue()[p].buttons[i].empty())
236 Settings::values.players[p].buttons[i] = default_param; 238 Settings::values.players.GetValue()[p].buttons[i] = default_param;
237 } 239 }
238 240
239 for (int i = 0; i < Settings::NativeAnalog::NumAnalogs; ++i) { 241 for (int i = 0; i < Settings::NativeAnalog::NumAnalogs; ++i) {
240 std::string default_param = InputCommon::GenerateAnalogParamFromKeys( 242 std::string default_param = InputCommon::GenerateAnalogParamFromKeys(
241 default_analogs[i][0], default_analogs[i][1], default_analogs[i][2], 243 default_analogs[i][0], default_analogs[i][1], default_analogs[i][2],
242 default_analogs[i][3], default_analogs[i][4], 0.5f); 244 default_analogs[i][3], default_analogs[i][4], 0.5f);
243 Settings::values.players[p].analogs[i] = 245 Settings::values.players.GetValue()[p].analogs[i] =
244 sdl2_config->Get(group, Settings::NativeAnalog::mapping[i], default_param); 246 sdl2_config->Get(group, Settings::NativeAnalog::mapping[i], default_param);
245 if (Settings::values.players[p].analogs[i].empty()) 247 if (Settings::values.players.GetValue()[p].analogs[i].empty())
246 Settings::values.players[p].analogs[i] = default_param; 248 Settings::values.players.GetValue()[p].analogs[i] = default_param;
247 } 249 }
248 } 250 }
249 251
@@ -286,6 +288,12 @@ void Config::ReadValues() {
286 Settings::values.debug_pad_analogs[i] = default_param; 288 Settings::values.debug_pad_analogs[i] = default_param;
287 } 289 }
288 290
291 Settings::values.vibration_enabled.SetValue(
292 sdl2_config->GetBoolean("ControlsGeneral", "vibration_enabled", true));
293 Settings::values.enable_accurate_vibrations.SetValue(
294 sdl2_config->GetBoolean("ControlsGeneral", "enable_accurate_vibrations", false));
295 Settings::values.motion_enabled.SetValue(
296 sdl2_config->GetBoolean("ControlsGeneral", "motion_enabled", true));
289 Settings::values.touchscreen.enabled = 297 Settings::values.touchscreen.enabled =
290 sdl2_config->GetBoolean("ControlsGeneral", "touch_enabled", true); 298 sdl2_config->GetBoolean("ControlsGeneral", "touch_enabled", true);
291 Settings::values.touchscreen.device = 299 Settings::values.touchscreen.device =
@@ -315,38 +323,30 @@ void Config::ReadValues() {
315 // Data Storage 323 // Data Storage
316 Settings::values.use_virtual_sd = 324 Settings::values.use_virtual_sd =
317 sdl2_config->GetBoolean("Data Storage", "use_virtual_sd", true); 325 sdl2_config->GetBoolean("Data Storage", "use_virtual_sd", true);
318 FileUtil::GetUserPath(FileUtil::UserPath::NANDDir, 326 FS::GetUserPath(
319 sdl2_config->Get("Data Storage", "nand_directory", 327 FS::UserPath::NANDDir,
320 FileUtil::GetUserPath(FileUtil::UserPath::NANDDir))); 328 sdl2_config->Get("Data Storage", "nand_directory", FS::GetUserPath(FS::UserPath::NANDDir)));
321 FileUtil::GetUserPath(FileUtil::UserPath::SDMCDir, 329 FS::GetUserPath(
322 sdl2_config->Get("Data Storage", "sdmc_directory", 330 FS::UserPath::SDMCDir,
323 FileUtil::GetUserPath(FileUtil::UserPath::SDMCDir))); 331 sdl2_config->Get("Data Storage", "sdmc_directory", FS::GetUserPath(FS::UserPath::SDMCDir)));
324 FileUtil::GetUserPath(FileUtil::UserPath::LoadDir, 332 FS::GetUserPath(
325 sdl2_config->Get("Data Storage", "load_directory", 333 FS::UserPath::LoadDir,
326 FileUtil::GetUserPath(FileUtil::UserPath::LoadDir))); 334 sdl2_config->Get("Data Storage", "load_directory", FS::GetUserPath(FS::UserPath::LoadDir)));
327 FileUtil::GetUserPath(FileUtil::UserPath::DumpDir, 335 FS::GetUserPath(
328 sdl2_config->Get("Data Storage", "dump_directory", 336 FS::UserPath::DumpDir,
329 FileUtil::GetUserPath(FileUtil::UserPath::DumpDir))); 337 sdl2_config->Get("Data Storage", "dump_directory", FS::GetUserPath(FS::UserPath::DumpDir)));
330 FileUtil::GetUserPath(FileUtil::UserPath::CacheDir, 338 FS::GetUserPath(FS::UserPath::CacheDir,
331 sdl2_config->Get("Data Storage", "cache_directory", 339 sdl2_config->Get("Data Storage", "cache_directory",
332 FileUtil::GetUserPath(FileUtil::UserPath::CacheDir))); 340 FS::GetUserPath(FS::UserPath::CacheDir)));
333 Settings::values.gamecard_inserted = 341 Settings::values.gamecard_inserted =
334 sdl2_config->GetBoolean("Data Storage", "gamecard_inserted", false); 342 sdl2_config->GetBoolean("Data Storage", "gamecard_inserted", false);
335 Settings::values.gamecard_current_game = 343 Settings::values.gamecard_current_game =
336 sdl2_config->GetBoolean("Data Storage", "gamecard_current_game", false); 344 sdl2_config->GetBoolean("Data Storage", "gamecard_current_game", false);
337 Settings::values.gamecard_path = sdl2_config->Get("Data Storage", "gamecard_path", ""); 345 Settings::values.gamecard_path = sdl2_config->Get("Data Storage", "gamecard_path", "");
338 Settings::values.nand_total_size = static_cast<Settings::NANDTotalSize>(sdl2_config->GetInteger(
339 "Data Storage", "nand_total_size", static_cast<long>(Settings::NANDTotalSize::S29_1GB)));
340 Settings::values.nand_user_size = static_cast<Settings::NANDUserSize>(sdl2_config->GetInteger(
341 "Data Storage", "nand_user_size", static_cast<long>(Settings::NANDUserSize::S26GB)));
342 Settings::values.nand_system_size = static_cast<Settings::NANDSystemSize>(
343 sdl2_config->GetInteger("Data Storage", "nand_system_size",
344 static_cast<long>(Settings::NANDSystemSize::S2_5GB)));
345 Settings::values.sdmc_size = static_cast<Settings::SDMCSize>(sdl2_config->GetInteger(
346 "Data Storage", "sdmc_size", static_cast<long>(Settings::SDMCSize::S16GB)));
347 346
348 // System 347 // System
349 Settings::values.use_docked_mode = sdl2_config->GetBoolean("System", "use_docked_mode", false); 348 Settings::values.use_docked_mode.SetValue(
349 sdl2_config->GetBoolean("System", "use_docked_mode", false));
350 const auto size = sdl2_config->GetInteger("System", "users_size", 0); 350 const auto size = sdl2_config->GetInteger("System", "users_size", 0);
351 351
352 Settings::values.current_user = std::clamp<int>( 352 Settings::values.current_user = std::clamp<int>(
@@ -354,60 +354,76 @@ void Config::ReadValues() {
354 354
355 const auto rng_seed_enabled = sdl2_config->GetBoolean("System", "rng_seed_enabled", false); 355 const auto rng_seed_enabled = sdl2_config->GetBoolean("System", "rng_seed_enabled", false);
356 if (rng_seed_enabled) { 356 if (rng_seed_enabled) {
357 Settings::values.rng_seed = sdl2_config->GetInteger("System", "rng_seed", 0); 357 Settings::values.rng_seed.SetValue(sdl2_config->GetInteger("System", "rng_seed", 0));
358 } else { 358 } else {
359 Settings::values.rng_seed = std::nullopt; 359 Settings::values.rng_seed.SetValue(std::nullopt);
360 } 360 }
361 361
362 const auto custom_rtc_enabled = sdl2_config->GetBoolean("System", "custom_rtc_enabled", false); 362 const auto custom_rtc_enabled = sdl2_config->GetBoolean("System", "custom_rtc_enabled", false);
363 if (custom_rtc_enabled) { 363 if (custom_rtc_enabled) {
364 Settings::values.custom_rtc = 364 Settings::values.custom_rtc.SetValue(
365 std::chrono::seconds(sdl2_config->GetInteger("System", "custom_rtc", 0)); 365 std::chrono::seconds(sdl2_config->GetInteger("System", "custom_rtc", 0)));
366 } else { 366 } else {
367 Settings::values.custom_rtc = std::nullopt; 367 Settings::values.custom_rtc.SetValue(std::nullopt);
368 } 368 }
369 369
370 Settings::values.language_index.SetValue(
371 sdl2_config->GetInteger("System", "language_index", 1));
372 Settings::values.time_zone_index.SetValue(
373 sdl2_config->GetInteger("System", "time_zone_index", 0));
374
370 // Core 375 // Core
371 Settings::values.use_multi_core = sdl2_config->GetBoolean("Core", "use_multi_core", false); 376 Settings::values.use_multi_core.SetValue(
377 sdl2_config->GetBoolean("Core", "use_multi_core", true));
372 378
373 // Renderer 379 // Renderer
374 const int renderer_backend = sdl2_config->GetInteger( 380 const int renderer_backend = sdl2_config->GetInteger(
375 "Renderer", "backend", static_cast<int>(Settings::RendererBackend::OpenGL)); 381 "Renderer", "backend", static_cast<int>(Settings::RendererBackend::OpenGL));
376 Settings::values.renderer_backend = static_cast<Settings::RendererBackend>(renderer_backend); 382 Settings::values.renderer_backend.SetValue(
383 static_cast<Settings::RendererBackend>(renderer_backend));
377 Settings::values.renderer_debug = sdl2_config->GetBoolean("Renderer", "debug", false); 384 Settings::values.renderer_debug = sdl2_config->GetBoolean("Renderer", "debug", false);
378 Settings::values.vulkan_device = sdl2_config->GetInteger("Renderer", "vulkan_device", 0); 385 Settings::values.vulkan_device.SetValue(
379 386 sdl2_config->GetInteger("Renderer", "vulkan_device", 0));
380 Settings::values.resolution_factor = 387
381 static_cast<float>(sdl2_config->GetReal("Renderer", "resolution_factor", 1.0)); 388 Settings::values.aspect_ratio.SetValue(
382 Settings::values.aspect_ratio = 389 static_cast<int>(sdl2_config->GetInteger("Renderer", "aspect_ratio", 0)));
383 static_cast<int>(sdl2_config->GetInteger("Renderer", "aspect_ratio", 0)); 390 Settings::values.max_anisotropy.SetValue(
384 Settings::values.max_anisotropy = 391 static_cast<int>(sdl2_config->GetInteger("Renderer", "max_anisotropy", 0)));
385 static_cast<int>(sdl2_config->GetInteger("Renderer", "max_anisotropy", 0)); 392 Settings::values.use_frame_limit.SetValue(
386 Settings::values.use_frame_limit = sdl2_config->GetBoolean("Renderer", "use_frame_limit", true); 393 sdl2_config->GetBoolean("Renderer", "use_frame_limit", true));
387 Settings::values.frame_limit = 394 Settings::values.frame_limit.SetValue(
388 static_cast<u16>(sdl2_config->GetInteger("Renderer", "frame_limit", 100)); 395 static_cast<u16>(sdl2_config->GetInteger("Renderer", "frame_limit", 100)));
389 Settings::values.use_disk_shader_cache = 396 Settings::values.use_disk_shader_cache.SetValue(
390 sdl2_config->GetBoolean("Renderer", "use_disk_shader_cache", false); 397 sdl2_config->GetBoolean("Renderer", "use_disk_shader_cache", false));
391 Settings::values.use_accurate_gpu_emulation = 398 const int gpu_accuracy_level = sdl2_config->GetInteger("Renderer", "gpu_accuracy", 0);
392 sdl2_config->GetBoolean("Renderer", "use_accurate_gpu_emulation", false); 399 Settings::values.gpu_accuracy.SetValue(static_cast<Settings::GPUAccuracy>(gpu_accuracy_level));
393 Settings::values.use_asynchronous_gpu_emulation = 400 Settings::values.use_asynchronous_gpu_emulation.SetValue(
394 sdl2_config->GetBoolean("Renderer", "use_asynchronous_gpu_emulation", false); 401 sdl2_config->GetBoolean("Renderer", "use_asynchronous_gpu_emulation", true));
395 Settings::values.use_vsync = 402 Settings::values.use_vsync.SetValue(
396 static_cast<u16>(sdl2_config->GetInteger("Renderer", "use_vsync", 1)); 403 static_cast<u16>(sdl2_config->GetInteger("Renderer", "use_vsync", 1)));
397 404 Settings::values.use_assembly_shaders.SetValue(
398 Settings::values.bg_red = static_cast<float>(sdl2_config->GetReal("Renderer", "bg_red", 0.0)); 405 sdl2_config->GetBoolean("Renderer", "use_assembly_shaders", true));
399 Settings::values.bg_green = 406 Settings::values.use_asynchronous_shaders.SetValue(
400 static_cast<float>(sdl2_config->GetReal("Renderer", "bg_green", 0.0)); 407 sdl2_config->GetBoolean("Renderer", "use_asynchronous_shaders", false));
401 Settings::values.bg_blue = static_cast<float>(sdl2_config->GetReal("Renderer", "bg_blue", 0.0)); 408 Settings::values.use_asynchronous_shaders.SetValue(
409 sdl2_config->GetBoolean("Renderer", "use_asynchronous_shaders", false));
410 Settings::values.use_fast_gpu_time.SetValue(
411 sdl2_config->GetBoolean("Renderer", "use_fast_gpu_time", true));
412
413 Settings::values.bg_red.SetValue(
414 static_cast<float>(sdl2_config->GetReal("Renderer", "bg_red", 0.0)));
415 Settings::values.bg_green.SetValue(
416 static_cast<float>(sdl2_config->GetReal("Renderer", "bg_green", 0.0)));
417 Settings::values.bg_blue.SetValue(
418 static_cast<float>(sdl2_config->GetReal("Renderer", "bg_blue", 0.0)));
402 419
403 // Audio 420 // Audio
404 Settings::values.sink_id = sdl2_config->Get("Audio", "output_engine", "auto"); 421 Settings::values.sink_id = sdl2_config->Get("Audio", "output_engine", "auto");
405 Settings::values.enable_audio_stretching = 422 Settings::values.enable_audio_stretching.SetValue(
406 sdl2_config->GetBoolean("Audio", "enable_audio_stretching", true); 423 sdl2_config->GetBoolean("Audio", "enable_audio_stretching", true));
407 Settings::values.audio_device_id = sdl2_config->Get("Audio", "output_device", "auto"); 424 Settings::values.audio_device_id = sdl2_config->Get("Audio", "output_device", "auto");
408 Settings::values.volume = static_cast<float>(sdl2_config->GetReal("Audio", "volume", 1)); 425 Settings::values.volume.SetValue(
409 426 static_cast<float>(sdl2_config->GetReal("Audio", "volume", 1)));
410 Settings::values.language_index = sdl2_config->GetInteger("System", "language_index", 1);
411 427
412 // Miscellaneous 428 // Miscellaneous
413 Settings::values.log_filter = sdl2_config->Get("Miscellaneous", "log_filter", "*:Trace"); 429 Settings::values.log_filter = sdl2_config->Get("Miscellaneous", "log_filter", "*:Trace");
@@ -425,6 +441,8 @@ void Config::ReadValues() {
425 Settings::values.reporting_services = 441 Settings::values.reporting_services =
426 sdl2_config->GetBoolean("Debugging", "reporting_services", false); 442 sdl2_config->GetBoolean("Debugging", "reporting_services", false);
427 Settings::values.quest_flag = sdl2_config->GetBoolean("Debugging", "quest_flag", false); 443 Settings::values.quest_flag = sdl2_config->GetBoolean("Debugging", "quest_flag", false);
444 Settings::values.disable_macro_jit =
445 sdl2_config->GetBoolean("Debugging", "disable_macro_jit", false);
428 446
429 const auto title_list = sdl2_config->Get("AddOns", "title_ids", ""); 447 const auto title_list = sdl2_config->Get("AddOns", "title_ids", "");
430 std::stringstream ss(title_list); 448 std::stringstream ss(title_list);
diff --git a/src/yuzu_cmd/default_ini.h b/src/yuzu_cmd/default_ini.h
index d63d7a58e..bcbbcd4ca 100644
--- a/src/yuzu_cmd/default_ini.h
+++ b/src/yuzu_cmd/default_ini.h
@@ -65,6 +65,14 @@ button_screenshot=
65lstick= 65lstick=
66rstick= 66rstick=
67 67
68# Whether to enable or disable vibration
69# 0: Disabled, 1 (default): Enabled
70vibration_enabled=
71
72# Whether to enable or disable accurate vibrations
73# 0 (default): Disabled, 1: Enabled
74enable_accurate_vibrations=
75
68# for motion input, the following devices are available: 76# for motion input, the following devices are available:
69# - "motion_emu" (default) for emulating motion input from mouse input. Required parameters: 77# - "motion_emu" (default) for emulating motion input from mouse input. Required parameters:
70# - "update_period": update period in milliseconds (default to 100) 78# - "update_period": update period in milliseconds (default to 100)
@@ -94,9 +102,42 @@ udp_pad_index=
94 102
95[Core] 103[Core]
96# Whether to use multi-core for CPU emulation 104# Whether to use multi-core for CPU emulation
97# 0 (default): Disabled, 1: Enabled 105# 0: Disabled, 1 (default): Enabled
98use_multi_core= 106use_multi_core=
99 107
108[Cpu]
109# Enable inline page tables optimization (faster guest memory access)
110# 0: Disabled, 1 (default): Enabled
111cpuopt_page_tables =
112
113# Enable block linking CPU optimization (reduce block dispatcher use during predictable jumps)
114# 0: Disabled, 1 (default): Enabled
115cpuopt_block_linking =
116
117# Enable return stack buffer CPU optimization (reduce block dispatcher use during predictable returns)
118# 0: Disabled, 1 (default): Enabled
119cpuopt_return_stack_buffer =
120
121# Enable fast dispatcher CPU optimization (use a two-tiered dispatcher architecture)
122# 0: Disabled, 1 (default): Enabled
123cpuopt_fast_dispatcher =
124
125# Enable context elimination CPU Optimization (reduce host memory use for guest context)
126# 0: Disabled, 1 (default): Enabled
127cpuopt_context_elimination =
128
129# Enable constant propagation CPU optimization (basic IR optimization)
130# 0: Disabled, 1 (default): Enabled
131cpuopt_const_prop =
132
133# Enable miscellaneous CPU optimizations (basic IR optimization)
134# 0: Disabled, 1 (default): Enabled
135cpuopt_misc_ir =
136
137# Enable reduction of memory misalignment checks (reduce memory fallbacks for misaligned access)
138# 0: Disabled, 1 (default): Enabled
139cpuopt_reduce_misalign_checks =
140
100[Renderer] 141[Renderer]
101# Which backend API to use. 142# Which backend API to use.
102# 0 (default): OpenGL, 1: Vulkan 143# 0 (default): OpenGL, 1: Vulkan
@@ -117,11 +158,6 @@ use_hw_renderer =
117# 0: Interpreter (slow), 1 (default): JIT (fast) 158# 0: Interpreter (slow), 1 (default): JIT (fast)
118use_shader_jit = 159use_shader_jit =
119 160
120# Resolution scale factor
121# 0: Auto (scales resolution to window size), 1: Native Switch screen resolution, Otherwise a scale
122# factor for the Switch resolution
123resolution_factor =
124
125# Aspect ratio 161# Aspect ratio
126# 0: Default (16:9), 1: Force 4:3, 2: Force 21:9, 3: Stretch to Window 162# 0: Default (16:9), 1: Force 4:3, 2: Force 21:9, 3: Stretch to Window
127aspect_ratio = 163aspect_ratio =
@@ -134,6 +170,14 @@ max_anisotropy =
134# 0 (default): Off, 1: On 170# 0 (default): Off, 1: On
135use_vsync = 171use_vsync =
136 172
173# Whether to use OpenGL assembly shaders or not. NV_gpu_program5 is required.
174# 0: Off, 1 (default): On
175use_assembly_shaders =
176
177# Whether to allow asynchronous shader building.
178# 0 (default): Off, 1: On
179use_asynchronous_shaders =
180
137# Turns on the frame limiter, which will limit frames output to the target game speed 181# Turns on the frame limiter, which will limit frames output to the target game speed
138# 0: Off, 1: On (default) 182# 0: Off, 1: On (default)
139use_frame_limit = 183use_frame_limit =
@@ -146,9 +190,9 @@ frame_limit =
146# 0 (default): Off, 1 : On 190# 0 (default): Off, 1 : On
147use_disk_shader_cache = 191use_disk_shader_cache =
148 192
149# Whether to use accurate GPU emulation 193# Which gpu accuracy level to use
150# 0 (default): Off (fast), 1 : On (slow) 194# 0 (Normal), 1 (High), 2 (Extreme)
151use_accurate_gpu_emulation = 195gpu_accuracy =
152 196
153# Whether to use asynchronous GPU emulation 197# Whether to use asynchronous GPU emulation
154# 0 : Off (slow), 1 (default): On (fast) 198# 0 : Off (slow), 1 (default): On (fast)
@@ -262,6 +306,10 @@ language_index =
262# -1: Auto-select (default), 0: Japan, 1: USA, 2: Europe, 3: Australia, 4: China, 5: Korea, 6: Taiwan 306# -1: Auto-select (default), 0: Japan, 1: USA, 2: Europe, 3: Australia, 4: China, 5: Korea, 6: Taiwan
263region_value = 307region_value =
264 308
309# The system time zone that yuzu will use during emulation
310# 0: Auto-select (default), 1: Default (system archive value), Others: Index for specified time zone
311time_zone_index =
312
265[Miscellaneous] 313[Miscellaneous]
266# A filter which removes logs below a certain logging level. 314# A filter which removes logs below a certain logging level.
267# Examples: *:Debug Kernel.SVC:Trace Service.*:Critical 315# Examples: *:Debug Kernel.SVC:Trace Service.*:Critical
@@ -280,6 +328,8 @@ dump_nso=false
280# Determines whether or not yuzu will report to the game that the emulated console is in Kiosk Mode 328# Determines whether or not yuzu will report to the game that the emulated console is in Kiosk Mode
281# false: Retail/Normal Mode (default), true: Kiosk Mode 329# false: Retail/Normal Mode (default), true: Kiosk Mode
282quest_flag = 330quest_flag =
331# Enables/Disables the macro JIT compiler
332disable_macro_jit=false
283 333
284[WebService] 334[WebService]
285# Whether or not to enable telemetry 335# Whether or not to enable telemetry
diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp
index 19584360c..521209622 100644
--- a/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp
+++ b/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp
@@ -13,23 +13,24 @@
13#include "input_common/sdl/sdl.h" 13#include "input_common/sdl/sdl.h"
14#include "yuzu_cmd/emu_window/emu_window_sdl2.h" 14#include "yuzu_cmd/emu_window/emu_window_sdl2.h"
15 15
16EmuWindow_SDL2::EmuWindow_SDL2(Core::System& system, bool fullscreen) : system{system} { 16EmuWindow_SDL2::EmuWindow_SDL2(InputCommon::InputSubsystem* input_subsystem_)
17 : input_subsystem{input_subsystem_} {
17 if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK) < 0) { 18 if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK) < 0) {
18 LOG_CRITICAL(Frontend, "Failed to initialize SDL2! Exiting..."); 19 LOG_CRITICAL(Frontend, "Failed to initialize SDL2! Exiting...");
19 exit(1); 20 exit(1);
20 } 21 }
21 InputCommon::Init(); 22 input_subsystem->Initialize();
22 SDL_SetMainReady(); 23 SDL_SetMainReady();
23} 24}
24 25
25EmuWindow_SDL2::~EmuWindow_SDL2() { 26EmuWindow_SDL2::~EmuWindow_SDL2() {
26 InputCommon::Shutdown(); 27 input_subsystem->Shutdown();
27 SDL_Quit(); 28 SDL_Quit();
28} 29}
29 30
30void EmuWindow_SDL2::OnMouseMotion(s32 x, s32 y) { 31void EmuWindow_SDL2::OnMouseMotion(s32 x, s32 y) {
31 TouchMoved((unsigned)std::max(x, 0), (unsigned)std::max(y, 0)); 32 TouchMoved((unsigned)std::max(x, 0), (unsigned)std::max(y, 0));
32 InputCommon::GetMotionEmu()->Tilt(x, y); 33 input_subsystem->GetMotionEmu()->Tilt(x, y);
33} 34}
34 35
35void EmuWindow_SDL2::OnMouseButton(u32 button, u8 state, s32 x, s32 y) { 36void EmuWindow_SDL2::OnMouseButton(u32 button, u8 state, s32 x, s32 y) {
@@ -41,9 +42,9 @@ void EmuWindow_SDL2::OnMouseButton(u32 button, u8 state, s32 x, s32 y) {
41 } 42 }
42 } else if (button == SDL_BUTTON_RIGHT) { 43 } else if (button == SDL_BUTTON_RIGHT) {
43 if (state == SDL_PRESSED) { 44 if (state == SDL_PRESSED) {
44 InputCommon::GetMotionEmu()->BeginTilt(x, y); 45 input_subsystem->GetMotionEmu()->BeginTilt(x, y);
45 } else { 46 } else {
46 InputCommon::GetMotionEmu()->EndTilt(); 47 input_subsystem->GetMotionEmu()->EndTilt();
47 } 48 }
48 } 49 }
49} 50}
@@ -79,9 +80,9 @@ void EmuWindow_SDL2::OnFingerUp() {
79 80
80void EmuWindow_SDL2::OnKeyEvent(int key, u8 state) { 81void EmuWindow_SDL2::OnKeyEvent(int key, u8 state) {
81 if (state == SDL_PRESSED) { 82 if (state == SDL_PRESSED) {
82 InputCommon::GetKeyboard()->PressKey(key); 83 input_subsystem->GetKeyboard()->PressKey(key);
83 } else if (state == SDL_RELEASED) { 84 } else if (state == SDL_RELEASED) {
84 InputCommon::GetKeyboard()->ReleaseKey(key); 85 input_subsystem->GetKeyboard()->ReleaseKey(key);
85 } 86 }
86} 87}
87 88
@@ -181,9 +182,10 @@ void EmuWindow_SDL2::PollEvents() {
181 const u32 current_time = SDL_GetTicks(); 182 const u32 current_time = SDL_GetTicks();
182 if (current_time > last_time + 2000) { 183 if (current_time > last_time + 2000) {
183 const auto results = Core::System::GetInstance().GetAndResetPerfStats(); 184 const auto results = Core::System::GetInstance().GetAndResetPerfStats();
184 const auto title = fmt::format( 185 const auto title =
185 "yuzu {} | {}-{} | FPS: {:.0f} ({:.0%})", Common::g_build_fullname, 186 fmt::format("yuzu {} | {}-{} | FPS: {:.0f} ({:.0f}%)", Common::g_build_fullname,
186 Common::g_scm_branch, Common::g_scm_desc, results.game_fps, results.emulation_speed); 187 Common::g_scm_branch, Common::g_scm_desc, results.game_fps,
188 results.emulation_speed * 100.0);
187 SDL_SetWindowTitle(render_window, title.c_str()); 189 SDL_SetWindowTitle(render_window, title.c_str());
188 last_time = current_time; 190 last_time = current_time;
189 } 191 }
diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2.h b/src/yuzu_cmd/emu_window/emu_window_sdl2.h
index fffac4252..53d756c3c 100644
--- a/src/yuzu_cmd/emu_window/emu_window_sdl2.h
+++ b/src/yuzu_cmd/emu_window/emu_window_sdl2.h
@@ -14,9 +14,13 @@ namespace Core {
14class System; 14class System;
15} 15}
16 16
17namespace InputCommon {
18class InputSubsystem;
19}
20
17class EmuWindow_SDL2 : public Core::Frontend::EmuWindow { 21class EmuWindow_SDL2 : public Core::Frontend::EmuWindow {
18public: 22public:
19 explicit EmuWindow_SDL2(Core::System& system, bool fullscreen); 23 explicit EmuWindow_SDL2(InputCommon::InputSubsystem* input_subsystem);
20 ~EmuWindow_SDL2(); 24 ~EmuWindow_SDL2();
21 25
22 /// Polls window events 26 /// Polls window events
@@ -28,9 +32,6 @@ public:
28 /// Returns if window is shown (not minimized) 32 /// Returns if window is shown (not minimized)
29 bool IsShown() const override; 33 bool IsShown() const override;
30 34
31 /// Presents the next frame
32 virtual void Present() = 0;
33
34protected: 35protected:
35 /// Called by PollEvents when a key is pressed or released. 36 /// Called by PollEvents when a key is pressed or released.
36 void OnKeyEvent(int key, u8 state); 37 void OnKeyEvent(int key, u8 state);
@@ -62,9 +63,6 @@ protected:
62 /// Called when a configuration change affects the minimal size of the window 63 /// Called when a configuration change affects the minimal size of the window
63 void OnMinimalClientAreaChangeRequest(std::pair<unsigned, unsigned> minimal_size) override; 64 void OnMinimalClientAreaChangeRequest(std::pair<unsigned, unsigned> minimal_size) override;
64 65
65 /// Instance of the system, used to access renderer for the presentation thread
66 Core::System& system;
67
68 /// Is the window still open? 66 /// Is the window still open?
69 bool is_open = true; 67 bool is_open = true;
70 68
@@ -76,4 +74,7 @@ protected:
76 74
77 /// Keeps track of how often to update the title bar during gameplay 75 /// Keeps track of how often to update the title bar during gameplay
78 u32 last_time = 0; 76 u32 last_time = 0;
77
78 /// Input subsystem to use with this window.
79 InputCommon::InputSubsystem* input_subsystem;
79}; 80};
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 411e7e647..5f35233b5 100644
--- a/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp
+++ b/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp
@@ -87,8 +87,8 @@ bool EmuWindow_SDL2_GL::SupportsRequiredGLExtensions() {
87 return unsupported_ext.empty(); 87 return unsupported_ext.empty();
88} 88}
89 89
90EmuWindow_SDL2_GL::EmuWindow_SDL2_GL(Core::System& system, bool fullscreen) 90EmuWindow_SDL2_GL::EmuWindow_SDL2_GL(InputCommon::InputSubsystem* input_subsystem, bool fullscreen)
91 : EmuWindow_SDL2{system, fullscreen} { 91 : EmuWindow_SDL2{input_subsystem} {
92 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4); 92 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4);
93 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3); 93 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
94 SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY); 94 SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY);
@@ -98,6 +98,9 @@ EmuWindow_SDL2_GL::EmuWindow_SDL2_GL(Core::System& system, bool fullscreen)
98 SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); 98 SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
99 SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 0); 99 SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 0);
100 SDL_GL_SetAttribute(SDL_GL_SHARE_WITH_CURRENT_CONTEXT, 1); 100 SDL_GL_SetAttribute(SDL_GL_SHARE_WITH_CURRENT_CONTEXT, 1);
101 if (Settings::values.renderer_debug) {
102 SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG);
103 }
101 SDL_GL_SetSwapInterval(0); 104 SDL_GL_SetSwapInterval(0);
102 105
103 std::string window_title = fmt::format("yuzu {} | {}-{}", Common::g_build_fullname, 106 std::string window_title = fmt::format("yuzu {} | {}-{}", Common::g_build_fullname,
@@ -159,13 +162,3 @@ EmuWindow_SDL2_GL::~EmuWindow_SDL2_GL() {
159std::unique_ptr<Core::Frontend::GraphicsContext> EmuWindow_SDL2_GL::CreateSharedContext() const { 162std::unique_ptr<Core::Frontend::GraphicsContext> EmuWindow_SDL2_GL::CreateSharedContext() const {
160 return std::make_unique<SDLGLContext>(); 163 return std::make_unique<SDLGLContext>();
161} 164}
162
163void EmuWindow_SDL2_GL::Present() {
164 SDL_GL_MakeCurrent(render_window, window_context);
165 SDL_GL_SetSwapInterval(Settings::values.use_vsync ? 1 : 0);
166 while (IsOpen()) {
167 system.Renderer().TryPresent(100);
168 SDL_GL_SwapWindow(render_window);
169 }
170 SDL_GL_MakeCurrent(render_window, nullptr);
171}
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 48bb41683..dba5c293c 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,15 @@
8#include "core/frontend/emu_window.h" 8#include "core/frontend/emu_window.h"
9#include "yuzu_cmd/emu_window/emu_window_sdl2.h" 9#include "yuzu_cmd/emu_window/emu_window_sdl2.h"
10 10
11namespace InputCommon {
12class InputSubsystem;
13}
14
11class EmuWindow_SDL2_GL final : public EmuWindow_SDL2 { 15class EmuWindow_SDL2_GL final : public EmuWindow_SDL2 {
12public: 16public:
13 explicit EmuWindow_SDL2_GL(Core::System& system, bool fullscreen); 17 explicit EmuWindow_SDL2_GL(InputCommon::InputSubsystem* input_subsystem, bool fullscreen);
14 ~EmuWindow_SDL2_GL(); 18 ~EmuWindow_SDL2_GL();
15 19
16 void Present() override;
17
18 std::unique_ptr<Core::Frontend::GraphicsContext> CreateSharedContext() const override; 20 std::unique_ptr<Core::Frontend::GraphicsContext> CreateSharedContext() const override;
19 21
20private: 22private:
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 f2990910e..3ba657c00 100644
--- a/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.cpp
+++ b/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.cpp
@@ -19,8 +19,8 @@
19#include <SDL.h> 19#include <SDL.h>
20#include <SDL_syswm.h> 20#include <SDL_syswm.h>
21 21
22EmuWindow_SDL2_VK::EmuWindow_SDL2_VK(Core::System& system, bool fullscreen) 22EmuWindow_SDL2_VK::EmuWindow_SDL2_VK(InputCommon::InputSubsystem* input_subsystem)
23 : EmuWindow_SDL2{system, fullscreen} { 23 : EmuWindow_SDL2{input_subsystem} {
24 const std::string window_title = fmt::format("yuzu {} | {}-{} (Vulkan)", Common::g_build_name, 24 const std::string window_title = fmt::format("yuzu {} | {}-{} (Vulkan)", Common::g_build_name,
25 Common::g_scm_branch, Common::g_scm_desc); 25 Common::g_scm_branch, Common::g_scm_desc);
26 render_window = 26 render_window =
@@ -29,6 +29,7 @@ EmuWindow_SDL2_VK::EmuWindow_SDL2_VK(Core::System& system, bool fullscreen)
29 SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI); 29 SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI);
30 30
31 SDL_SysWMinfo wm; 31 SDL_SysWMinfo wm;
32 SDL_VERSION(&wm.version);
32 if (SDL_GetWindowWMInfo(render_window, &wm) == SDL_FALSE) { 33 if (SDL_GetWindowWMInfo(render_window, &wm) == SDL_FALSE) {
33 LOG_CRITICAL(Frontend, "Failed to get information from the window manager"); 34 LOG_CRITICAL(Frontend, "Failed to get information from the window manager");
34 std::exit(EXIT_FAILURE); 35 std::exit(EXIT_FAILURE);
@@ -70,9 +71,5 @@ EmuWindow_SDL2_VK::EmuWindow_SDL2_VK(Core::System& system, bool fullscreen)
70EmuWindow_SDL2_VK::~EmuWindow_SDL2_VK() = default; 71EmuWindow_SDL2_VK::~EmuWindow_SDL2_VK() = default;
71 72
72std::unique_ptr<Core::Frontend::GraphicsContext> EmuWindow_SDL2_VK::CreateSharedContext() const { 73std::unique_ptr<Core::Frontend::GraphicsContext> EmuWindow_SDL2_VK::CreateSharedContext() const {
73 return nullptr; 74 return std::make_unique<DummyContext>();
74}
75
76void EmuWindow_SDL2_VK::Present() {
77 // TODO (bunnei): ImplementMe
78} 75}
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 b8021ebea..bdfdc3c6f 100644
--- a/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.h
+++ b/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.h
@@ -13,12 +13,16 @@ namespace Core {
13class System; 13class System;
14} 14}
15 15
16namespace InputCommon {
17class InputSubsystem;
18}
19
16class EmuWindow_SDL2_VK final : public EmuWindow_SDL2 { 20class EmuWindow_SDL2_VK final : public EmuWindow_SDL2 {
17public: 21public:
18 explicit EmuWindow_SDL2_VK(Core::System& system, bool fullscreen); 22 explicit EmuWindow_SDL2_VK(InputCommon::InputSubsystem* input_subsystem);
19 ~EmuWindow_SDL2_VK(); 23 ~EmuWindow_SDL2_VK() override;
20
21 void Present() override;
22 24
23 std::unique_ptr<Core::Frontend::GraphicsContext> CreateSharedContext() const override; 25 std::unique_ptr<Core::Frontend::GraphicsContext> CreateSharedContext() const override;
24}; 26};
27
28class DummyContext : public Core::Frontend::GraphicsContext {};
diff --git a/src/yuzu_cmd/yuzu.cpp b/src/yuzu_cmd/yuzu.cpp
index 4d2ea7e9e..14a23c71b 100644
--- a/src/yuzu_cmd/yuzu.cpp
+++ b/src/yuzu_cmd/yuzu.cpp
@@ -2,6 +2,7 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <chrono>
5#include <iostream> 6#include <iostream>
6#include <memory> 7#include <memory>
7#include <string> 8#include <string>
@@ -22,12 +23,15 @@
22#include "common/telemetry.h" 23#include "common/telemetry.h"
23#include "core/core.h" 24#include "core/core.h"
24#include "core/crypto/key_manager.h" 25#include "core/crypto/key_manager.h"
26#include "core/file_sys/registered_cache.h"
25#include "core/file_sys/vfs_real.h" 27#include "core/file_sys/vfs_real.h"
26#include "core/gdbstub/gdbstub.h" 28#include "core/gdbstub/gdbstub.h"
29#include "core/hle/kernel/process.h"
27#include "core/hle/service/filesystem/filesystem.h" 30#include "core/hle/service/filesystem/filesystem.h"
28#include "core/loader/loader.h" 31#include "core/loader/loader.h"
29#include "core/settings.h" 32#include "core/settings.h"
30#include "core/telemetry_session.h" 33#include "core/telemetry_session.h"
34#include "input_common/main.h"
31#include "video_core/renderer_base.h" 35#include "video_core/renderer_base.h"
32#include "yuzu_cmd/config.h" 36#include "yuzu_cmd/config.h"
33#include "yuzu_cmd/emu_window/emu_window_sdl2.h" 37#include "yuzu_cmd/emu_window/emu_window_sdl2.h"
@@ -36,8 +40,6 @@
36#include "yuzu_cmd/emu_window/emu_window_sdl2_vk.h" 40#include "yuzu_cmd/emu_window/emu_window_sdl2_vk.h"
37#endif 41#endif
38 42
39#include "core/file_sys/registered_cache.h"
40
41#ifdef _WIN32 43#ifdef _WIN32
42// windows.h needs to be included before shellapi.h 44// windows.h needs to be included before shellapi.h
43#include <windows.h> 45#include <windows.h>
@@ -81,8 +83,8 @@ static void InitializeLogging() {
81 83
82 Log::AddBackend(std::make_unique<Log::ColorConsoleBackend>()); 84 Log::AddBackend(std::make_unique<Log::ColorConsoleBackend>());
83 85
84 const std::string& log_dir = FileUtil::GetUserPath(FileUtil::UserPath::LogDir); 86 const std::string& log_dir = Common::FS::GetUserPath(Common::FS::UserPath::LogDir);
85 FileUtil::CreateFullPath(log_dir); 87 Common::FS::CreateFullPath(log_dir);
86 Log::AddBackend(std::make_unique<Log::FileBackend>(log_dir + LOG_FILE)); 88 Log::AddBackend(std::make_unique<Log::FileBackend>(log_dir + LOG_FILE));
87#ifdef _WIN32 89#ifdef _WIN32
88 Log::AddBackend(std::make_unique<Log::DebuggerBackend>()); 90 Log::AddBackend(std::make_unique<Log::DebuggerBackend>());
@@ -178,15 +180,16 @@ int main(int argc, char** argv) {
178 Settings::Apply(); 180 Settings::Apply();
179 181
180 Core::System& system{Core::System::GetInstance()}; 182 Core::System& system{Core::System::GetInstance()};
183 InputCommon::InputSubsystem input_subsystem;
181 184
182 std::unique_ptr<EmuWindow_SDL2> emu_window; 185 std::unique_ptr<EmuWindow_SDL2> emu_window;
183 switch (Settings::values.renderer_backend) { 186 switch (Settings::values.renderer_backend.GetValue()) {
184 case Settings::RendererBackend::OpenGL: 187 case Settings::RendererBackend::OpenGL:
185 emu_window = std::make_unique<EmuWindow_SDL2_GL>(system, fullscreen); 188 emu_window = std::make_unique<EmuWindow_SDL2_GL>(&input_subsystem, fullscreen);
186 break; 189 break;
187 case Settings::RendererBackend::Vulkan: 190 case Settings::RendererBackend::Vulkan:
188#ifdef HAS_VULKAN 191#ifdef HAS_VULKAN
189 emu_window = std::make_unique<EmuWindow_SDL2_VK>(system, fullscreen); 192 emu_window = std::make_unique<EmuWindow_SDL2_VK>(&input_subsystem);
190 break; 193 break;
191#else 194#else
192 LOG_CRITICAL(Frontend, "Vulkan backend has not been compiled!"); 195 LOG_CRITICAL(Frontend, "Vulkan backend has not been compiled!");
@@ -228,19 +231,20 @@ int main(int argc, char** argv) {
228 } 231 }
229 } 232 }
230 233
231 system.TelemetrySession().AddField(Telemetry::FieldType::App, "Frontend", "SDL"); 234 system.TelemetrySession().AddField(Common::Telemetry::FieldType::App, "Frontend", "SDL");
232 235
233 // Core is loaded, start the GPU (makes the GPU contexts current to this thread) 236 // Core is loaded, start the GPU (makes the GPU contexts current to this thread)
234 system.GPU().Start(); 237 system.GPU().Start();
235 238
236 system.Renderer().Rasterizer().LoadDiskResources(); 239 system.Renderer().Rasterizer().LoadDiskResources(
240 system.CurrentProcess()->GetTitleID(), false,
241 [](VideoCore::LoadCallbackStage, size_t value, size_t total) {});
237 242
238 std::thread render_thread([&emu_window] { emu_window->Present(); }); 243 void(system.Run());
239 while (emu_window->IsOpen()) { 244 while (emu_window->IsOpen()) {
240 system.RunLoop(); 245 std::this_thread::sleep_for(std::chrono::milliseconds(1));
241 } 246 }
242 render_thread.join(); 247 void(system.Pause());
243
244 system.Shutdown(); 248 system.Shutdown();
245 249
246 detached_tasks.WaitForAllTasks(); 250 detached_tasks.WaitForAllTasks();
diff --git a/src/yuzu_cmd/yuzu.rc b/src/yuzu_cmd/yuzu.rc
index 7de8ef3d9..0cde75e2f 100644
--- a/src/yuzu_cmd/yuzu.rc
+++ b/src/yuzu_cmd/yuzu.rc
@@ -14,4 +14,4 @@ YUZU_ICON ICON "../../dist/yuzu.ico"
14// RT_MANIFEST 14// RT_MANIFEST
15// 15//
16 16
171 RT_MANIFEST "../../dist/yuzu.manifest" 170 RT_MANIFEST "../../dist/yuzu.manifest"