diff options
Diffstat (limited to 'src/yuzu_cmd')
| -rw-r--r-- | src/yuzu_cmd/config.cpp | 13 | ||||
| -rw-r--r-- | src/yuzu_cmd/default_ini.h | 28 | ||||
| -rw-r--r-- | src/yuzu_cmd/emu_window/emu_window_sdl2.cpp | 63 | ||||
| -rw-r--r-- | src/yuzu_cmd/emu_window/emu_window_sdl2.h | 8 | ||||
| -rw-r--r-- | src/yuzu_cmd/yuzu.cpp | 69 | ||||
| -rw-r--r-- | src/yuzu_cmd/yuzu.rc | 2 |
6 files changed, 130 insertions, 53 deletions
diff --git a/src/yuzu_cmd/config.cpp b/src/yuzu_cmd/config.cpp index bf79d2e81..ee6e4d658 100644 --- a/src/yuzu_cmd/config.cpp +++ b/src/yuzu_cmd/config.cpp @@ -27,17 +27,17 @@ bool Config::LoadINI(const std::string& default_contents, bool retry) { const char* location = this->sdl2_config_loc.c_str(); if (sdl2_config->ParseError() < 0) { if (retry) { - LOG_WARNING(Config, "Failed to load %s. Creating file from defaults...", location); + NGLOG_WARNING(Config, "Failed to load {}. Creating file from defaults...", location); FileUtil::CreateFullPath(location); FileUtil::WriteStringToFile(true, default_contents, location); sdl2_config = std::make_unique<INIReader>(location); // Reopen file return LoadINI(default_contents, false); } - LOG_ERROR(Config, "Failed."); + NGLOG_ERROR(Config, "Failed."); return false; } - LOG_INFO(Config, "Successfully loaded %s", location); + NGLOG_INFO(Config, "Successfully loaded {}", location); return true; } @@ -90,8 +90,8 @@ void Config::ReadValues() { sdl2_config->Get("Controls", "touch_device", "engine:emu_window"); // Core - Settings::values.cpu_core = - static_cast<Settings::CpuCore>(sdl2_config->GetInteger("Core", "cpu_core", 0)); + Settings::values.use_cpu_jit = sdl2_config->GetBoolean("Core", "use_cpu_jit", true); + Settings::values.use_multi_core = sdl2_config->GetBoolean("Core", "use_multi_core", false); // Renderer Settings::values.resolution_factor = @@ -107,6 +107,9 @@ void Config::ReadValues() { Settings::values.use_virtual_sd = sdl2_config->GetBoolean("Data Storage", "use_virtual_sd", true); + // System + Settings::values.use_docked_mode = sdl2_config->GetBoolean("System", "use_docked_mode", true); + // Miscellaneous Settings::values.log_filter = sdl2_config->Get("Miscellaneous", "log_filter", "*:Trace"); diff --git a/src/yuzu_cmd/default_ini.h b/src/yuzu_cmd/default_ini.h index 156f7a1a4..1c438c3f5 100644 --- a/src/yuzu_cmd/default_ini.h +++ b/src/yuzu_cmd/default_ini.h @@ -8,7 +8,7 @@ namespace DefaultINI { const char* sdl2_config_file = R"( [Controls] -# The input devices and parameters for each 3DS native input +# The input devices and parameters for each Switch native input # It should be in the format of "engine:[engine_name],[param1]:[value1],[param2]:[value2]..." # Escape characters $0 (for ':'), $1 (for ',') and $2 (for '$') can be used in values @@ -76,9 +76,13 @@ motion_device= touch_device= [Core] -# Which CPU core to use for CPU emulation -# 0 (default): Unicorn (slow), 1: Dynarmic (faster) -cpu_core = +# Whether to use the Just-In-Time (JIT) compiler for CPU emulation +# 0: Interpreter (slow), 1 (default): JIT (fast) +use_cpu_jit = + +# Whether to use multi-core for CPU emulation +# 0 (default): Disabled, 1: Enabled +use_multi_core= [Renderer] # Whether to use software or hardware rendering. @@ -154,9 +158,9 @@ output_device = use_virtual_sd = [System] -# The system model that Citra will try to emulate -# 0: Old 3DS (default), 1: New 3DS -is_new_3ds = +# Whether the system is docked +# 1 (default): Yes, 0: No +use_docked_mode = # The system region that Citra will use during emulation # -1: Auto-select (default), 0: Japan, 1: USA, 2: Europe, 3: Australia, 4: China, 5: Korea, 6: Taiwan @@ -177,12 +181,12 @@ gdbstub_port=24689 # 0: No, 1 (default): Yes enable_telemetry = # Endpoint URL for submitting telemetry data -telemetry_endpoint_url = https://services.citra-emu.org/api/telemetry +telemetry_endpoint_url = # Endpoint URL to verify the username and token -verify_endpoint_url = https://services.citra-emu.org/api/profile -# Username and token for Citra Web Service +verify_endpoint_url = +# Username and token for yuzu Web Service # See https://services.citra-emu.org/ for more info -citra_username = -citra_token = +yuzu_username = +yuzu_token = )"; } diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp index 3d7cd06a4..cfd8eb7e6 100644 --- a/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp +++ b/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp @@ -7,6 +7,7 @@ #include <string> #define SDL_MAIN_HANDLED #include <SDL.h> +#include <fmt/format.h> #include <glad/glad.h> #include "common/logging/log.h" #include "common/scm_rev.h" @@ -56,14 +57,53 @@ void EmuWindow_SDL2::OnResize() { UpdateCurrentFramebufferLayout(width, height); } -EmuWindow_SDL2::EmuWindow_SDL2() { +void EmuWindow_SDL2::Fullscreen() { + if (SDL_SetWindowFullscreen(render_window, SDL_WINDOW_FULLSCREEN) == 0) { + return; + } + + NGLOG_ERROR(Frontend, "Fullscreening failed: {}", SDL_GetError()); + + // Try a different fullscreening method + NGLOG_INFO(Frontend, "Attempting to use borderless fullscreen..."); + if (SDL_SetWindowFullscreen(render_window, SDL_WINDOW_FULLSCREEN_DESKTOP) == 0) { + return; + } + + NGLOG_ERROR(Frontend, "Borderless fullscreening failed: {}", SDL_GetError()); + + // Fallback algorithm: Maximise window. + // Works on all systems (unless something is seriously wrong), so no fallback for this one. + NGLOG_INFO(Frontend, "Falling back on a maximised window..."); + SDL_MaximizeWindow(render_window); +} + +bool EmuWindow_SDL2::SupportsRequiredGLExtensions() { + std::vector<std::string> unsupported_ext; + + if (!GLAD_GL_ARB_program_interface_query) + unsupported_ext.push_back("ARB_program_interface_query"); + if (!GLAD_GL_ARB_separate_shader_objects) + unsupported_ext.push_back("ARB_separate_shader_objects"); + if (!GLAD_GL_ARB_shader_storage_buffer_object) + unsupported_ext.push_back("ARB_shader_storage_buffer_object"); + if (!GLAD_GL_ARB_vertex_attrib_binding) + unsupported_ext.push_back("ARB_vertex_attrib_binding"); + + for (const std::string& ext : unsupported_ext) + NGLOG_CRITICAL(Frontend, "Unsupported GL extension: {}", ext); + + return unsupported_ext.empty(); +} + +EmuWindow_SDL2::EmuWindow_SDL2(bool fullscreen) { InputCommon::Init(); SDL_SetMainReady(); // Initialize the window if (SDL_Init(SDL_INIT_VIDEO) < 0) { - LOG_CRITICAL(Frontend, "Failed to initialize SDL2! Exiting..."); + NGLOG_CRITICAL(Frontend, "Failed to initialize SDL2! Exiting..."); exit(1); } @@ -76,8 +116,8 @@ EmuWindow_SDL2::EmuWindow_SDL2() { SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 0); - std::string window_title = Common::StringFromFormat("yuzu %s| %s-%s ", Common::g_build_name, - Common::g_scm_branch, Common::g_scm_desc); + std::string window_title = fmt::format("yuzu {} | {}-{}", Common::g_build_name, + Common::g_scm_branch, Common::g_scm_desc); render_window = SDL_CreateWindow(window_title.c_str(), SDL_WINDOWPOS_UNDEFINED, // x position @@ -86,19 +126,28 @@ EmuWindow_SDL2::EmuWindow_SDL2() { SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI); if (render_window == nullptr) { - LOG_CRITICAL(Frontend, "Failed to create SDL2 window! Exiting..."); + NGLOG_CRITICAL(Frontend, "Failed to create SDL2 window! Exiting..."); exit(1); } + if (fullscreen) { + Fullscreen(); + } + gl_context = SDL_GL_CreateContext(render_window); if (gl_context == nullptr) { - LOG_CRITICAL(Frontend, "Failed to create SDL2 GL context! Exiting..."); + NGLOG_CRITICAL(Frontend, "Failed to create SDL2 GL context! Exiting..."); exit(1); } if (!gladLoadGLLoader(static_cast<GLADloadproc>(SDL_GL_GetProcAddress))) { - LOG_CRITICAL(Frontend, "Failed to initialize GL functions! Exiting..."); + NGLOG_CRITICAL(Frontend, "Failed to initialize GL functions! Exiting..."); + exit(1); + } + + if (!SupportsRequiredGLExtensions()) { + NGLOG_CRITICAL(Frontend, "GPU does not support all required OpenGL extensions! Exiting..."); exit(1); } diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2.h b/src/yuzu_cmd/emu_window/emu_window_sdl2.h index 3664d2fbe..1d835c3c6 100644 --- a/src/yuzu_cmd/emu_window/emu_window_sdl2.h +++ b/src/yuzu_cmd/emu_window/emu_window_sdl2.h @@ -12,7 +12,7 @@ struct SDL_Window; class EmuWindow_SDL2 : public EmuWindow { public: - EmuWindow_SDL2(); + explicit EmuWindow_SDL2(bool fullscreen); ~EmuWindow_SDL2(); /// Swap buffers to display the next frame @@ -43,6 +43,12 @@ private: /// Called by PollEvents when any event that may cause the window to be resized occurs void OnResize(); + /// Called when user passes the fullscreen parameter flag + void Fullscreen(); + + /// Whether the GPU and driver supports the OpenGL extension required + bool SupportsRequiredGLExtensions(); + /// Called when a configuration change affects the minimal size of the window void OnMinimalClientAreaChangeRequest( const std::pair<unsigned, unsigned>& minimal_size) override; diff --git a/src/yuzu_cmd/yuzu.cpp b/src/yuzu_cmd/yuzu.cpp index 8f7c75796..95e568b7b 100644 --- a/src/yuzu_cmd/yuzu.cpp +++ b/src/yuzu_cmd/yuzu.cpp @@ -7,8 +7,19 @@ #include <string> #include <thread> -// This needs to be included before getopt.h because the latter #defines symbols used by it +#include "common/logging/backend.h" +#include "common/logging/filter.h" +#include "common/logging/log.h" #include "common/microprofile.h" +#include "common/scm_rev.h" +#include "common/scope_exit.h" +#include "common/string_util.h" +#include "core/core.h" +#include "core/gdbstub/gdbstub.h" +#include "core/loader/loader.h" +#include "core/settings.h" +#include "yuzu_cmd/config.h" +#include "yuzu_cmd/emu_window/emu_window_sdl2.h" #ifdef _MSC_VER #include <getopt.h> @@ -24,23 +35,20 @@ #include <shellapi.h> #endif -#include "common/logging/backend.h" -#include "common/logging/filter.h" -#include "common/logging/log.h" -#include "common/scm_rev.h" -#include "common/scope_exit.h" -#include "common/string_util.h" -#include "core/core.h" -#include "core/gdbstub/gdbstub.h" -#include "core/loader/loader.h" -#include "core/settings.h" -#include "yuzu_cmd/config.h" -#include "yuzu_cmd/emu_window/emu_window_sdl2.h" +#ifdef _WIN32 +extern "C" { +// tells Nvidia and AMD drivers to use the dedicated GPU by default on laptops with switchable +// graphics +__declspec(dllexport) unsigned long NvOptimusEnablement = 0x00000001; +__declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1; +} +#endif 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"; } @@ -61,21 +69,24 @@ int main(int argc, char** argv) { auto argv_w = CommandLineToArgvW(GetCommandLineW(), &argc_w); if (argv_w == nullptr) { - LOG_CRITICAL(Frontend, "Failed to get command line arguments"); + NGLOG_CRITICAL(Frontend, "Failed to get command line arguments"); return -1; } #endif std::string filepath; + 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'}, {0, 0, 0, 0}, }; while (optind < argc) { - char arg = getopt_long(argc, argv, "g:hv", long_options, &option_index); + char arg = getopt_long(argc, argv, "g:fhv", long_options, &option_index); if (arg != -1) { switch (arg) { case 'g': @@ -89,6 +100,10 @@ int main(int argc, char** argv) { exit(1); } break; + case 'f': + fullscreen = true; + NGLOG_INFO(Frontend, "Starting in fullscreen mode..."); + break; case 'h': PrintHelp(argv[0]); return 0; @@ -117,7 +132,7 @@ int main(int argc, char** argv) { SCOPE_EXIT({ MicroProfileShutdown(); }); if (filepath.empty()) { - LOG_CRITICAL(Frontend, "Failed to load ROM: No ROM specified"); + NGLOG_CRITICAL(Frontend, "Failed to load ROM: No ROM specified"); return -1; } @@ -128,7 +143,7 @@ int main(int argc, char** argv) { Settings::values.use_gdbstub = use_gdbstub; Settings::Apply(); - std::unique_ptr<EmuWindow_SDL2> emu_window{std::make_unique<EmuWindow_SDL2>()}; + std::unique_ptr<EmuWindow_SDL2> emu_window{std::make_unique<EmuWindow_SDL2>(fullscreen)}; Core::System& system{Core::System::GetInstance()}; @@ -138,28 +153,28 @@ int main(int argc, char** argv) { switch (load_result) { case Core::System::ResultStatus::ErrorGetLoader: - LOG_CRITICAL(Frontend, "Failed to obtain loader for %s!", filepath.c_str()); + NGLOG_CRITICAL(Frontend, "Failed to obtain loader for %s!", filepath.c_str()); return -1; case Core::System::ResultStatus::ErrorLoader: - LOG_CRITICAL(Frontend, "Failed to load ROM!"); + NGLOG_CRITICAL(Frontend, "Failed to load ROM!"); return -1; case Core::System::ResultStatus::ErrorLoader_ErrorEncrypted: - LOG_CRITICAL(Frontend, "The game that you are trying to load must be decrypted before " - "being used with yuzu. \n\n For more information on dumping and " - "decrypting games, please refer to: " - "https://citra-emu.org/wiki/dumping-game-cartridges/"); + NGLOG_CRITICAL(Frontend, "The game that you are trying to load must be decrypted before " + "being used with yuzu. \n\n For more information on dumping and " + "decrypting games, please refer to: " + "https://yuzu-emu.org/wiki/dumping-game-cartridges/"); return -1; case Core::System::ResultStatus::ErrorLoader_ErrorInvalidFormat: - LOG_CRITICAL(Frontend, "Error while loading ROM: The ROM format is not supported."); + NGLOG_CRITICAL(Frontend, "Error while loading ROM: The ROM format is not supported."); return -1; case Core::System::ResultStatus::ErrorNotInitialized: - LOG_CRITICAL(Frontend, "CPUCore not initialized"); + NGLOG_CRITICAL(Frontend, "CPUCore not initialized"); return -1; case Core::System::ResultStatus::ErrorSystemMode: - LOG_CRITICAL(Frontend, "Failed to determine system mode!"); + NGLOG_CRITICAL(Frontend, "Failed to determine system mode!"); return -1; case Core::System::ResultStatus::ErrorVideoCore: - LOG_CRITICAL(Frontend, "VideoCore not initialized"); + NGLOG_CRITICAL(Frontend, "VideoCore not initialized"); return -1; case Core::System::ResultStatus::Success: break; // Expected case diff --git a/src/yuzu_cmd/yuzu.rc b/src/yuzu_cmd/yuzu.rc index 7cb8a14e1..7de8ef3d9 100644 --- a/src/yuzu_cmd/yuzu.rc +++ b/src/yuzu_cmd/yuzu.rc @@ -6,7 +6,7 @@ // Icon with lowest ID value placed first to ensure application icon // remains consistent on all systems. -CITRA_ICON ICON "../../dist/yuzu.ico" +YUZU_ICON ICON "../../dist/yuzu.ico" ///////////////////////////////////////////////////////////////////////////// |
