diff options
Diffstat (limited to 'src/yuzu/main.cpp')
-rw-r--r-- | src/yuzu/main.cpp | 151 |
1 files changed, 98 insertions, 53 deletions
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index e4b782fea..31aabb78a 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -47,6 +47,7 @@ #include "core/hle/service/am/applet_ae.h" #include "core/hle/service/am/applet_oe.h" #include "core/hle/service/am/applets/applets.h" +#include "core/hle/service/set/set_sys.h" #include "yuzu/multiplayer/state.h" #include "yuzu/util/controller_navigation.h" @@ -128,6 +129,7 @@ static FileSys::VirtualFile VfsDirectoryCreateFileWrapper(const FileSys::Virtual #include "core/loader/loader.h" #include "core/perf_stats.h" #include "core/telemetry_session.h" +#include "frontend_common/config.h" #include "input_common/drivers/tas_input.h" #include "input_common/drivers/virtual_amiibo.h" #include "input_common/main.h" @@ -140,9 +142,9 @@ static FileSys::VirtualFile VfsDirectoryCreateFileWrapper(const FileSys::Virtual #include "yuzu/bootmanager.h" #include "yuzu/compatdb.h" #include "yuzu/compatibility_list.h" -#include "yuzu/configuration/config.h" #include "yuzu/configuration/configure_dialog.h" #include "yuzu/configuration/configure_input_per_game.h" +#include "yuzu/configuration/qt_config.h" #include "yuzu/debugger/console.h" #include "yuzu/debugger/controller.h" #include "yuzu/debugger/profiler.h" @@ -310,7 +312,7 @@ bool GMainWindow::CheckDarkMode() { #endif // __unix__ } -GMainWindow::GMainWindow(std::unique_ptr<Config> config_, bool has_broken_vulkan) +GMainWindow::GMainWindow(std::unique_ptr<QtConfig> config_, bool has_broken_vulkan) : ui{std::make_unique<Ui::MainWindow>()}, system{std::make_unique<Core::System>()}, input_subsystem{std::make_shared<InputCommon::InputSubsystem>()}, config{std::move(config_)}, vfs{std::make_shared<FileSys::RealVfsFilesystem>()}, @@ -672,7 +674,7 @@ void GMainWindow::ControllerSelectorReconfigureControllers( // Don't forget to apply settings. system->HIDCore().DisableAllControllerConfiguration(); system->ApplySettings(); - config->Save(); + config->SaveAllValues(); UpdateStatusButtons(); @@ -1043,7 +1045,12 @@ void GMainWindow::InitializeWidgets() { statusBar()->addPermanentWidget(label); } - // TODO (flTobi): Add the widget when multiplayer is fully implemented + firmware_label = new QLabel(); + firmware_label->setObjectName(QStringLiteral("FirmwareLabel")); + firmware_label->setVisible(false); + firmware_label->setFocusPolicy(Qt::NoFocus); + statusBar()->addPermanentWidget(firmware_label); + statusBar()->addPermanentWidget(multiplayer_state->GetStatusText(), 0); statusBar()->addPermanentWidget(multiplayer_state->GetStatusIcon(), 0); @@ -1125,7 +1132,7 @@ void GMainWindow::InitializeWidgets() { connect(aa_status_button, &QPushButton::customContextMenuRequested, [this](const QPoint& menu_location) { QMenu context_menu; - for (auto const& aa_text_pair : Config::anti_aliasing_texts_map) { + for (auto const& aa_text_pair : ConfigurationShared::anti_aliasing_texts_map) { context_menu.addAction(aa_text_pair.second, [this, aa_text_pair] { Settings::values.anti_aliasing.SetValue(aa_text_pair.first); UpdateAAText(); @@ -1149,7 +1156,7 @@ void GMainWindow::InitializeWidgets() { connect(filter_status_button, &QPushButton::customContextMenuRequested, [this](const QPoint& menu_location) { QMenu context_menu; - for (auto const& filter_text_pair : Config::scaling_filter_texts_map) { + for (auto const& filter_text_pair : ConfigurationShared::scaling_filter_texts_map) { context_menu.addAction(filter_text_pair.second, [this, filter_text_pair] { Settings::values.scaling_filter.SetValue(filter_text_pair.first); UpdateFilterText(); @@ -1172,7 +1179,7 @@ void GMainWindow::InitializeWidgets() { [this](const QPoint& menu_location) { QMenu context_menu; - for (auto const& pair : Config::use_docked_mode_texts_map) { + for (auto const& pair : ConfigurationShared::use_docked_mode_texts_map) { context_menu.addAction(pair.second, [this, &pair] { if (pair.first != Settings::values.use_docked_mode.GetValue()) { OnToggleDockedMode(); @@ -1196,7 +1203,7 @@ void GMainWindow::InitializeWidgets() { [this](const QPoint& menu_location) { QMenu context_menu; - for (auto const& gpu_accuracy_pair : Config::gpu_accuracy_texts_map) { + for (auto const& gpu_accuracy_pair : ConfigurationShared::gpu_accuracy_texts_map) { if (gpu_accuracy_pair.first == Settings::GpuAccuracy::Extreme) { continue; } @@ -1225,7 +1232,8 @@ void GMainWindow::InitializeWidgets() { [this](const QPoint& menu_location) { QMenu context_menu; - for (auto const& renderer_backend_pair : Config::renderer_backend_texts_map) { + for (auto const& renderer_backend_pair : + ConfigurationShared::renderer_backend_texts_map) { if (renderer_backend_pair.first == Settings::RendererBackend::Null) { continue; } @@ -1290,16 +1298,17 @@ void GMainWindow::InitializeRecentFileMenuActions() { void GMainWindow::LinkActionShortcut(QAction* action, const QString& action_name, const bool tas_allowed) { - static const QString main_window = QStringLiteral("Main Window"); - action->setShortcut(hotkey_registry.GetKeySequence(main_window, action_name)); - action->setShortcutContext(hotkey_registry.GetShortcutContext(main_window, action_name)); + static const auto main_window = std::string("Main Window"); + action->setShortcut(hotkey_registry.GetKeySequence(main_window, action_name.toStdString())); + action->setShortcutContext( + hotkey_registry.GetShortcutContext(main_window, action_name.toStdString())); action->setAutoRepeat(false); this->addAction(action); auto* controller = system->HIDCore().GetEmulatedController(Core::HID::NpadIdType::Player1); const auto* controller_hotkey = - hotkey_registry.GetControllerHotkey(main_window, action_name, controller); + hotkey_registry.GetControllerHotkey(main_window, action_name.toStdString(), controller); connect( controller_hotkey, &ControllerShortcut::Activated, this, [action, tas_allowed, this] { @@ -1331,10 +1340,11 @@ void GMainWindow::InitializeHotkeys() { static const QString main_window = QStringLiteral("Main Window"); const auto connect_shortcut = [&]<typename Fn>(const QString& action_name, const Fn& function) { - const auto* hotkey = hotkey_registry.GetHotkey(main_window, action_name, this); + const auto* hotkey = + hotkey_registry.GetHotkey(main_window.toStdString(), action_name.toStdString(), this); auto* controller = system->HIDCore().GetEmulatedController(Core::HID::NpadIdType::Player1); - const auto* controller_hotkey = - hotkey_registry.GetControllerHotkey(main_window, action_name, controller); + const auto* controller_hotkey = hotkey_registry.GetControllerHotkey( + main_window.toStdString(), action_name.toStdString(), controller); connect(hotkey, &QShortcut::activated, this, function); connect(controller_hotkey, &ControllerShortcut::Activated, this, function, Qt::QueuedConnection); @@ -1906,7 +1916,7 @@ void GMainWindow::BootGame(const QString& filename, u64 program_id, std::size_t // Save configurations UpdateUISettings(); game_list->SaveInterfaceLayout(); - config->Save(); + config->SaveAllValues(); u64 title_id{0}; @@ -1924,7 +1934,7 @@ void GMainWindow::BootGame(const QString& filename, u64 program_id, std::size_t const auto config_file_name = title_id == 0 ? Common::FS::PathToUTF8String(file_path.filename()) : fmt::format("{:016X}", title_id); - Config per_game_config(config_file_name, Config::ConfigType::PerGameConfig); + QtConfig per_game_config(config_file_name, Config::ConfigType::PerGameConfig); system->HIDCore().ReloadInputDevices(); system->ApplySettings(); } @@ -2149,6 +2159,10 @@ void GMainWindow::OnEmulationStopped() { emu_frametime_label->setVisible(false); renderer_status_button->setEnabled(!UISettings::values.has_broken_vulkan); + if (!firmware_label->text().isEmpty()) { + firmware_label->setVisible(true); + } + current_game_path.clear(); // When closing the game, destroy the GLWindow to clear the context after the game is closed @@ -3123,7 +3137,7 @@ void GMainWindow::OnGameListAddDirectory() { return; } - UISettings::GameDir game_dir{dir_path, false, true}; + UISettings::GameDir game_dir{dir_path.toStdString(), false, true}; if (!UISettings::values.game_dirs.contains(game_dir)) { UISettings::values.game_dirs.append(game_dir); game_list->PopulateAsync(UISettings::values.game_dirs); @@ -3169,14 +3183,14 @@ void GMainWindow::OnMenuLoadFile() { "%1 is an identifier for the Switch executable file extensions.") .arg(extensions); const QString filename = QFileDialog::getOpenFileName( - this, tr("Load File"), UISettings::values.roms_path, file_filter); + this, tr("Load File"), QString::fromStdString(UISettings::values.roms_path), file_filter); is_load_file_select_active = false; if (filename.isEmpty()) { return; } - UISettings::values.roms_path = QFileInfo(filename).path(); + UISettings::values.roms_path = QFileInfo(filename).path().toStdString(); BootGame(filename); } @@ -3209,7 +3223,8 @@ void GMainWindow::OnMenuInstallToNAND() { "Image (*.xci)"); QStringList filenames = QFileDialog::getOpenFileNames( - this, tr("Install Files"), UISettings::values.roms_path, file_filter); + this, tr("Install Files"), QString::fromStdString(UISettings::values.roms_path), + file_filter); if (filenames.isEmpty()) { return; @@ -3227,7 +3242,7 @@ void GMainWindow::OnMenuInstallToNAND() { } // Save folder location of the first selected file - UISettings::values.roms_path = QFileInfo(filenames[0]).path(); + UISettings::values.roms_path = QFileInfo(filenames[0]).path().toStdString(); int remaining = filenames.size(); @@ -3572,7 +3587,7 @@ void GMainWindow::OnExit() { void GMainWindow::OnSaveConfig() { system->ApplySettings(); - config->Save(); + config->SaveAllValues(); } void GMainWindow::ErrorDisplayDisplayError(QString error_code, QString error_text) { @@ -3828,7 +3843,7 @@ void GMainWindow::OnConfigure() { Settings::values.disabled_addons.clear(); - config = std::make_unique<Config>(); + config = std::make_unique<QtConfig>(); UISettings::values.reset_to_defaults = false; UISettings::values.game_dirs = std::move(old_game_dirs); @@ -3863,7 +3878,7 @@ void GMainWindow::OnConfigure() { UISettings::values.configuration_applied = false; - config->Save(); + config->SaveAllValues(); if ((UISettings::values.hide_mouse || Settings::values.mouse_panning) && emulation_running) { render_window->installEventFilter(render_window); @@ -4079,7 +4094,7 @@ void GMainWindow::OpenPerGameConfiguration(u64 title_id, const std::string& file UISettings::values.configuration_applied = false; if (!is_powered_on) { - config->Save(); + config->SaveAllValues(); } } @@ -4312,7 +4327,7 @@ void GMainWindow::OnAlbum() { system->GetAppletManager().SetCurrentAppletId(Service::AM::Applets::AppletId::PhotoViewer); const auto filename = QString::fromStdString(album_nca->GetFullPath()); - UISettings::values.roms_path = QFileInfo(filename).path(); + UISettings::values.roms_path = QFileInfo(filename).path().toStdString(); BootGame(filename, AlbumId); } @@ -4336,7 +4351,7 @@ void GMainWindow::OnCabinet(Service::NFP::CabinetMode mode) { system->GetAppletManager().SetCabinetMode(mode); const auto filename = QString::fromStdString(cabinet_nca->GetFullPath()); - UISettings::values.roms_path = QFileInfo(filename).path(); + UISettings::values.roms_path = QFileInfo(filename).path().toStdString(); BootGame(filename, CabinetId); } @@ -4359,7 +4374,7 @@ void GMainWindow::OnMiiEdit() { system->GetAppletManager().SetCurrentAppletId(Service::AM::Applets::AppletId::MiiEdit); const auto filename = QString::fromStdString((mii_applet_nca->GetFullPath())); - UISettings::values.roms_path = QFileInfo(filename).path(); + UISettings::values.roms_path = QFileInfo(filename).path().toStdString(); BootGame(filename, MiiEditId); } @@ -4384,7 +4399,7 @@ void GMainWindow::OnOpenControllerMenu() { system->GetAppletManager().SetCurrentAppletId(Service::AM::Applets::AppletId::Controller); const auto filename = QString::fromStdString((controller_applet_nca->GetFullPath())); - UISettings::values.roms_path = QFileInfo(filename).path(); + UISettings::values.roms_path = QFileInfo(filename).path().toStdString(); BootGame(filename, ControllerAppletId); } @@ -4574,11 +4589,13 @@ void GMainWindow::UpdateStatusBar() { emu_speed_label->setVisible(!Settings::values.use_multi_core.GetValue()); game_fps_label->setVisible(true); emu_frametime_label->setVisible(true); + firmware_label->setVisible(false); } void GMainWindow::UpdateGPUAccuracyButton() { const auto gpu_accuracy = Settings::values.gpu_accuracy.GetValue(); - const auto gpu_accuracy_text = Config::gpu_accuracy_texts_map.find(gpu_accuracy)->second; + const auto gpu_accuracy_text = + ConfigurationShared::gpu_accuracy_texts_map.find(gpu_accuracy)->second; gpu_accuracy_button->setText(gpu_accuracy_text.toUpper()); gpu_accuracy_button->setChecked(gpu_accuracy != Settings::GpuAccuracy::Normal); } @@ -4587,31 +4604,32 @@ void GMainWindow::UpdateDockedButton() { const auto console_mode = Settings::values.use_docked_mode.GetValue(); dock_status_button->setChecked(Settings::IsDockedMode()); dock_status_button->setText( - Config::use_docked_mode_texts_map.find(console_mode)->second.toUpper()); + ConfigurationShared::use_docked_mode_texts_map.find(console_mode)->second.toUpper()); } void GMainWindow::UpdateAPIText() { const auto api = Settings::values.renderer_backend.GetValue(); - const auto renderer_status_text = Config::renderer_backend_texts_map.find(api)->second; + const auto renderer_status_text = + ConfigurationShared::renderer_backend_texts_map.find(api)->second; renderer_status_button->setText( api == Settings::RendererBackend::OpenGL - ? tr("%1 %2").arg( - renderer_status_text.toUpper(), - Config::shader_backend_texts_map.find(Settings::values.shader_backend.GetValue()) - ->second) + ? tr("%1 %2").arg(renderer_status_text.toUpper(), + ConfigurationShared::shader_backend_texts_map + .find(Settings::values.shader_backend.GetValue()) + ->second) : renderer_status_text.toUpper()); } void GMainWindow::UpdateFilterText() { const auto filter = Settings::values.scaling_filter.GetValue(); - const auto filter_text = Config::scaling_filter_texts_map.find(filter)->second; + const auto filter_text = ConfigurationShared::scaling_filter_texts_map.find(filter)->second; filter_status_button->setText(filter == Settings::ScalingFilter::Fsr ? tr("FSR") : filter_text.toUpper()); } void GMainWindow::UpdateAAText() { const auto aa_mode = Settings::values.anti_aliasing.GetValue(); - const auto aa_text = Config::anti_aliasing_texts_map.find(aa_mode)->second; + const auto aa_text = ConfigurationShared::anti_aliasing_texts_map.find(aa_mode)->second; aa_status_button->setText(aa_mode == Settings::AntiAliasing::None ? QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "NO AA")) : aa_text.toUpper()); @@ -4775,6 +4793,8 @@ void GMainWindow::OnReinitializeKeys(ReinitializeKeyBehavior behavior) { "games.")); } + SetFirmwareVersion(); + if (behavior == ReinitializeKeyBehavior::Warning) { game_list->PopulateAsync(UISettings::values.game_dirs); } @@ -4802,7 +4822,7 @@ bool GMainWindow::CheckSystemArchiveDecryption() { } bool GMainWindow::CheckFirmwarePresence() { - constexpr u64 MiiEditId = 0x0100000000001009ull; + constexpr u64 MiiEditId = static_cast<u64>(Service::AM::Applets::AppletProgramId::MiiEdit); auto bis_system = system->GetFileSystemController().GetSystemNANDContents(); if (!bis_system) { @@ -4817,6 +4837,28 @@ bool GMainWindow::CheckFirmwarePresence() { return true; } +void GMainWindow::SetFirmwareVersion() { + Service::Set::FirmwareVersionFormat firmware_data{}; + const auto result = Service::Set::GetFirmwareVersionImpl( + firmware_data, *system, Service::Set::GetFirmwareVersionType::Version2); + + if (result.IsError() || !CheckFirmwarePresence()) { + LOG_INFO(Frontend, "Installed firmware: No firmware available"); + firmware_label->setVisible(false); + return; + } + + firmware_label->setVisible(true); + + const std::string display_version(firmware_data.display_version.data()); + const std::string display_title(firmware_data.display_title.data()); + + LOG_INFO(Frontend, "Installed firmware: {}", display_title); + + firmware_label->setText(QString::fromStdString(display_version)); + firmware_label->setToolTip(QString::fromStdString(display_title)); +} + bool GMainWindow::SelectRomFSDumpTarget(const FileSys::ContentProvider& installed, u64 program_id, u64* selected_title_id, u8* selected_content_record_type) { using ContentInfo = std::tuple<u64, FileSys::TitleType, FileSys::ContentRecordType>; @@ -4898,6 +4940,7 @@ void GMainWindow::closeEvent(QCloseEvent* event) { UpdateUISettings(); game_list->SaveInterfaceLayout(); + UISettings::SaveWindowState(); hotkey_registry.SaveHotkeys(); // Unload controllers early @@ -5036,9 +5079,9 @@ static void AdjustLinkColor() { } void GMainWindow::UpdateUITheme() { - const QString default_theme = - QString::fromUtf8(UISettings::themes[static_cast<size_t>(Config::default_theme)].second); - QString current_theme = UISettings::values.theme; + const QString default_theme = QString::fromUtf8( + UISettings::themes[static_cast<size_t>(UISettings::default_theme)].second); + QString current_theme = QString::fromStdString(UISettings::values.theme); if (current_theme.isEmpty()) { current_theme = default_theme; @@ -5066,7 +5109,7 @@ void GMainWindow::UpdateUITheme() { QFile f(theme_uri); if (!f.open(QFile::ReadOnly | QFile::Text)) { LOG_ERROR(Frontend, "Unable to open style \"{}\", fallback to the default theme", - UISettings::values.theme.toStdString()); + UISettings::values.theme); current_theme = default_theme; } } @@ -5079,7 +5122,7 @@ void GMainWindow::UpdateUITheme() { setStyleSheet(ts.readAll()); } else { LOG_ERROR(Frontend, "Unable to set style \"{}\", stylesheet file not found", - UISettings::values.theme.toStdString()); + UISettings::values.theme); qApp->setStyleSheet({}); setStyleSheet({}); } @@ -5088,27 +5131,28 @@ void GMainWindow::UpdateUITheme() { void GMainWindow::LoadTranslation() { bool loaded; - if (UISettings::values.language.isEmpty()) { + if (UISettings::values.language.empty()) { // If the selected language is empty, use system locale loaded = translator.load(QLocale(), {}, {}, QStringLiteral(":/languages/")); } else { // Otherwise load from the specified file - loaded = translator.load(UISettings::values.language, QStringLiteral(":/languages/")); + loaded = translator.load(QString::fromStdString(UISettings::values.language), + QStringLiteral(":/languages/")); } if (loaded) { qApp->installTranslator(&translator); } else { - UISettings::values.language = QStringLiteral("en"); + UISettings::values.language = std::string("en"); } } void GMainWindow::OnLanguageChanged(const QString& locale) { - if (UISettings::values.language != QStringLiteral("en")) { + if (UISettings::values.language != std::string("en")) { qApp->removeTranslator(&translator); } - UISettings::values.language = locale; + UISettings::values.language = locale.toStdString(); LoadTranslation(); ui->retranslateUi(this); multiplayer_state->retranslateUi(); @@ -5134,7 +5178,7 @@ void GMainWindow::changeEvent(QEvent* event) { // UpdateUITheme is a decent work around if (event->type() == QEvent::PaletteChange) { const QPalette test_palette(qApp->palette()); - const QString current_theme = UISettings::values.theme; + const QString current_theme = QString::fromStdString(UISettings::values.theme); // Keeping eye on QPalette::Window to avoid looping. QPalette::Text might be useful too static QColor last_window_color; const QColor window_color = test_palette.color(QPalette::Active, QPalette::Window); @@ -5228,7 +5272,8 @@ static void SetHighDPIAttributes() { } int main(int argc, char* argv[]) { - std::unique_ptr<Config> config = std::make_unique<Config>(); + std::unique_ptr<QtConfig> config = std::make_unique<QtConfig>(); + UISettings::RestoreWindowState(config); bool has_broken_vulkan = false; bool is_child = false; if (CheckEnvVars(&is_child)) { |