summaryrefslogtreecommitdiff
path: root/src/yuzu/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/yuzu/main.cpp')
-rw-r--r--src/yuzu/main.cpp285
1 files changed, 247 insertions, 38 deletions
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index 24bfa4d34..5f6cdc0c6 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -79,6 +79,7 @@ static FileSys::VirtualFile VfsDirectoryCreateFileWrapper(const FileSys::Virtual
#ifdef ARCHITECTURE_x86_64
#include "common/x64/cpu_detect.h"
#endif
+#include "common/settings.h"
#include "common/telemetry.h"
#include "core/core.h"
#include "core/crypto/key_manager.h"
@@ -98,9 +99,9 @@ static FileSys::VirtualFile VfsDirectoryCreateFileWrapper(const FileSys::Virtual
#include "core/hle/service/sm/sm.h"
#include "core/loader/loader.h"
#include "core/perf_stats.h"
-#include "core/settings.h"
#include "core/telemetry_session.h"
#include "input_common/main.h"
+#include "util/overlay_dialog.h"
#include "video_core/gpu.h"
#include "video_core/shader_notify.h"
#include "yuzu/about_dialog.h"
@@ -164,19 +165,21 @@ void GMainWindow::ShowTelemetryCallout() {
"<br/><br/>Would you like to share your usage data with us?");
if (QMessageBox::question(this, tr("Telemetry"), telemetry_message) != QMessageBox::Yes) {
Settings::values.enable_telemetry = false;
- Settings::Apply(Core::System::GetInstance());
+ Core::System::GetInstance().ApplySettings();
}
}
const int GMainWindow::max_recent_files_item;
static void InitializeLogging() {
+ using namespace Common;
+
Log::Filter log_filter;
log_filter.ParseFilterString(Settings::values.log_filter);
Log::SetGlobalFilter(log_filter);
- const std::string& log_dir = Common::FS::GetUserPath(Common::FS::UserPath::LogDir);
- Common::FS::CreateFullPath(log_dir);
+ const std::string& log_dir = FS::GetUserPath(FS::UserPath::LogDir);
+ FS::CreateFullPath(log_dir);
Log::AddBackend(std::make_unique<Log::FileBackend>(log_dir + LOG_FILE));
#ifdef _WIN32
Log::AddBackend(std::make_unique<Log::DebuggerBackend>());
@@ -225,6 +228,8 @@ GMainWindow::GMainWindow()
SetDiscordEnabled(UISettings::values.enable_discord_presence);
discord_rpc->Update();
+ RegisterMetaTypes();
+
InitializeWidgets();
InitializeDebugWidgets();
InitializeRecentFileMenuActions();
@@ -320,6 +325,34 @@ GMainWindow::GMainWindow()
continue;
}
+ // Launch game with a specific user
+ if (args[i] == QStringLiteral("-u")) {
+ if (i >= args.size() - 1) {
+ continue;
+ }
+
+ if (args[i + 1].startsWith(QChar::fromLatin1('-'))) {
+ continue;
+ }
+
+ bool argument_ok;
+ const std::size_t selected_user = args[++i].toUInt(&argument_ok);
+
+ if (!argument_ok) {
+ LOG_ERROR(Frontend, "Invalid user argument");
+ continue;
+ }
+
+ const Service::Account::ProfileManager manager;
+ if (!manager.UserExistsIndex(selected_user)) {
+ LOG_ERROR(Frontend, "Selected user doesn't exist");
+ continue;
+ }
+
+ Settings::values.current_user = selected_user;
+ continue;
+ }
+
// Launch game at path
if (args[i] == QStringLiteral("-g")) {
if (i >= args.size() - 1) {
@@ -345,6 +378,55 @@ GMainWindow::~GMainWindow() {
delete render_window;
}
+void GMainWindow::RegisterMetaTypes() {
+ // Register integral and floating point types
+ qRegisterMetaType<u8>("u8");
+ qRegisterMetaType<u16>("u16");
+ qRegisterMetaType<u32>("u32");
+ qRegisterMetaType<u64>("u64");
+ qRegisterMetaType<u128>("u128");
+ qRegisterMetaType<s8>("s8");
+ qRegisterMetaType<s16>("s16");
+ qRegisterMetaType<s32>("s32");
+ qRegisterMetaType<s64>("s64");
+ qRegisterMetaType<f32>("f32");
+ qRegisterMetaType<f64>("f64");
+
+ // Register string types
+ qRegisterMetaType<std::string>("std::string");
+ qRegisterMetaType<std::wstring>("std::wstring");
+ qRegisterMetaType<std::u8string>("std::u8string");
+ qRegisterMetaType<std::u16string>("std::u16string");
+ qRegisterMetaType<std::u32string>("std::u32string");
+ qRegisterMetaType<std::string_view>("std::string_view");
+ qRegisterMetaType<std::wstring_view>("std::wstring_view");
+ qRegisterMetaType<std::u8string_view>("std::u8string_view");
+ qRegisterMetaType<std::u16string_view>("std::u16string_view");
+ qRegisterMetaType<std::u32string_view>("std::u32string_view");
+
+ // Register applet types
+
+ // Controller Applet
+ qRegisterMetaType<Core::Frontend::ControllerParameters>("Core::Frontend::ControllerParameters");
+
+ // Software Keyboard Applet
+ qRegisterMetaType<Core::Frontend::KeyboardInitializeParameters>(
+ "Core::Frontend::KeyboardInitializeParameters");
+ qRegisterMetaType<Core::Frontend::InlineAppearParameters>(
+ "Core::Frontend::InlineAppearParameters");
+ qRegisterMetaType<Core::Frontend::InlineTextParameters>("Core::Frontend::InlineTextParameters");
+ qRegisterMetaType<Service::AM::Applets::SwkbdResult>("Service::AM::Applets::SwkbdResult");
+ qRegisterMetaType<Service::AM::Applets::SwkbdTextCheckResult>(
+ "Service::AM::Applets::SwkbdTextCheckResult");
+ qRegisterMetaType<Service::AM::Applets::SwkbdReplyType>("Service::AM::Applets::SwkbdReplyType");
+
+ // Web Browser Applet
+ qRegisterMetaType<Service::AM::Applets::WebExitReason>("Service::AM::Applets::WebExitReason");
+
+ // Register loader types
+ qRegisterMetaType<Core::System::ResultStatus>("Core::System::ResultStatus");
+}
+
void GMainWindow::ControllerSelectorReconfigureControllers(
const Core::Frontend::ControllerParameters& parameters) {
QtControllerSelectorDialog dialog(this, parameters, input_subsystem.get());
@@ -357,7 +439,7 @@ void GMainWindow::ControllerSelectorReconfigureControllers(
emit ControllerSelectorReconfigureFinished();
// Don't forget to apply settings.
- Settings::Apply(Core::System::GetInstance());
+ Core::System::GetInstance().ApplySettings();
config->Save();
UpdateStatusButtons();
@@ -384,25 +466,112 @@ void GMainWindow::ProfileSelectorSelectProfile() {
emit ProfileSelectorFinishedSelection(uuid);
}
-void GMainWindow::SoftwareKeyboardGetText(
- const Core::Frontend::SoftwareKeyboardParameters& parameters) {
- QtSoftwareKeyboardDialog dialog(this, parameters);
- dialog.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint |
- Qt::WindowTitleHint | Qt::WindowSystemMenuHint |
- Qt::WindowCloseButtonHint);
- dialog.setWindowModality(Qt::WindowModal);
+void GMainWindow::SoftwareKeyboardInitialize(
+ bool is_inline, Core::Frontend::KeyboardInitializeParameters initialize_parameters) {
+ if (software_keyboard) {
+ LOG_ERROR(Frontend, "The software keyboard is already initialized!");
+ return;
+ }
- if (dialog.exec() == QDialog::Rejected) {
- emit SoftwareKeyboardFinishedText(std::nullopt);
+ software_keyboard = new QtSoftwareKeyboardDialog(render_window, Core::System::GetInstance(),
+ is_inline, std::move(initialize_parameters));
+
+ if (is_inline) {
+ connect(
+ software_keyboard, &QtSoftwareKeyboardDialog::SubmitInlineText, this,
+ [this](Service::AM::Applets::SwkbdReplyType reply_type, std::u16string submitted_text,
+ s32 cursor_position) {
+ emit SoftwareKeyboardSubmitInlineText(reply_type, submitted_text, cursor_position);
+ },
+ Qt::QueuedConnection);
+ } else {
+ connect(
+ software_keyboard, &QtSoftwareKeyboardDialog::SubmitNormalText, this,
+ [this](Service::AM::Applets::SwkbdResult result, std::u16string submitted_text) {
+ emit SoftwareKeyboardSubmitNormalText(result, submitted_text);
+ },
+ Qt::QueuedConnection);
+ }
+}
+
+void GMainWindow::SoftwareKeyboardShowNormal() {
+ if (!software_keyboard) {
+ LOG_ERROR(Frontend, "The software keyboard is not initialized!");
+ return;
+ }
+
+ const auto& layout = render_window->GetFramebufferLayout();
+
+ const auto x = layout.screen.left;
+ const auto y = layout.screen.top;
+ const auto w = layout.screen.GetWidth();
+ const auto h = layout.screen.GetHeight();
+
+ software_keyboard->ShowNormalKeyboard(render_window->mapToGlobal(QPoint(x, y)), QSize(w, h));
+}
+
+void GMainWindow::SoftwareKeyboardShowTextCheck(
+ Service::AM::Applets::SwkbdTextCheckResult text_check_result,
+ std::u16string text_check_message) {
+ if (!software_keyboard) {
+ LOG_ERROR(Frontend, "The software keyboard is not initialized!");
return;
}
- emit SoftwareKeyboardFinishedText(dialog.GetText());
+ software_keyboard->ShowTextCheckDialog(text_check_result, text_check_message);
}
-void GMainWindow::SoftwareKeyboardInvokeCheckDialog(std::u16string error_message) {
- QMessageBox::warning(this, tr("Text Check Failed"), QString::fromStdU16String(error_message));
- emit SoftwareKeyboardFinishedCheckDialog();
+void GMainWindow::SoftwareKeyboardShowInline(
+ Core::Frontend::InlineAppearParameters appear_parameters) {
+ if (!software_keyboard) {
+ LOG_ERROR(Frontend, "The software keyboard is not initialized!");
+ return;
+ }
+
+ const auto& layout = render_window->GetFramebufferLayout();
+
+ const auto x =
+ static_cast<int>(layout.screen.left + (0.5f * layout.screen.GetWidth() *
+ ((2.0f * appear_parameters.key_top_translate_x) +
+ (1.0f - appear_parameters.key_top_scale_x))));
+ const auto y =
+ static_cast<int>(layout.screen.top + (layout.screen.GetHeight() *
+ ((2.0f * appear_parameters.key_top_translate_y) +
+ (1.0f - appear_parameters.key_top_scale_y))));
+ const auto w = static_cast<int>(layout.screen.GetWidth() * appear_parameters.key_top_scale_x);
+ const auto h = static_cast<int>(layout.screen.GetHeight() * appear_parameters.key_top_scale_y);
+
+ software_keyboard->ShowInlineKeyboard(std::move(appear_parameters),
+ render_window->mapToGlobal(QPoint(x, y)), QSize(w, h));
+}
+
+void GMainWindow::SoftwareKeyboardHideInline() {
+ if (!software_keyboard) {
+ LOG_ERROR(Frontend, "The software keyboard is not initialized!");
+ return;
+ }
+
+ software_keyboard->HideInlineKeyboard();
+}
+
+void GMainWindow::SoftwareKeyboardInlineTextChanged(
+ Core::Frontend::InlineTextParameters text_parameters) {
+ if (!software_keyboard) {
+ LOG_ERROR(Frontend, "The software keyboard is not initialized!");
+ return;
+ }
+
+ software_keyboard->InlineTextChanged(std::move(text_parameters));
+}
+
+void GMainWindow::SoftwareKeyboardExit() {
+ if (!software_keyboard) {
+ return;
+ }
+
+ software_keyboard->ExitKeyboard();
+
+ software_keyboard = nullptr;
}
void GMainWindow::WebBrowserOpenWebPage(std::string_view main_url, std::string_view additional_args,
@@ -622,7 +791,7 @@ void GMainWindow::InitializeWidgets() {
Settings::values.use_asynchronous_gpu_emulation.SetValue(
!Settings::values.use_asynchronous_gpu_emulation.GetValue());
async_status_button->setChecked(Settings::values.use_asynchronous_gpu_emulation.GetValue());
- Settings::Apply(Core::System::GetInstance());
+ Core::System::GetInstance().ApplySettings();
});
async_status_button->setText(tr("ASYNC"));
async_status_button->setCheckable(true);
@@ -638,7 +807,7 @@ void GMainWindow::InitializeWidgets() {
}
Settings::values.use_multi_core.SetValue(!Settings::values.use_multi_core.GetValue());
multicore_status_button->setChecked(Settings::values.use_multi_core.GetValue());
- Settings::Apply(Core::System::GetInstance());
+ Core::System::GetInstance().ApplySettings();
});
multicore_status_button->setText(tr("MULTICORE"));
multicore_status_button->setCheckable(true);
@@ -669,7 +838,7 @@ void GMainWindow::InitializeWidgets() {
Settings::values.renderer_backend.SetValue(Settings::RendererBackend::OpenGL);
}
- Settings::Apply(Core::System::GetInstance());
+ Core::System::GetInstance().ApplySettings();
});
statusBar()->insertPermanentWidget(0, renderer_status_button);
@@ -948,6 +1117,10 @@ void GMainWindow::ConnectWidgetEvents() {
connect(this, &GMainWindow::EmulationStopping, render_window,
&GRenderWindow::OnEmulationStopping);
+ // Software Keyboard Applet
+ connect(this, &GMainWindow::EmulationStarting, this, &GMainWindow::SoftwareKeyboardExit);
+ connect(this, &GMainWindow::EmulationStopping, this, &GMainWindow::SoftwareKeyboardExit);
+
connect(&status_bar_update_timer, &QTimer::timeout, this, &GMainWindow::UpdateStatusBar);
}
@@ -2157,15 +2330,6 @@ void GMainWindow::OnStartGame() {
emu_thread->SetRunning(true);
- qRegisterMetaType<Core::Frontend::ControllerParameters>("Core::Frontend::ControllerParameters");
- qRegisterMetaType<Core::Frontend::SoftwareKeyboardParameters>(
- "Core::Frontend::SoftwareKeyboardParameters");
- qRegisterMetaType<Core::System::ResultStatus>("Core::System::ResultStatus");
- qRegisterMetaType<std::string>("std::string");
- qRegisterMetaType<std::optional<std::u16string>>("std::optional<std::u16string>");
- qRegisterMetaType<std::string_view>("std::string_view");
- qRegisterMetaType<Service::AM::Applets::WebExitReason>("Service::AM::Applets::WebExitReason");
-
connect(emu_thread.get(), &EmuThread::ErrorThrown, this, &GMainWindow::OnCoreError);
ui.action_Start->setEnabled(false);
@@ -2214,8 +2378,11 @@ void GMainWindow::OnExecuteProgram(std::size_t program_index) {
BootGame(last_filename_booted, program_index);
}
-void GMainWindow::ErrorDisplayDisplayError(QString body) {
- QMessageBox::critical(this, tr("Error Display"), body);
+void GMainWindow::ErrorDisplayDisplayError(QString error_code, QString error_text) {
+ OverlayDialog dialog(render_window, Core::System::GetInstance(), error_code, error_text,
+ QString{}, tr("OK"), Qt::AlignLeft | Qt::AlignVCenter);
+ dialog.exec();
+
emit ErrorDisplayFinished();
}
@@ -2267,24 +2434,66 @@ void GMainWindow::ToggleFullscreen() {
void GMainWindow::ShowFullscreen() {
if (ui.action_Single_Window_Mode->isChecked()) {
UISettings::values.geometry = saveGeometry();
+
ui.menubar->hide();
statusBar()->hide();
- showFullScreen();
+
+ if (Settings::values.fullscreen_mode.GetValue() == 1) {
+ showFullScreen();
+ return;
+ }
+
+ hide();
+ setWindowFlags(windowFlags() | Qt::FramelessWindowHint);
+ const auto screen_geometry = QApplication::desktop()->screenGeometry(this);
+ setGeometry(screen_geometry.x(), screen_geometry.y(), screen_geometry.width(),
+ screen_geometry.height() + 1);
+ raise();
+ showNormal();
} else {
UISettings::values.renderwindow_geometry = render_window->saveGeometry();
- render_window->showFullScreen();
+
+ if (Settings::values.fullscreen_mode.GetValue() == 1) {
+ render_window->showFullScreen();
+ return;
+ }
+
+ render_window->hide();
+ render_window->setWindowFlags(windowFlags() | Qt::FramelessWindowHint);
+ const auto screen_geometry = QApplication::desktop()->screenGeometry(this);
+ render_window->setGeometry(screen_geometry.x(), screen_geometry.y(),
+ screen_geometry.width(), screen_geometry.height() + 1);
+ render_window->raise();
+ render_window->showNormal();
}
}
void GMainWindow::HideFullscreen() {
if (ui.action_Single_Window_Mode->isChecked()) {
+ if (Settings::values.fullscreen_mode.GetValue() == 1) {
+ showNormal();
+ restoreGeometry(UISettings::values.geometry);
+ } else {
+ hide();
+ setWindowFlags(windowFlags() & ~Qt::FramelessWindowHint);
+ restoreGeometry(UISettings::values.geometry);
+ raise();
+ show();
+ }
+
statusBar()->setVisible(ui.action_Show_Status_Bar->isChecked());
ui.menubar->show();
- showNormal();
- restoreGeometry(UISettings::values.geometry);
} else {
- render_window->showNormal();
- render_window->restoreGeometry(UISettings::values.renderwindow_geometry);
+ if (Settings::values.fullscreen_mode.GetValue() == 1) {
+ render_window->showNormal();
+ render_window->restoreGeometry(UISettings::values.renderwindow_geometry);
+ } else {
+ render_window->hide();
+ render_window->setWindowFlags(windowFlags() & ~Qt::FramelessWindowHint);
+ render_window->restoreGeometry(UISettings::values.renderwindow_geometry);
+ render_window->raise();
+ render_window->show();
+ }
}
}