diff options
Diffstat (limited to 'src/yuzu_cmd')
| -rw-r--r-- | src/yuzu_cmd/CMakeLists.txt | 30 | ||||
| -rw-r--r-- | src/yuzu_cmd/config.cpp | 47 | ||||
| -rw-r--r-- | src/yuzu_cmd/default_ini.h | 17 | ||||
| -rw-r--r-- | src/yuzu_cmd/emu_window/emu_window_sdl2.cpp | 143 | ||||
| -rw-r--r-- | src/yuzu_cmd/emu_window/emu_window_sdl2.h | 30 | ||||
| -rw-r--r-- | src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp | 44 | ||||
| -rw-r--r-- | src/yuzu_cmd/emu_window/emu_window_sdl2_gl.h | 5 | ||||
| -rw-r--r-- | src/yuzu_cmd/emu_window/emu_window_sdl2_vk.cpp | 11 | ||||
| -rw-r--r-- | src/yuzu_cmd/emu_window/emu_window_sdl2_vk.h | 7 | ||||
| -rw-r--r-- | src/yuzu_cmd/yuzu.cpp | 65 |
10 files changed, 183 insertions, 216 deletions
diff --git a/src/yuzu_cmd/CMakeLists.txt b/src/yuzu_cmd/CMakeLists.txt index a15719a0f..8461f8896 100644 --- a/src/yuzu_cmd/CMakeLists.txt +++ b/src/yuzu_cmd/CMakeLists.txt @@ -1,29 +1,30 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/CMakeModules) +function(create_resource file output filename) + # Read hex data from file + file(READ ${file} filedata HEX) + # Convert hex data for C compatibility + string(REGEX REPLACE "([0-9a-f][0-9a-f])" "0x\\1," filedata ${filedata}) + # Write data to output file + set(RESOURCES_DIR "${PROJECT_BINARY_DIR}/dist" PARENT_SCOPE) + file(WRITE "${PROJECT_BINARY_DIR}/dist/${output}" "const unsigned char ${filename}[] = {${filedata}};\nconst unsigned ${filename}_size = sizeof(${filename});\n") +endfunction() + add_executable(yuzu-cmd config.cpp config.h default_ini.h - emu_window/emu_window_sdl2_gl.cpp - emu_window/emu_window_sdl2_gl.h emu_window/emu_window_sdl2.cpp emu_window/emu_window_sdl2.h emu_window/emu_window_sdl2_gl.cpp emu_window/emu_window_sdl2_gl.h + emu_window/emu_window_sdl2_vk.cpp + emu_window/emu_window_sdl2_vk.h resource.h yuzu.cpp yuzu.rc ) -if (ENABLE_VULKAN) - target_sources(yuzu-cmd PRIVATE - emu_window/emu_window_sdl2_vk.cpp - emu_window/emu_window_sdl2_vk.h) - - target_include_directories(yuzu-cmd PRIVATE ../../externals/Vulkan-Headers/include) - target_compile_definitions(yuzu-cmd PRIVATE HAS_VULKAN) -endif() - create_target_directory_groups(yuzu-cmd) target_link_libraries(yuzu-cmd PRIVATE common core input_common) @@ -33,13 +34,16 @@ if (MSVC) endif() target_link_libraries(yuzu-cmd PRIVATE ${PLATFORM_LIBRARIES} SDL2 Threads::Threads) +create_resource("../../dist/yuzu.bmp" "yuzu_cmd/yuzu_icon.h" "yuzu_icon") +target_include_directories(yuzu-cmd PRIVATE ${RESOURCES_DIR}) + +target_include_directories(yuzu-cmd PRIVATE ../../externals/Vulkan-Headers/include) + if(UNIX AND NOT APPLE) install(TARGETS yuzu-cmd RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}/bin") endif() if (MSVC) include(CopyYuzuSDLDeps) - include(CopyYuzuUnicornDeps) copy_yuzu_SDL_deps(yuzu-cmd) - copy_yuzu_unicorn_deps(yuzu-cmd) endif() diff --git a/src/yuzu_cmd/config.cpp b/src/yuzu_cmd/config.cpp index e9f1c6500..aa0a9f288 100644 --- a/src/yuzu_cmd/config.cpp +++ b/src/yuzu_cmd/config.cpp @@ -228,24 +228,24 @@ static const std::array<int, 8> keyboard_mods{ void Config::ReadValues() { // Controls - for (std::size_t p = 0; p < Settings::values.players.size(); ++p) { + for (std::size_t p = 0; p < Settings::values.players.GetValue().size(); ++p) { const auto group = fmt::format("ControlsP{}", p); for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) { std::string default_param = InputCommon::GenerateKeyboardParam(default_buttons[i]); - Settings::values.players[p].buttons[i] = + Settings::values.players.GetValue()[p].buttons[i] = sdl2_config->Get(group, Settings::NativeButton::mapping[i], default_param); - if (Settings::values.players[p].buttons[i].empty()) - Settings::values.players[p].buttons[i] = default_param; + if (Settings::values.players.GetValue()[p].buttons[i].empty()) + Settings::values.players.GetValue()[p].buttons[i] = default_param; } for (int i = 0; i < Settings::NativeAnalog::NumAnalogs; ++i) { std::string default_param = InputCommon::GenerateAnalogParamFromKeys( default_analogs[i][0], default_analogs[i][1], default_analogs[i][2], default_analogs[i][3], default_analogs[i][4], 0.5f); - Settings::values.players[p].analogs[i] = + Settings::values.players.GetValue()[p].analogs[i] = sdl2_config->Get(group, Settings::NativeAnalog::mapping[i], default_param); - if (Settings::values.players[p].analogs[i].empty()) - Settings::values.players[p].analogs[i] = default_param; + if (Settings::values.players.GetValue()[p].analogs[i].empty()) + Settings::values.players.GetValue()[p].analogs[i] = default_param; } } @@ -288,24 +288,22 @@ void Config::ReadValues() { Settings::values.debug_pad_analogs[i] = default_param; } - Settings::values.vibration_enabled = - sdl2_config->GetBoolean("ControlsGeneral", "vibration_enabled", true); + 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)); Settings::values.touchscreen.enabled = sdl2_config->GetBoolean("ControlsGeneral", "touch_enabled", true); - Settings::values.touchscreen.device = - sdl2_config->Get("ControlsGeneral", "touch_device", "engine:emu_window"); - Settings::values.touchscreen.finger = - sdl2_config->GetInteger("ControlsGeneral", "touch_finger", 0); Settings::values.touchscreen.rotation_angle = sdl2_config->GetInteger("ControlsGeneral", "touch_angle", 0); Settings::values.touchscreen.diameter_x = sdl2_config->GetInteger("ControlsGeneral", "touch_diameter_x", 15); Settings::values.touchscreen.diameter_y = sdl2_config->GetInteger("ControlsGeneral", "touch_diameter_y", 15); - Settings::values.udp_input_address = - sdl2_config->Get("Controls", "udp_input_address", InputCommon::CemuhookUDP::DEFAULT_ADDR); - Settings::values.udp_input_port = static_cast<u16>(sdl2_config->GetInteger( - "Controls", "udp_input_port", InputCommon::CemuhookUDP::DEFAULT_PORT)); + Settings::values.udp_input_servers = + sdl2_config->Get("Controls", "udp_input_address", InputCommon::CemuhookUDP::DEFAULT_SRV); std::transform(keyboard_keys.begin(), keyboard_keys.end(), Settings::values.keyboard_keys.begin(), InputCommon::GenerateKeyboardParam); @@ -341,8 +339,8 @@ void Config::ReadValues() { Settings::values.gamecard_path = sdl2_config->Get("Data Storage", "gamecard_path", ""); // System - Settings::values.use_docked_mode = sdl2_config->GetBoolean("System", "use_docked_mode", false); - const auto size = sdl2_config->GetInteger("System", "users_size", 0); + Settings::values.use_docked_mode.SetValue( + sdl2_config->GetBoolean("System", "use_docked_mode", true)); Settings::values.current_user = std::clamp<int>( sdl2_config->GetInteger("System", "current_user", 0), 0, Service::Account::MAX_USERS - 1); @@ -369,7 +367,7 @@ void Config::ReadValues() { // Core Settings::values.use_multi_core.SetValue( - sdl2_config->GetBoolean("Core", "use_multi_core", false)); + sdl2_config->GetBoolean("Core", "use_multi_core", true)); // Renderer const int renderer_backend = sdl2_config->GetInteger( @@ -390,14 +388,14 @@ void Config::ReadValues() { static_cast<u16>(sdl2_config->GetInteger("Renderer", "frame_limit", 100))); Settings::values.use_disk_shader_cache.SetValue( sdl2_config->GetBoolean("Renderer", "use_disk_shader_cache", false)); - const int gpu_accuracy_level = sdl2_config->GetInteger("Renderer", "gpu_accuracy", 0); + 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", false)); + 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.use_assembly_shaders.SetValue( - sdl2_config->GetBoolean("Renderer", "use_assembly_shaders", false)); + 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_asynchronous_shaders.SetValue( @@ -427,9 +425,6 @@ void Config::ReadValues() { // Debugging Settings::values.record_frame_times = sdl2_config->GetBoolean("Debugging", "record_frame_times", false); - Settings::values.use_gdbstub = sdl2_config->GetBoolean("Debugging", "use_gdbstub", false); - Settings::values.gdbstub_port = - static_cast<u16>(sdl2_config->GetInteger("Debugging", "gdbstub_port", 24689)); 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); diff --git a/src/yuzu_cmd/default_ini.h b/src/yuzu_cmd/default_ini.h index aa9e40380..3ee0e037d 100644 --- a/src/yuzu_cmd/default_ini.h +++ b/src/yuzu_cmd/default_ini.h @@ -65,6 +65,14 @@ button_screenshot= lstick= rstick= +# Whether to enable or disable vibration +# 0: Disabled, 1 (default): Enabled +vibration_enabled= + +# Whether to enable or disable accurate vibrations +# 0 (default): Disabled, 1: Enabled +enable_accurate_vibrations= + # 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) @@ -94,7 +102,7 @@ udp_pad_index= [Core] # Whether to use multi-core for CPU emulation -# 0 (default): Disabled, 1: Enabled +# 0: Disabled, 1 (default): Enabled use_multi_core= [Cpu] @@ -163,7 +171,7 @@ max_anisotropy = use_vsync = # Whether to use OpenGL assembly shaders or not. NV_gpu_program5 is required. -# 0 (default): Off, 1: On +# 0: Off, 1 (default): On use_assembly_shaders = # Whether to allow asynchronous shader building. @@ -266,7 +274,7 @@ gamecard_path = [System] # Whether the system is docked -# 1: Yes, 0 (default): No +# 1 (default): Yes, 0: No use_docked_mode = # Allow the use of NFC in games @@ -310,9 +318,6 @@ log_filter = *:Trace [Debugging] # Record frame time data, can be found in the log directory. Boolean value record_frame_times = -# Port for listening to GDB connections. -use_gdbstub=false -gdbstub_port=24689 # Determines whether or not yuzu will dump the ExeFS of all games it attempts to load while loading them dump_exefs=false # Determines whether or not yuzu will dump all NSOs it attempts to load while loading them diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp index a804d5185..7e391ab89 100644 --- a/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp +++ b/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp @@ -9,13 +9,13 @@ #include "core/perf_stats.h" #include "input_common/keyboard.h" #include "input_common/main.h" -#include "input_common/motion_emu.h" +#include "input_common/mouse/mouse_input.h" #include "input_common/sdl/sdl.h" #include "yuzu_cmd/emu_window/emu_window_sdl2.h" +#include "yuzu_cmd/yuzu_icon.h" -EmuWindow_SDL2::EmuWindow_SDL2(Core::System& system, bool fullscreen, - InputCommon::InputSubsystem* input_subsystem_) - : system{system}, input_subsystem{input_subsystem_} { +EmuWindow_SDL2::EmuWindow_SDL2(InputCommon::InputSubsystem* input_subsystem_) + : input_subsystem{input_subsystem_} { if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK) < 0) { LOG_CRITICAL(Frontend, "Failed to initialize SDL2! Exiting..."); exit(1); @@ -30,22 +30,23 @@ EmuWindow_SDL2::~EmuWindow_SDL2() { } void EmuWindow_SDL2::OnMouseMotion(s32 x, s32 y) { - TouchMoved((unsigned)std::max(x, 0), (unsigned)std::max(y, 0)); - input_subsystem->GetMotionEmu()->Tilt(x, y); + TouchMoved((unsigned)std::max(x, 0), (unsigned)std::max(y, 0), 0); + + input_subsystem->GetMouse()->MouseMove(x, y, 0, 0); } void EmuWindow_SDL2::OnMouseButton(u32 button, u8 state, s32 x, s32 y) { if (button == SDL_BUTTON_LEFT) { if (state == SDL_PRESSED) { - TouchPressed((unsigned)std::max(x, 0), (unsigned)std::max(y, 0)); + TouchPressed((unsigned)std::max(x, 0), (unsigned)std::max(y, 0), 0); } else { - TouchReleased(); + TouchReleased(0); } } else if (button == SDL_BUTTON_RIGHT) { if (state == SDL_PRESSED) { - input_subsystem->GetMotionEmu()->BeginTilt(x, y); + input_subsystem->GetMouse()->PressButton(x, y, button); } else { - input_subsystem->GetMotionEmu()->EndTilt(); + input_subsystem->GetMouse()->ReleaseButton(button); } } } @@ -67,16 +68,16 @@ void EmuWindow_SDL2::OnFingerDown(float x, float y) { // 3DS does const auto [px, py] = TouchToPixelPos(x, y); - TouchPressed(px, py); + TouchPressed(px, py, 0); } void EmuWindow_SDL2::OnFingerMotion(float x, float y) { const auto [px, py] = TouchToPixelPos(x, y); - TouchMoved(px, py); + TouchMoved(px, py, 0); } void EmuWindow_SDL2::OnFingerUp() { - TouchReleased(); + TouchReleased(0); } void EmuWindow_SDL2::OnKeyEvent(int key, u8 state) { @@ -122,62 +123,64 @@ void EmuWindow_SDL2::Fullscreen() { SDL_MaximizeWindow(render_window); } -void EmuWindow_SDL2::PollEvents() { +void EmuWindow_SDL2::WaitEvent() { + // Called on main thread SDL_Event event; - // SDL_PollEvent returns 0 when there are no more events in the event queue - while (SDL_PollEvent(&event)) { - switch (event.type) { - case SDL_WINDOWEVENT: - switch (event.window.event) { - case SDL_WINDOWEVENT_SIZE_CHANGED: - case SDL_WINDOWEVENT_RESIZED: - case SDL_WINDOWEVENT_MAXIMIZED: - case SDL_WINDOWEVENT_RESTORED: - OnResize(); - break; - case SDL_WINDOWEVENT_MINIMIZED: - case SDL_WINDOWEVENT_EXPOSED: - is_shown = event.window.event == SDL_WINDOWEVENT_EXPOSED; - OnResize(); - break; - case SDL_WINDOWEVENT_CLOSE: - is_open = false; - break; - } - break; - case SDL_KEYDOWN: - case SDL_KEYUP: - OnKeyEvent(static_cast<int>(event.key.keysym.scancode), event.key.state); - break; - case SDL_MOUSEMOTION: - // ignore if it came from touch - if (event.button.which != SDL_TOUCH_MOUSEID) - OnMouseMotion(event.motion.x, event.motion.y); - break; - case SDL_MOUSEBUTTONDOWN: - case SDL_MOUSEBUTTONUP: - // ignore if it came from touch - if (event.button.which != SDL_TOUCH_MOUSEID) { - OnMouseButton(event.button.button, event.button.state, event.button.x, - event.button.y); - } - break; - case SDL_FINGERDOWN: - OnFingerDown(event.tfinger.x, event.tfinger.y); - break; - case SDL_FINGERMOTION: - OnFingerMotion(event.tfinger.x, event.tfinger.y); + if (!SDL_WaitEvent(&event)) { + LOG_CRITICAL(Frontend, "SDL_WaitEvent failed: {}", SDL_GetError()); + exit(1); + } + + switch (event.type) { + case SDL_WINDOWEVENT: + switch (event.window.event) { + case SDL_WINDOWEVENT_SIZE_CHANGED: + case SDL_WINDOWEVENT_RESIZED: + case SDL_WINDOWEVENT_MAXIMIZED: + case SDL_WINDOWEVENT_RESTORED: + OnResize(); break; - case SDL_FINGERUP: - OnFingerUp(); + case SDL_WINDOWEVENT_MINIMIZED: + case SDL_WINDOWEVENT_EXPOSED: + is_shown = event.window.event == SDL_WINDOWEVENT_EXPOSED; + OnResize(); break; - case SDL_QUIT: + case SDL_WINDOWEVENT_CLOSE: is_open = false; break; - default: - break; } + break; + case SDL_KEYDOWN: + case SDL_KEYUP: + OnKeyEvent(static_cast<int>(event.key.keysym.scancode), event.key.state); + break; + case SDL_MOUSEMOTION: + // ignore if it came from touch + if (event.button.which != SDL_TOUCH_MOUSEID) + OnMouseMotion(event.motion.x, event.motion.y); + break; + case SDL_MOUSEBUTTONDOWN: + case SDL_MOUSEBUTTONUP: + // ignore if it came from touch + if (event.button.which != SDL_TOUCH_MOUSEID) { + OnMouseButton(event.button.button, event.button.state, event.button.x, event.button.y); + } + break; + case SDL_FINGERDOWN: + OnFingerDown(event.tfinger.x, event.tfinger.y); + break; + case SDL_FINGERMOTION: + OnFingerMotion(event.tfinger.x, event.tfinger.y); + break; + case SDL_FINGERUP: + OnFingerUp(); + break; + case SDL_QUIT: + is_open = false; + break; + default: + break; } const u32 current_time = SDL_GetTicks(); @@ -192,6 +195,22 @@ void EmuWindow_SDL2::PollEvents() { } } +void EmuWindow_SDL2::SetWindowIcon() { + SDL_RWops* const yuzu_icon_stream = SDL_RWFromConstMem((void*)yuzu_icon, yuzu_icon_size); + if (yuzu_icon_stream == nullptr) { + LOG_WARNING(Frontend, "Failed to create yuzu icon stream."); + return; + } + SDL_Surface* const window_icon = SDL_LoadBMP_RW(yuzu_icon_stream, 1); + if (window_icon == nullptr) { + LOG_WARNING(Frontend, "Failed to read BMP from stream."); + return; + } + // The icon is attached to the window pointer + SDL_SetWindowIcon(render_window, window_icon); + SDL_FreeSurface(window_icon); +} + void EmuWindow_SDL2::OnMinimalClientAreaChangeRequest(std::pair<unsigned, unsigned> minimal_size) { SDL_SetWindowMinimumSize(render_window, minimal_size.first, minimal_size.second); } diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2.h b/src/yuzu_cmd/emu_window/emu_window_sdl2.h index 82750ffec..51a12a6a9 100644 --- a/src/yuzu_cmd/emu_window/emu_window_sdl2.h +++ b/src/yuzu_cmd/emu_window/emu_window_sdl2.h @@ -20,45 +20,44 @@ class InputSubsystem; class EmuWindow_SDL2 : public Core::Frontend::EmuWindow { public: - explicit EmuWindow_SDL2(Core::System& system, bool fullscreen, - InputCommon::InputSubsystem* input_subsystem); + explicit EmuWindow_SDL2(InputCommon::InputSubsystem* input_subsystem); ~EmuWindow_SDL2(); - /// Polls window events - void PollEvents() override; - /// Whether the window is still open, and a close request hasn't yet been sent bool IsOpen() const; /// Returns if window is shown (not minimized) bool IsShown() const override; - /// Presents the next frame - virtual void Present() = 0; + /// Wait for the next event on the main thread. + void WaitEvent(); + + // Sets the window icon from yuzu.bmp + void SetWindowIcon(); protected: - /// Called by PollEvents when a key is pressed or released. + /// Called by WaitEvent when a key is pressed or released. void OnKeyEvent(int key, u8 state); - /// Called by PollEvents when the mouse moves. + /// Called by WaitEvent when the mouse moves. void OnMouseMotion(s32 x, s32 y); - /// Called by PollEvents when a mouse button is pressed or released + /// 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 PollEvents when a finger starts touching the touchscreen + /// Called by WaitEvent when a finger starts touching the touchscreen void OnFingerDown(float x, float y); - /// Called by PollEvents when a finger moves while touching the touchscreen + /// Called by WaitEvent when a finger moves while touching the touchscreen void OnFingerMotion(float x, float y); - /// Called by PollEvents when a finger stops touching the touchscreen + /// Called by WaitEvent when a finger stops touching the touchscreen void OnFingerUp(); - /// Called by PollEvents when any event that may cause the window to be resized occurs + /// Called by WaitEvent when any event that may cause the window to be resized occurs void OnResize(); /// Called when user passes the fullscreen parameter flag @@ -67,9 +66,6 @@ protected: /// Called when a configuration change affects the minimal size of the window void OnMinimalClientAreaChangeRequest(std::pair<unsigned, unsigned> minimal_size) override; - /// Instance of the system, used to access renderer for the presentation thread - Core::System& system; - /// Is the window still open? bool is_open = true; 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 881b67a76..a02485c14 100644 --- a/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp +++ b/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp @@ -17,7 +17,6 @@ #include "core/settings.h" #include "input_common/keyboard.h" #include "input_common/main.h" -#include "input_common/motion_emu.h" #include "video_core/renderer_base.h" #include "yuzu_cmd/emu_window/emu_window_sdl2_gl.h" @@ -60,38 +59,25 @@ private: bool EmuWindow_SDL2_GL::SupportsRequiredGLExtensions() { std::vector<std::string_view> unsupported_ext; - if (!GLAD_GL_ARB_buffer_storage) - unsupported_ext.push_back("ARB_buffer_storage"); - if (!GLAD_GL_ARB_direct_state_access) - unsupported_ext.push_back("ARB_direct_state_access"); - if (!GLAD_GL_ARB_vertex_type_10f_11f_11f_rev) - unsupported_ext.push_back("ARB_vertex_type_10f_11f_11f_rev"); - if (!GLAD_GL_ARB_texture_mirror_clamp_to_edge) - unsupported_ext.push_back("ARB_texture_mirror_clamp_to_edge"); - if (!GLAD_GL_ARB_multi_bind) - unsupported_ext.push_back("ARB_multi_bind"); - if (!GLAD_GL_ARB_clip_control) - unsupported_ext.push_back("ARB_clip_control"); - // Extensions required to support some texture formats. - if (!GLAD_GL_EXT_texture_compression_s3tc) + if (!GLAD_GL_EXT_texture_compression_s3tc) { unsupported_ext.push_back("EXT_texture_compression_s3tc"); - if (!GLAD_GL_ARB_texture_compression_rgtc) + } + if (!GLAD_GL_ARB_texture_compression_rgtc) { unsupported_ext.push_back("ARB_texture_compression_rgtc"); - if (!GLAD_GL_ARB_depth_buffer_float) - unsupported_ext.push_back("ARB_depth_buffer_float"); + } - for (const auto& extension : unsupported_ext) + for (const auto& extension : unsupported_ext) { LOG_CRITICAL(Frontend, "Unsupported GL extension: {}", extension); + } return unsupported_ext.empty(); } -EmuWindow_SDL2_GL::EmuWindow_SDL2_GL(Core::System& system, bool fullscreen, - InputCommon::InputSubsystem* input_subsystem) - : EmuWindow_SDL2{system, fullscreen, input_subsystem} { +EmuWindow_SDL2_GL::EmuWindow_SDL2_GL(InputCommon::InputSubsystem* input_subsystem, bool fullscreen) + : EmuWindow_SDL2{input_subsystem} { SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 6); SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); @@ -121,6 +107,8 @@ EmuWindow_SDL2_GL::EmuWindow_SDL2_GL(Core::System& system, bool fullscreen, dummy_window = SDL_CreateWindow(NULL, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 0, 0, SDL_WINDOW_HIDDEN | SDL_WINDOW_OPENGL); + SetWindowIcon(); + if (fullscreen) { Fullscreen(); } @@ -163,13 +151,3 @@ EmuWindow_SDL2_GL::~EmuWindow_SDL2_GL() { std::unique_ptr<Core::Frontend::GraphicsContext> EmuWindow_SDL2_GL::CreateSharedContext() const { return std::make_unique<SDLGLContext>(); } - -void EmuWindow_SDL2_GL::Present() { - SDL_GL_MakeCurrent(render_window, window_context); - SDL_GL_SetSwapInterval(Settings::values.use_vsync.GetValue() ? 1 : 0); - while (IsOpen()) { - system.Renderer().TryPresent(100); - SDL_GL_SwapWindow(render_window); - } - SDL_GL_MakeCurrent(render_window, nullptr); -} 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 732a64edd..dba5c293c 100644 --- a/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.h +++ b/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.h @@ -14,12 +14,9 @@ class InputSubsystem; class EmuWindow_SDL2_GL final : public EmuWindow_SDL2 { public: - explicit EmuWindow_SDL2_GL(Core::System& system, bool fullscreen, - InputCommon::InputSubsystem* input_subsystem); + explicit EmuWindow_SDL2_GL(InputCommon::InputSubsystem* input_subsystem, bool fullscreen); ~EmuWindow_SDL2_GL(); - void Present() override; - std::unique_ptr<Core::Frontend::GraphicsContext> CreateSharedContext() const override; private: 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 53491f86e..6f9b00461 100644 --- a/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.cpp +++ b/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.cpp @@ -19,9 +19,8 @@ #include <SDL.h> #include <SDL_syswm.h> -EmuWindow_SDL2_VK::EmuWindow_SDL2_VK(Core::System& system, bool fullscreen, - InputCommon::InputSubsystem* input_subsystem) - : EmuWindow_SDL2{system, fullscreen, input_subsystem} { +EmuWindow_SDL2_VK::EmuWindow_SDL2_VK(InputCommon::InputSubsystem* input_subsystem) + : EmuWindow_SDL2{input_subsystem} { const std::string window_title = fmt::format("yuzu {} | {}-{} (Vulkan)", Common::g_build_name, Common::g_scm_branch, Common::g_scm_desc); render_window = @@ -36,6 +35,8 @@ EmuWindow_SDL2_VK::EmuWindow_SDL2_VK(Core::System& system, bool fullscreen, std::exit(EXIT_FAILURE); } + SetWindowIcon(); + switch (wm.subsystem) { #ifdef SDL_VIDEO_DRIVER_WINDOWS case SDL_SYSWM_TYPE::SDL_SYSWM_WINDOWS: @@ -74,7 +75,3 @@ EmuWindow_SDL2_VK::~EmuWindow_SDL2_VK() = default; std::unique_ptr<Core::Frontend::GraphicsContext> EmuWindow_SDL2_VK::CreateSharedContext() const { return std::make_unique<DummyContext>(); } - -void EmuWindow_SDL2_VK::Present() { - // TODO (bunnei): ImplementMe -} 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 f99704d4c..bdfdc3c6f 100644 --- a/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.h +++ b/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.h @@ -19,11 +19,8 @@ class InputSubsystem; class EmuWindow_SDL2_VK final : public EmuWindow_SDL2 { public: - explicit EmuWindow_SDL2_VK(Core::System& system, bool fullscreen, - InputCommon::InputSubsystem* input_subsystem); - ~EmuWindow_SDL2_VK(); - - void Present() override; + explicit EmuWindow_SDL2_VK(InputCommon::InputSubsystem* input_subsystem); + ~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 4f00c804d..982c41785 100644 --- a/src/yuzu_cmd/yuzu.cpp +++ b/src/yuzu_cmd/yuzu.cpp @@ -17,6 +17,7 @@ #include "common/logging/filter.h" #include "common/logging/log.h" #include "common/microprofile.h" +#include "common/nvidia_flags.h" #include "common/scm_rev.h" #include "common/scope_exit.h" #include "common/string_util.h" @@ -25,7 +26,7 @@ #include "core/crypto/key_manager.h" #include "core/file_sys/registered_cache.h" #include "core/file_sys/vfs_real.h" -#include "core/gdbstub/gdbstub.h" +#include "core/hle/kernel/process.h" #include "core/hle/service/filesystem/filesystem.h" #include "core/loader/loader.h" #include "core/settings.h" @@ -35,9 +36,7 @@ #include "yuzu_cmd/config.h" #include "yuzu_cmd/emu_window/emu_window_sdl2.h" #include "yuzu_cmd/emu_window/emu_window_sdl2_gl.h" -#ifdef HAS_VULKAN #include "yuzu_cmd/emu_window/emu_window_sdl2_vk.h" -#endif #ifdef _WIN32 // windows.h needs to be included before shellapi.h @@ -64,7 +63,6 @@ __declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1; static void PrintHelp(const char* argv0) { std::cout << "Usage: " << argv0 << " [options] <filename>\n" - "-g, --gdbport=NUMBER Enable gdb stub on port NUMBER\n" "-f, --fullscreen Start in fullscreen mode\n" "-h, --help Display this help and exit\n" "-v, --version Output version information and exit\n" @@ -96,12 +94,8 @@ int main(int argc, char** argv) { Config config; int option_index = 0; - bool use_gdbstub = Settings::values.use_gdbstub; - u32 gdb_port = static_cast<u32>(Settings::values.gdbstub_port); InitializeLogging(); - - char* endarg; #ifdef _WIN32 int argc_w; auto argv_w = CommandLineToArgvW(GetCommandLineW(), &argc_w); @@ -116,26 +110,17 @@ int main(int argc, char** argv) { bool fullscreen = false; static struct option long_options[] = { - {"gdbport", required_argument, 0, 'g'}, {"fullscreen", no_argument, 0, 'f'}, - {"help", no_argument, 0, 'h'}, {"version", no_argument, 0, 'v'}, - {"program", optional_argument, 0, 'p'}, {0, 0, 0, 0}, + {"fullscreen", no_argument, 0, 'f'}, + {"help", no_argument, 0, 'h'}, + {"version", no_argument, 0, 'v'}, + {"program", optional_argument, 0, 'p'}, + {0, 0, 0, 0}, }; while (optind < argc) { int arg = getopt_long(argc, argv, "g:fhvp::", long_options, &option_index); if (arg != -1) { switch (static_cast<char>(arg)) { - case 'g': - errno = 0; - gdb_port = strtoul(optarg, &endarg, 0); - use_gdbstub = true; - if (endarg == optarg) - errno = EINVAL; - if (errno != 0) { - perror("--gdbport"); - exit(1); - } - break; case 'f': fullscreen = true; LOG_INFO(Frontend, "Starting in fullscreen mode..."); @@ -168,32 +153,27 @@ int main(int argc, char** argv) { MicroProfileOnThreadCreate("EmuThread"); SCOPE_EXIT({ MicroProfileShutdown(); }); + Common::ConfigureNvidiaEnvironmentFlags(); + if (filepath.empty()) { LOG_CRITICAL(Frontend, "Failed to load ROM: No ROM specified"); return -1; } - // Apply the command line arguments - Settings::values.gdbstub_port = gdb_port; - Settings::values.use_gdbstub = use_gdbstub; - Settings::Apply(); - - Core::System& system{Core::System::GetInstance()}; + auto& system{Core::System::GetInstance()}; InputCommon::InputSubsystem input_subsystem; + // Apply the command line arguments + Settings::Apply(system); + 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>(system, fullscreen, &input_subsystem); + emu_window = std::make_unique<EmuWindow_SDL2_GL>(&input_subsystem, fullscreen); break; case Settings::RendererBackend::Vulkan: -#ifdef HAS_VULKAN - emu_window = std::make_unique<EmuWindow_SDL2_VK>(system, fullscreen, &input_subsystem); + emu_window = std::make_unique<EmuWindow_SDL2_VK>(&input_subsystem); break; -#else - LOG_CRITICAL(Frontend, "Vulkan backend has not been compiled!"); - return 1; -#endif } system.SetContentProvider(std::make_unique<FileSys::ContentProviderUnion>()); @@ -223,7 +203,7 @@ int main(int argc, char** argv) { const u16 loader_id = static_cast<u16>(Core::System::ResultStatus::ErrorLoader); const u16 error_id = static_cast<u16>(load_result) - loader_id; LOG_CRITICAL(Frontend, - "While attempting to load the ROM requested, an error occured. Please " + "While attempting to load the ROM requested, an error occurred. Please " "refer to the yuzu wiki for more information or the yuzu discord for " "additional help.\n\nError Code: {:04X}-{:04X}\nError Description: {}", loader_id, error_id, static_cast<Loader::ResultStatus>(error_id)); @@ -235,16 +215,15 @@ 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().Rasterizer().LoadDiskResources(); + system.Renderer().ReadRasterizer()->LoadDiskResources( + system.CurrentProcess()->GetTitleID(), false, + [](VideoCore::LoadCallbackStage, size_t value, size_t total) {}); - std::thread render_thread([&emu_window] { emu_window->Present(); }); - system.Run(); + void(system.Run()); while (emu_window->IsOpen()) { - std::this_thread::sleep_for(std::chrono::milliseconds(1)); + emu_window->WaitEvent(); } - system.Pause(); - render_thread.join(); - + void(system.Pause()); system.Shutdown(); detached_tasks.WaitForAllTasks(); |
