summaryrefslogtreecommitdiff
path: root/src/yuzu_cmd
diff options
context:
space:
mode:
Diffstat (limited to 'src/yuzu_cmd')
-rw-r--r--src/yuzu_cmd/config.cpp13
-rw-r--r--src/yuzu_cmd/default_ini.h28
-rw-r--r--src/yuzu_cmd/emu_window/emu_window_sdl2.cpp63
-rw-r--r--src/yuzu_cmd/emu_window/emu_window_sdl2.h8
-rw-r--r--src/yuzu_cmd/yuzu.cpp69
-rw-r--r--src/yuzu_cmd/yuzu.rc2
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"
/////////////////////////////////////////////////////////////////////////////